Files
beaver_project/app-instance/frontend/FRONTEND_MULTIAGENT_PROCESS_UI_CHANGE.md
2026-03-13 16:40:08 +08:00

22 KiB
Raw Blame History

Frontend Multi-Agent / MCP Process UI Change

1. 目标

前端聊天页要从“单一消息流”升级成“可视化协作工作台”,让用户在一次聊天里同时看到:

  1. 主对话区里的用户问题与最终总结回复。
  2. 每个 sub-agent / A2A agent / MCP server 的独立处理框。
  3. agent 之间的流式进展、状态变化、问答片段。
  4. MCP 工具调用产物,例如文本结果、结构化 JSON、文件、链接、图片。
  5. 一个固定的结果侧栏,用来汇总当前运行中的过程结果与最终产物。
  6. 独立的 Agent 管理页和 MCP 管理页,体验上与现有 skills / plugins 页面一致。

这个需求本质上不是“把聊天页面做复杂一点”,而是要把聊天 UI 的数据模型从 messages[] 升级成 messages[] + process runs[] + artifacts[] + actor registry[]

2. 当前现状

2.1 前端现状

当前前端的核心限制如下:

  • 聊天页集中在 /home/ivan/xuan/steven_project/nanobot-fronted/app/page.tsx
  • 聊天状态只在 /home/ivan/xuan/steven_project/nanobot-fronted/lib/store.ts 里维护:
    • messages
    • isLoading
    • isThinking
    • streamingContent
  • WebSocket 只在 /home/ivan/xuan/steven_project/nanobot-fronted/lib/api.ts 里处理非常薄的一层消息:
    • type=status
    • type=message
  • 类型定义 /home/ivan/xuan/steven_project/nanobot-fronted/types/index.ts 没有“运行事件 / agent 卡片 / artifact / process timeline”概念。
  • 顶部导航 /home/ivan/xuan/steven_project/nanobot-fronted/components/Header.tsx 目前没有 Agents / MCP 页入口。
  • 现有 skills / plugins 页面适合复用作管理页风格参考:
    • /home/ivan/xuan/steven_project/nanobot-fronted/app/skills/page.tsx
    • /home/ivan/xuan/steven_project/nanobot-fronted/app/plugins/page.tsx

2.2 后端现状

后端已经具备部分多 agent 能力,但还不够支撑前端过程可视化:

  • 已有统一 agent 列表接口:GET /api/agents
    • 位置:/home/ivan/xuan/steven_project/nanobot-backend/nanobot/web/server.py
  • 已有 A2A / group delegation 逻辑:
    • /home/ivan/xuan/steven_project/nanobot-backend/nanobot/agent/delegation.py
  • 已有 A2A streaming / resubscribe / cancel
    • /home/ivan/xuan/steven_project/nanobot-backend/nanobot/a2a/client.py
  • 但当前对前端暴露的实时消息仍然只有:
    • status=thinking
    • assistant message
  • DelegationManager 现在对外发布的也只是普通 _progress 文本,例如:
    • [AgentName] ...
  • MCP 目前只有后端连接配置和工具注册,没有独立的 Web 管理接口,也没有结构化 MCP 运行事件。

结论:

前端可以先做布局和状态层改造,但如果想真正展示“每个 agent 的框、每个 MCP 的产物、agent 间问答”,后端必须补一层结构化 process event 协议。只靠现在的纯文本 progress 不够。

3. 推荐的界面形态

桌面端建议改成三栏工作台,而不是继续沿用现在的单栏聊天布局。

3.1 桌面布局

┌──────────────┬───────────────────────────────────────┬──────────────────────────┐
│ 会话侧栏     │ 主聊天 + 过程泳道                    │ 结果侧栏                 │
│ Sessions     │                                       │ Results / Artifacts      │
│              │ 用户消息                              │ 当前运行摘要             │
│              │ assistant 最终总结                    │ agent 产物列表           │
│              │ ───────────────────────────────────   │ MCP 产物列表             │
│              │ Agent A 卡片                          │ 文件/图片/JSON 预览      │
│              │ Agent B 卡片                          │ 错误/告警                │
│              │ MCP github 卡片                       │ 最终汇总结论             │
│              │ MCP browser 卡片                      │                          │
└──────────────┴───────────────────────────────────────┴──────────────────────────┘

3.2 移动端布局

移动端不要硬保留三栏:

  1. 主聊天区保留为默认视图。
  2. 过程泳道和结果侧栏改成底部 TabsDrawer
  3. 正在运行时,顶部显示一个 Process (3) 悬浮入口。

3.3 视觉原则

不要把过程信息混成普通 assistant markdown。

应明确区分三类对象:

  1. Chat Message:用户问题、最终总结。
  2. Process Card:某个 agent 或 MCP 的运行容器。
  3. Artifact:某个步骤产出的结构化结果。

建议:

  • Agent 卡片用清晰的状态边框和标题区。
  • MCP 卡片强调“工具/服务器”属性,避免与 agent 混淆。
  • 结果侧栏始终可见,展示当前选中卡片的详细结果。

4. 目标交互

4.1 单 Agent

用户发出问题后:

  1. 主聊天区出现用户消息。
  2. assistant 进入 thinking
  3. 若命中 spawn / A2A delegation过程泳道新增一个 Agent 卡片。
  4. 卡片内部流式更新:
    • 状态queued / running / waiting / done / error / cancelled
    • 文本片段
    • agent 生成的中间消息
    • 关键参数或结果摘要
  5. 如果 agent 调了 MCP再在该卡片内部挂子步骤或在泳道新增 MCP 卡片。
  6. 右侧结果栏展示:
    • 当前 agent 的最新摘要
    • 产物列表
    • 可预览文件
  7. 所有 agent 结束后,主 assistant 再给一条最终总结回复。

4.2 多 Agent Group

如果是 group delegation

  1. 过程泳道里要同时出现多个 Agent 卡片。
  2. 每个卡片独立流式刷新,不要合并成一条文本。
  3. 结果侧栏支持切换:
    • All
    • Agent A
    • Agent B
    • MCP Outputs
  4. 最终 assistant 总结要包含:
    • 共识
    • 分歧
    • 失败项
    • 最终建议

4.3 Agent 间“一问一答”

如果未来后端能发出 agent-to-agent message event前端直接把这些消息渲染到卡片里的 transcript 区。

建议 UI 表现:

  • 卡片头agent 名称、来源、状态、耗时
  • 卡片体:
    • Transcript
    • Steps
    • Artifacts
  • 卡片尾:最终摘要 / 错误信息

5. 前端改造点

5.1 先不要继续把逻辑堆进 app/page.tsx

当前 /home/ivan/xuan/steven_project/nanobot-fronted/app/page.tsx 已经过大。这个需求如果继续直接堆,会很快失控。

建议拆分。

5.2 建议新增的组件与文件

建议新增目录:

  • components/chat-workbench/ChatWorkbench.tsx
  • components/chat-workbench/ProcessLane.tsx
  • components/chat-workbench/ProcessRunCard.tsx
  • components/chat-workbench/ProcessTranscript.tsx
  • components/chat-workbench/ArtifactSidebar.tsx
  • components/chat-workbench/RunSummaryPanel.tsx
  • components/chat-workbench/AgentBadge.tsx
  • components/chat-workbench/McpBadge.tsx
  • components/chat-workbench/StatusPill.tsx

建议职责:

  • ChatWorkbench.tsx
    • 负责三栏布局组合。
  • ProcessLane.tsx
    • 渲染当前 session 的所有 process run。
  • ProcessRunCard.tsx
    • 渲染单个 agent / MCP 卡片。
  • ProcessTranscript.tsx
    • 渲染步骤流、问答片段、进度文本。
  • ArtifactSidebar.tsx
    • 渲染右侧产物栏。
  • RunSummaryPanel.tsx
    • 展示当前 run 的状态概览和最终摘要。

5.3 对现有文件的插入建议

/home/ivan/xuan/steven_project/nanobot-fronted/app/page.tsx

保留职责:

  • session 列表
  • 输入框
  • 顶层页面组织

减少职责:

  • 不再在这里直接渲染复杂过程 UI
  • 不再在这里直接解析 process 事件

建议修改为:

  1. 左侧会话侧栏基本保留。
  2. 中间改成 <ChatWorkbench />
  3. MessageBubble 可以保留,但只负责普通 user/assistant 消息。
  4. 新增一个 selectedRunId / selectedArtifactId 的页面级状态,或者放进 Zustand store。

/home/ivan/xuan/steven_project/nanobot-fronted/lib/store.ts

这里需要从“聊天 store”升级成“聊天 + 过程 store”。

建议新增状态:

  • processRuns: ProcessRun[]
  • processEvents: ProcessEvent[]
  • artifacts: ProcessArtifact[]
  • selectedRunId: string | null
  • selectedArtifactId: string | null
  • activeRunIds: string[]
  • agentRegistry: UiAgentDescriptor[]
  • mcpRegistry: UiMcpServerDescriptor[]

建议新增 action

  • resetProcessState(sessionId)
  • upsertProcessRun(run)
  • appendProcessEvent(event)
  • appendProcessArtifact(artifact)
  • finishProcessRun(runId, status)
  • cancelProcessRun(runId)
  • setSelectedRunId(runId)
  • setSelectedArtifactId(artifactId)
  • setAgentRegistry(agents)
  • setMcpRegistry(servers)

/home/ivan/xuan/steven_project/nanobot-fronted/types/index.ts

这里需要新增完整类型层。

建议新增:

export type ProcessActorType = 'agent' | 'mcp' | 'system';
export type ProcessRunStatus = 'queued' | 'running' | 'waiting' | 'done' | 'error' | 'cancelled';
export type ProcessEventKind =
  | 'run_started'
  | 'run_progress'
  | 'run_message'
  | 'run_artifact'
  | 'run_status'
  | 'run_finished'
  | 'run_cancelled';

export interface UiAgentDescriptor {
  id: string;
  name: string;
  description: string;
  source: 'workspace' | 'plugin' | 'skill' | 'builtin';
  kind: string;
  protocol: string | null;
  tags: string[];
  aliases: string[];
  support_group: boolean;
  support_streaming: boolean;
}

export interface UiMcpServerDescriptor {
  id: string;
  name: string;
  transport: 'stdio' | 'http';
  url?: string;
  command?: string;
  enabled: boolean;
  tool_count?: number;
  tool_names?: string[];
  status?: 'connected' | 'disconnected' | 'error';
  last_error?: string | null;
}

export interface ProcessRun {
  run_id: string;
  parent_run_id?: string | null;
  session_id: string;
  actor_type: ProcessActorType;
  actor_id: string;
  actor_name: string;
  title: string;
  status: ProcessRunStatus;
  started_at: string;
  finished_at?: string | null;
  summary?: string | null;
  source?: string | null;
}

export interface ProcessEvent {
  event_id: string;
  run_id: string;
  parent_run_id?: string | null;
  kind: ProcessEventKind;
  actor_type: ProcessActorType;
  actor_id: string;
  actor_name: string;
  text?: string;
  status?: ProcessRunStatus;
  message_role?: 'system' | 'user' | 'assistant' | 'tool';
  metadata?: Record<string, unknown>;
  created_at: string;
}

export interface ProcessArtifact {
  artifact_id: string;
  run_id: string;
  actor_type: ProcessActorType;
  actor_id: string;
  title: string;
  artifact_type: 'text' | 'json' | 'file' | 'image' | 'link' | 'markdown';
  content?: string;
  data?: Record<string, unknown> | unknown[];
  file_id?: string;
  url?: string;
  created_at: string;
}

/home/ivan/xuan/steven_project/nanobot-fronted/lib/api.ts

这里要扩展三类能力:

  1. Agent 管理 API
  2. MCP 管理 API
  3. WebSocket process event 订阅

建议新增:

  • listAgents()
  • addAgent()
  • deleteAgent()
  • refreshAgents()
  • listMcpServers()
  • addMcpServer()
  • updateMcpServer()
  • deleteMcpServer()
  • testMcpServer()

同时把 WsMessageHandler 从现在的宽松结构,升级成联合类型:

export type WsEvent =
  | ChatAssistantEvent
  | ChatThinkingEvent
  | ProcessRunStartedEvent
  | ProcessRunUpdatedEvent
  | ProcessArtifactEvent
  | ProcessRunFinishedEvent
  | ProcessRunCancelledEvent;

/home/ivan/xuan/steven_project/nanobot-fronted/components/Header.tsx

导航中建议新增:

  • /agents
  • /mcp

放在 skills / plugins 旁边,不要塞进聊天页内部。

5.4 建议新增页面

  • /home/ivan/xuan/steven_project/nanobot-fronted/app/agents/page.tsx
  • /home/ivan/xuan/steven_project/nanobot-fronted/app/mcp/page.tsx

Agent 页面参考 skills + plugins 的中间态:

  • 列表视图
  • 支持新增、删除、刷新
  • 展示来源workspace / plugin / skill / builtin
  • 展示协议a2a / local
  • 展示标签、别名、streaming/group 支持

MCP 页面建议分两块:

  1. Configured Servers
  2. Discovered Tools

每个 MCP server 展示:

  • 连接方式stdio / http
  • 地址或命令
  • tool 数量
  • 连接状态
  • 最后错误
  • 编辑/删除/测试按钮

6. 聊天页的推荐逻辑链路

这是前端应当遵守的主链路。

6.1 用户发消息

  1. 用户在 app/page.tsx 输入消息。
  2. 立即写入 messages[]
  3. 设置 isLoading=true
  4. 如果 WebSocket 已连接,消息通过 wsManager.sendRaw() 发出去。
  5. 前端等待两类数据:
    • 普通 assistant reply
    • process events

6.2 触发 sub-agent / group / MCP

后端一旦进入 delegation / MCP tool 调用,应向前端发结构化 process event。

前端收到后:

  1. run_started -> 创建卡片。
  2. run_progress -> 更新卡片中的 transcript。
  3. run_artifact -> 写入右侧侧栏。
  4. run_status -> 更新状态 pill。
  5. run_finished -> 收起 loading保留结果。
  6. 最终 assistant message -> 输出总结性回复。

6.3 用户点击某个 Agent / MCP 卡片

  1. 设置 selectedRunId
  2. 右侧 ArtifactSidebar 切换到该 run 的 artifact 列表。
  3. 中间卡片高亮。
  4. 若有 transcript则显示完整流。

6.4 用户取消运行

如果后端暴露 cancel 接口或 WebSocket cancel command

  1. 卡片上显示 Cancel
  2. 用户点击后发送 cancel 请求。
  3. run 状态变为 cancelled
  4. 侧栏保留已有产物,但标记“未完成”。

7. 后端必须补的事件协议

这是这次前端能否做成的关键。

当前后端只发普通文本 _progress,不够。

必须新增结构化 WebSocket 事件。建议统一成 type=process_*

7.1 建议的事件集合

process_run_started

{
  "type": "process_run_started",
  "session_id": "web:default",
  "run_id": "deleg-123",
  "parent_run_id": null,
  "actor_type": "agent",
  "actor_id": "repo-reviewer",
  "actor_name": "Repo Reviewer",
  "source": "workspace",
  "title": "Review auth refactor",
  "status": "running",
  "created_at": "2026-03-06T10:00:00Z"
}

process_run_progress

{
  "type": "process_run_progress",
  "run_id": "deleg-123",
  "actor_type": "agent",
  "actor_id": "repo-reviewer",
  "text": "Scanning auth middleware and session lifecycle",
  "created_at": "2026-03-06T10:00:03Z"
}

process_run_message

用于展示 agent 间问答或 agent 内部消息。

{
  "type": "process_run_message",
  "run_id": "deleg-123",
  "actor_type": "agent",
  "actor_id": "repo-reviewer",
  "message_role": "assistant",
  "text": "I need the gateway config file before deciding.",
  "created_at": "2026-03-06T10:00:04Z"
}

process_run_artifact

{
  "type": "process_run_artifact",
  "run_id": "mcp-456",
  "actor_type": "mcp",
  "actor_id": "github",
  "title": "Pull Request Diff Summary",
  "artifact_type": "markdown",
  "content": "...",
  "created_at": "2026-03-06T10:00:08Z"
}

process_run_status

{
  "type": "process_run_status",
  "run_id": "deleg-123",
  "status": "waiting",
  "text": "Waiting for remote agent task completion",
  "created_at": "2026-03-06T10:00:10Z"
}

process_run_finished

{
  "type": "process_run_finished",
  "run_id": "deleg-123",
  "status": "done",
  "summary": "Found 2 risks in auth token refresh flow.",
  "created_at": "2026-03-06T10:00:20Z"
}

process_run_cancelled

{
  "type": "process_run_cancelled",
  "run_id": "deleg-123",
  "status": "cancelled",
  "created_at": "2026-03-06T10:00:12Z"
}

7.2 后端推荐插入点

如果你后面让我直接改前后端,我会从这些点切:

/home/ivan/xuan/steven_project/nanobot-backend/nanobot/agent/delegation.py

这里最适合发 agent 级 process event

  • dispatch() 开始时发 process_run_started
  • _build_progress_callback() 中把 A2A stream 文本转成 process_run_progress
  • _run_group() 中每个 descriptor 启动时发独立子 run
  • _announce_single_result() 之前发 process_run_finished
  • _announce_group_result() 之前发 group summary run finished
  • cancel() / _announce_cancelled()process_run_cancelled

/home/ivan/xuan/steven_project/nanobot-backend/nanobot/a2a/client.py

这里最适合补更细的远端 agent 消息:

  • _consume_stream_method()
  • _resume_subscription()

如果远端流里有 message chunk / state / artifact就在这里归一化后向上抛给 DelegationManager

/home/ivan/xuan/steven_project/nanobot-backend/nanobot/agent/tools/mcp.py

这里最适合发 MCP 级事件:

  • MCP 工具调用开始 -> process_run_started (actor_type=mcp)
  • 工具标准输出 / 中间结果 -> process_run_progress
  • 工具返回文本 / JSON / 文件 -> process_run_artifact
  • 工具调用完成 -> process_run_finished
  • 超时 / 失败 -> process_run_status + process_run_finished(status=error)

/home/ivan/xuan/steven_project/nanobot-backend/nanobot/web/server.py

这里需要扩展 WebSocket 发送协议,而不是只发 thinking/message

8. Agent 管理页方案

8.1 页面目标

让用户能像管理 skills 一样管理委派目标 agent。

8.2 数据来源

直接用现有接口:

  • GET /api/agents
  • POST /api/agents
  • DELETE /api/agents/{id}
  • POST /api/agents/refresh

8.3 页面布局建议

参考 plugins 页的卡片布局,但要比 plugins 更偏“资源管理”。

建议字段:

  • 名称
  • id
  • description
  • source
  • protocol
  • tags
  • aliases
  • support_group
  • support_streaming
  • endpoint / base_url / card_url

建议交互:

  1. 顶部 Refresh
  2. 顶部 Add Agent
  3. 列表卡片
  4. workspace agent 允许删除
  5. plugin / skill / builtin agent 只读

8.4 Add Agent 弹窗字段

  • id
  • name
  • description
  • protocol,先只放 a2a
  • base_url
  • endpoint
  • card_url
  • auth_env
  • tags
  • aliases
  • enabled

9. MCP 管理页方案

9.1 结论先说

这个页面前端不能单独完成,因为当前后端没有 MCP 管理 API。

所以文档给的是“前端页面方案 + 后端配套接口定义”。

9.2 后端建议增加的 API

建议新增:

  • GET /api/mcp/servers
  • POST /api/mcp/servers
  • PUT /api/mcp/servers/{id}
  • DELETE /api/mcp/servers/{id}
  • POST /api/mcp/servers/{id}/test
  • GET /api/mcp/tools

9.3 MCP server 返回结构建议

{
  "id": "github",
  "name": "github",
  "transport": "http",
  "url": "http://localhost:3001/mcp",
  "command": "",
  "args": [],
  "enabled": true,
  "tool_timeout": 30,
  "headers": {},
  "status": "connected",
  "tool_count": 12,
  "tool_names": ["search_repos", "list_prs"],
  "last_error": null
}

9.4 页面布局建议

上半区MCP servers

  • 卡片或表格
  • 编辑 / 删除 / 测试连接

下半区Discovered tools

  • 按 server 分组
  • 展示工具名、说明、schema 摘要

10. 建议的前端实现顺序

按这个顺序做最稳。

Phase 1: 先做前端数据结构重构

  1. types/index.ts
  2. lib/store.ts
  3. lib/api.ts 的 ws event 类型
  4. app/page.tsx 拆出 ChatWorkbench

这一步即使后端结构化事件还没补,也可以先用 mock data 跑布局。

Phase 2: 落三栏工作台 UI

  1. 中间主聊天区保留现有 message bubble
  2. ProcessLane
  3. ArtifactSidebar
  4. 支持选中某个 run

Phase 3: 接后端 process events

  1. wsManager.onMessage() 加 process 事件分发
  2. store 按 event 更新 process state
  3. 卡片流式刷新

Phase 4: 新增 Agent 管理页

  1. app/agents/page.tsx
  2. lib/api.ts 增 Agent API
  3. Header.tsx 增导航

Phase 5: 新增 MCP 管理页

  1. 后端先补接口
  2. 前端 app/mcp/page.tsx
  3. 管理 + 测试连接 + 工具查看

11. 为什么我建议最好由同一个 Codex 连前后端一起改

如果只是做视觉壳子,另一个 Codex 在前端仓库里单独改也可以。

但如果目标是你描述的完整体验:

  • 每个 agent / MCP 弹出独立框
  • 展示过程中的一问一答
  • 展示 MCP 产物
  • 最后再统一总结

那就不是纯前端问题,而是“后端事件模型 + 前端状态模型”联动问题。

结论:

  • 只写前端:可以先做静态布局和 store 重构。
  • 真正做成:最好同一个人连续改 backend + frontend避免事件协议和 UI 状态设计脱节。

12. 给另一个 Codex 的明确施工指令

如果你把这份文档交给另一个 Codex建议直接给它下面这段要求

  1. 先阅读:
    • /home/ivan/xuan/steven_project/nanobot-fronted/app/page.tsx
    • /home/ivan/xuan/steven_project/nanobot-fronted/lib/store.ts
    • /home/ivan/xuan/steven_project/nanobot-fronted/lib/api.ts
    • /home/ivan/xuan/steven_project/nanobot-fronted/types/index.ts
    • /home/ivan/xuan/steven_project/nanobot-fronted/app/plugins/page.tsx
    • /home/ivan/xuan/steven_project/nanobot-fronted/app/skills/page.tsx
  2. 先把聊天页拆成三栏工作台,不要继续把复杂逻辑堆在 app/page.tsx
  3. 先做 processRuns / processEvents / artifacts 的前端数据模型。
  4. 先接 /api/agents 做 Agent 管理页。
  5. MCP 管理页先按文档搭 UI 壳子,但要显式标记“依赖后端 MCP API”。
  6. 如果要做真实过程可视化,不要拿普通 markdown 消息硬解析,必须等结构化 WebSocket process events。

13. 最小可交付版本

如果要先做一个能看的版本,建议这样收敛:

  1. 聊天页先做三栏布局。
  2. 用当前 _progress 文本先临时映射成 Agent 卡片日志。
  3. 先接 /api/agents 做管理页。
  4. MCP 页先做只读占位页,提示“等待后端 MCP API”。
  5. 第二轮再补真正结构化 process events。

这条路径的好处是:

  • UI 先起来
  • 后端协议第二轮再精修
  • 不会一开始就卡死在全链路联调上

14. 推荐文档结论

最合适的落地方式是:

  1. 前端先重构成“聊天消息”和“过程运行”两套状态。
  2. 聊天页改成三栏工作台。
  3. 先接现有 /api/agents 做 Agent 管理页。
  4. MCP 管理页需要后端先补接口。
  5. 真正的过程可视化必须补结构化 WebSocket process events核心后端插入点是
    • nanobot/agent/delegation.py
    • nanobot/a2a/client.py
    • nanobot/agent/tools/mcp.py
    • nanobot/web/server.py