197 lines
6.5 KiB
Markdown
197 lines
6.5 KiB
Markdown
# Phase 003 — 砍 I 组(编程代理)+ J 组(ekko-agent)
|
||
|
||
| 项 | 值 |
|
||
|---|---|
|
||
| 目标 | 删除 Claude Code / Codex 编程代理与自有 Agent,聊天链路只走 Hermes 桥 |
|
||
| 前置 | Phase 002 通过 |
|
||
| 产出 | 三条聊天链路(普通聊天 / 全局 Agent / 群聊)功能对等 |
|
||
| 参考 | `docs/03-施工蓝图.md` §5 |
|
||
|
||
---
|
||
|
||
## 0. 为什么可以安全砍(已核实)
|
||
|
||
`run-chat/index.ts` 的 dispatch 结构:
|
||
|
||
```
|
||
ensureBridgeReadyForChatRun()
|
||
→ handleBridgeRun() ← 主路径,最先执行且 return
|
||
→ if (isEkkoAgentExecution(data)) handleEkkoAgentRun() ← J 组
|
||
→ handleCodingAgentRun() ← I 组兜底
|
||
```
|
||
|
||
- bridge 分支在最前且有 `return`,删掉后面两条不影响它
|
||
- 全局 Agent 走 `global-agent/server.ts` → `getChatRunServer().runAndWait()`,砍 I/J 后自动只走桥
|
||
- 群聊走 `group-chat/agent-clients.ts` 的 `AgentBridgeClient` 直连,与 I/J 无关
|
||
|
||
---
|
||
|
||
## 1. 功能任务 1 — 删文件
|
||
|
||
### 1.1 I 组
|
||
|
||
```bash
|
||
rm -rf packages/client/src/views/hermes/CodingAgentsView.vue
|
||
rm -f packages/client/src/api/coding-agents.ts
|
||
rm -f packages/server/src/routes/coding-agents.ts
|
||
rm -f packages/server/src/routes/claude-code-proxy.ts
|
||
rm -f packages/server/src/routes/codex-proxy.ts
|
||
rm -f packages/server/src/controllers/coding-agents.ts
|
||
rm -f packages/server/src/services/coding-agents.ts
|
||
rm -rf packages/server/src/services/agent-runner/ # 含 stream-tee 网关 + adapters
|
||
```
|
||
|
||
### 1.2 J 组
|
||
|
||
```bash
|
||
rm -rf packages/server/src/services/ekko-agent/
|
||
rm -f packages/server/src/services/hermes/run-chat/handle-ekko-agent-run.ts
|
||
```
|
||
|
||
### 1.3 相关测试
|
||
|
||
```bash
|
||
rm -f tests/server/coding-agents-*.test.ts
|
||
rm -f tests/server/coding-agent-run-manager-windows.test.ts
|
||
rm -f tests/server/agent-runner-gateway.test.ts
|
||
rm -f tests/server/handle-coding-agent-run.test.ts
|
||
rm -f tests/client/coding-agent-api-modes.test.ts
|
||
```
|
||
|
||
> 先 `ls tests/server/ | grep -i "coding\|agent-runner\|ekko"` 拿到实际清单再删,别只按上面猜。
|
||
|
||
---
|
||
|
||
## 2. 功能任务 2 — server 路由层
|
||
|
||
`packages/server/src/routes/index.ts`:
|
||
|
||
1. 删 `codingAgentRoutes` / `claudeCodeProxyRoutes` / `codexProxyRoutes` 的 import
|
||
2. 删对应的 `app.use(...)`(在原文件 L64/65/79 附近)
|
||
3. **保持 L78 那条注释的约束**:本地 API 路由必须注册在 proxy 兜底路由之前
|
||
|
||
`packages/server/src/controllers/hermes/sessions.ts`:删代理相关字段。
|
||
|
||
---
|
||
|
||
## 3. 功能任务 3 — run-chat dispatch 简化(**核心**)
|
||
|
||
`packages/server/src/services/hermes/run-chat/index.ts`:
|
||
|
||
### 3.1 删 import
|
||
|
||
```
|
||
handle-coding-agent-run
|
||
handle-ekko-agent-run
|
||
```
|
||
|
||
### 3.2 删两个判定函数
|
||
|
||
```
|
||
isCodingAgentExecution()
|
||
isEkkoAgentExecution()
|
||
```
|
||
|
||
### 3.3 删 dispatch 分支
|
||
|
||
`handleBridgeRun()` 之后直接结束,删掉 `isEkkoAgentExecution` / `handleCodingAgentRun` 两条。
|
||
|
||
### 3.4 修 `isWorking` 判定(三处,**最容易漏**)
|
||
|
||
`isCodingAgentExecution` 同时被用于工作状态判定:
|
||
|
||
| 原行 | 原逻辑 | 改后 |
|
||
|---|---|---|
|
||
| L289 | `state.isWorking = !isCodingAgentExecution(source, data)` | `state.isWorking = true` |
|
||
| L423 | `if (!isCodingAgentExecution(source, data)) { ... }` | 去掉条件,保留花括号内逻辑 |
|
||
| L707 | `state.isWorking = !isCodingAgentExecution(source, data)` | `state.isWorking = true` |
|
||
|
||
**不要留空壳函数**。行号以本项目 `run-chat/index.ts` 实际为准,用 `grep -n isCodingAgentExecution` 定位。
|
||
|
||
### 3.5 同目录其他文件
|
||
|
||
| 文件 | 改动 |
|
||
|---|---|
|
||
| `run-chat/types.ts` | 删 `ChatCodingAgentId` 类型及其引用 |
|
||
| `run-chat/session-command.ts` | 删代理分支 |
|
||
| `run-chat/load-state.ts` | 删代理分支 |
|
||
| `run-chat/abort.ts` | 删代理分支 |
|
||
|
||
---
|
||
|
||
## 4. 功能任务 4 — client 导航与视图
|
||
|
||
| 文件 | 改动 |
|
||
|---|---|
|
||
| `router/index.ts` | 删 `name: 'hermes.codingAgents'` 路由块 |
|
||
| `components/layout/AppSidebar.vue` | 删编程代理导航项 |
|
||
| `components/hermes/chat/SessionListItem.vue` | 删代理类型图标分支 |
|
||
| `components/hermes/chat/ChatInput.vue` | 删代理选择 UI |
|
||
| `components/hermes/chat/ChatPanel.vue` | 删代理相关分支 |
|
||
| `components/hermes/chat/MessageList.vue` | 删代理消息渲染分支 |
|
||
| `components/hermes/chat/HistoryMessageList.vue` | 删代理消息渲染分支 |
|
||
| `components/hermes/usage/AgentBreakdown.vue` | 删 ekko / coding agent 分组 |
|
||
| `stores/hermes/chat.ts` | 删代理选择器 state 与 setter |
|
||
| `shared/session-display.ts` | 删代理类型标签 |
|
||
|
||
---
|
||
|
||
## 5. 功能任务 5 — 工作流与用量
|
||
|
||
| 文件 | 改动 |
|
||
|---|---|
|
||
| `components/hermes/workflow/types.ts` | 删 `coding_agent_id` |
|
||
| `components/hermes/workflow/WorkflowAgentNode.vue` | 删 agent 类型选择 |
|
||
| `views/hermes/WorkflowView.vue` | 删对应 UI |
|
||
| `views/hermes/HistoryView.vue` | 删对应列 |
|
||
| `services/hermes/workflow-manager.ts` | 删 `coding_agent_id` 持久化 |
|
||
| `services/usage-recorder.ts` | 删 ekko / coding agent 用量归类 |
|
||
|
||
**历史数据兼容**:旧会话里可能存有 `coding_agent_id`。读侧改成「读到就忽略」,**不做数据迁移**。
|
||
|
||
---
|
||
|
||
## 6. 验收
|
||
|
||
### 6.1 命令
|
||
|
||
```bash
|
||
cd /Users/jack/source/MyProject/js/hermes-ui
|
||
|
||
# 残留检查(harness 机械门禁,RETIRED_RUNTIME_ALLOWED 登记保留理由)
|
||
npm run harness:check
|
||
# 期望:Harness check passed
|
||
|
||
npm run build
|
||
npm run test
|
||
npm run test:e2e
|
||
```
|
||
|
||
### 6.2 手工(**三条链路必须逐条走**)
|
||
|
||
- [ ] 普通聊天:发消息 → 流式输出 → 完成
|
||
- [ ] 全局 Agent:跑一条 → 走桥正常
|
||
- [ ] 群聊:多 agent 房间发消息 → 路由正常
|
||
- [ ] 会话列表不再出现代理类型图标
|
||
- [ ] 用量页 AgentBreakdown 不再显示 ekko / coding 分组
|
||
- [ ] 工作流页不再能选编程代理
|
||
- [ ] 侧边栏无编程代理入口
|
||
|
||
---
|
||
|
||
## 7. 风险
|
||
|
||
| # | 风险 | 缓解 |
|
||
|---|---|---|
|
||
| P3-1 | `isWorking` 三处漏改 → 聊天状态卡死或一直转圈 | `npm run harness:check` 的 RETIRED_RUNTIME 扫描必须零命中 |
|
||
| P3-2 | 历史会话带 `coding_agent_id` 导致渲染报错 | 读侧容忍未知字段;手工造一条旧会话验证 |
|
||
| P3-3 | 删 `agent-runner/` 时误删共用工具 | 先 `grep -rn "agent-runner"` 确认引用方只在这两组内 |
|
||
| P3-4 | e2e 有用例依赖 coding-agents API | `npm run test:e2e` 必跑,红了删对应用例 |
|
||
| P3-5 | `AgentBreakdown` 删分组后百分比除零 | 该组件有空态处理,确认无 `NaN%` |
|
||
|
||
---
|
||
|
||
## 8. 完成标志
|
||
|
||
进入 Phase 004(砍桌面端 + 官网)。
|