第一次提交
This commit is contained in:
793
app-instance/frontend/FRONTEND_MULTIAGENT_PROCESS_UI_CHANGE.md
Normal file
793
app-instance/frontend/FRONTEND_MULTIAGENT_PROCESS_UI_CHANGE.md
Normal 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`
|
||||
|
||||
Reference in New Issue
Block a user