---
title: "feat: AgentKit Platform Experience Upgrade"
status: active
created: 2026-06-13
plan-type: feat
depth: deep
origin: docs/brainstorms/2026-06-13-agentkit-platform-experience-upgrade-requirements.md
---

# feat: AgentKit Platform Experience Upgrade

## Summary

对 Fischer AgentKit 进行平台级体验升级，四线并行推进：布局重构为左对话+右双栏、对话体验深化（首 Token 即渲染+消息格式增强+@-mention 四类引用）、响应速度核心优化、暗色主题与交互增强、Computer Use MVP——分三个冲击波迭代交付。

## Problem Frame

AgentKit 后端能力丰富（ReAct、Skill、Pipeline、记忆、自进化、多 Agent 市场），但 GUI 仍处于"功能可用但体验粗糙"状态。核心痛点：对话空间被压缩到 1/4 屏幕、消息纯文本无高亮、首 Token 延迟 5-10 秒、无暗色主题、无交互反馈、Computer Use 为占位。需求文档（见 origin）定义了 25 个需求（R1-R25），本计划定义如何实现。

---

## Key Technical Decisions

**KTD-1: 布局重构通过调整 SplitPane 嵌套实现，子视图零修改。** 当前 AgentLayout 使用三层 SplitPane（水平→左垂直+右垂直），重构为两层（水平→右垂直），ChatView 直接作为水平 SplitPane 的 first slot。QuadrantPanel 和 SplitPane 组件不变，只改 AgentLayout 的嵌套结构和路由映射。(see origin: R1)

**KTD-2: 消息格式增强基于 MarkdownIt 插件扩展 + DOMPurify 白名单扩展。** 当前 ChatMessage 已使用 MarkdownIt 渲染，添加 `markdown-it-highlightjs` 插件实现代码高亮，自定义 `tool_call` 和 `file_preview` 块级渲染器实现工具调用卡片和文件预览。关键：当前 DOMPurify 的 `ALLOWED_TAGS` 白名单不包含 `div`、`img`、`button`，自定义渲染器输出的 HTML 元素会被过滤，必须扩展白名单。不引入新的 Markdown 渲染引擎。(see origin: R8, R9, R10)

**KTD-3: @-mention 通过扩展 WebSocket 消息协议实现。** 在现有 `WsClientMessage` 的 `sources` 字段基础上扩展，引用项编码为 `{type: "mention", mention_type: "file"|"skill"|"workflow"|"agent", id: string, label: string}`，后端解析后注入 Agent 上下文。新增 `/api/v1/portal/mention-suggest` REST 端点提供 autocomplete 数据。(see origin: R13, R14)

**KTD-4: Computer Use MVP 使用 pyautogui + screencapture 实现截屏和点击。** 替换 `DockerComputerUseSession` 的 stub 为 `LocalComputerUseSession`，macOS 使用 `screencapture` 截屏 + `pyautogui` 执行点击/输入操作，Linux 使用 `xdotool` + `scrot`。不依赖 Docker 容器化。前端新增 ComputerUseView 实际界面替代占位页。(see origin: R19, R20)

**KTD-5: 暗色主题通过 `[data-theme="dark"]` CSS 选择器覆盖 + 响应式 Ant Design token。** 在现有 `tokens.css` 中添加 `[data-theme="dark"]` 块覆盖同名 CSS 变量，新增 `stores/theme.ts` 管理主题状态和 localStorage 持久化。关键：`styles/theme.ts` 的 `readToken()` 是模块加载时一次性执行的，切换主题后需重新调用生成新的 `themeConfig` 并传给 ConfigProvider，否则 Ant Design 组件不跟随暗色主题。(see origin: R11)

**KTD-6: 响应速度优化 U1-U4 已实现，仅补充 portal.py 的 ReActEngine 复用。** `HeuristicClassifier`、`_classify_merged`、`parallel_tools`、`AsyncWriteQueue` 均已在代码中。`chat.py` 已有 ReActEngine 复用逻辑，但 `portal.py` 每次创建新实例，需对齐。(see origin: R5, R6, R7)

---

## High-Level Technical Design

### 迭代 1 架构：对话体验质变

```mermaid
flowchart TB
    subgraph Frontend
        AL[AgentLayout] --> SP_H[SplitPane horizontal 55:45]
        SP_H --> CV[ChatView 全高]
        SP_H --> SP_V[SplitPane vertical 60:40]
        SP_V --> QP_TR[QuadrantPanel 右上]
        SP_V --> QP_BR[QuadrantPanel 右下]

        CV --> CI[ChatInput]
        CV --> CM[ChatMessage]
        CM --> MD[MarkdownIt + highlightjs]
        CM --> TC[ToolCallCard 渲染器]
        CM --> FP[FilePreview 渲染器]

        CI --> WS[WebSocket]
    end

    subgraph Backend
        WS --> PORTAL[portal.py]
        PORTAL --> HC[HeuristicClassifier 已实现]
        PORTAL --> MERGE[_classify_merged 已实现]
        PORTAL --> RE[ReActEngine 复用]
        RE --> STREAM[execute_stream]
        STREAM --> |token 事件| WS
    end
```

### @-mention 数据流（迭代 2）

```mermaid
sequenceDiagram
    participant U as User
    participant CI as ChatInput
    participant API as /mention-suggest
    participant WS as WebSocket
    participant PORTAL as portal.py
    participant AGENT as Agent

    U->>CI: 输入 @
    CI->>API: GET /mention-suggest?q=keyword
    API-->>CI: [{type, id, label, icon}]
    U->>CI: 选择引用项
    CI->>CI: 添加 ContextPill
    U->>CI: 发送消息
    CI->>WS: {type:chat, message, mentions:[...]}
    WS->>PORTAL: 解析 mentions
    PORTAL->>PORTAL: 查询引用内容
    PORTAL->>AGENT: 注入上下文
    AGENT-->>WS: 流式响应
    WS-->>CI: 渲染响应
```

---

## Requirements Traceability

| Requirement | Iteration | Implementation Unit(s) |
|-------------|-----------|----------------------|
| R1. 左对话+右双栏 | 1 | U1 |
| R2. 面板折叠 | 1 | U1 |
| R3. 侧边导航图标 | 1 | U2 |
| R4. 小屏幕适配 | 1 | U1 |
| R5. 启发式分类器 | 1 | 已实现 |
| R6. 合并路由调用 | 1 | 已实现 |
| R7. 首 Token 即渲染 | 1 | U3 |
| R8. 代码块高亮 | 1 | U4 |
| R9. 工具调用可视化 | 1 | U5 |
| R10. 图片/文件预览 | 1 | U6 |
| R11. 暗色主题 | 2 | U7 |
| R12. 组件样式统一 | 2 | U8 |
| R13. @-mention Autocomplete | 2 | U9 |
| R14. @-mention 上下文注入 | 2 | U10 |
| R15. @-mention 引用标签 | 2 | U9 |
| R16. 过渡动画 | 2 | U11 |
| R17. 操作反馈 | 2 | U12 |
| R18. 空状态设计 | 2 | U13 |
| R19. 截屏查看 | 3 | U14 |
| R20. 简单点击操作 | 3 | U14 |
| R21. Computer Use 面板 | 3 | U15 |
| R22. 并行工具执行 | 3 | 已实现 |
| R23. 异步会话写入 | 3 | 已实现 |
| R24. 分割线拖拽增强 | 3 | U16 |
| R25. 面板折叠缩略预览 | 3 | U17 |

---

## Implementation Units

### 迭代 1：对话体验质变

---

### U1. AgentLayout 布局重构

**Goal:** 将四象限等分布局重构为左对话+右双栏布局，对话面板占满左半屏。

**Requirements:** R1, R2, R4

**Dependencies:** None

**Files:**
- `src/agentkit/server/frontend/src/components/layout/AgentLayout.vue` — 重构 SplitPane 嵌套
- `src/agentkit/server/frontend/src/router/index.ts` — 移除 terminal 路由，调整 quadrant 元数据
- `src/agentkit/server/frontend/src/styles/responsive.css` — 调整断点

**Approach:**

1. 移除左侧垂直 SplitPane，ChatView 直接作为水平 SplitPane 的 `#first` slot
2. 保留右侧垂直 SplitPane（右上：代码/工作流/知识库，右下：监控/技能/设置）
3. 水平 SplitPane 默认比例改为 0.55（55:45）
4. 移除 `agent-terminal` 路由定义
5. 调整 responsive.css：≥1280px 完整展示，1024-1280px 右下面板默认折叠，<1024px 提示。**注意：** 当前 responsive.css 的选择器基于四象限布局结构（如 `.split-pane--horizontal > .split-pane__second .split-pane--vertical > .split-pane__second .quadrant-panel`），重构后这些选择器完全失效，必须根据新的两层 SplitPane 结构重写所有象限相关选择器

**Patterns to follow:** 现有 SplitPane 嵌套模式；QuadrantPanel 的 Tab 配置模式；localStorage 持久化 key 命名 `agent-*`

**Test scenarios:**
- 布局渲染为左对话+右双栏，ChatView 占满左半屏高度
- 左右分割线可拖拽，默认 55:45，范围 20%-80%
- 右侧上下分割线可拖拽，默认 60:40
- 分割比例保存到 localStorage，刷新后恢复
- 右上面板折叠后仅显示 Tab 栏（约 38px）
- 右下面板折叠后仅显示 Tab 栏
- 两个面板可同时折叠
- 折叠/展开有 200ms ease 过渡动画
- 屏幕宽度 <1024px 显示提示
- 屏幕宽度 1024-1280px 右下面板默认折叠
- terminal 路由不再存在

**Verification:** 手动测试布局在不同屏幕宽度下的表现；折叠/展开动画流畅；localStorage 持久化正常。

---

### U2. 侧边导航精简为图标模式

**Goal:** 将侧边导航精简为 32px 宽图标导航栏，点击图标切换右侧面板 Tab 并展开。

**Requirements:** R3

**Dependencies:** U1

**Files:**
- `src/agentkit/server/frontend/src/components/layout/TopNav.vue` — 添加侧边导航切换按钮
- `src/agentkit/server/frontend/src/components/layout/IconNav.vue` — 新建 32px 图标导航组件
- `src/agentkit/server/frontend/src/components/layout/AgentLayout.vue` — 集成 IconNav

**Approach:**

1. 新建 `IconNav.vue`：32px 宽图标导航栏，只显示图标（对话、工作流、知识库、技能、监控、设置）。注意：现有 `SideNav.vue` 是遗留的 AppLayout 组件（240px 宽暗色侧边栏），不在 AgentLayout 中使用，不需要修改。
2. 点击图标：调用对应 QuadrantPanel 的 `setActiveTab()` 并展开面板
3. 当前激活图标高亮（使用 `--color-primary` Token）
4. TopNav 添加折叠/展开 SideNav 的按钮
5. SideNav 状态保存到 localStorage

**Patterns to follow:** QuadrantPanel 的 `setActiveTab()` 暴露方法；现有 SideNav 的导航项定义模式

**Test scenarios:**
- SideNav 宽度为 32px，只显示图标
- 点击对话图标，ChatView 获得焦点
- 点击工作流图标，右上面板切换到 workflow Tab 并展开
- 点击监控图标，右下面板切换到 monitor Tab 并展开
- 当前激活图标高亮
- TopNav 按钮可折叠/展开 SideNav
- 折叠状态保存到 localStorage

**Verification:** 手动测试图标导航与面板联动；折叠/展开正常。

---

### U3. 首步骤即渲染 + portal.py ReActEngine 复用

**Goal:** 前端接收到首个流式步骤即开始渲染；后端 portal.py 复用 ReActEngine 实例。

**Requirements:** R7

**Dependencies:** None

**Files:**
- `src/agentkit/server/frontend/src/stores/chat.ts` — 确认流式渲染逻辑正确处理首个步骤
- `src/agentkit/server/frontend/src/components/chat/ChatMessage.vue` — 确认流式内容渲染无闪烁
- `src/agentkit/server/routes/portal.py` — ReActEngine 复用（对齐 chat.py 模式，覆盖 SSE + WS 两个路径）

**Approach:**

1. 前端：当前 `handleWsMessage` 的 `step` 事件在 `event_type === 'final_answer'` 时逐块累加 content，确认首个步骤到达即渲染。注意：后端当前按"步骤"粒度推送（thinking/tool_call/tool_result/final_answer），不是逐 Token 推送。"首 Token 即渲染"在此架构下实际含义是"首步骤即渲染"——`final_answer` 事件的 `data.output` 是文本块，到达即显示。
2. 后端：portal.py 有两处创建 ReActEngine（SSE 路径约第 342 行，WS 路径约第 661 行），均需改为复用 agent 上已绑定的 `_react_engine`（对齐 chat.py 第 197 行的 `getattr(agent, "_react_engine", None)` 模式）。复用时调用 `react_engine.reset()` 重置内部状态。
3. 注意 `agent_pool.py` 的 `create_agent_from_skill()` 已在 agent 上绑定 `agent._react_engine`，portal.py 应优先使用该实例。

**Patterns to follow:** chat.py 的 `getattr(agent, "_react_engine", None)` 复用模式

**Test scenarios:**
- 发送简单问候，首 Token 在 1 秒内渲染
- 流式输出逐字显示，无整体延迟
- ReActEngine 在同一会话中复用，不创建新实例
- 会话结束后 ReActEngine 正确重置
- token 事件和 final_answer 事件均触发前端渲染更新

**Verification:** 手动测试对话首 Token 延迟；检查 portal.py 日志确认 ReActEngine 复用。

---

### U4. 代码块语法高亮

**Goal:** 消息中的代码块自动识别语言并语法高亮，支持复制按钮。

**Requirements:** R8

**Dependencies:** None

**Files:**
- `src/agentkit/server/frontend/src/components/chat/ChatMessage.vue` — 添加 highlight.js 插件 + 扩展 DOMPurify 白名单
- `src/agentkit/server/frontend/src/styles/` — 代码高亮主题样式
- `src/agentkit/server/frontend/package.json` — 添加 `highlight.js` 依赖

**Approach:**

1. 安装 `highlight.js` 和 `markdown-it-highlightjs`（或手动配置 MarkdownIt 的 highlight 选项）
2. 在 ChatMessage 的 MarkdownIt 实例中配置 highlight 函数使用 highlight.js
3. 代码高亮主题使用 Catppuccin Mocha（与 tokens.css 中的代码主题一致）
4. 添加代码块复制按钮（点击复制代码内容到剪贴板，显示 Toast 反馈）
5. 代码块语言标签显示在右上角
6. **扩展 DOMPurify 白名单**：当前 `ALLOWED_TAGS` 不包含 `code`、`pre`、`span`（highlight.js 生成的标签），需添加这些标签及 `class`、`data-language` 属性

**Patterns to follow:** 现有 MarkdownIt 配置模式；tokens.css 中的代码主题色（`--color-code-*`）

**Test scenarios:**
- Python 代码块正确高亮（关键字、字符串、注释、函数名）
- JavaScript 代码块正确高亮
- 未指定语言的代码块使用自动检测
- 复制按钮点击后内容复制到剪贴板，显示 Toast
- 代码块语言标签正确显示
- 流式输出时代码块逐步高亮（不闪烁）

**Verification:** 手动测试不同语言代码块的渲染效果。

---

### U5. 工具调用可视化

**Goal:** 工具调用显示为可折叠的步骤卡片，展示工具名称、参数摘要、执行状态、结果预览。

**Requirements:** R9

**Dependencies:** U3

**Files:**
- `src/agentkit/server/frontend/src/components/chat/ChatMessage.vue` — 添加工具调用渲染逻辑 + 扩展 DOMPurify 白名单
- `src/agentkit/server/frontend/src/components/chat/ToolCallCard.vue` — 新建工具调用卡片组件

**Approach:**

1. 创建 `ToolCallCard.vue` 组件：可折叠卡片，显示工具名称（图标+名称）、参数摘要（截断显示）、执行状态（pending/running/completed/error）、结果预览（折叠时显示前 2 行）
2. 在 ChatMessage 中，检测 `step` 事件中的 `tool_call` 和 `tool_result` 事件类型，将配对的工具调用渲染为 ToolCallCard
3. 利用 chat store 中 `streamingSteps` 的数据，匹配工具调用和结果
4. 折叠/展开动画使用现有 `transitions.css` 的 `collapse` 类
5. **扩展 DOMPurify 白名单**：添加 `div`、`button`、`data-tool-call`、`data-tool-result` 等标签和属性，确保 ToolCallCard 的 HTML 不被过滤

**Patterns to follow:** 现有 `streamingSteps` 数据结构；transitions.css 的 collapse 动画；QuadrantPanel 的折叠模式

**Test scenarios:**
- 工具调用显示为卡片，包含工具名称和参数摘要
- 执行中状态显示 loading 指示器
- 完成后显示结果预览（前 2 行）
- 点击卡片展开查看完整参数和结果
- 多个工具调用按顺序显示
- 折叠/展开有平滑过渡动画
- 错误状态的工具调用显示错误信息

**Verification:** 手动测试触发工具调用的对话，验证卡片渲染和交互。

---

### U6. 图片和文件预览

**Goal:** 消息中的图片内联显示缩略图，文件显示为可下载卡片。

**Requirements:** R10

**Dependencies:** U4

**Files:**
- `src/agentkit/server/frontend/src/components/chat/ChatMessage.vue` — 添加图片/文件渲染逻辑 + 扩展 DOMPurify 白名单
- `src/agentkit/server/frontend/src/components/chat/FilePreview.vue` — 新建文件预览卡片组件

**Approach:**

1. 创建 `FilePreview.vue` 组件：文件名+大小+类型图标+下载按钮
2. 在 ChatMessage 的 MarkdownIt 渲染中，自定义 `image` 渲染规则：内联缩略图，点击放大
3. 检测消息中的文件链接（URL 以常见文件扩展名结尾），渲染为 FilePreview 卡片
4. 图片缩略图使用 CSS `object-fit: contain`，最大高度 200px
5. **扩展 DOMPurify 白名单**：添加 `img` 标签及 `src`、`alt`、`loading` 属性

**Patterns to follow:** 现有 MarkdownIt 自定义渲染器模式；tokens.css 的间距和圆角 Token

**Test scenarios:**
- 消息中的图片 URL 显示为内联缩略图
- 点击缩略图放大查看
- 文件链接显示为卡片（文件名+大小+类型图标）
- 下载按钮点击触发文件下载
- 非图片/文件链接正常渲染为超链接

**Verification:** 手动测试包含图片和文件链接的消息渲染。

---

### 迭代 2：专业感 + 精准度

---

### U7. 暗色主题 Token 定义与切换

**Goal:** 在浅色 Token 基础上新增暗色主题 Token 变体，支持一键切换。

**Requirements:** R11

**Dependencies:** U1

**Files:**
- `src/agentkit/server/frontend/src/styles/tokens.css` — 添加 `[data-theme="dark"]` 块
- `src/agentkit/server/frontend/src/stores/theme.ts` — 新建主题 store
- `src/agentkit/server/frontend/src/styles/theme.ts` — 改造 `readToken()` 为可重复调用的函数，支持主题切换时重新生成 `themeConfig`
- `src/agentkit/server/frontend/src/components/layout/TopNav.vue` — 添加主题切换按钮
- `src/agentkit/server/frontend/src/App.vue` — 监听主题变化，更新 `data-theme` 属性和 ConfigProvider

**Approach:**

1. 在 tokens.css 末尾添加 `[data-theme="dark"]` 选择器块，覆盖所有颜色变量（背景、前景、边框、品牌色、语义色、代码主题色）
2. 暗色配色方案：深色背景 `#1a1a2e` 系列、荧光强调色、终端原生感
3. 创建 `stores/theme.ts`：`currentTheme` ref（'light'|'dark'），`toggleTheme()` 方法，localStorage 持久化
4. **改造 `styles/theme.ts`**：当前 `readToken()` 在模块加载时一次性执行，生成静态 `themeConfig`。切换暗色主题后 CSS 变量值变了，但 `themeConfig` 不会重新计算。需将 `themeConfig` 改为响应式：导出 `getThemeConfig()` 函数，App.vue 监听 `currentTheme` 变化时重新调用生成新 config 并传给 ConfigProvider
5. App.vue 监听 `currentTheme` 变化，更新 `document.documentElement.dataset.theme` 和 ConfigProvider 的 `theme` prop
6. TopNav 添加太阳/月亮图标切换按钮

**Patterns to follow:** 现有 tokens.css 的变量命名模式；theme.ts 的 `readToken()` 运行时映射

**Test scenarios:**
- 点击切换按钮，界面从浅色切换到暗色
- 所有组件在暗色主题下正常显示（文字可读、对比度足够）
- 代码块在暗色主题下使用 Catppuccin Mocha 配色
- 主题偏好保存到 localStorage，刷新后恢复
- 切换过渡平滑（CSS transition on color variables）

**Verification:** 手动测试暗色主题下所有页面的显示效果。

---

### U8. 组件样式统一

**Goal:** 所有组件统一引用 Design Token，消除硬编码值。

**Requirements:** R12

**Dependencies:** U7

**Files:**
- `src/agentkit/server/frontend/src/components/layout/SideNav.vue` — 替换硬编码颜色
- `src/agentkit/server/frontend/src/App.vue` — 替换 `!important` 全局覆盖为 Token 驱动
- 各组件 scoped 样式中的硬编码值逐一替换

**Approach:**

1. 全局搜索 `rgba(`、`#` 开头的硬编码颜色值（排除 tokens.css 本身）
2. 逐一替换为对应的 CSS 变量引用
3. App.vue 中的 Ant Design 全局覆盖从 `!important` 改为通过 ConfigProvider token 注入
4. 确保暗色主题下替换后的变量值正确

**Patterns to follow:** tokens.css 的变量命名；theme.ts 的 readToken() 映射

**Test scenarios:**
- 零硬编码颜色值（tokens.css 除外）
- 浅色和暗色主题下所有组件样式一致
- Ant Design 组件通过 ConfigProvider token 驱动样式
- 无 `!important` 覆盖（特殊情况除外）

**Verification:** 代码搜索确认无硬编码颜色值；双主题视觉验证。

---

### U9. @-mention Autocomplete 前端

**Goal:** 对话输入框中输入 `@` 触发下拉选择器，支持四类引用，选中后显示为 ContextPill。

**Requirements:** R13, R15

**Dependencies:** U1

**Files:**
- `src/agentkit/server/frontend/src/components/chat/ChatInput.vue` — 添加 @-mention 触发和选择逻辑
- `src/agentkit/server/frontend/src/components/chat/MentionDropdown.vue` — 新建下拉选择器组件
- `src/agentkit/server/frontend/src/api/client.ts` — 添加 mention-suggest API 调用
- `src/agentkit/server/frontend/src/api/types.ts` — 添加 MentionItem 类型定义 + 扩展 WsClientMessage 添加 `mentions` 字段

**Approach:**

1. 定义 `MentionItem` 类型：`{type: 'file'|'skill'|'workflow'|'agent', id: string, label: string, icon?: string, description?: string}`
2. ChatInput 监听输入，检测 `@` 字符触发 MentionDropdown
3. MentionDropdown 调用 `/api/v1/portal/mention-suggest?q=keyword` 获取建议列表
4. 选中后生成 ContextPill 添加到 `contextPills` 数组（复用现有 ContextPillData 接口，扩展 type/id 字段）
5. 发送消息时，将 mentions 数组附加到 WebSocket 消息
6. **R15 覆盖**：ChatMessage 渲染时检测消息的 mentions 元数据，将 @引用渲染为可点击的标签/链接（点击跳转到对应面板或打开详情）

**⚠ 前后端协议耦合**：U9 和 U10 必须在同一迭代内同步交付，否则 WebSocket 协议不兼容。

**Patterns to follow:** 现有 ContextPill 数据结构；Ant Design Vue 的 AutoComplete/Select 组件模式

**Test scenarios:**
- 输入 `@` 触发下拉选择器
- 输入 `@文件名` 过滤显示匹配的知识库文档
- 输入 `@技能名` 过滤显示匹配的技能
- 输入 `@工作流名` 过滤显示匹配的工作流
- 输入 `@Agent名` 过滤显示匹配的 Agent
- 选中引用项后显示为 ContextPill
- ContextPill 可点击删除
- 发送消息时 mentions 数组正确附加

**Verification:** 手动测试四类 @-mention 的 autocomplete 和选择流程。

---

### U10. @-mention 后端上下文注入

**Goal:** 后端解析 @-mention 引用，将对应内容注入 Agent 推理上下文。

**Requirements:** R14

**Dependencies:** U9

**Files:**
- `src/agentkit/server/routes/portal.py` — 解析 mentions，注入上下文
- `src/agentkit/server/routes/portal.py` — 新增 `/portal/mention-suggest` 端点

**Approach:**

1. 新增 `GET /api/v1/portal/mention-suggest?q=keyword` 端点，聚合查询知识库文档、技能、工作流、Agent，返回 `MentionItem[]`
2. WebSocket 消息中解析 `mentions` 字段
3. 根据 mention_type 和 id 查询对应内容：
   - `file` → 从 KnowledgeBase 检索文档片段
   - `skill` → 从 SkillRegistry 获取技能描述和工具定义
   - `workflow` → 从 WorkflowStore 获取工作流定义
   - `agent` → 从 AgentPool 获取 Agent 配置
4. 将引用内容作为结构化上下文注入 system_prompt 或 messages

**Patterns to follow:** 现有 portal.py 的路由和 CostAwareRouter 模式；各 Registry 的查询 API

**Test scenarios:**
- `/mention-suggest?q=test` 返回匹配的文件、技能、工作流、Agent
- @文件引用后，Agent 回复中引用了文档内容
- @技能引用后，Agent 使用了指定技能
- @工作流引用后，Agent 了解工作流定义
- @Agent 引用后，Agent 了解目标 Agent 的能力
- 多个 @-mention 同时使用，所有引用内容均注入
- 无效引用（ID 不存在）优雅降级，不阻塞对话

**Verification:** 手动测试各类 @-mention 的上下文注入效果。

---

### U11. 过渡动画

**Goal:** 为所有交互添加过渡动画。

**Requirements:** R16

**Dependencies:** U1

**Files:**
- `src/agentkit/server/frontend/src/styles/transitions.css` — 确认/补充动画类
- `src/agentkit/server/frontend/src/components/layout/QuadrantPanel.vue` — Tab 切换淡入淡出
- `src/agentkit/server/frontend/src/components/layout/AgentLayout.vue` — 路由切换动画
- 各列表渲染组件 — 交错渐入

**Approach:**

1. 确认 transitions.css 中已有 fade、collapse、scale、stagger-list 类
2. QuadrantPanel Tab 切换添加 `<Transition name="fade">` 包裹
3. AgentLayout 路由切换添加 `<Transition name="fade">`
4. 列表项使用 `<TransitionGroup name="stagger-list">`
5. 所有时长引用 Design Token：`--transition-fast: 150ms`、`--transition-normal: 200ms`

**Patterns to follow:** 现有 transitions.css 的动画类定义模式

**Test scenarios:**
- 面板折叠/展开有 200ms ease 过渡
- Tab 切换有 150ms 淡入淡出
- 列表项交错渐入（stagger 50ms）
- 路由切换有 200ms 淡入淡出
- 动画不阻塞交互（使用 CSS transition 而非 JS 动画）

**Verification:** 手动测试各交互动画效果。

---

### U12. 操作反馈

**Goal:** 为用户操作提供即时反馈。

**Requirements:** R17

**Dependencies:** U7

**Files:**
- `src/agentkit/server/frontend/src/components/common/ToastService.ts` — 新建 Toast 服务
- `src/agentkit/server/frontend/src/components/chat/ChatInput.vue` — 按钮点击反馈
- `src/agentkit/server/frontend/src/components/layout/TopNav.vue` — WebSocket 断连横幅
- 各加载状态组件 — 骨架屏替代 a-spin

**Approach:**

1. 创建 ToastService：基于 Ant Design Vue 的 `message` 组件，封装 success/error/warning/info 方法
2. 按钮点击添加 `:active` 缩放反馈（CSS `transform: scale(0.97)`）
3. 加载状态：关键区域使用骨架屏（复用 transitions.css 的 `skeleton-pulse` 动画）
4. WebSocket 断连：TopNav 下方显示红色横幅提示，重连后自动消失

**Patterns to follow:** Ant Design Vue message 组件；transitions.css 的 skeleton-pulse 动画

**Test scenarios:**
- 操作成功显示绿色 Toast
- 操作失败显示红色 Toast
- 按钮点击有缩放反馈
- 加载状态显示骨架屏而非 Spin
- WebSocket 断连时顶部显示红色横幅
- 重连后横幅自动消失

**Verification:** 手动测试各类操作反馈。

---

### U13. 空状态设计

**Goal:** 为所有空状态提供品牌化插图和引导文案。

**Requirements:** R18

**Dependencies:** U7

**Files:**
- `src/agentkit/server/frontend/src/components/common/EmptyState.vue` — 新建空状态组件
- `src/agentkit/server/frontend/src/views/ChatView.vue` — 对话空状态
- `src/agentkit/server/frontend/src/views/WorkflowView.vue` — 工作流空状态
- `src/agentkit/server/frontend/src/views/EvolutionView.vue` — 监控空状态
- `src/agentkit/server/frontend/src/views/KnowledgeBaseView.vue` — 知识库空状态
- `src/agentkit/server/frontend/src/views/SkillsView.vue` — 技能空状态

**Approach:**

1. 创建 EmptyState.vue 通用组件：接受 `title`、`description`、`icon`、`action` props
2. 各视图在数据为空时渲染 EmptyState，提供引导文案和操作按钮
3. 图标使用 Ant Design Vue 的内置图标，配合品牌色

**Patterns to follow:** Ant Design Vue 的 `a-empty` 组件模式

**Test scenarios:**
- 对话空状态显示"开始你的第一次对话"引导
- 工作流空状态显示"创建第一个工作流"引导
- 监控空状态显示数据来源说明
- 知识库空状态显示"上传文档或配置信息源"引导
- 技能空状态显示"注册技能"引导
- 空状态组件在暗色主题下正常显示

**Verification:** 手动测试各视图的空状态显示。

---

### 迭代 3：能力扩展

---

### U14. Computer Use MVP 后端（pyautogui + screencapture）

**Goal:** 实现本地截屏和点击操作的后端闭环。

**Requirements:** R19, R20

**Dependencies:** None

**Files:**
- `src/agentkit/tools/computer_use_session.py` — 新增 `LocalComputerUseSession` 类
- `src/agentkit/tools/computer_use.py` — 确保工具注册和降级链正确

**Approach:**

1. 创建 `LocalComputerUseSession` 类，实现 `start()`、`stop()`、`screenshot()`、`execute_action()` 方法
2. `screenshot()` 实现：macOS 使用 `screencapture -x -t png <path>` 命令截屏，读取文件返回 base64；Linux 使用 `scrot` 或 `xdg-screenshot`
3. `execute_action()` 实现：使用 `pyautogui` 库执行点击（`pyautogui.click(x, y)`）、输入（`pyautogui.typewrite()`）、滚动等操作
4. 注册到 `ComputerUseSessionManager`，作为默认会话类型（替代 Docker stub）
5. 确保降级链正确：Anthropic API → LocalComputerUseSession → Shell 替代建议
6. 添加 `pyautogui` 到项目依赖（`pyproject.toml`）

**Patterns to follow:** 现有 `InMemoryComputerUseSession` 的接口模式；ToolRegistry 注册模式

**Test scenarios:**
- OpenCLI 会话创建和销毁正常
- 截屏返回有效的 base64 PNG 数据
- 点击操作执行并返回结果
- ComputerUseTool 的降级链正确工作
- 会话管理器正确管理 OpenCLI 会话生命周期

**Verification:** 手动测试通过对话触发截屏和点击操作。

---

### U15. Computer Use 前端面板

**Goal:** 右上面板新增 Computer Use Tab，展示截屏画面和操作历史。

**Requirements:** R21

**Dependencies:** U14

**Files:**
- `src/agentkit/server/frontend/src/views/ComputerUseView.vue` — 替换占位页为实际界面
- `src/agentkit/server/frontend/src/components/layout/AgentLayout.vue` — 右上面板添加 Computer Use Tab
- `src/agentkit/server/frontend/src/router/index.ts` — 添加 Computer Use 路由

**Approach:**

1. 重写 ComputerUseView.vue：截屏画面显示区域（支持缩放和滚动）、操作历史列表、手动截屏按钮
2. 截屏画面通过 WebSocket 接收 base64 图片数据，渲染为 `<img>` 标签
3. 操作历史显示时间戳、操作类型、坐标/参数、结果摘要
4. 手动截屏按钮触发后端截屏命令
5. 右上面板 QuadrantPanel 添加 Computer Use Tab

**Patterns to follow:** 现有 QuadrantPanel Tab 配置模式；WebSocket 消息处理模式

**Test scenarios:**
- Computer Use Tab 在右上面板显示
- 截屏画面正确渲染
- 截屏画面支持缩放和滚动
- 操作历史按时间倒序显示
- 手动截屏按钮触发截屏
- 暗色主题下正常显示

**Verification:** 手动测试 Computer Use 面板的截屏显示和操作历史。

---

### U16. 分割线拖拽增强

**Goal:** 拖拽分割线时高亮显示，显示当前比例百分比。

**Requirements:** R24

**Dependencies:** U1

**Files:**
- `src/agentkit/server/frontend/src/components/layout/SplitPane.vue` — 添加拖拽高亮和比例显示

**Approach:**

1. 拖拽时 handle 元素添加高亮样式（加宽 + 品牌色背景）
2. 拖拽时显示比例百分比标签（如 "55%"），定位在 handle 旁边
3. 使用 CSS transition 确保高亮和标签的显示/隐藏平滑

**Patterns to follow:** 现有 SplitPane 的拖拽逻辑和 handle 样式

**Test scenarios:**
- 拖拽时分割线高亮
- 拖拽时显示当前比例百分比
- 百分比标签定位正确不遮挡内容
- 拖拽结束后高亮和标签消失

**Verification:** 手动测试拖拽交互。

---

### U17. 面板折叠缩略预览

**Goal:** 面板折叠时显示缩略内容预览。

**Requirements:** R25

**Dependencies:** U1

**Files:**
- `src/agentkit/server/frontend/src/components/layout/QuadrantPanel.vue` — 折叠时显示缩略预览

**Approach:**

1. 折叠状态下，在 Tab 栏下方显示约 60px 高的缩略预览区域
2. 预览内容根据当前活跃 Tab 类型显示：监控显示关键指标数字、技能显示技能数量、工作流显示节点缩略图
3. 预览区域使用半透明背景，不占用过多空间

**Patterns to follow:** QuadrantPanel 的折叠模式；Design Token 的间距和圆角

**Test scenarios:**
- 右上面板折叠后显示缩略预览
- 右下面板折叠后显示缩略预览
- 预览内容根据活跃 Tab 更新
- 预览区域不遮挡 Tab 栏
- 暗色主题下预览区域正常显示

**Verification:** 手动测试折叠预览效果。

---

## Scope Boundaries

**在范围内：** 见需求文档的 Scope Boundaries。

**延迟到后续迭代：**
- Cmd+K 内联编辑
- Computer Use Docker 容器化隔离
- 代码 Diff 查看器实现
- 代码 Diff Accept/Reject 回滚
- 响应式移动端适配
- httpx 连接池配置优化（U5 已实现，无需额外工作）
- A/B 测试框架和性能基准 CI
- Ant Design Vue 按需引入（unplugin-vue-components）
- ECharts 按需引入

**不在本产品身份内：**
- 多用户协作/实时协同编辑
- 插件市场
- 代码编辑器

---

## Risks & Mitigations

| Risk | Likelihood | Impact | Mitigation |
|------|-----------|--------|------------|
| @-mention 后端查询聚合性能差 | Medium | Medium — 慢速 autocomplete 影响体验 | mention-suggest 端点添加缓存（TTL 30s），结果集限制 20 条 |
| 本地截屏兼容性问题 | Medium | High — 不同 OS 环境截屏命令不同 | 检测 OS 类型选择对应命令，添加 fallback 到 InMemory 模式 |
| 暗色主题对比度不足 | Low | Medium — 部分组件在暗色下不可读 | 使用 WCAG AA 标准验证对比度，添加自动化对比度检查 |
| 消息格式增强破坏现有渲染 | Low | High — 已有消息显示异常 | MarkdownIt 插件添加 fallback，解析失败时回退到纯文本；DOMPurify 白名单扩展需谨慎测试 |
| 布局重构影响现有路由和状态 | Medium | Medium — localStorage 旧 key 导致异常 | 添加 key 版本化，旧 key 自动迁移或清理 |
| DOMPurify 白名单扩展引入 XSS | Low | High — 恶意内容可能注入 | 仅添加必要的标签和属性，不开放 `on*` 事件属性，`img` 的 `src` 限制为相对路径和已知域名 |
| Ant Design token 不跟随暗色切换 | Medium | Medium — 组件颜色不一致 | 改造 theme.ts 为响应式，切换时重新生成 themeConfig |
| 与 001 计划的 U-unit 重叠 | High | High — 并行执行产生合并冲突 | 003 吸收 001 的重叠 U-unit，001 标注为"由 003 覆盖"，不并行执行 |

---

## System-Wide Impact

- **前端布局：** AgentLayout 从三层 SplitPane 改为两层，所有依赖象限位置的路由和状态需调整
- **前端样式：** 暗色主题影响所有组件，需全面测试
- **WebSocket 协议：** @-mention 扩展了 `WsClientMessage` 的 `mentions` 字段，需前后端同步升级
- **后端路由：** 新增 `/portal/mention-suggest` 端点，portal.py 需解析 mentions
- **工具系统：** 新增 OpenCLIComputerUseSession，ComputerUseTool 降级链调整
- **响应速度：** portal.py 的 ReActEngine 复用减少实例创建开销

---

## Outstanding Questions

**Deferred to Implementation:**
- @-mention 后端解析的具体协议细节：mentions 字段在 WebSocket 消息中的 JSON 结构
- 工具调用步骤卡片的折叠/展开交互细节：默认折叠还是展开
- 骨架屏的具体形状和占位内容
- 暗色主题的具体色值需要视觉调优
- R22/R23 对 portal.py 路径无效的决策：portal.py 使用自己的 ConversationStore（内存 dict），不使用 SessionManager，异步写入和并行工具执行对 portal 路径无影响。是否需要迁移 portal.py 到 SessionManager？

**Plan Relationship:**
- 本计划（003）吸收了 001 计划（GUI 产品化）的所有重叠 U-unit（布局重构、暗色主题、交互增强），001 计划应标注为"由 003 覆盖"，避免并行执行产生合并冲突

---

## Sources & Research

- 需求文档：`docs/brainstorms/2026-06-13-agentkit-platform-experience-upgrade-requirements.md`
- 响应速度优化计划（U1-U4 已实现）：`docs/plans/2026-06-12-021-feat-chat-response-speed-optimization-plan.md`
- GUI 产品化计划（前一轮）：`docs/plans/2026-06-13-001-feat-gui-productization-plan.md`
- 前端产品化计划：`docs/plans/2026-06-12-023-feat-frontend-productization-plan.md`
- 现有 Design Token 体系：`src/agentkit/server/frontend/src/styles/tokens.css`
- 现有 WebSocket 协议：`src/agentkit/server/frontend/src/api/types.ts`
- 现有 Computer Use 工具：`src/agentkit/tools/computer_use.py`、`src/agentkit/tools/computer_use_session.py`
