新增: todo 标 Wave2 完成 + docs 落地 aichat 审查报告/构想
- todo: AR-2/3/4 标完成 + 已完成区加 WF-F(含审查误判记录) - docs 落地 3 份历史遗留(todo/memory 指针此前断链):aichat-review-2026-06-14.md(审查报告,todo AR 段引用)+ aichat-async-approval-concept.md + aichat-info-density-concept.md(构想) - task-advance-concept.md 为 Wave2 agent 越权自主产出,保留未追踪待评估
This commit is contained in:
64
docs/02-架构设计/aichat-async-approval-concept.md
Normal file
64
docs/02-架构设计/aichat-async-approval-concept.md
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
# 构想:对话 AI 异步审批 — 2026-06-14
|
||||||
|
|
||||||
|
> 性质:功能升级构想,未实现。记录用户提出的方向 + 可行性评估。
|
||||||
|
|
||||||
|
## 构想
|
||||||
|
|
||||||
|
对话 AI 的对话与审批改成**异步审批**:审批 pending 时不卡住整个对话,用户可继续聊别的,审批挂着随时处理。
|
||||||
|
|
||||||
|
## 痛点:当前同步审批卡住对话
|
||||||
|
|
||||||
|
当前审批是同步阻塞模型:
|
||||||
|
|
||||||
|
1. LLM 返回 Medium/High `tool_calls` → `process_tool_calls`(`audit.rs:170-191`)推 `pending_approvals` + 占位 `tool_result`("需要用户审批,等待确认")→ agentic loop `return`(`agentic.rs:184-192`),**`generating` 保持 true**。
|
||||||
|
2. 等待期间:`session.generating = true` → 新 `ai_chat_send` 直接 `Err("AI 正在生成中")`(`commands.rs:45`)→ 前端 `sendMessage` 把新消息入队(`useAiSend.ts:36`),`streaming = true` 输入框变停止按钮。
|
||||||
|
3. 用户必须先审批(或 stop)才能继续对话。**整个对话被审批阻塞。**
|
||||||
|
|
||||||
|
典型困扰:AI 提出待审批操作,用户想先问个别的(比如"等等,这个项目之前是不是建过?"),被阻塞,必须先处理审批。
|
||||||
|
|
||||||
|
## 难点分析
|
||||||
|
|
||||||
|
异步审批的真正难点不在 UI,而在 **agent loop 的语义**:
|
||||||
|
|
||||||
|
- 同步模型:LLM 发 tool_call → 占位 tool_result → loop 挂起 → 审批后 tool_result 替换为真实结果 → LLM 据真实结果生成下一步。上下文连贯。
|
||||||
|
- 异步模型:若审批 pending 时对话继续,LLM 已基于"占位结果"生成后续 → 审批结果回流时上下文已前进 → 不一致。
|
||||||
|
|
||||||
|
核心瓶颈是 `AiSession` 单例 + `generating` 单标志互斥(防并发混乱)。异步审批 + 并发对话需要 AiSession 多实例化或 sub-session——正是 [[aichat-arch-extensibility]] 记录的"剩四空壳/AiSession 单例未动"部分,属 B 路线。
|
||||||
|
|
||||||
|
## 方案分两档
|
||||||
|
|
||||||
|
### 档位一:轻量 — 跨对话异步(推荐先做)
|
||||||
|
|
||||||
|
审批 pending 的对话挂起(释放 generating 锁),用户**切到别的对话**继续聊,审批在原对话挂着,通过后结果回流原对话。
|
||||||
|
|
||||||
|
- 触及:AiSession 从单例 → 多对话独立状态(每对话一个活跃 loop 槽)。
|
||||||
|
- 不触及:同对话内 agent loop 语义不变(同对话内审批仍阻塞)。
|
||||||
|
- 复杂度:中等,是 B 路线(AiSession 多实例化)的一部分。
|
||||||
|
- 价值:解决"审批时想干别的"主诉求(切对话即可),不破坏 agent 语义。
|
||||||
|
|
||||||
|
### 档位二:完整 — 同对话异步
|
||||||
|
|
||||||
|
审批不阻塞同一对话,用户在同一对话里继续发消息,审批通过后工具结果作为新上下文回流。
|
||||||
|
|
||||||
|
- 触及:agent loop 语义重设计——LLM 上下文如何处理"待执行工具"(标记转审批?LLM 基于"已转人工"假设继续?)。
|
||||||
|
- 可能形态:审批转独立审批队列/通知中心,对话流遇到待审批工具不阻塞,告知"有 N 个待审批"后继续;审批通过后台执行工具,结果追加为新消息。
|
||||||
|
- 复杂度:高,接近重做 agent loop。
|
||||||
|
- 风险:LLM 上下文一致性、工具结果时效性、多任务并发安全。
|
||||||
|
|
||||||
|
## 评估
|
||||||
|
|
||||||
|
| 维度 | 档位一(跨对话异步) | 档位二(同对话异步) |
|
||||||
|
|------|---------------------|----------------------|
|
||||||
|
| 解决主诉求 | ✅ 切对话即可继续 | ✅ 同对话继续 |
|
||||||
|
| 架构改动 | AiSession 多实例化 | agent loop 语义重设计 |
|
||||||
|
| 与 B 路线 | 一部分 | 接近独立重做 |
|
||||||
|
| 风险 | 中(并发状态管理) | 高(上下文一致性) |
|
||||||
|
| 建议 | 先做 | 评估后定 |
|
||||||
|
|
||||||
|
**建议**:作为 B 路线一部分,先做档位一(跨对话异步),需先完成 AiSession 多实例化。档位二待 agent 能力升级时再评估。
|
||||||
|
|
||||||
|
## 关联
|
||||||
|
|
||||||
|
- 触及 [[aichat-arch-extensibility]] 记录的 AiSession 单例瓶颈。
|
||||||
|
- 与 [[aichat-roadmap-ab-split]] B 路线(补决策/并发能力)相关。
|
||||||
|
- 当前同步审批的其他问题(审批态 stop 卡死、新建对话破坏 session)见 `aichat-review-2026-06-14.md` H2/H3,异步化时一并解决。
|
||||||
102
docs/02-架构设计/aichat-info-density-concept.md
Normal file
102
docs/02-架构设计/aichat-info-density-concept.md
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
# 构想:AI Chat 信息密度优化 — 折叠 + 会话详情面板 — 2026-06-14
|
||||||
|
|
||||||
|
> 性质:功能升级构想(瞬时灵感),未实现。记录作为后期优化参考。
|
||||||
|
|
||||||
|
## 背景
|
||||||
|
|
||||||
|
提高 AI chat 对话区有用信息密度。当前长回复/代码块/历史轮次全展开,信息密度低,关键内容被淹没。两个构想:① 卡片与消息折叠策略;② 会话详情面板组件。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 构想一:卡片与消息折叠
|
||||||
|
|
||||||
|
### 当前折叠现状(2026-06-14 探索)
|
||||||
|
|
||||||
|
**已有折叠**:
|
||||||
|
- 工具卡片:卡片级折叠(`ToolCardList.vue` expandedCards)+ read_file 内容级折叠(expandedTools,max-height 180px + 渐隐)+ list_directory max-height 220px + 通用 result max-height 100px。
|
||||||
|
- `shouldKeepOpen`:running/pending_approval/rejected/write_file 保持展开。
|
||||||
|
- auto-collapse(`AiChat.vue:639-667` watch):新内容追加时收起旧已完成/已拒绝卡。
|
||||||
|
- 侧栏归档分组可折叠。
|
||||||
|
|
||||||
|
**未折叠(可优化)**:
|
||||||
|
- AI 消息正文:template `AiChat.vue:191-198` `v-html` 全展开,长 markdown 无截断。
|
||||||
|
- 代码块:markdown `pre code` 无折叠(`:1103-1118` 仅样式)。
|
||||||
|
- 用户消息:`ai-msg-bubble--user` 全展开(`:1058`)。
|
||||||
|
- 同消息多 toolCall:逐卡渲染,无聚合。
|
||||||
|
- 历史 agent 轮次:每轮独立气泡全展开,无折叠。
|
||||||
|
|
||||||
|
### 可折叠优化点
|
||||||
|
|
||||||
|
| 对象 | 当前 | 折叠策略建议 |
|
||||||
|
|------|------|-------------|
|
||||||
|
| AI 消息正文 | 全展开 | >N 行(如 15)截断 + 渐隐 + "展开"(复用 read_file 卡的 max-height + ::after 模式);折叠态显示首行摘要 |
|
||||||
|
| 代码块 | 全展开 | >20 行折叠,显示"展开 N 行";默认显示首尾几行 |
|
||||||
|
| 用户消息 | 全展开 | >5 行折叠为摘要 + "展开" |
|
||||||
|
| 同消息多 toolCall | 逐卡 | ≥3 个聚合成"完成 N 个工具调用 [展开]",展开后逐卡(已有 auto-collapse 配合) |
|
||||||
|
| 历史 agent 轮次 | 每轮全展开 | 非最新轮折叠为单行(轮次标识 + 文本摘要 + 工具数),点击展开 |
|
||||||
|
| 错误消息 | 各自气泡 | 连续多条错误可堆叠折叠 |
|
||||||
|
|
||||||
|
### 设计原则
|
||||||
|
- 折叠态必须有**摘要**(避免光秃秃):AI 消息取首行/工具卡已有 `toolResultSummary`。
|
||||||
|
- 最新/活跃内容默认展开,历史默认折叠(与现有 auto-collapse 一致)。
|
||||||
|
- 流式生成中不折叠(避免重渲染抖动,与 H1 流式重解析问题联动)。
|
||||||
|
- 折叠状态可记忆(同会话内持久,刷新重置)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 构想二:会话详情面板
|
||||||
|
|
||||||
|
> 在 AI Chat 对话面板增加"会话详情"功能组件,聚合展示当前会话的全维度信息。
|
||||||
|
|
||||||
|
### 功能建议
|
||||||
|
|
||||||
|
**1. 当前会话整体信息**
|
||||||
|
- 标题 / provider / model / conversation_id
|
||||||
|
- token 总量(prompt + completion,来自 conversation 表累加字段)
|
||||||
|
- 消息数 / 工具调用数 / 审批数(通过/拒绝/待审)
|
||||||
|
- 创建时间 / 更新时间 / 持续时长
|
||||||
|
|
||||||
|
**2. 历史整体对话**
|
||||||
|
- 侧栏已有对话列表;详情面板补:搜索(标题/内容)、按时间/provider/状态筛选、批量归档/删除、导出(Markdown/JSON)。
|
||||||
|
|
||||||
|
**3. 审计类能力**
|
||||||
|
- 工具执行时间线(来自 `ai_tool_executions` 表:tool_name / arguments / result / status / risk_level / requested_at / executed_at / decided_by)。
|
||||||
|
- 风险分布(Low/Medium/High 统计)、审批通过率。
|
||||||
|
- token 消耗趋势(按轮次/按时间)。
|
||||||
|
- 决策记录跳转(若有 DecisionJournal 关联)。
|
||||||
|
|
||||||
|
**4. 快捷获取某类信息**
|
||||||
|
- 按工具类型筛选(只看 read_file / 只看 create_project)。
|
||||||
|
- 按风险/状态筛选(只看待审批)。
|
||||||
|
- 关键词搜消息全文。
|
||||||
|
- 时间范围筛选。
|
||||||
|
|
||||||
|
### 后端数据支撑(已有,无需新建)
|
||||||
|
|
||||||
|
| 数据 | 来源 |
|
||||||
|
|------|------|
|
||||||
|
| 对话元信息 + token | `conversations` 表(title/model/provider_id/prompt_tokens/completion_tokens/messages),`conversation.rs` 累加 |
|
||||||
|
| 工具执行审计 | `ai_tool_executions` 表,`audit.rs` 写入 + `list_pending` / `find_by_tool_call_id` 查询 |
|
||||||
|
| 消息全文 | `ai_conversation_detail` IPC(已返回 messages JSON) |
|
||||||
|
|
||||||
|
**待补 IPC**:工具执行按 conversation 聚合查询(现有 list_pending / find_by_tool_call_id,需加 by_conversation 全量时间线);token 趋势(按轮次拆分,当前只存总量)。
|
||||||
|
|
||||||
|
### 组件设想
|
||||||
|
- 入口:header 加"详情"按钮,或对话项右键菜单。
|
||||||
|
- 形态:侧滑面板(drawer,不离开对话)/ modal / 独立路由(/ai-detail/:id)。
|
||||||
|
- 结构:Tab 分「概览 / 审计时间线 / 消息检索」。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 评估
|
||||||
|
|
||||||
|
| 构想 | 复杂度 | 依赖 | 建议 |
|
||||||
|
|------|--------|------|------|
|
||||||
|
| 折叠策略 | 中 | 纯前端,复用现有 max-height 模式 | 优先做 AI 消息正文 + 代码块折叠,收益最大 |
|
||||||
|
| 会话详情面板 | 中高 | 前端新组件 + 后端补聚合 IPC | 审计时间线最有价值(数据已在),先做概览 + 审计两 tab |
|
||||||
|
|
||||||
|
两者都与信息密度相关:折叠压缩单条信息,详情面板聚合全局信息。可并行推进。
|
||||||
|
|
||||||
|
## 关联
|
||||||
|
- 折叠与 [[devflow-aichat-review-pending]] H1(流式重解析)联动——流式中不折叠,完成后折叠。
|
||||||
|
- 会话详情审计能力复用 audit.rs 已有审计表。
|
||||||
225
docs/02-架构设计/aichat-review-2026-06-14.md
Normal file
225
docs/02-架构设计/aichat-review-2026-06-14.md
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
# aichat 审查报告 — 2026-06-14
|
||||||
|
|
||||||
|
> 性质:只审查不改代码。本报告汇总本次会话对 devflow AI chat 全链路的核对发现。
|
||||||
|
|
||||||
|
## 审查范围
|
||||||
|
|
||||||
|
- **前端**:`src/components/AiChat.vue` + `src/composables/ai/*.ts`(events/stream/send/conversations/window/panel 六个)+ `src/components/ToolCard*.vue` + `src/views/AiDetached.vue` + `src/App.vue` 面板挂载
|
||||||
|
- **后端**:`src-tauri/src/commands/ai/*.rs`(commands/agentic/audit/stream_recv)+ `crates/df-ai/src/context.rs` + `src-tauri/src/commands/ai/tool_registry.rs`
|
||||||
|
- **i18n** + **数据联动机制** + **工具定义**
|
||||||
|
|
||||||
|
发现分六块:交互流畅性 / 信息卡片完整性 / clean 与压缩对话 / create_project 双审 / 数据联动方案 / 想法→灵感迁移。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、AI chat 交互流畅性
|
||||||
|
|
||||||
|
### 🔴 高危
|
||||||
|
|
||||||
|
**H1 流式 Markdown 全量重解析** — `AiChat.vue:343-354` `renderMd` 缓存 key 是完整文本。流式时 `currentText` 每 delta 都变 → 每次新 key → 缓存几乎不命中 → 每个 token 都 `marked.parse(全文) + DOMPurify.sanitize(全文)`。长回复(1000+ 字 + 代码块)时主线程阻塞、光标掉帧。**流式不流畅的主因。**
|
||||||
|
|
||||||
|
**H2 审批 pending 中新建对话永久卡死** — `ai_conversation_create`(`commands.rs:362-375`)**缺 generating 守卫**(对比 `ai_conversation_switch` 有只读保护),直接 `messages.clear()` + `pending_approvals.clear()`。而审批等待期间 `generating 保持 true`(`agentic.rs:192`)。触发链:待审批时点新对话 → 后端 session 被清空 → 用户审批 → `ai_approve` 因 pending 已清返回 Err(`commands.rs:115`)→ generating 永不复位 → 审批态看门狗已 clear(`useAiEvents.ts:143`)无兜底 → **面板卡死需重启**。
|
||||||
|
|
||||||
|
**H3 审批态 stop 无本地兜底** — `stopChat`(`useAiSend.ts:111-113`)只 `await aiApi.stopChat()`,不改 `state.streaming`,依赖后端 `AiCompleted`。审批态 stop 后端确实 emit(`commands.rs:241`),但审批态看门狗已 clear(`useAiEvents.ts:143`),若 `AiCompleted` 竞态丢失 → streaming 永久 true 无兜底 → 卡死。
|
||||||
|
|
||||||
|
### 🟡 中危
|
||||||
|
|
||||||
|
**M1 流式 delta 无节流** — `stream_recv.rs` 逐 chunk `app.emit(AiTextDelta)`,前端同步 `state.currentText += delta`。每 delta:IPC 序列化 + Vue reactive + renderMd 全量解析(叠加 H1)+ scrollToBottom。后端无 50ms 合批,前端无 rAF/throttle。
|
||||||
|
|
||||||
|
**M2 scrollToBottom 高频强制滚** — `AiChat.vue:625-633` watch `currentText` → `onContentChange` → 在底部则 `nextTick(scrollToBottom)`。每 delta 强制 `scrollTop = scrollHeight`,大 DOM 重排掉帧。
|
||||||
|
|
||||||
|
**M3 Low 工具失败语义冲突** — `audit.rs` Low 工具失败 emit `AiError`,但 `process_tool_calls` 返回 `pending_count=0`,`agentic.rs:195` 续下一轮。前端收 AiError 置 streaming=false + 错误气泡,后端 loop 仍跑,后续 delta 继续追加(handleEvent delta 分支不检查 streaming),最终 AiCompleted 又 flushCurrentText 写残留文本 → 一次错误又"完成",状态紊乱。
|
||||||
|
|
||||||
|
**M4 friendlyError 硬编码中文** — `useAiEvents.ts:42-48` 错误提示硬编码中文,绕过 i18n。看门狗超时文案(`useAiStream.ts:29`)同样。en 用户看到中文。
|
||||||
|
|
||||||
|
**M5 分离窗口与主窗口 state 完全隔离** — 独立 webview → 独立 JS realm → 独立 `state` 单例。localStorage 只快照生成态初始文本,不解决双向同步。detach 后两窗口 messages/conversations 各自独立,一边操作另一边看不到。
|
||||||
|
|
||||||
|
**M6 AiChat 卸载不调 stopListener** — `AiChat.vue` 无 `onUnmounted`。面板 v-if 开关销毁重建 AiChat,但 `stopListener`(`useAiEvents.ts:240`)从不调用,Tauri listener 累积泄漏(幂等防住重复注册,但旧 listener 不释放)。
|
||||||
|
|
||||||
|
### 🟢 低危
|
||||||
|
|
||||||
|
**L1 队列续发失败丢消息** — `useAiSend.ts:25-29` `drainQueue` 先 `queue.shift()` 再 `void sendMessage`,IPC 失败时 catch 回滚 streaming + 移除空气泡,但消息已 shift 丢失无回滚入队。理论竞态,正常路径(AiCompleted 时后端 generating 已 false)不撞。
|
||||||
|
|
||||||
|
**L2 生成中切 provider 无守卫** — `AiChat.vue:458-464` `cycleProvider` 生成中可切,当前回复仍用旧 provider(spawn 快照),provider bar 立即显示新名 → 用户误判。
|
||||||
|
|
||||||
|
**L3 handleKeydown Escape 分支冗余** — `AiChat.vue:532-536` 与 `:554-558` 两处 Escape 判断,逻辑可工作但分叉冗余。
|
||||||
|
|
||||||
|
**L4 selectSkill/clearSkill 未 autoResize** — `:409-419` 清空 inputText 不调 autoResize,textarea 可能残留高度。
|
||||||
|
|
||||||
|
**L5 deep watch + JSON.stringify 快照** — `AiChat.vue:639-667` watch messages(deep)每次 `JSON.stringify` 整数组。流式 delta 不触发,工具密集轮次时开销可见。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、信息卡片完整性(审批/工具卡片)
|
||||||
|
|
||||||
|
> 用户反馈:"只有 1 个 ID,根本不知道审批要做什么"。核对所有 Medium/High 审批工具。
|
||||||
|
|
||||||
|
### 三层缺陷
|
||||||
|
|
||||||
|
**缺陷 1 — 审批 reason 两句固定模板**(`audit.rs:179-182`):
|
||||||
|
```rust
|
||||||
|
let reason = match risk_level {
|
||||||
|
RiskLevel::High => "高风险操作,必须人工批准".to_string(),
|
||||||
|
_ => "创建操作,请确认是否执行".to_string(),
|
||||||
|
};
|
||||||
|
```
|
||||||
|
所有 High 文案相同,所有 Medium 文案相同,**不含操作对象**。
|
||||||
|
|
||||||
|
**缺陷 2 — id/project_id 原样展示**(`ToolCard.vue:149-169` `toolArgsEntries` + `formatArgValue`):字符串直接展示(截断 300),`id`/`project_id` 以裸值出现。
|
||||||
|
|
||||||
|
**缺陷 3 — 完成态 resultSummary 缺 delete/restore/purge 分支**(`ToolCard.vue:272-288`):这三类完成后只显示 header + 裸 JSON `{"deleted":true,"id":"..."}`。
|
||||||
|
|
||||||
|
### 逐工具核对表
|
||||||
|
|
||||||
|
| 工具 | 风险 | args | 裸 id | 审批卡片可见性 |
|
||||||
|
|------|------|------|-------|--------------|
|
||||||
|
| **delete_project** | High | `id` | id | 🔴 "Delete Project" + `id=proj_xxx` + 模板 reason,完全不知删哪个 |
|
||||||
|
| **restore_project** | High | `id` | id | 🔴 同上 |
|
||||||
|
| **purge_project** | High | `id` | id | 🔴 永久删除却不知删啥 |
|
||||||
|
| update_project | Med | `id, field, value` | id | 🟡 改什么可读,对象不可读 |
|
||||||
|
| bind_directory | Med | `id, path` | id | 🟡 path 可读,哪个项目不可读(用户实测反馈) |
|
||||||
|
| create_task | Med | `project_id, title, ...` | project_id | 🟡 title 可读,归哪个项目不可读 |
|
||||||
|
| create_project | Med | `name, description` | 无 | ✅ |
|
||||||
|
| create_idea | Med | `title, ...` | 无 | ✅ |
|
||||||
|
| write_file | Med | `path, content` | 无 | ✅ |
|
||||||
|
| run_workflow | High | `name, dag` | 无 | 🟡 name 可读,dag 庞大 |
|
||||||
|
|
||||||
|
**9 个审批工具:3 个完全不可用,3 个对象不可读,仅 3 个完整。**
|
||||||
|
|
||||||
|
### 修复方向
|
||||||
|
- P0 后端 emit `AiApprovalRequired` 前按工具查对象名拼 reason(如"删除项目「前端重构」(id=xxx),移入回收站")。
|
||||||
|
- P0 前端 `toolArgsEntries` 对 id/project_id 特化(查 store 或后端 args 补 `__label`)。
|
||||||
|
- P1 `toolResultSummary` 补 delete/restore/purge case。
|
||||||
|
- P1 `toolDisplayName` CRUD 类从 args 取 name/title 拼上。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、clean(清空对话)与压缩对话
|
||||||
|
|
||||||
|
### clean — ❌ 具备但不可用
|
||||||
|
|
||||||
|
| 维度 | 状态 |
|
||||||
|
|------|------|
|
||||||
|
| 后端 `ai_chat_clear` | ✅ `commands.rs:215-220` |
|
||||||
|
| 前端 `clearChat` | ✅ `useAiPanel.ts:89-96` |
|
||||||
|
| **UI 入口** | ❌ 零组件调用(grep clearChat 仅命中 api/composable/store,AiChat.vue 无按钮) |
|
||||||
|
| 语义 | ❌ 只清内存 session 不删 DB,刷新恢复 |
|
||||||
|
|
||||||
|
### 压缩对话 — ❌ 不具备
|
||||||
|
|
||||||
|
- 无显式压缩/总结功能(grep compress/compact/summarize 仅命中 context.rs 的"裁剪")。
|
||||||
|
- 无 `/compact` 命令、无压缩技能、无对话总结。
|
||||||
|
- 唯一相关:`ContextManager.build_for_request`(`context.rs:215-264`)预算感知裁剪——超 token 预算(默认 128k,0.85 安全 → budget ≈102k)自动丢弃旧消息,保留工具三元组原子性 + 最近 6 条(保护区)。
|
||||||
|
- 裁剪机制本身良好(三元组原子、视图不污染持久化、有测试),但**是滑动窗口丢弃非摘要压缩**,且 128k 窗口日常难触发。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、create_project 双审双 API(用户实测痛点)
|
||||||
|
|
||||||
|
### 根因:AI 工具 schema 比 IPC 接口窄
|
||||||
|
|
||||||
|
| 层 | create_project 参数 | 建带目录项目 |
|
||||||
|
|----|---------------------|-------------|
|
||||||
|
| IPC `create_project`(`project.rs:43-83`) | name, description, idea_id, **path, stack** | ✅ 一步完成(校验+防重复+探测 stack) |
|
||||||
|
| AI 工具 `create_project`(`tool_registry.rs:148`) | name, description(**无 path**) | ❌ 只能建空项目,handler 写死 path=None(:159) |
|
||||||
|
|
||||||
|
→ LLM 建带目录项目被逼拆两步:`create_project`(Medium 审1 + LLM 轮次1)→ `bind_directory`(Medium 审2 + LLM 轮次2)= **双审批双 API**。IPC 本可一步完成,AI 工具没用上。
|
||||||
|
|
||||||
|
### 方案
|
||||||
|
`create_project` AI 工具 schema 加可选 `path`/`stack`(对齐 IPC `CreateProjectInput`),handler 复用 IPC 的绑定+探测逻辑。`bind_directory` 保留用于后期改绑(relocate)。
|
||||||
|
|
||||||
|
### 关联
|
||||||
|
问题 1 修好后 `bind_directory` 使用频率大降(只剩改绑),第二章 bind_directory 信息缺口随之缓解;但 bind_directory 仍需补信息完整性。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、数据变更联动刷新方案
|
||||||
|
|
||||||
|
> 需求:AI chat 工具执行产生数据变更 → 左侧已打开视图(Projects/Tasks/Ideas/Dashboard)自动刷新。
|
||||||
|
|
||||||
|
### 现状缺口
|
||||||
|
- `useProjectStore` 单例持 projects/tasks/ideas,各 view onMounted 调 loadXxx(Ideas.vue:444 / ProjectDetail.vue:412 / Dashboard.vue:212)。
|
||||||
|
- **无应用级事件总线**(grep mitt/EventBus 零匹配)。
|
||||||
|
- AI 工具执行 emit `AiToolCallCompleted`,前端**只更新 ToolCard,不通知 project store** → 视图不刷新。
|
||||||
|
|
||||||
|
### 方案对比
|
||||||
|
|
||||||
|
| 方案 | 机制 | 优 | 缺 |
|
||||||
|
|------|------|----|----|
|
||||||
|
| **A 后端 emit 数据变更事件(推荐)** | 工具成功后 emit `df-data-changed {entity,action,id?}`,各 store 监听刷新 | 后端是真相源埋点准;store 自治解耦;可扩展到手动 CRUD | 需后端埋点 |
|
||||||
|
| B 前端据 `AiToolCallCompleted.name` 推断 | handleEvent 映射 entity 调 loadXxx | 零后端改动 | ai composable 耦合 project store;ai_approve 路径不走 AiToolCallCompleted 会漏 |
|
||||||
|
| C store watch AI 状态 | project store watch ai.lastToolCall | — | 跨 store 耦合最重 |
|
||||||
|
|
||||||
|
### 推荐方案 A 要点
|
||||||
|
- **后端埋点**:`audit.rs:206-214`(Low 执行成功)+ `commands.rs:148-184`(ai_approve 成功),按 tool name 映射 entity,emit `df-data-changed`。失败不 emit;run_workflow 不改实体表不 emit。
|
||||||
|
- **tool→entity 映射**:create/update/delete/restore/purge/bind_directory=project;create task=task;create/update idea=idea。
|
||||||
|
- **前端监听**:`useProjectStore` 创建时 listen,debounce + rAF 合并(一轮多 tool 只刷一次),加 loaded 标志仅刷新已加载实体。
|
||||||
|
- 分离窗口独立 realm 各自 listen 各自刷新(天然支持)。
|
||||||
|
- **未拍板**:A vs B;是否扩展到手动 CRUD 全局实时同步。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、「想法→灵感」中文文案迁移残留
|
||||||
|
|
||||||
|
> 产品决定"想法"改称"灵感",迁移半途。
|
||||||
|
|
||||||
|
### 用户可见(必改)
|
||||||
|
- `src/i18n/zh-CN/ideas.ts:18/42/65/68/71/75` — 详情/操作/模态框 6 处(页头已改灵感,这些漏改)
|
||||||
|
- `src/i18n/zh-CN/aiTool.ts:24` — `ideaCount: '{n} 条想法'`(AI 工具结果摘要)
|
||||||
|
- `src/i18n/zh-CN/projectDetail.ts:9/24/25/26` — 阶段标签/来源想法
|
||||||
|
- `src/stores/project.ts:150/160` — 错误 toast
|
||||||
|
|
||||||
|
### 后端用户可见
|
||||||
|
- `src-tauri/src/commands/idea.rs:105/108/148/152/179` — 错误信息(toast)
|
||||||
|
- `src-tauri/src/commands/ai/tool_registry.rs:112/230` — LLM 工具描述(AI 回复会用"想法")
|
||||||
|
|
||||||
|
### en 版
|
||||||
|
用 Ideas/Idea(英文术语),若产品要求统一 Inspiration 也需改,待定。
|
||||||
|
|
||||||
|
### docs + crates 注释
|
||||||
|
大量"想法"(低优先),含文件名 `docs/03-模块文档/想法探索-对抗式评估.md`。
|
||||||
|
|
||||||
|
### 根因
|
||||||
|
上次迁移只改 ideas.ts 页头区,详情/操作/模态框 + 其他 i18n + 后端错误 + LLM 工具描述未跟进。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、设计亮点(明确无问题)
|
||||||
|
|
||||||
|
| 机制 | 评价 |
|
||||||
|
|------|------|
|
||||||
|
| 流式看门狗(`useAiStream.ts`) | 无数据超时兜底,130s > 后端 120s 留余量 |
|
||||||
|
| generating 复位先于 emit(`agentic.rs:74/170/228`) | 保证前端收 AiCompleted 时后端已可接下条 |
|
||||||
|
| 错误路径 AiError 覆盖全 | idle/流中断/chunk error/provider 失败,无静默失败 |
|
||||||
|
| 工具卡片折叠自治 + auto-collapse | shouldKeepOpen 保留 running/pending/rejected/write_file |
|
||||||
|
| 审批乐观更新 + IPC 失败不回滚 | `useAiSend.ts:80-98` 防按钮卡死 |
|
||||||
|
| Markdown 懒加载 + 历史消息缓存 | 首屏不阻塞,已完成消息命中缓存 |
|
||||||
|
| 回到底部智能判断 | isNearBottom 避免上滑被打断 |
|
||||||
|
| ContextManager 裁剪 | 三元组原子、视图不污染持久化、测试覆盖 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、修复优先级
|
||||||
|
|
||||||
|
| 优先 | 问题 | 方向 |
|
||||||
|
|------|------|------|
|
||||||
|
| P0 | H1 流式 Markdown 重解析 | 流式态纯文本/增量渲染,完成后再 markdown;rAF 合并 |
|
||||||
|
| P0 | H2 审批态新建对话卡死 | `ai_conversation_create` 加 generating 守卫 |
|
||||||
|
| P0 | 第二章 审批卡片裸 id + reason 模板 | 后端 reason 拼对象名;前端 id→name |
|
||||||
|
| P0 | 第四章 create_project 双审 | AI 工具 schema 加 path/stack |
|
||||||
|
| P1 | H3 审批态 stop 无兜底 | stopChat 本地先复位 streaming |
|
||||||
|
| P1 | M3 Low 工具失败语义 | 统一 AiError 后 loop 也退出,或不 emit AiError |
|
||||||
|
| P1 | 第三章 clean 无入口 | AiChat 加清空按钮 + 后端真删当前对话消息 |
|
||||||
|
| P2 | M1+M2 delta 节流 + 滚动 | 后端 50ms 合批 / 前端 rAF |
|
||||||
|
| P2 | M4 friendlyError i18n | 抽 i18n key |
|
||||||
|
| P2 | 第六章 灵感迁移残留 | i18n + 后端错误 + LLM 描述统一改 |
|
||||||
|
| P2 | 第五章 数据联动 | 方案 A 后端 emit + store 监听 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 附:相关 memory(指针)
|
||||||
|
- `devflow-aichat-review-pending.md`
|
||||||
|
- `devflow-idea-inspiration-migration.md`
|
||||||
|
- `devflow-data-change-sync.md`
|
||||||
|
|
||||||
|
三者在 memory 中仅留指针,详情以本报告为准。
|
||||||
@@ -36,9 +36,9 @@
|
|||||||
|
|
||||||
**P0(用户可感硬伤)**
|
**P0(用户可感硬伤)**
|
||||||
- [ ] AR-1 流式 Markdown 全量重解析(renderMd 缓存 key=完整文本,每 delta 全量 marked.parse+sanitize,长回复主线程阻塞掉帧)— AiChat.vue:343-354 — ⚠️复杂,需先设计增量渲染/流式纯文本态+rAF
|
- [ ] AR-1 流式 Markdown 全量重解析(renderMd 缓存 key=完整文本,每 delta 全量 marked.parse+sanitize,长回复主线程阻塞掉帧)— AiChat.vue:343-354 — ⚠️复杂,需先设计增量渲染/流式纯文本态+rAF
|
||||||
- [ ] AR-2 审批态新建对话永久卡死(ai_conversation_create 缺 generating 守卫,直接 clear session,审批返回 Err→generating 永不复位→面板卡死需重启)— commands.rs:362-375
|
- [x] AR-2 ~~审批态新建对话卡死~~ ✅ WF-F 完成(ai_conversation_create 加 generating 守卫,位于 clear 前,对齐 switch:433 写法)(commit 057a212)
|
||||||
- [ ] AR-3 审批卡片不可读(后端 reason 两句固定模板不含对象名 + 前端 id/project_id 裸值 + resultSummary 缺 delete/restore/purge 分支)— audit.rs:179-182 + ToolCard.vue:149-169,272-288
|
- [x] AR-3 ~~审批卡片不可读~~ ✅ WF-F 完成(audit.rs build_approval_reason 按 9 工具特化拼对象名 + ToolCard resultSummary 补 restore/purge case + ARG_LABEL_MAP id 加友好标签 + i18n 双语补 4 key)(commit 057a212)
|
||||||
- [ ] AR-4 create_project 双审双 API(AI schema 仅 name/description 缺 path/stack,比 IPC 接口窄触发二次确认)— tool_registry.rs:148
|
- [x] AR-4 ~~create_project 双审双 API~~ ✅ WF-F 完成(schema 加 path/stack + handler 有 path 时合并绑定 spawn_blocking 探测栈,消除二次 bind_directory;TODO 标注可抽公共绑定函数)(commit 057a212)
|
||||||
|
|
||||||
**P1**
|
**P1**
|
||||||
- [ ] AR-5 审批态 stop 无本地兜底(stopChat 只 await 不复位 streaming,AiCompleted 竞态丢失则卡死)— useAiSend.ts:111-113
|
- [ ] AR-5 审批态 stop 无本地兜底(stopChat 只 await 不复位 streaming,AiCompleted 竞态丢失则卡死)— useAiSend.ts:111-113
|
||||||
@@ -115,6 +115,7 @@
|
|||||||
- [x] WF-C 前端(Sprint 20 ⑥⑦⑧)— 扫描文案 i18n + parseStack 抽公共 + 8 处 alert/confirm 换组件(commit 02ff88f)
|
- [x] WF-C 前端(Sprint 20 ⑥⑦⑧)— 扫描文案 i18n + parseStack 抽公共 + 8 处 alert/confirm 换组件(commit 02ff88f)
|
||||||
- [x] WF-D 审批闭环(B-06/B-07/B-03a)— execution_id 下沉 + 共享状态机 + HumanNode select! 实现(commit 22964a2)
|
- [x] WF-D 审批闭环(B-06/B-07/B-03a)— execution_id 下沉 + 共享状态机 + HumanNode select! 实现(commit 22964a2)
|
||||||
- [x] WF-E Wave1 收尾清债(commit 4aa689e + 89da9fa)— B-03b 审批取消端到端(StateMachine Arc<Mutex> 共享 + execution_id 注册表,**主代理补完 agent 半成品**:agent 初版 workflow_cancel_state 全局孤立实例写了读不到,Explore 审查漏抓语义缺陷)+ T-09 立项回滚级联删(delete→purge_with_descendants)+ T-10 判定已解决(normalize_path 已 canonicalize,零改)+ T-12 df-ideas 清 capture.rs 死码;cargo check / test(含 clone_shares)/ vue-tsc 全绿
|
- [x] WF-E Wave1 收尾清债(commit 4aa689e + 89da9fa)— B-03b 审批取消端到端(StateMachine Arc<Mutex> 共享 + execution_id 注册表,**主代理补完 agent 半成品**:agent 初版 workflow_cancel_state 全局孤立实例写了读不到,Explore 审查漏抓语义缺陷)+ T-09 立项回滚级联删(delete→purge_with_descendants)+ T-10 判定已解决(normalize_path 已 canonicalize,零改)+ T-12 df-ideas 清 capture.rs 死码;cargo check / test(含 clone_shares)/ vue-tsc 全绿
|
||||||
|
- [x] WF-F Wave2 aichat P0 三项(commit 057a212)— AR-2 新建对话守卫 + AR-3 审批卡片可读化(reason 拼 9 工具对象名 + restore/purge case + id 标签 + i18n)+ AR-4 create_project schema 加 path/stack 合并绑定;**审查 boundary 全误判**(3 agent 并行同工作区,审查 git diff 被三人累计改动污染互相指责越权;correctness "i18n 未添加"亦臆断),主代理独立核查三任务代码全正确,cargo check/vue-tsc 全过;遗留:task-advance-concept.md(agent 越权自主产出,保留未追踪待评估)
|
||||||
|
|
||||||
## Bug
|
## Bug
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user