---
date: "2026-06-12"
status: active
origin: docs/brainstorms/2026-06-12-frontend-productization-requirements.md
type: feat
---

## Summary

对 Fischer AgentKit 前端三个核心界面（可视化编排器、监控数据看板、知识库管理）进行产品级重建，补齐后端 API 缺口（终端、设置、工作流执行历史、KB 文档管理），引入 ECharts 图表库，抽取前端 API 公共基类，实现 Ant Design Vue 和 ECharts 按需引入，使整体达到面向外部用户交付的产品化标准。

## Problem Frame

AgentKit 后端能力丰富但前端停留在 70% 完成度的内部工具水平。可视化编排器拖拽放置未完成、并行节点缺失；进化仪表盘用原生 SVG 画折线图无交互无实时推送；知识库上传数据回填有 bug、文档管理不完整。后端存在多个 API 缺口（终端、设置、执行历史、KB 文档管理），前端重建依赖这些 API 补齐。产品化交付需要前后端协同推进，三个模块并行达到可交付水平。

---

## Requirements Traceability

| R-ID | 需求摘要 | 覆盖单元 |
|------|----------|----------|
| R1 | 拖拽放置功能完整可用 | U1 |
| R2 | 并行节点自定义组件 | U1 |
| R3 | 条件分支可视化引导 | U1 |
| R4 | 撤销/重做支持 | U2 |
| R5 | 工作流执行动画 | U3 |
| R6 | 工作流执行历史列表 | U4 |
| R7 | ECharts 替换原生 SVG | U5 |
| R8 | 进化仪表盘实时推送 | U6 |
| R9 | 经验时间线筛选修复 | U5 |
| R10 | 全局概览页 | U7 |
| R11 | 用量统计面板 | U7 |
| R12 | 文档上传数据回填修复 | U8 |
| R13 | 文档列表与删除 | U9 |
| R14 | 信息源同步触发 | U9 |
| R15 | 信息源配置更新 | U9 |
| R16 | 检索高级选项 | U9 |
| R17 | 终端 API 实现 | U10 |
| R18 | 设置 API 实现 | U11 |
| R19 | 工作流 Skill 真实执行 | U4 |
| R20 | 前端 API 公共基类 | U12 |
| R21 | Ant Design Vue 按需引入 | U12 |
| R22 | ECharts 按需引入 | U12 |

---

## Key Technical Decisions

**KTD1. 终端 API 安全策略：白名单 + 用户确认 + 可加入白名单。** 复用 `ShellTool` 的 `_SAFE_COMMAND_PREFIXES` 和 `_is_dangerous()` 检测逻辑。白名单内命令直接执行；非白名单命令通过 WebSocket 推送确认请求，用户确认后执行，确认时可选择将命令加入白名单。白名单存储在服务端内存中（与 ShellTool 一致），不持久化到配置文件。

**KTD2. 工作流执行引擎改造：Skill 阶段接入 SkillRegistry。** 在 `_execute_workflow` 的 skill 类型分支中，通过 `app.state.skill_registry` 查找并执行对应 Skill，将结果写入 `stage_results`。Parallel 阶段使用 `asyncio.gather()` 并行执行子阶段。Condition 阶段增加分支跳过逻辑（不满足条件的下游阶段标记为 skipped）。

**KTD3. ECharts 按需引入策略。** 使用 ECharts 5.x 的 tree-shakable API（`echarts/use` + 手动注册所需图表类型和组件），配合 Vite 的自然 tree-shaking。不引入全量 `echarts` 包。需引入：LineChart、BarChart、PieChart、TooltipComponent、LegendComponent、GridComponent、DataZoomComponent。

**KTD4. 前端 API 层统一：class 风格基类。** 将 6 个 API 文件统一为 class 风格（与现有 `ApiClient`、`WorkflowApiClient`、`EvolutionApiClient` 一致），提取公共 `request<T>()` 方法到 `BaseApiClient`，各模块继承并指定 `baseUrl`。WebSocket 创建逻辑也统一到基类。

**KTD5. 撤销/重做实现：命令模式 + 栈。** 使用命令模式（Command Pattern）封装画布编辑操作（AddNode、DeleteNode、AddEdge、DeleteEdge、UpdateProperty），维护 undo/redo 两个栈。每次操作执行时压入 undo 栈并清空 redo 栈，撤销时从 undo 弹出执行 inverse 并压入 redo，重做反之。

**KTD6. 进化仪表盘 WebSocket 推送激活。** 在 `evolution_dashboard.py` 的 REST 端点中，写操作完成后调用 `_broadcast_event()`。前端在 `EvolutionView` 挂载时建立 WebSocket 连接，按频道订阅（experiences/metrics/pitfalls/optimizations），收到推送后调用对应 store 方法刷新数据。

---

## High-Level Technical Design

```mermaid
flowchart TB
    subgraph Frontend["前端 (Vue 3 + TypeScript)"]
        WF[工作流编排器] --> WFStore[WorkflowStore]
        EV[进化仪表盘] --> EVStore[EvolutionStore]
        KB[知识库管理] --> KBStore[KnowledgeStore]
        TM[终端] --> TMStore[TerminalStore]
        ST[设置] --> STStore[SettingsStore]

        WFStore --> API[BaseApiClient]
        EVStore --> API
        KBStore --> API
        TMStore --> API
        STStore --> API

        API --> HTTP[REST API]
        API --> WS[WebSocket]
    end

    subgraph Backend["后端 (FastAPI)"]
        HTTP --> WFRoutes[Workflow Routes]
        HTTP --> EVDRoutes[Evolution Dashboard Routes]
        HTTP --> KBRoutes[KB Management Routes]
        HTTP --> TMRoutes[Terminal Routes]
        HTTP --> STRoutes[Settings Routes]

        WS --> WFWS[Workflow WS]
        WS --> EVWS[Evolution WS]
        WS --> TMWS[Terminal WS]

        WFRoutes --> WFEngine[Workflow Execution Engine]
        TMRoutes --> PTY[PTYSession]
        TMRoutes --> Security[ShellTool 白名单]
        STRoutes --> Config[Config Hot Reload]
        WFEngine --> SkillReg[SkillRegistry]
    end
```

---

## Implementation Units

### U1. 工作流编排器核心修复

**Goal:** 修复拖拽放置、添加并行节点组件、实现条件分支可视化引导，使编排器基本可用

**Requirements:** R1, R2, R3

**Dependencies:** 无

**Files:**
- `src/agentkit/server/frontend/src/components/workflow/FlowCanvas.vue` -- 修复 onDrop，添加节点到画布
- `src/agentkit/server/frontend/src/components/workflow/NodePalette.vue` -- 无需修改（拖拽发起端已正常）
- `src/agentkit/server/frontend/src/components/workflow/ParallelNode.vue` -- 新建并行节点自定义组件
- `src/agentkit/server/frontend/src/components/workflow/ConditionNode.vue` -- 修改条件节点，添加"是/否"端口标签
- `src/agentkit/server/frontend/src/stores/workflow.ts` -- addNode 支持 parallel 类型，条件分支端口映射
- `src/agentkit/server/frontend/src/views/WorkflowView.vue` -- 注册 parallel 节点类型，监听 drop 事件

**Approach:**
1. 修复 FlowCanvas.vue 的 `onDrop`：调用 `store.addNode(nodeType, position)` 将节点添加到画布，位置对齐 15px 网格
2. 新建 ParallelNode.vue：绿色主题自定义组件，显示并行图标和最大并行数，包含输入端口和输出端口
3. 在 FlowCanvas.vue 的 `nodeTypes` 中注册 `parallel: ParallelNode`
4. 修改 ConditionNode.vue：两个输出端口分别标注"是"和"否"标签，使用 Handle 组件的 `id` 和 `position` 属性区分
5. 修改 workflowSerializer.ts：序列化时将条件节点的边映射到 `branch_targets`（true/false），反序列化时还原

**Patterns to follow:** 现有 SkillNode.vue、ConditionNode.vue、ApprovalNode.vue 的组件结构

**Test scenarios:**
- 拖拽技能节点到画布，节点出现在正确位置且对齐网格
- 拖拽并行节点到画布，渲染为绿色自定义组件
- 拖拽条件节点到画布，"是/否"端口标签可见
- 从条件节点"是"端口连线到目标节点，序列化后 branch_targets 包含 true 分支
- 拖拽到画布外区域，节点不被创建
- 连续拖拽 3 个不同类型节点，位置均正确

**Verification:** 前端 dev server 启动后，在工作流页面可拖拽创建所有 4 种节点，条件节点端口标注正确，序列化/反序列化后属性不丢失

---

### U2. 工作流撤销/重做

**Goal:** 实现画布编辑操作的撤销/重做功能

**Requirements:** R4

**Dependencies:** U1

**Files:**
- `src/agentkit/server/frontend/src/stores/workflow.ts` -- 添加 undo/redo 栈和命令执行逻辑
- `src/agentkit/server/frontend/src/components/workflow/FlowCanvas.vue` -- 注册 Ctrl+Z / Ctrl+Shift+Z 快捷键
- `src/agentkit/server/frontend/src/components/workflow/PropertyPanel.vue` -- 属性修改操作入栈

**Approach:**
1. 定义 Command 接口：`{ execute(), undo() }`
2. 实现 AddNodeCommand、DeleteNodeCommand、AddEdgeCommand、DeleteEdgeCommand、UpdatePropertyCommand
3. WorkflowStore 增加 `undoStack: Command[]` 和 `redoStack: Command[]`
4. 每次操作执行时创建 Command 压入 undoStack，清空 redoStack
5. `undo()` 从 undoStack 弹出执行 `command.undo()`，压入 redoStack
6. `redo()` 从 redoStack 弹出执行 `command.execute()`，压入 undoStack
7. FlowCanvas 注册 `onKeyDown` 监听 Ctrl+Z / Ctrl+Shift+Z

**Patterns to follow:** Vue Flow 官方示例中的 undo/redo 实现

**Test scenarios:**
- 添加节点后 Ctrl+Z，节点从画布消失
- 删除节点后 Ctrl+Z，节点恢复原位
- 连线后 Ctrl+Z，连线消失
- 修改属性后 Ctrl+Z，属性恢复原值
- 撤销后 Ctrl+Shift+Z，操作重做
- 连续 5 次操作后全部撤销再全部重做，画布状态一致

**Verification:** 在工作流编辑器中执行各种操作后，Ctrl+Z/Ctrl+Shift+Z 可正确撤销/重做

---

### U3. 工作流执行动画

**Goal:** 工作流执行时画布节点实时显示状态动画

**Requirements:** R5

**Dependencies:** U1

**Files:**
- `src/agentkit/server/frontend/src/stores/workflow.ts` -- 接入 WebSocket，更新节点状态
- `src/agentkit/server/frontend/src/components/workflow/FlowCanvas.vue` -- 根据节点状态渲染动画样式
- `src/agentkit/server/frontend/src/components/workflow/SkillNode.vue` -- 添加状态样式（运行中脉冲、完成绿色、失败红色）
- `src/agentkit/server/frontend/src/components/workflow/ConditionNode.vue` -- 添加状态样式
- `src/agentkit/server/frontend/src/components/workflow/ApprovalNode.vue` -- 添加等待图标样式
- `src/agentkit/server/frontend/src/components/workflow/ParallelNode.vue` -- 添加状态样式

**Approach:**
1. WorkflowStore 建立 WebSocket 连接（复用 `createWorkflowWebSocket`），订阅执行事件
2. 收到 `stage_started` 事件时，更新对应节点的 `data.status = 'running'`
3. 收到 `stage_completed` 事件时，更新 `data.status = 'completed'`
4. 收到 `stage_failed` 事件时，更新 `data.status = 'failed'`
5. 收到 `approval_required` 事件时，更新 `data.status = 'waiting_approval'`
6. 各节点组件根据 `data.status` 渲染不同样式：running 脉冲动画、completed 绿色勾选、failed 红色错误、waiting_approval 等待图标
7. 替换当前的轮询机制为 WebSocket 推送

**Patterns to follow:** 现有 WorkflowApi 的 `createWorkflowWebSocket` 方法

**Test scenarios:**
- 执行工作流后，当前阶段节点显示脉冲动画
- 阶段完成后节点变为绿色勾选
- 阶段失败后节点变为红色错误
- 审批节点暂停时显示等待图标
- 未执行节点保持默认样式
- WebSocket 断开后自动重连

**Verification:** 执行工作流时，画布节点实时反映执行状态，延迟不超过 1 秒

---

### U4. 工作流执行历史与 Skill 真实执行

**Goal:** 后端新增执行历史 API，工作流 Skill 阶段调用真实 Skill 执行

**Requirements:** R6, R19

**Dependencies:** U3

**Files:**
- `src/agentkit/server/routes/workflows.py` -- 新增执行历史端点，改造 skill/parallel 阶段执行逻辑
- `src/agentkit/orchestrator/workflow_schema.py` -- WorkflowStore 增加按 workflow_id 查询执行记录方法
- `src/agentkit/server/frontend/src/api/workflow.ts` -- 新增 listExecutions 方法
- `src/agentkit/server/frontend/src/stores/workflow.ts` -- 加载执行历史
- `src/agentkit/server/frontend/src/views/WorkflowView.vue` -- 执行历史表格展示
- `tests/unit/server/test_workflow_routes.py` -- 新增测试

**Approach:**
1. WorkflowStore 新增 `list_executions(workflow_id)` 方法，从内存存储中过滤
2. 后端新增 `GET /workflows/{workflow_id}/executions` 端点，返回分页执行记录
3. 改造 `_execute_workflow` 中 skill 类型分支：通过 `app.state.skill_registry` 查找 Skill，调用 `skill.execute()` 或通过 AgentPool 分发任务
4. 改造 parallel 类型分支：使用 `asyncio.gather()` 并行执行子阶段
5. 前端新增执行历史面板，展示表格（execution_id、状态、开始/结束时间），支持展开查看阶段结果

**Patterns to follow:** 现有 `test_workflow_routes.py` 的 fixture 和测试组织模式

**Test scenarios:**
- GET /workflows/{id}/executions 返回指定工作流的执行记录列表
- Skill 阶段执行返回真实输出而非 dry_run 模拟数据
- Skill 执行失败时阶段状态标记为 failed
- Parallel 阶段并行执行子阶段
- 前端执行历史表格正确展示记录
- 空历史时显示空状态提示

**Verification:** 执行包含 skill 阶段的工作流后，执行历史中可查看真实 Skill 输出

---

### U5. ECharts 图表替换与筛选修复

**Goal:** 用 ECharts 替换原生 SVG 图表，修复经验时间线筛选 bug

**Requirements:** R7, R9

**Dependencies:** U12（ECharts 按需引入需先完成）

**Files:**
- `src/agentkit/server/frontend/src/components/evolution/MetricsChart.vue` -- 用 ECharts 重写
- `src/agentkit/server/frontend/src/views/EvolutionView.vue` -- 修复 onExperienceFilter
- `src/agentkit/server/frontend/src/utils/echarts.ts` -- 新建 ECharts 按需引入配置

**Approach:**
1. 新建 `utils/echarts.ts`：按需注册 LineChart、BarChart、PieChart、TooltipComponent、LegendComponent、GridComponent、DataZoomComponent，导出 `use` 函数
2. 重写 MetricsChart.vue：使用 ECharts 折线图，配置 tooltip、legend、dataZoom，自适应容器宽度（ResizeObserver）
3. 修复 EvolutionView.vue 的 `onExperienceFilter`：正确传递 outcome 参数（`store.loadExperiences(outcome || undefined)`），同时修正 `loadExperiences` 的参数语义（从 taskType 改为 outcome）
4. 删除原生 SVG 绘制代码

**Patterns to follow:** ECharts 5.x 按需引入官方文档

**Test scenarios:**
- 指标趋势图使用 ECharts 渲染，无原生 SVG 代码残留
- 鼠标悬停数据点显示 tooltip
- 点击图例切换显示/隐藏趋势线
- 时间周期切换后图表正确刷新
- 图表自适应容器宽度
- 选择"成功"筛选后仅显示 success 记录
- 选择"失败"筛选后仅显示 failure 记录

**Verification:** 进化仪表盘页面图表交互正常，筛选功能生效

---

### U6. 进化仪表盘实时 WebSocket 推送

**Goal:** 激活后端 WebSocket 推送，前端接收后自动刷新面板

**Requirements:** R8

**Dependencies:** U5

**Files:**
- `src/agentkit/server/routes/evolution_dashboard.py` -- 在写操作后调用 _broadcast_event
- `src/agentkit/server/frontend/src/stores/evolution.ts` -- 建立 WebSocket 连接，处理推送事件
- `src/agentkit/server/frontend/src/views/EvolutionView.vue` -- 挂载时连接 WebSocket，卸载时断开
- `tests/unit/server/test_evolution_dashboard.py` -- 新增 WebSocket 推送测试

**Approach:**
1. 后端：在 `POST /evolution/trigger`、经验记录新增、指标更新等写操作完成后调用 `_broadcast_event(connections, event_type, data)`
2. 前端 EvolutionStore：增加 `connectWebSocket()` 和 `disconnectWebSocket()` 方法
3. WebSocket 消息处理：收到 `experience_added` 刷新经验时间线，收到 `metrics_updated` 刷新趋势图，收到 `pitfall_detected` 刷新避坑预警
4. EvolutionView `onMounted` 时调用 `connectWebSocket()`，`onUnmounted` 时调用 `disconnectWebSocket()`
5. 断线重连：最多 3 次，间隔 5 秒

**Patterns to follow:** 现有 workflow WebSocket 连接模式（`createWorkflowWebSocket`）

**Test scenarios:**
- WebSocket 连接建立后收到 subscribed 确认
- 新经验记录产生后，经验时间线在 2 秒内自动追加
- 指标更新后趋势图自动刷新
- WebSocket 断开后自动重连（最多 3 次）
- 页面卸载时 WebSocket 正确断开

**Verification:** 打开进化仪表盘，触发进化操作后页面自动刷新

---

### U7. 全局概览页与用量统计面板

**Goal:** 新增进化模块首页概览和 LLM 用量统计面板

**Requirements:** R10, R11

**Dependencies:** U5

**Files:**
- `src/agentkit/server/frontend/src/views/EvolutionView.vue` -- 重构为带子路由的布局
- `src/agentkit/server/frontend/src/components/evolution/DashboardOverview.vue` -- 新建概览页
- `src/agentkit/server/frontend/src/components/evolution/UsagePanel.vue` -- 新建用量统计面板
- `src/agentkit/server/frontend/src/router/index.ts` -- 添加进化子路由
- `src/agentkit/server/frontend/src/api/evolution.ts` -- 新增用量统计 API 调用

**Approach:**
1. 重构 EvolutionView 为容器布局：左侧导航（概览/经验/指标/避坑/路径优化/用量统计），右侧内容区
2. 新建 DashboardOverview.vue：4 个摘要卡片（总任务数、Agent 活跃数、LLM 用量、质量通过率），数据从 `/metrics` 和 `/health` 端点聚合
3. 新建 UsagePanel.vue：ECharts 折线图展示 Token 用量趋势（按 Provider 分组），摘要卡片展示请求成功率和平均延迟，时间范围选择器
4. 路由：`/evolution` 默认跳转到 `/evolution/overview`

**Patterns to follow:** 现有 EvolutionView 的面板布局模式

**Test scenarios:**
- 概览页展示 4 个摘要卡片，数据来自后端 API
- 每个卡片可点击跳转到对应子面板
- 页面加载时显示 loading 状态
- 数据为空时显示零值
- 用量统计折线图按 Provider 分组显示
- 时间范围切换后图表刷新
- 无数据时显示空状态提示

**Verification:** 访问 /evolution 默认显示概览页，各卡片数据正确，可跳转到子面板

---

### U8. 知识库上传数据回填修复

**Goal:** 修复文档上传后使用后端返回的真实数据

**Requirements:** R12

**Dependencies:** 无

**Files:**
- `src/agentkit/server/frontend/src/components/kb/DocumentUpload.vue` -- 使用后端返回值
- `src/agentkit/server/frontend/src/stores/knowledge.ts` -- uploadDocument 返回后端数据

**Approach:**
1. 修改 `uploadDocument` store 方法：返回后端响应数据（document_id、chunks、status）
2. 修改 DocumentUpload.vue 的 `handleUpload` 回调：使用后端返回的 document_id 和 chunks 替换 `Date.now()` 伪造值
3. 上传失败时不将文档添加到列表，显示错误提示

**Patterns to follow:** 现有上传流程的 FormData + custom-request 模式

**Test scenarios:**
- 上传文档后列表显示后端返回的真实 document_id
- 分块数显示后端返回的 chunks 值
- 上传多个文档后每个 id 唯一
- 上传失败时文档不出现在列表中

**Verification:** 上传文档后列表数据与后端返回值一致

---

### U9. 知识库文档管理与检索增强

**Goal:** 补齐后端 KB 文档管理 API，前端实现文档列表/删除、信息源同步/更新、检索高级选项

**Requirements:** R13, R14, R15, R16

**Dependencies:** U8

**Files:**
- `src/agentkit/server/routes/kb_management.py` -- 新增文档列表/删除/同步/更新端点，检索支持高级参数
- `src/agentkit/server/frontend/src/api/kb.ts` -- 新增 API 调用方法
- `src/agentkit/server/frontend/src/components/kb/DocumentUpload.vue` -- 文档列表和删除功能
- `src/agentkit/server/frontend/src/components/kb/SourceConfig.vue` -- 同步按钮和编辑功能
- `src/agentkit/server/frontend/src/components/kb/SearchTest.vue` -- 高级选项折叠面板
- `tests/unit/server/test_kb_management.py` -- 新增测试

**Approach:**
1. 后端新增 `GET /kb-management/documents`：返回文档列表（从 `_source_store.list_documents()` 暴露）
2. 后端新增 `DELETE /kb-management/documents/{document_id}`：从存储中删除文档
3. 后端新增 `POST /kb-management/sources/{source_id}/sync`：触发外部源同步（飞书/Confluence），返回同步状态
4. 后端新增 `PUT /kb-management/sources/{source_id}`：更新信息源配置
5. 后端 `POST /kb-management/search` 增加 `source_ids`、`top_k`、`strategy` 参数
6. 前端 DocumentUpload：加载文档列表，删除按钮带确认弹窗
7. 前端 SourceConfig：每行添加"同步"和"编辑"按钮
8. 前端 SearchTest：新增"高级选项"折叠面板（信息源多选、top_k 输入、策略选择）

**Patterns to follow:** 现有 kb_management.py 的路由和存储模式

**Test scenarios:**
- GET /kb-management/documents 返回文档列表
- DELETE /kb-management/documents/{id} 删除成功后文档不存在
- POST /kb-management/sources/{id}/sync 触发同步并返回状态
- PUT /kb-management/sources/{id} 更新配置后返回新对象
- 检索请求带 source_ids/top_k/strategy 参数时后端正确处理
- 前端文档列表正确展示，删除后列表刷新
- 同步按钮 loading 状态正确
- 高级选项参数随检索请求发送

**Verification:** 知识库页面可完整管理文档和信息源，检索支持高级选项

---

### U10. 终端 API 实现

**Goal:** 后端新增终端路由模块，对接 PTYSession，前端终端页面可用

**Requirements:** R17

**Dependencies:** 无

**Files:**
- `src/agentkit/server/routes/terminal.py` -- 新建终端路由模块
- `src/agentkit/server/app.py` -- 注册终端路由
- `src/agentkit/server/frontend/src/api/terminal.ts` -- 适配新 API
- `src/agentkit/server/frontend/src/stores/terminal.ts` -- 对接 WebSocket
- `src/agentkit/server/frontend/src/views/TerminalView.vue` -- 集成 xterm.js
- `tests/unit/server/test_terminal_routes.py` -- 新建测试

**Approach:**
1. 新建 `routes/terminal.py`，实现 4 个端点：
   - `POST /terminal/execute`：创建 PTYSession 执行命令，白名单检查，非白名单命令返回需确认状态
   - `GET /terminal/sessions`：返回活跃会话列表
   - `GET /terminal/sessions/{session_id}/history`：返回命令历史
   - `WS /terminal/ws`：实时命令输入/输出流，非白名单命令推送确认请求，用户确认后执行，确认时可选择加入白名单
2. 安全策略：复用 `ShellTool` 的 `_is_dangerous()` 检测逻辑，白名单内命令直接执行，非白名单通过 WebSocket 推送确认请求
3. 白名单管理：服务端内存维护可扩展白名单（用户确认时选择加入的命令），不持久化
4. 前端集成 xterm.js（需新增依赖），通过 WebSocket 连接实现交互式终端

**Patterns to follow:** 现有 `routes/chat.py` 的 WebSocket 端点模式；`tools/shell.py` 的白名单机制

**Test scenarios:**
- POST /terminal/execute 执行白名单命令返回输出
- POST /terminal/execute 非白名单命令返回需确认状态
- WebSocket 连接后可交互式执行命令
- 非白名单命令推送确认请求，确认后执行
- 确认时选择加入白名单后，后续相同命令直接执行
- GET /terminal/sessions 返回活跃会话列表
- GET /terminal/sessions/{id}/history 返回命令历史

**Verification:** 前端终端页面可执行命令、查看输出、确认非白名单命令

---

### U11. 设置 API 实现

**Goal:** 后端新增设置路由模块，前端 Settings 页面可读写配置

**Requirements:** R18

**Dependencies:** 无

**Files:**
- `src/agentkit/server/routes/settings.py` -- 新建设置路由模块
- `src/agentkit/server/app.py` -- 注册设置路由
- `src/agentkit/server/frontend/src/api/settings.ts` -- 新建设置 API
- `src/agentkit/server/frontend/src/stores/settings.ts` -- 对接 API
- `src/agentkit/server/frontend/src/views/SettingsView.vue` -- 对接真实 API
- `tests/unit/server/test_settings_routes.py` -- 新建测试

**Approach:**
1. 新建 `routes/settings.py`，实现 4 组端点：
   - `GET/PUT /settings/llm`：读写 LLM 配置（Provider 列表、默认模型、别名），GET 不暴露 API Key 明文
   - `GET/PUT /settings/skills`：读写技能路径配置
   - `GET/PUT /settings/kb`：读写知识库连接配置
   - `GET/PUT /settings/general`：读写通用设置（日志级别、Server 端口等）
2. PUT 操作触发配置热重载（复用 `_on_config_change` 机制）
3. 前端 SettingsView 对接真实 API，替换当前内存数据

**Patterns to follow:** 现有 `app.py` 的 `_on_config_change` 热重载机制

**Test scenarios:**
- GET /settings/llm 返回 LLM 配置，API Key 被脱敏
- PUT /settings/llm 更新配置后触发热重载
- GET/PUT /settings/skills 读写技能路径
- GET/PUT /settings/kb 读写知识库配置
- GET/PUT /settings/general 读写通用设置
- 前端 Settings 页面可展示和修改配置
- 配置修改后无需重启服务即生效

**Verification:** 前端 Settings 页面可读写所有配置项，修改后立即生效

---

### U12. 前端基础设施改进

**Goal:** 抽取 API 公共基类，实现 Ant Design Vue 和 ECharts 按需引入

**Requirements:** R20, R21, R22

**Dependencies:** 无（应最先实施，其他单元依赖其产出）

**Files:**
- `src/agentkit/server/frontend/src/api/base.ts` -- 新建 API 基类
- `src/agentkit/server/frontend/src/api/client.ts` -- 继承基类
- `src/agentkit/server/frontend/src/api/workflow.ts` -- 继承基类
- `src/agentkit/server/frontend/src/api/evolution.ts` -- 继承基类
- `src/agentkit/server/frontend/src/api/kb.ts` -- 重构为 class 风格继承基类
- `src/agentkit/server/frontend/src/api/terminal.ts` -- 重构为 class 风格继承基类
- `src/agentkit/server/frontend/src/api/skills.ts` -- 重构为 class 风格继承基类
- `src/agentkit/server/frontend/vite.config.ts` -- 添加 unplugin 插件
- `src/agentkit/server/frontend/package.json` -- 新增依赖
- `src/agentkit/server/frontend/src/main.ts` -- 移除 app.use(Antd)

**Approach:**
1. 新建 `api/base.ts`：`BaseApiClient` 类，包含 `request<T>(method, path, options)` 方法（统一 baseURL、超时、错误处理、响应拦截）和 `createWebSocket(path)` 方法
2. 6 个 API 文件重构为继承 `BaseApiClient`，指定各自的 `baseUrl`
3. 安装 `unplugin-vue-components` 和 `unplugin-auto-import`，配置 Vite 插件实现 Ant Design Vue 按需引入
4. `main.ts` 移除 `app.use(Antd)` 全量注册
5. 安装 `echarts`，按需引入配置（在 U5 的 `utils/echarts.ts` 中完成）

**Patterns to follow:** 现有 `ApiClient`、`WorkflowApiClient`、`EvolutionApiClient` 的 class 风格

**Test scenarios:**
- BaseApiClient 的 request 方法统一处理错误和响应
- 6 个 API 模块均使用基类，无独立 request 函数
- 现有页面渲染和交互行为不变（回归验证）
- 构建无报错、无运行时组件缺失警告
- ant-design-vue 打包体积较全量引入减少 40% 以上

**Verification:** `npm run build` 成功，所有现有页面功能正常

---

## Scope Boundaries

**In scope:** 22 条需求（R1-R22），涵盖可视化编排器、监控数据看板、知识库管理、后端 API 补齐、技术改进

**Deferred to follow-up work:**

- 暗色模式——需设计系统层面改造
- 角色视图切换——通过信息架构区分，不做独立视图
- Computer Use 页面——功能独立
- CI/CD 流水线——独立于前端重建
- 前端单元测试和 E2E 测试——后续专项
- xterm.js 终端模拟器集成——U10 实现后端 API 和 WebSocket，前端终端交互式体验可后续增强

---

## Open Questions

**Deferred to implementation:**

- 全局概览页（R10）数据聚合方式：从现有多个端点聚合还是新增专用概览端点——实现时根据性能需求决定
- 工作流执行动画（R5）节点状态样式方案：在现有组件上叠加状态层还是创建带状态变体——实现时根据组件复杂度决定
- 工作流 Skill 真实执行（R19）的变量传递机制：上游 stage_results 如何传递给下游 Skill inputs——实现时根据 Skill 接口设计

---

## Risks & Dependencies

| 风险 | 影响 | 缓解措施 |
|------|------|----------|
| ECharts 按需引入配置复杂，可能遗漏组件导致运行时错误 | 图表渲染失败 | 先全量引入验证功能，再逐步切换为按需引入 |
| 工作流执行引擎改造影响现有 approval/condition 逻辑 | 现有功能回归 | 改造时保持现有分支不变，仅修改 skill/parallel 分支，增加集成测试 |
| 终端 API 安全策略绕过风险 | 安全漏洞 | 复用 ShellTool 成熟的白名单机制，链式操作符一律视为危险 |
| 前端 API 层重构导致现有调用行为变化 | 页面功能回归 | 逐模块迁移，每个模块迁移后回归验证 |
| 后端 KB 文档管理当前为纯内存存储，重启丢失 | 数据丢失 | 本次不解决持久化问题，但在 API 文档中标注此限制 |

---

## System-Wide Impact

- **前端构建流程变化**：新增 unplugin 插件和 ECharts 依赖，`npm install` 和 `npm run build` 行为变化
- **后端路由注册变化**：新增 terminal 和 settings 两个路由模块，`app.py` 需更新
- **前端 API 层架构变化**：6 个 API 文件重构为 class 继承模式，所有 store 的 API 调用方式变化
- **工作流执行引擎行为变化**：Skill 阶段从 dry-run 变为真实执行，可能影响执行时间和错误处理

---

## Sources & Research

- 需求文档：`docs/brainstorms/2026-06-12-frontend-productization-requirements.md`
- 前端构建配置：`src/agentkit/server/frontend/vite.config.ts`、`package.json`
- 工作流编辑器：`src/agentkit/server/frontend/src/components/workflow/FlowCanvas.vue`（拖拽断裂点在第 96-110 行）
- 进化仪表盘：`src/agentkit/server/frontend/src/components/evolution/MetricsChart.vue`（原生 SVG 实现）
- 筛选 bug：`src/agentkit/server/frontend/src/views/EvolutionView.vue`（第 55-57 行）
- 后端工作流执行：`src/agentkit/server/routes/workflows.py`（skill/parallel dry-run 在第 378-387 行）
- 后端进化推送：`src/agentkit/server/routes/evolution_dashboard.py`（`_broadcast_event` 未被调用）
- 后端 KB 管理：`src/agentkit/server/routes/kb_management.py`（文档列表/删除/同步端点缺失）
- PTYSession：`src/agentkit/tools/pty_session.py`
- ShellTool 白名单：`src/agentkit/tools/shell.py`（`_SAFE_COMMAND_PREFIXES` 和 `_is_dangerous()`）
- 配置热重载：`src/agentkit/server/app.py`（`_on_config_change` 第 242-336 行）
- 现有测试模式：`tests/unit/server/test_workflow_routes.py`、`test_evolution_dashboard.py`、`test_kb_management.py`
