第一次提交

This commit is contained in:
2026-03-13 16:40:08 +08:00
commit 0a49bcfb2d
277 changed files with 61890 additions and 0 deletions

View File

@ -0,0 +1,793 @@
# 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 桌面布局
```text
┌──────────────┬───────────────────────────────────────┬──────────────────────────┐
│ 会话侧栏 │ 主聊天 + 过程泳道 │ 结果侧栏 │
│ Sessions │ │ Results / Artifacts │
│ │ 用户消息 │ 当前运行摘要 │
│ │ assistant 最终总结 │ agent 产物列表 │
│ │ ─────────────────────────────────── │ MCP 产物列表 │
│ │ Agent A 卡片 │ 文件/图片/JSON 预览 │
│ │ Agent B 卡片 │ 错误/告警 │
│ │ MCP github 卡片 │ 最终汇总结论 │
│ │ MCP browser 卡片 │ │
└──────────────┴───────────────────────────────────────┴──────────────────────────┘
```
### 3.2 移动端布局
移动端不要硬保留三栏:
1. 主聊天区保留为默认视图。
2. 过程泳道和结果侧栏改成底部 `Tabs``Drawer`
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`
这里需要新增完整类型层。
建议新增:
```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` 从现在的宽松结构,升级成联合类型:
```ts
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`
```json
{
"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`
```json
{
"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 内部消息。
```json
{
"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`
```json
{
"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`
```json
{
"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`
```json
{
"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`
```json
{
"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 返回结构建议
```json
{
"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`