Implemented a new permission mode between and , including backend policy, runtime behavior, frontend display, and documentation updates. Backend & policy changes: - Added to permission mode validation and persistence paths. - Updated tool permission evaluation: workspace-local direct pass, out-of-workspace requires approval. - Kept readonly-first flow and added auto-approval decision path when permission denial occurs. - Added approval reason/decider support in tool approval manager. - Improved rejection tool-content format to natural language: '工具调用被拒绝\n原因:...' - Fixed permission-mode sync edge cases on conversation create/load and restart-first-switch behavior. Approval agent subsystem: - Added and . - Added lightweight auto-approval config at (name/url/key/model/extra_params + timeouts). - Added optional transcript debug switch in code and transcript output under logs/approval_agent. - Aligned transcript saving toward cumulative messages format and captured reasoning/content/tool_calls/tool sequence. Frontend changes: - Added option to personalization and permission menus. - Reworked approval panel auto-review display into a dedicated block with simplified lines: start, command, final approve/reject + reason. - Added delayed sidebar auto-close (10s) after approval resolved. - Added stricter permission-switch verification and rollback on mismatch/error. Docs updated: - Synced AGENTS.md, README.md, and docs/host_sandbox_and_permission_model.md with new permission mode, approval-agent behavior, config, and current constraints (including docker caveat). |
||
|---|---|---|
| .. | ||
| analysis-conversation-loading.md | ||
| analysis-stop-button.md | ||
| analysis-task-recovery.md | ||
| host_sandbox_and_permission_model.md | ||
| mcp-tool-config-guide.md | ||
| README.md | ||
AI Agent 系统对话区域功能分析文档
本目录包含对 AI Agent 系统对话显示区域的详细功能分析,用于识别历史包袱和需要改造为纯轮询模式的部分。
📋 分析文档列表
✅ 已完成的分析
-
停止按钮和运行状态机制 (22KB)
- 停止按钮的显示/隐藏逻辑
- 运行状态的设置和清除
- WebSocket vs REST API 的停止机制
- 已知问题:状态同步、竞态条件、页面刷新恢复
-
对话记录加载机制 (21KB)
- 切换对话时的加载流程
- 历史消息的数据结构
- 防止重复加载的机制
- 初始化阶段的特殊处理
-
运行中对话恢复机制 (20KB)
- 页面刷新后的任务恢复
_rebuildingFromScratch标志的作用- 历史事件的重放机制
- 轮询的恢复逻辑
-
思考块机制 (分析已完成)
- 思考块的创建和内容追加
- 展开/折叠逻辑(流式输出 vs 历史加载)
- 自动折叠机制(1秒延迟)
- 无打字机效果,直接追加内容
-
工具块机制 (分析已完成)
- 工具块的创建和状态变化(preparing → running → completed/failed)
- tool_intent 的打字机效果(0.5-1秒)
- 工具块的堆叠和融合机制
- toolActionIndex 注册机制
- append_payload 和 modify_payload 处理
-
模型输出内容显示 (分析已完成)
- 文本流式显示(text_start/chunk/end)
- Markdown 渲染(marked.js + Prism.js + KaTeX)
- 代码块的语法高亮和复制功能
- 双事件监听系统(可能导致复制bug)
- 图片和视频的显示
⏸️ 未完成的分析
- 子智能体机制 (分析中断)
- waitingForSubAgent 状态
- sub_agent_waiting 事件
- WebSocket 在子智能体场景下的特殊作用
🎯 重点关注的问题区域
1. 停止按钮(Bug最多)
主要问题:
- 前端在后端确认前就清理状态,导致同步问题
- 多个布尔标志(taskInProgress, streamingMessage, stopRequested)难以维护
- 存在竞态条件
- 页面刷新后状态恢复复杂
涉及文件:
static/src/components/input/InputComposer.vue- 停止按钮UIstatic/src/app/methods/message.ts- 停止逻辑static/src/stores/task.ts- 任务状态管理server/tasks.py- 后端停止处理
2. 思考块和工具块
展开/折叠机制:
- 流式输出时:思考块自动展开,1秒后折叠
- 历史加载时:所有块默认折叠
- 用户手动点击:状态存储在
expandedBlocksSet(不持久化)
打字机效果:
- 思考块:无打字机效果,直接追加
- 工具块 intent:0.5-1秒打字机效果
- 历史加载时:跳过打字机效果
堆叠机制:
- 连续的思考/工具块会被分组
- 默认显示最后6个,其余折叠
- 使用 ResizeObserver 跟踪高度变化
3. 对话恢复机制
_rebuildingFromScratch 标志:
- 用于区分"从头重建"和"增量恢复"
- 影响思考块展开、工具意图动画、生成标签显示
- 页面刷新后,如果历史不完整,从 offset=0 重放所有事件
轮询恢复:
- 150ms 间隔轮询
- 通过
lastEventIndex避免重复处理 - 支持从任意 offset 恢复
4. 代码块复制功能
可能的Bug原因:
- 双事件监听系统(全局 + Vue方法)
- Clipboard API 权限问题
- HTML 实体编码/解码问题
- 流式输出时按钮添加时机
实现位置:
static/index.html- 全局事件监听static/src/app/methods/ui.ts- Vue 复制方法static/src/app/bootstrap.ts- Markdown 渲染初始化
🔄 WebSocket vs 轮询模式
当前状态
系统已设置 usePollingMode: true,大部分聊天事件通过 REST API 轮询处理。
WebSocket 仍在使用的场景:
- 子智能体通知(
sub_agent_waiting) - 配额更新(
quota_update) - 系统消息(
system_message) - 错误处理(
error)
事件过滤机制:
if (ctx.usePollingMode && !ctx.waitingForSubAgent) {
// 跳过 WebSocket 事件处理
return;
}
需要改造的部分
完全移除 WebSocket 依赖:
- 删除
useLegacySocket.ts中的聊天事件处理(~1200行) - 删除流式文本处理代码(
streamingState,~500行) - 统一停止逻辑到 REST API
- 子智能体通知改为 SSE(Server-Sent Events)
后端改造:
server/socket_handlers.py- 简化为仅处理连接管理server/tasks.py- 添加任务清理、重试、优先级server/chat_flow.py- 移除 WebSocket emit
📊 代码统计
前端关键文件
| 文件 | 行数 | 功能 | 需要改造 |
|---|---|---|---|
useLegacySocket.ts |
1706 | WebSocket 事件处理 | ✅ 删除聊天事件 |
taskPolling.ts |
989 | 轮询事件处理 | ⚠️ 修复bug |
task.ts (store) |
296 | 任务状态管理 | ⚠️ 添加重试 |
ChatArea.vue |
~800 | 对话显示 | ⚠️ 修复UI bug |
InputComposer.vue |
~200 | 输入框和停止按钮 | ⚠️ 简化状态 |
后端关键文件
| 文件 | 行数 | 功能 | 需要改造 |
|---|---|---|---|
socket_handlers.py |
353 | WebSocket 处理 | ✅ 移除聊天事件 |
tasks.py |
380 | 任务管理 | ⚠️ 增强功能 |
chat_flow.py |
241 | 聊天流程 | ⚠️ 移除 WebSocket |
🚀 重构优先级
优先级1(必须做)
- ✅ 修复停止按钮的状态同步问题
- ✅ 修复代码块复制功能
- ✅ 修复重复推送内容的问题
- ✅ 修复任务无法结束的问题
优先级2(建议做)
- 删除
useLegacySocket.ts中的聊天事件处理 - 统一停止逻辑到 REST API
- 添加轮询重试机制
- 任务清理机制
优先级3(可选)
- WebSocket 改为 SSE
- 任务存储改为 Redis
- 改进错误提示
📝 使用说明
- 阅读分析文档:按照上述列表顺序阅读各个分析文档
- 对比实际网页:在浏览器中打开系统,对比文档描述和实际行为
- 标记问题点:记录不一致的地方、bug、历史包袱
- 制定重构计划:根据优先级制定具体的重构步骤
🔗 相关资源
生成时间: 2026-04-04 分析工具: Claude Code + 7个并行子智能体 总分析时间: ~15分钟