squash合并: - 意图识别层论证(8维度+10业界佐证) - 多主题上下文管理愿景+并存论证+补充论证(多轮agentic) - 架构设计文档物理分类(四子目录+INDEX+命名规范+引用同步+边界清晰化) - 前端架构技术债清单归档
43 KiB
Todo 归档 2026-06-18
从 docs/todo.md 迁移的已完成项 归档日期: 2026-06-18 来源: 三文档巡检归档 (todo.md/待决策.md/待审查.md)
已完成功能需求 (F- 系列)
2026-06-16 新需求 (已实施)
-
✅(batch38·2026-06-16·workflow wx5vd8ppk) F-260616-01 [P2] — aichat Agentic 最大循环轮次支持配置(Settings)。已落地(1:1 复刻 llm_concurrency,8 处改动全闭环)。
-
✅(batch37·2026-06-16·workflow wg8x18y9y) F-260616-02 [P2] — 知识库「待审」(pending_review) 不应进第一个 tab(知识库/library)。决策 a 落地:inbox 收 candidate+pending_review,library 纯 published。
-
✅(batch44 后端 + batch45 前端·2026-06-16) F-260616-03 [P2] — aichat 达最大轮次时询问「是否继续」+ 确认后续 loop。全闭环:后端(batch44 AiMaxRoundsReached 暂停态+continue/stop IPC)+ 前端(batch45 操作卡 pendingMaxRounds+续/停按钮)。
-
✅(batch42·2026-06-16·workflow w95hzp9tw) F-260616-04 [P1] — run_command 超时→LLM 重试→反复审批循环。已根治(tool_registry.rs 超时标注「勿盲目重试」+ DEFAULT_RUN_COMMAND_TIMEOUT_SECS 常量,handler map_err 改写)。
-
✅(batch53·2026-06-16·workflow wbh8mu1iq·run_command 循环核心解决) F-260616-05 [P1](共性根治)— agentic loop 工具调用去重缺失。batch53 落地 High risk 审批前去重(audit.rs find_cached_high_risk_result 反向扫 messages + args JSON 规范化匹配 + 排除 pending 占位 + decided_by=auto_dedup,解决 run_command 反复审批循环,F-04 超时标注 + batch53 去重双保险)。
-
✅(batch56·2026-06-16·workflow wsxxurgbr+主代核查) F-260616-06 [P2] — 「未找到挂起的审批」体验。全闭环落地:①
commands.rs:217ai_approve 幂等——内存 pending_approvals remove None 时查ai_tool_executions审计表,已 executed/rejected/failed 返回「已处理({status})」非报错 ②useAiSend.ts:305审批按钮防抖——_pendingApprovalIdsSet 守卫,同 id 短期多次点击只发一次 IPC,finally 块清理。 -
✅(batch56·2026-06-16·workflow wsxxurgbr+主代核查) F-260616-07 [P2] — 流式对话失败自动重试。全闭环落地:①
agentic.rsstream_llm 调用处包重试循环(max_retries 形参,退避 1s→2s→4s,持 permit 防挤占) ②每重试 emitAiStreamRetry事件(attempt/max_attempts) ③耗尽走原有 guard.reset+return ④state.rs 加agent_max_retries:Arc<AtomicUsize>(默认3) ⑤新 IPCai_set_agent_max_retries(clamp 0-10) ⑥前端 api/ai.ts + types.ts(AiStreamRetry variant) + Settings.vue(input 0-10+debounce sync+i18n zh/en)。 -
✅(batch56·2026-06-16·workflow wsxxurgbr+主代核查) F-260616-08 [P2] — AI 数据获取工具 offset 分页 + 探总量。全闭环落地:①6 工具(list_projects/tasks/ideas/trash/read_file搜索模式/search_files)全部补 offset+limit 参数,返回 items/total/has_more 替代 truncated ②新增
get_project_count+get_task_count探总量工具 ③knowledge_search 解钳min(3)→min(20)。 -
✅(batch58·2026-06-16·workflow w2dw65maz+主代核查,vue-tsc 0err) F-260616-10 [P1·bug] — provider 切换/默认值重启·刷新后失效(前端 activeProvider 不同步 DB 默认)。用户实测:Settings 设 A 为默认 → 重启 → 默认变 B(列表第一个)。根因全在前端,后端链路正确(独立核验不信 PROGRESS.md):
ai_set_provider(commands.rs:747-774) 互斥落库✅ +update_full(crud.rs:1127) SQL UPDATE 含is_default✅ +get_active_provider(prompt.rs:9-32) 走DB.is_default✅。根因链:①重启后前端store.activeProvider = null(stores/ai.ts:53,无 localStorage 持久化 + 无启动恢复) ②loadProviders(useAiPanel.ts:91-93) 只拉列表不同步 DB 默认 → activeProvider 仍 null ③UI 错觉:activeProviderName(AiChat.vue:1169-1172) null 时 fallbackproviders[0](列表第一个) ≠ 用户设的 A → 「默认变另一个」 ④真覆盖:用户点 provider bar 切换cycleProvider(AiChat.vue:1180-1185),findIndex(activeProvider=null)返回 -1 →next = ps[(−1+1)%len] = ps[0]= 列表第一个 B →setProvider(B)→ 后端互斥落库把DB.is_default从 A 真改成 B。 -
✅(batch60合批·2026-06-16·主代核查,cargo 0err) F-260616-11 [P1·决策a累计计数] — 审批后 iteration 重置致 max_iterations/token 超配。决策(2026-06-16):a 累计计数(try_continue 不重置 iteration,跨审批续跑延续累计)。已实施:
iteration_used:usize累计字段(mod.rs:215/230AiSession+new init 0)+start_iteration:usize参数(agentic.rs:114run_agentic_loop signature +:176loop 边界start_iteration..max_iterations+:210一致性块iteration_used=iteration+1+:578try_continue 加参 +:675spawn 透传)+三处 reset(commands.rs:55/152/412ai_chat_send/ai_regenerate/ai_edit_last 新生命周期)+ai_approve 两处累计读 iteration_used(:260-262拒绝续跑 +:313-315通过续跑)+ai_continue_loop:601reset+传0(F-03 决策a 达max重计区分)。两路径严格:审批累计(ai_approve) vs 达max重计(ai_continue_loop,F-03 a 用户授权重来) vs 新消息 reset。 -
✅(batch60·2026-06-16·workflow whae812z5+主代核查,cargo 0err) F-260616-13 [P2] — build_for_request 持锁重活 + system_prompt token 每轮重估。性能分析批次发现:每轮
stream_llm前session_arc.lock()(agentic.rs:251)持锁期间做TokenEstimator::estimate_text(system_prompt)(L252)+build_for_request(L253 history clone + 裁剪)。system_prompt loop 外固定传入,每轮重估其 token 是浪费(可缓存);build_for_request 持锁做 history clone 是重活,消息多时(200 cap)锁持有期长。方向:①system_prompt token loop 外算一次缓存 ②build_for_request 先 clone messages 释放锁再裁剪。低收益优化。 -
✅(主代核验·2026-06-16) F-260616-14 [P2/核验] — max_tokens 8192 截断 + 前端批量审批核验。核验结论:①
max_tokens=8192(实际agentic.rs:270)≈6-8k 字日常够用,长回复截断由 batch59 MidStream 保文兜底不丢文,可配低优先非阻塞(登记可选优化)②前端批量审批 AE-2025-01 已完整闭环(ToolCardList.vue:4-11ai-batch-approve栏 + AiChat.vue:444@batch-approve→store.batchApprove+ useAiSend.ts:338 遍历 pendingApprovals 逐个 approveToolCall + i18n approveAll/rejectAll),满足「一轮多 Med/High 全 insert pending→一次批量批全部」③audit.rs:496process_tool_calls一轮多工具 Med/High 进审批门控 insert pending + Low 并行执行链路通。无阻塞 bug,销账。 -
✅(波4·2026-06-17·wd5a1dgqz+主代核查,cargo 0err+tool_registry 76test) F-260617-01 [P2] — patch_file 工具增强:行号区间替换 + 锚点匹配两种备选模式。当前 patch_file 仅支持
old_text精确匹配,对超长行(todo.md 单行 1000-2000 字符)+ 含大量反引号/引号/中文标点的场景,匹配极易失败(JSON 转义错位一个字符就全盘失败)。新增两种可选模式作为备选。 -
✅(波3+5+6+8·2026-06-16/17·全阶段完成) F-260616-15 [P1] — AI Chat 上下文管理增强:会话分段 + 手动压缩 + 智能裁剪。三个子需求,详见 F-15-上下文管理增强设计-2026-06-16.md。阶段1 基础部分 ✅(波3·8a142c2 is_active 白名单+push token 修正);阶段1 剩余 ✅(波5·63bff8b compress_prompt四段式+compress_via_llm+context 9辅助方法,幂等/单向不可逆/纯函数/零行为变化,df-ai 107pass);阶段2 手动功能 ✅(波6·4194842+主代核查,cargo0err+vue-tsc0+devflow79pass,2 IPC ai_chat_clear_context/compress_context+3事件 AiContextCleared/AiCompressing/AiCompressed+前端2按钮+status分组渲染+useAiContext composable,clear标archived_segment不删DB/compress LLM失败不阻塞);阶段3 自动 ✅(波8·0202b51+主代核查,cargo0err+vue-tsc0+devflow79pass,loop顶部检测budget×0.6+压缩+降级原裁剪,set_compressing成对,延迟mutate失败零副作用)。F-15 全阶段完成 ✅。
其他已完成功能需求
-
✅(workflow wfryptv2t·代理A核验已落地·2026-06-17·主代独立grep核验非误判) UX-260616-03 [P2] — 对话内容输出时自动收起旧工具卡片分组。已落地:①触发时机扩展——AiChat.vue:2093 agentRound watch(AiAgentRound 新轮次→collapseAllToolLists(buildActiveToolIds))收起上一轮;既有 messages deep watch(:2085)覆盖新消息追加+toolCall状态翻转;触发链 useAiEvents.ts:169
if(event.round>0) state.agentRound=event.round+ stores/ai.ts:75 agentRound字段。②collapseInactive增强——ToolCardList.vue:71 userExpandedCards 记忆态 Set,:180 isCardExpanded 优先读它(用户主动展开不被自动收起),:220 collapseInactive 仅清 expandedCards/expandedTools 不清 userExpandedCards。 -
✅(波2·2026-06-16·w76d81dno+主代核查,vue-tsc,决策a逐条续发) UX-260616-05 [P1] — 打断按钮只停当前回复 + 队列保留续发(不清队列)。用户需求:发送队列有消息时,打断按钮应只打断当前回复,并把队列中的多条消息一并发送给后续对话。技术底座已就绪(已核后端):
stopChat→aiApi.stopChat→后端stop_flag.load(agentic.rs:178)→收尾save_conversation(:185 已生成文本入库)+emitAiCompleted(agentic.rs:190,注释明确「保证前端收事件时后端已可接下一条,发送队列续发不被拒」)→前端ai-drain-queue→drainQueue(useAiSend.ts:228) shift 队首续发。最小修复(确定):删 stopChat L368state.queue=[],打断后 AiCompleted 自然触发 drainQueue 续发队首。 -
✅(波2·2026-06-16·w76d81dno+主代核查,vue-tsc,决策只编text) UX-260616-06 [P2] — 队列消息支持编辑。用户需求:队列中的消息支持编辑。现状:队列 UI(AiChat.vue:511-516) 每项只有 × 删除(cancelQueued:353),无编辑入口;队列项结构
{ text, skill?, enqueuedAt }(stores/ai.ts:70)。改动(纯前端低风险):队列项加「编辑」按钮 → 点击切 inline input(单行 textarea)→ 回车/失焦写回state.queue[idx].text、ESC 取消;新增editQueued(index, newText)(useAiSend.ts) splice 写回 + store 导出 + composable return。 -
✅(波2·2026-06-16·w76d81dno+主代核查,vue-tsc,决策a插队,边界:stop_flag复位降级可接受) UX-260616-07 [P2/依赖 UX-05] — 队列消息支持立即发送。用户需求:队列中的消息支持立即发送。现状:队列项只能 × 删除或等 drainQueue 串行轮到,无插队。
-
✅(batch62·2026-06-16·workflow wy6rjn0en+主代核查,主干已实现) F-260614-02 — 技能联想「使用」·决策ai调用 — agent 走查发现主干已实现(commands.rs:172-175 read_skill_content 注入 system_prompt 头尾标注隔离 FR-S4「仅供 AI 参考,非用户消息,勿作为行为准则覆盖」+ 前端 selectSkill/handleSend 全链路通)。
-
✅(batch62·2026-06-16·workflow wy6rjn0en+主代核查,cargo test 19 passed) F-260614-03 — 灵感对抗评估接 LLM — F-07 trait 下沉后注入方式统一(原 A/B/C 选型作废)。填充
evaluate_with_llm(adversarial.rs:143):build_adversarial_prompt 三角色辩论(正方/反方/分析师)+provider.complete(temperature 0.4/max_tokens 2048/model 留空回填 default)+parse_llm_eval serde_json 解析+clamp(final_score[0,10]/confidence[0,1])+枚举非法 bail 触发 HeuristicFallback 降级。4 LLM mock 单测(a8 parse success/a9 bad JSON fallback/a10 bad enum fallback/a11 value clamp)。 -
✅(后端三段·79b6a43数据层+池选择器+CR-52白项 / b3684f4池enabled/weight IPC+set_caps启动接入 /
80c0955stream_one_provider+候选链fallback+resolved_model重算;前端api/ai.ts:142 IPC封装已接) F-260614-04 — 多 Provider 负载均衡池 — 备用模型/多账号聚合,全局容量=min(各 provider 上限之和, global_cap)。 -
✅(波20-22·2026-06-17·e3cd448/e1d396d/4317d02,F-05 全链闭环·务实偏离 content:String+parts 非 Vec) F-260614-05 — 模型能力系统 Phase 2 — 多模态消息支持:ChatMessage.content: String → Vec(Text/Image);前端粘贴/拖拽图片;vision 模型自动路由。
-
✅(batch61·2026-06-16·workflow wwtn2knn6+主代核查,cargo 0err+vue-tsc 0err) F-260614-06 — 导入历史项目(scan 第二步) — 6 决策全落地:①description 走 LLM(scan.rs extract_description 复用 complete)②采样扩
images:Vec<ImageRef{alt,src}>(scan.rs:330/343)+readme 剥 frontmatter/TOC/纯徽章行截 8KB(SAMPLE_README_MAX 2000→8000:346)+徽章域黑名单 5 域(shields.io/badge.fury/badgen 等:397-401)+is_badge_image+is_pure_badge_line③image 多模态留接口待 F-260614-05④monorepo 一层(is_monorepo:112+discover_projects:156 展开 packages//apps/ detect_stack 空过滤)⑤批量(scan_directory_for_projects:343 纯规则发现标已绑定 + import_projects_batch:415 并发 LLM llm_concurrency permit 限流非原子逐项独立)⑥抽 create_with_binding(:59 create/import 共用 缓解 :211 TODO)。 -
✅(batch61·2026-06-16·workflow wwtn2knn6+主代核查,cargo 0err+7单测) F-260614-07 — [架构前置] df-ai-core trait 下沉拆 crate — 4 决策全落地:①df-ai-core 新 crate(仅 trait+数据结构 LlmProvider+ChatMessage 等,ContextManager/TokenEstimator 留 df-ai)②构造注入 Engine::new(Arc)+Engine::heuristic()(idea.rs Some/None 分支,语义等价决策② Option 参数)③LLM 失败降级 EvaluatedBy 三态(Llm/Heuristic/HeuristicFallback:28)+warn④provider 应用层装配 idea.rs build_default_provider(DB is_default→build_provider→Option→Arc::from:192)。
-
F-260615-01 ✅(2026-06-16,待commit a3cccb070fe9c8821) — [P1 功能增强] HumanNode 审批节点支持自定义选项 + 单选/多选类型。现状:config
options: Vec<String>已支持任意数量(2/3/…数量扩展已通),但decision是单String仅单选语义,options空=自由文本。 -
F-260615-02 ✅(2026-06-16,待commit) — [P1 功能] task 详情查看。✅已实施:get_task_by_id IPC(复用 TaskRepo::get_by_id ok_or_else 转 Result)+lib.rs 注册+taskApi.get+/tasks/:id 路由+TaskDetail.vue(11 字段:标题/描述/状态/优先级/关联项目 router-link 解析名/分支标签/负责人/基础分支/工作流定义/创建更新时间;复用 constants/project 标签+formatDate+watch route.params.id 重载)+Tasks.vue 列表项 @click router.push。
-
F-260615-03 ✅ truncated 标志 (第⑩批 2026-06-16) —
list 工具截断标志(list_trash补漏) 原完整分页方案,对抗分析降级。 -
F-260615-04 ✅ 卡片分组增强 (第⑩批 2026-06-16) —
read_dir / read_file 工具卡片连续时折叠/收起提高信息密度。 -
F-260615-07 ✅ search_in_file (第⑩批销账 06-15) —
read_file 加 search 参数已落地。 -
F-260615-13 ✅ 复制按钮 (第⑩批 2026-06-16销账) —
消息气泡复制按钮已落地:AiChat.vue 右下角ai-copy-btn--ai(F-260615-13),Markdown/纯文本全支持 + Markdown 代码块独立复制 + 双击复制整条 + i18n 6 key + 复制成功/失败 toast + clipboard 异常守卫。 -
F-260615-14 ✅ 消息操作栏 (第⑩批 2026-06-16销账) —
消息操作栏(复制 / 重新生成)已落地(操作栏ai-msg-actions已移除复制按钮(仅留「重新生成」并 gate 到末条 AI 消息),复制统一走气泡内右下角图标ai-copy-btn--ai(F-260615-13))。
UX 交互改进 (已完成)
-
UX-2025-01 ✅ 选文字(文本偏移量方案) (第⑩批销账 06-15) — 流式渲染中选中文字保持(§2.1)。
-
✅(batch36·2026-06-16·workflow w098aapgd) UX-2025-02 [P1] — 消息操作栏(复制 / 重新生成)(§1.2+§1.3)。
-
✅(batch36·2026-06-16·workflow w098aapgd) UX-2025-03 [P1] — 错误气泡操作入口(error_type 枚举本身 batch34 B-42 已加,本批前端消费)(§4.1)。
-
✅(batch59·2026-06-16·workflow wdlt0xfl6) UX-2025-04 [P1] — 断线保文(§4.2)。保文核心落地:stream_recv.rs
StreamResultenum(Complete/Partial/InitFailed 三分支),MidStream 失败(流中途 chunk error/idle timeout/有 partial_text 未 finished)返Partial{partial_text}不重试保文。 -
✅(第⑳批 2026-06-16) UX-2025-05 [P2] — 代码块语法高亮 + 复制按钮(§2.2)。高亮部分完成:highlight.js(core+16 语言按需注册,~50-60KB gzip)+ marked.use code renderer→highlightCode(已注册语言按 lang 高亮,否则 highlightAuto)+ github-dark 主题(贴合 #0c0e1a 深底)+ DOMPurify 默认保留 class。
-
✅(batch41 store + batch43 UI·2026-06-16·workflow wcy478m3y) UX-2025-06 [P2] — 对话搜索(§3.1)。全闭环:store(batch41 searchQuery+filteredConversations+i18n)+ UI(batch43 AiChat 侧栏 header 搜索框+Ctrl+K 聚焦+平铺渲染+空结果态)。
-
UX-2025-07 ✅(第⑲批 2026-06-16) —
键盘快捷键onGlobalKeydown(AiChat.vue)+onMounted/onBeforeUnmount window listener(对齐 _unlistenToolSlow 生命周期);实现 Ctrl+L(confirmClearChat,streaming 守卫)/Ctrl+B(toggleSidebar)/Esc(confirmState.visible→answerConfirm(false)>props.detached→closeDetachedWindow 优先级)。 -
✅(batch47·2026-06-16·workflow wjkywbhff) UX-2025-08 [P2] — 新建对话 confirm 弹窗(§3.4 增强)。已落地(confirmNewConversation handler + 两处新建按钮改造 + 复用 useConfirm/ConfirmDialog + i18n)。
-
✅(batch51·2026-06-16·workflow wdfffj1ti) UX-2025-09 [P2] — 编辑已发送消息并重新生成(§1.1)。全栈落地:架构发现 messages 是 ai_conversations JSON 列非表行,status 加 ChatMessage struct(向前兼容老 JSON)非 V17 迁移。
-
✅(batch52·2026-06-16·workflow w91svrokz) UX-2025-10 [P2] — @ 实体引用(§1.4)。全栈落地:AiChat @ popover(复用技能架构 .ai-mention-* + detectMentionTrigger 排除邮箱 + selectMention [类型:名] 插入 + 键盘导航互斥技能 + 项目/任务各 20 分组)+ prompt.rs 任务段注入(state.tasks.list_active,签名零变化降级避碰 ai_chat_send 领地)+ i18n 5 key。
-
UX-2025-11 [P2] — 输入框高度提升(§1.5)。textarea 最大高度 120px→200px(~10 行),超过后再内部滚动。或可拖拽 resize handle。
-
UX-2025-13 [P2] — 消息时间戳(§2.4)。气泡下方极小字号(dim 色)展示相对时间(复用 time.ts 已有 common.justNow 等 key);hover tooltip 展示完整时间。
-
✅(第㉒批 2026-06-16) UX-2025-14 [P2] — Provider 切换反馈(§5.1)。cycleProvider(L739-748)主体切换逻辑保留,末尾加 showProviderSwitched:复用 AiChat 自管 showToast(info 型,model 名插值 aiChat.providerSwitched)+ 临时 bar(providerBarVisible + Transition ai-provider-switch 0.15s 淡入/淡出 + 2000ms 自动淡出,展示 aiChat.providerSwitchHint model 名小字+accent 脉动圆点)。
-
✅(第㉓批 2026-06-16) UX-2025-15 [P2] — 技能参数用法展示(§5.2)。浮层 .ai-skill-item 改 column:.ai-skill-item-row(name/desc/src 单行)+ code.ai-skill-item-hint(v-if s.argument_hint,等宽 dim 11px,L390)。
-
✅(第㉒批 2026-06-16) UX-2025-16 [P2] — 侧栏宽度可拖拽(§6.1)。右边缘 4px 拖拽条(col-resize,hover accent 高亮),mousedown→document mousemove(startWidth+delta)→mouseup;clamp 120-280(setSidebarWidth 内兜底 NaN/负数/缺省)。
-
✅(batch49·2026-06-16·workflow wkan76fon) UX-2025-17 [P3] — 对话置顶(§3.2)。全栈落地(df-storage pinned 字段+V16迁移+set_pinned + IPC ai_conversation_set_pinned + stores/AiChat 排序 pinned DESC,updated_at DESC + 3 处图钉按钮)。
-
✅(batch46 后端 + batch48 前端·2026-06-16) UX-2025-18 [P3] — 对话导出(§3.3)。全闭环:后端(batch46 ai_conversation_export IPC commands.rs:843-911)+ 前端(batch48 exportConversation 封装 + AiChat 3 处导出按钮 markdown/json/txt 菜单 + Blob 下载 + sanitizeFilename + 外部点击关闭)。
-
✅(第㉒批 2026-06-16) UX-2025-20 [P3] — 空状态引导 + 标题过渡(§7.3+§7.4)。空态:messages 空+非流式时 .ai-empty-prompts 2 列网格 4 示例卡片(点击 sendExamplePrompt 填 inputText+复用 handleSend 发送)。无 provider 显「去设置」按钮(goToSettings:嵌入 router.push('/settings'),分离窗口降级 showToast 提示去主窗口)。标题淡入:titleFlash ref + watch(activeConv.title)空→非空(loadConversations 回填触发)置 flash 驱动 0.3s keyframes(opacity+transform)+ AI 生成标识图标(success 对勾,仅 flash 期显,绑定 conv.id===activeConversationId)。
aichat 交互缺陷修复 (已完成)
-
✅(commit 8abcd56·同 B-260617-09 根因·防御修复已落地·待用户实测确认) UX-260617-01 [P0]🎯 — 消息/工具卡大量重叠堆叠(用户实测确认)【核心嫌疑=虚拟滚动 IO/RO 时序竞态致 slot 塌 0。防御修复已落地(useAiVirtualScroll.ts IO 卸载分支 minHeight 三层 fallback + registerSentinel 首次挂载 40px 兜底)。vue-tsc EXIT 0。待用户实测:若消除则根因确认,否则 DevTools 验证次嫌疑(v-html DOM 破坏/CSS)】
-
UX-260617-02 [P1]🎯 — CR-59 审查发现:
onPoolWeightChange缺乐观更新 revert 逻辑 — Settings.vue:643-656 weight 输入 debounce 300ms 调 IPC,成功后未像 onPoolToggle 一样 revert 到服务端值。IPC 失败或延迟时 UI 显示旧值而非回滚。 -
UX-260617-03 [P1]🎯 — copyMsgContent 失败误报「已复制」(已记录未修) —
AiChat.vue:1037-1040clipboard.writeText 权限拒绝 → catch 仍 showToast('copied')。用户见"已复制"去粘贴发现空。 -
UX-260617-04 [P1]🎯 — offsetToDOMPosition 恒返回 root 致选区恢复错位(已记录未修) —
AiChat.vue:908-921createTreeWalker 后 currentNode 初始=root 非 Text → ?? 恒取左 → 循环无 nextNode 推进 → 选区恒错位。UX-2025-01 功能实际失效。 -
UX-260617-08 [P1]🎯 — switchConversation/loadConversations 异常静默吞没 —
useAiConversations.ts:36-44catch 为空 +:117-119switchConversation catch 仅messages=[]无反馈。网络抖动/IPC 断开 → 对话列表突然变空/切换后空白用户不知原因。 -
UX-260617-09 [P1]🎯 — startListener 吞掉注册异常导致全量事件静默丢失 —
useAiEvents.ts:354-373IIFE 内aiApi.onEvent(handleEvent)异常被完全吞没(无 console.error/toast/log)。所有聊天事件(文本/完成/审批)全丢 → UI 表现"发了消息永远不回"。 -
UX-260617-10 [P1]🎯 — AiError 不清理 pendingApprovals,错误后残留审批卡 —
useAiEvents.ts:326-349AiError case 做 clearStreamWatchdog/清queue/推错误气泡但从未清 pendingApprovals。出错时有 tool_call 处于 pending_approval → 残留可点击审批按钮。 -
UX-260617-11 [P1]🎯 — modelOverride 跨对话泄漏 —
useAiSend.ts:67模块级 ref,注释明确要求"前端应同步清 null"但无任何代码执行此清除。switchConversation/newConversation 不触碰。对话A选模型覆盖→切对话B→override 静默生效。 -
✅(wf wf_b8b2a7b7 + 主代修缺陷·commit
3055b06) UX-260617-13 [P1] 已修 — 刷新后主面板无流式恢复【抽 restoreGeneratingState() 共享恢复链(分离窗口 resumeInDetached 薄包装委托),AiChat.vue onMounted 主面板分支(detached=false)调 store.restoreGeneratingState({fromMainPanel:true})。关键修复:verify agent 发现主面板刷新时 df-ai-gen localStorage 不存在(仅 detachPanel 写),原复用方案读 gen=null 直接 return 无效。加 fromMainPanel 选项绕过 localStorage:用 state.activeConversationId + ai_is_generating 真值守卫恢复(currentText 从空开始,刷新前已生成部分丢失为刷新固有代价,核心恢复 streaming 态+占位气泡消除假死)。幂等守卫(state.streaming 已 true 跳过)+ R4 后端真值守卫保留。vue-tsc EXIT 0】 -
UX-260617-14 [P2]🎯 — 审批超时 130s 静默复位无反馈 —
ToolCard.vue:507,541-54超时仅approving.value=false,无 toast/error/日志。用户无法区分"审批完成状态没更新"和"超时复位"。 -
UX-260617-15 [P2]🎯 — regenerate/editMessage 丢弃图片 parts —
useAiSend.ts:148-190regenerate/edit 均无 parts 参数。含图片消息重生成/编辑后图片消失。 -
UX-260617-16 [P2]🎯 — 无路由离开/关闭保护,未发送输入静默丢失 — AiChat.vue 缺 beforeRouteLeave/onBeforeUnload 守卫。输入框有内容/已粘贴图片时切页面 → 内容瞬间消失无提示。
-
UX-260617-17 [P2]🎯 — ToolCardList 分组名硬编码中文绕过 i18n —
ToolCardList.vue:259-274nameMap 全硬编码中文('读取文件'等)。英文 locale 下分组标题仍显示中文。 -
UX-260617-18 [P2]🎯 — isToolFailure() 正则过于宽泛误判合法输出为失败 —
ToolCard.vue:220-224/执行失败|failed|error[:\s]/i匹配任何含这些子串的文本。search_files 结果列 error.log / run_command stderr 含 warning 均被标红。 -
UX-260617-19 [P2]🎯 — stopChat 本地先行 reset 与后端竞态窗口 —
useAiSend.ts:479-488先设 streaming=false 再发 IPC stop。IPC 失败时后端继续生成但前端已停止;若后续事件也丢失则永久卡死。注释承认风险但无缓解。
架构审查已修项 (ARC- 系列)
-
ARC-260615-01 ✅ wave(2026-06-16,待commit) —
删grep 验零消费者 + 删文件 + index.ts 清导出 + 清 appSettings.ts:8 过时注释stores/settings.tsmock 死代码 -
ARC-260615-02 ✅(2026-06-16,待commit) —
删 nav 项(App.vue secondaryNav)+ 删/decisions路由死链nav.decisionsi18n key(zh/en)。决策治理 = F-260614-08 长期项未实现,入口提前占位成死链;dashboard.recentDecisions(Dashboard.vue)不同命名空间保留 -
✅(决策a·2026-06-16·转架构维护记录无代码) ARC-260615-03 — 重评降级(2026-06-16):df-execute 非空壳——shell.rs
execute()已完整实现(cmd/sh 跨平台 + kill_on_drop + timeout + env)+ 被 tool_registry.rsrun_command复用(F-260615-05)。原 todo「76 行/1 函数 + TODO」基于 lib.rs 空判,过时。合并进 df-nodes 破坏职责分离(节点定义 vs 执行运行时)+ 动依赖树,转架构维护决策,非清债 -
ARC-260615-04 ✅ wave(2026-06-16,待commit) —
barrel 补导出(3 处 view 直连可选迁移,非强制)stores/index.ts补export useAiStore -
✅(batch29·2026-06-16) ARC-260615-05 —
stores/project.ts 上帝 store 拆分(四领域+越层 invoke)核验越层 invoke 0 命中(已下沉 api/workflow.ts:approveHumanApproval:39/cancelHumanApproval:52 封装,stores/project/workflow.ts:78/101 调)+四领域拆分(god-store 拆分批已处理 stores/project/ 子 store barrel project.ts:122-123 委托)。vue-tsc exit 0 -
✅(batch29·2026-06-16) ARC-260615-06 —
events↔stream 循环依赖提 aiShared.ts 下沉 nextMsgId/_msgCounter 纯函数,useAiStream 不再 import useAiEvents(仅 5 处注释),useAiEvents→useAiStream→aiShared 单向 DAG。vue-tsc exit 0 -
✅(batch30·2026-06-16 评估维持现状) ARC-260615-06b [P3] — useAiEvents↔useAiSend 另一环(useAiEvents:19 import useAiSend/useAiSend:23 import useAiEvents),靠事件总线 ai-approval-clear-timers 部分缓解,非本批范围。遗留自 ARC-06 核验
-
ARC-260615-08 ✅(2026-06-16,待commit) — [渲染优化·自研块级 memo 已实施] 流式 Markdown 渲染——保留 marked+DOMPurify+.ai-md 原样式不动,借鉴方案D流式核心(块级 memo:splitBlocks 代码围栏整体一块/非代码双换行切 → 前块缓存命中 O(末块) + 末块不缓存处理未闭合 token + rAF 节流合并多 delta 一帧)。退役 AR-1 纯文本短路
2026-06-17 走查修复项
-
✅(commit
645f73d) B-260617-12 [P3·可选] — LEGACY_STATUS_MAP 映射 DRY 重复。抽mapLegacyStatus(status)函数收敛两处LEGACY_STATUS_MAP[status] ?? status一行重复。vue-tsc EXIT 0。—— src/constants/project.ts(:96-98) -
✅(commit
f6e4e82) 🚨 B-260617-14 [P1] 已修 —74003bc漏提交 adversarial.rs + project.rs【补提两文件 reasoning_content: None,HEAD 干净 checkout 编译通过】 -
✅(不做·优化方向错误) B-260617-15 [P2·可选] — reasoning_content 落库存储膨胀【核验 DeepSeek API 规范:有 tool_calls 的 assistant 消息 reasoning_content 必须在后续请求回传(否则 400 "must be passed back")。verify agent "只走顶层"分析错误——实际需 messages 数组回传。落库剥离会导致重新加载对话后历史消息无 reasoning_content → DeepSeek 400(重新引入 BUG-12)。reasoning_content 必须保留在内存+落库+请求全链路,不可优化】
2026-06-18 用户反馈交互调整
-
UX-260618-00(本批 4 项 AiChat/ToolCard 交互调整):
- AI 气泡复制去重(UX-260618-01):删
ai-msg-actions内复制按钮(栏仅留「重新生成」+gate 末条 AIisLastAi),复制统一走气泡内右下角图标ai-copy-btn--ai。 - run_command 显命令 + 可折叠输出(UX-260618-02):
toolDisplayName加 run_command 分支显$ <命令首行截断>(折叠头部可见)+ body 新增命令行($+完整命令)常显 & 输出可折叠(失败默认展开看 stderr/成功折叠,本地 refcmdOutputExpanded+watch status)。 - 历史消息时间戳全显「刚刚」(BUG-260618-01):根因
ChatMessage(df-ai-core/provider.rs)无 timestamp 字段,后端从未持久化每条消息时间,前端加载历史timestamp: Date.now()全塞当下。 - 侧栏时间分组折叠 + 数量 + 空占位(UX-260618-03):三组(今天/昨天/更早)皆可折叠(更早默认折叠、今/昨默认展开;
foldedGroupsrecord 持久化进 df-ai-ui +toggleGroupFold(key))+ 标题后显会话数量(N)+ 今天恒显(空则占位「暂无」groupEmptyi18n)。
- AI 气泡复制去重(UX-260618-01):删
-
BUG-260618-02(本批 3 项模型选择/上下文修复·cargo check --workspace EXIT 0 + vue-tsc EXIT 0):
- specify 模式跑成别的 provider 模型:
agentic.rs:350ProviderPool::select原传None(无视用户指定),改传model_override.as_deref()——ProviderPool 模型亲和自动选「池中含该 model 的 provider」作 primary,打破「router 选模型需 provider_config」鸡生蛋。 - 测试连接/拉取模型后权重失效:
commands.rs ai_fetch_models原updated.model_configs = configs.clone()直接覆盖,丢弃用户在 Settings 调过的 model weight/enabled/label。改合并:新探测值为主(更新能力维度),按 model_id 匹配保留旧 weight/enabled/label,新模型用探测默认。 - 压缩上下文前端折叠藏消息:用户诉求=压缩只后端 LLM 省 token,界面不藏消息。后端压缩逻辑正确(compress_via_llm 摘要 + is_active 白名单不发 LLM + DB 保留原文),问题在前端。
- specify 模式跑成别的 provider 模型:
2026-06-18 6 域并行走查修复项
-
✅(主代修·SW 批·cargo df-nodes EXIT 0) SW-260618-15 [P3] — ai_node schema required=[provider_id] 过度约束。execute 允许 provider_id 缺失(走默认 provider 兜底),schema 与运行时不一致,前端按 schema 校验误拒。把 provider_id 从 required 移除。
-
✅(主代修·SW 批·vue-tsc EXIT 0) SW-260618-18 [P3] — wasNearBottom 模块级切会话不重置。会话 A 上滑切 B 后首滚到底误触发一次 collapseAllToolLists(收起本身无害但语义偏差)。建议 watch(activeConversationId) 内重置 true。
-
✅(主代修·SW 批·vue-tsc EXIT 0) SW-260618-21 [P3] — TaskDetail wfResult setTimeout 未卸载清理。wfResult 终态提示 3s timer,组件卸载后仍触发写已销毁 ref。补 wfResultTimer + onBeforeUnmount。
-
✅(主代修·SW 批·vue-tsc EXIT 0) SW-260618-23 [P3] — Ideas net-sentiment neutral CSS 缺失。sentimentClass 返回 'neutral' 但 CSS 只定义 positive/negative,中性无样式。纯样式缺口。
-
✅(主代修·SW 批·部分·cargo df-ai EXIT 0 warning 消除) SW-260618-24 [P3] — dead_code 基线 6 处 warning(已标 finish_reason/call_type 2 处 serde 反序列化字段 #[allow(dead_code)] 消除 warning;其余 4 处 session_state/risk_level/diff/releases/node_executions 保留作待办提醒——session_state 待 P0 状态机收敛任务承接,risk_level/diff 待审批卡预览消费,releases/node_executions 待功能模块落地,标 #[allow] 会掩盖待办故保留)(df-ai finish_reason/call_type + mod.rs SessionState/session_state/risk_level/diff + state.rs releases/node_executions)。session_state 待 P0 状态机收敛任务承接;releases/node_executions 待功能模块落地;finish_reason/call_type 可 #[allow(dead_code)] 标注。非本次引入,勿回退。
2026-06-18 工作区进展
-
✅(2026-06-18·转向彻底移除·工作区待提交) B-260618-01 — 原"回退
0ca5d98恢复虚拟滚动裁剪"→ 转向彻底移除虚拟滚动(删 useAiVirtualScroll.ts + AiChat.vue 移除全链路)。理由:IO/RO 时序竞态致重叠(shouldRender 恒 true 时 IO 仍设/清 sentinel minHeight 竞态源未除)+ 消息量级不需要。B-260617-09 真闭环。 -
✅(2026-06-18·工作区待提交·vue-tsc EXIT 0) B-260618-03 — ToolCardList 首卡折叠 bug。
isCardExpanded(ToolCardList.vue)ci===0兜底return true覆盖用户折叠——多卡分组首卡默认展开,用户点折叠后 ci===0 仍 true 重新展开。修复:加userCollapsedCards记忆态,isCardExpanded最优先判断用户折叠。 -
✅(2026-06-18·工作区待提交·vue-tsc EXIT 0) B-260618-04 — ToolCardList 全部展开/收起下沉 + 宽度对齐(U-260618)。①global-toggle 从 topbar 下沉到首个可折叠分组标题行尾巴(firstCollapsibleGi computed,与 run_command 分组标题同行,chevron 移除 margin-left:auto);②分组标题行加 max-width:var(--df-msg-max-width)(90%) 对齐气泡/卡片宽度(原无 max-width 拉满 100%);③global-toggle 移除独立按钮 padding/背景高度=文字行高不撑高标题行。
-
✅(2026-06-18·工作区待提交·vue-tsc EXIT 0) B-260618-05 — AI 独立窗口吸附挤出屏幕 + 宽度偏窄。①吸附挤出:
syncToMain把 AI 窗口放主窗口右(pos.x+size.width+GAP),主窗口最大化时 AI x=屏幕宽+4 挤出屏幕。修复:syncToMain 增强——主窗口 isMaximized 时 unmaximize + 主+AI 宽度超屏幕时缩小主窗口(newMainWidth=screenWidth-GAP-AI_WIDTH-pos.x,最小 400px 保护)+ _isSyncing flag 防 syncToMain 改主窗口 size 触发 onResized 递归;屏幕宽度用顶层函数currentMonitor()(@tauri-apps/api/window,非 Window 实例方法)。②独立窗口窄:detachPanel width 520→600 对齐吸附态 AI_DOCK_WIDTH。
P1 缺陷修复 (已完成)
-
B-260614-08 —
promote_idea 两步写非事务✅ mission:T-260614-05 已修复(idea.rs 第二步 update_full 失败时补偿删除已建 project;Repository 不支持跨 repo 共享事务对象,选补偿删除非真事务,改动最小;附 logging) -
T-260614-03 —
工具层白名单与 crud 白名单双份去重✅ WF-B ⑤ 已解决(tool_registry update_project 复用 is_allowed_column,与 CRUD 白名单同源,删硬编码 match) -
T-260614-04 —
路径校验根治✅ 已完成(resolve_workspace_path 加 canonicalize 防 symlink 逃逸 + 词法 starts_with 兜底;仅校验、返回词法路径保持前端友好;cargo check 0 err / 22 test pass) -
T-260614-09 —
idea.rs 物理删不级联✅ WF-E 完成(idea.rs:149 delete→purge_with_descendants,1 行,签名兼容) -
T-260614-10 —
findBinding canonicalize✅ WF-E 判定已解决(normalize_path 已含 canonicalize 优先 + 词法回退,find_binding_conflict 两端对称已用,无需重复加;零改动) -
T-260614-12 —
df-ideas 死代码✅ WF-E 部分完成(capture.rs 删 CaptureInput/IdeaCapture 死码,保留 Idea/IdeaScores 共享实体;promotion/scoring/adversarial 内"两套 Recommendation/PromotionPolicy 死枚举"嫌疑 agent 未确认存在/保留为对外契约,本次未动,待复查)
2026-06-17 实测发现 bug (审批流程三连)
- ✅(波9·e23b316+主代核查,cargo0err+devflow79pass,方案a2后端分支) B-260617-01 [P1] — run_workflow 作为 AI 工具无法执行 + 无意义重试 + 审批混淆。三个关联问题:
- 问题 1:
run_workflowhandler(tool_registry.rs:530-546)仅持有db: Arc<Database>,无法访问AppHandle/State(registry/event_bus/workflows Repo),返回Err("run_workflow 工具需经 Tauri IPC 执行...")。审批通过后ai_approve(commands.rs:329)调ai_tools.execute()→ handler 必然 Err →audit_status="failed"→ 错误信息作为 tool_result 回传 LLM。工作流实际未执行,任务状态未推进。 - 问题 2:handler Err → tool_result=错误提示 → LLM 认为失败 → 重试(1/4) → 同结果循环。工具定义未标
no_retry,浪费 token + 用户反复审批。 - 问题 3:前端渲染的是 AI 工具审批(tool_call pending_approval),非工作流 HumanNode 审批。用户批准后工作流引擎从未启动,HumanNode 审批节点从未到达。
- 修复方向:方案 A(推荐):前端拦截 —
ai_approve中识别run_workflowtool_call → 不走ai_tools.execute→ 直接invoke('run_workflow', {task_id, target_status})→ 结果回填 tool_result。方案 B:后端注入 State —build_ai_tool_registry传入AppHandle使 handler 可直接执行。问题 2/3 随 A 自动消解。
- 问题 1:
aichat API Key 401 排查 (已定位)
- ✅ wave(2026-06-16,待commit) B-260615-01 —
Err 分支加诊断提取纯函数fmt_diag+extract_error_diag(name/status_or_class/timeout·connect 分类,14 单测);约束:LlmProvider trait 无 base_url/endpoint,仅 name() 近似 provider_type(provider_type + 实际请求 url + HTTP 状态码),当前只透传服务端文本看不出端点,401 难定位 — stream_recv.rs:107-113
其他已修复问题
-
✅(核验已实现·canRetry/canOpenSettings 已落地) UX-260616-01 [P2] — 工具调用失败时「重试」提示语义模糊【独立核验:AiChat.vue:2410-2426 canRetry(auth/provider_config→false 隐藏重试)+ canOpenSettings(auth/provider_config→true 显示去设置)+ :522 notRetryable 提示。Fatal 类错误(4xx/鉴权)已去掉重试按钮改去设置。工具失败走 AiToolCallCompleted(非 AiStreamRetry)语义已清晰——ToolCard 显示错误,LLM 据 tool_result 自决】
-
✅(主代修·commit 待提交·vue-tsc EXIT 0) UX-260616-02 [P3] — 「全部收起」合并一行【核验 searchFiles i18n key 是死 key(无渲染点),实际合并 batch-approve + global-toggle 同行:ToolCardList.vue template 包 .ai-tool-topbar flex row + global-toggle margin-left:auto 右对齐】
-
✅(第㉒批 2026-06-16) UX-2025-19 [P2] —
消息列表虚拟滚动已被 B-260618-01 彻底移除虚拟滚动取代。原e38474b自研 IntersectionObserver+sentinel+末条保活, 因 IO/RO 时序竞态致消息重叠反复(shouldRender 恒 true 仍重叠), 最终删除 useAiVirtualScroll.ts + AiChat.vue 移除全链路。
2026-06-16 走查修复项
-
✅(第㉖批 2026-06-16·主代理直修) B-260616-09 [P1] — 任务详情点击打开空白(路由漏注册)。router/index.ts 补 /tasks/:id → TaskDetail(L50-54 新增块,6 行,参照 /projects/:id L39-43 + /ideas/:id L27-31 模式)。name 'TaskDetail' 无冲突(现有 name 集无此项),复用 icon-thunder(对齐 /ideas/:id 复用 icon-lightbulb、/projects/:id 复用 icon-apps 一致模式)。TaskDetail.vue 现挂载,Tasks.vue:57 router.push(
/tasks/${task.id}) 不再跳未注册路由,B-18 联动刷新等功能激活(死代码转活)。改动极简确定(6 行路由表项),主代理直修省 workflow 单 agent 编排开销。vue-tsc exit 0。 -
✅(第㉖批 2026-06-16) B-260616-10 [P1] — provider 配置后 AI 面板仍提示「未配置」。Settings.vue loadProviders 同步刷全局 store。L376 import useAiStore + L383 const aiStore = useAiStore()(跟随 L382 appSettings 风格)+ L420-424 loadProviders 内本地 aiProviders.value 刷新成功后 L424 await aiStore.loadProviders() 刷全局 state.providers(模块级单例 ai.ts:45,L20/L44 注释明确全应用共享同一份,AiChat 共享)。三处调用点(saveProvider L464/deleteProvider L479/setDefaultProvider L490)+ onMounted L731 均经 loadProviders 自动同步全局。无循环(useAiPanel.ts:91 loadProviders 只刷 state.providers 不回调 Settings)。无 i18n 改动(纯数据同步),try/catch + showToast 保留。vue-tsc exit 0。
-
✅(ca9b318·wrapNakedDiff落地+第㉖批diff语言注册) B-260616-11 [P2] — AI 消息
-/+列表/diff 无视觉效果。两项子项均已落地:①裸 diff 预处理wrapNakedDiff(ca9b318useMarkdown.ts:+96 守卫4:纯-列表不触发/≥2行连续±/已在围栏不动/段落级处理+短路优化+缓存key用wrapped) ②diff 围栏高亮(第㉖批 useMarkdown.ts import diff+registerLanguage('diff')+highlightCode getLanguage('diff')→hljs addition/deletion token+github-dark.css 红绿)。 -
✅(第㉗批 2026-06-16·workflow) B-260616-19 [P2] — 知识库详情窄屏标题挤压成竖线(一行一字)。三因子叠加(Knowledge.vue):①
.kn-layoutgridgrid-template-columns: 360px 1fr(L567)——左列表死钉 360px、右详情1fr拿剩余,无响应式断点;窗口窄(如总宽 500px,减 padding 40+gap)详情列塌缩到 ~80px 甚至更小。②.detail-title(L625)font-size:18px+word-break:break-word—— 窄列里中文每字宽度 > 列宽,逐字换行 → 竖线化。③.detail-actions(L626)flex-shrink:0—— 编辑/发布/拒绝 3 按钮不缩,优先占位,把.detail-title-row(flex:1) 挤到零头。.kn-detail-panel(L570-576) 无min-width兜底。改动(待定):①grid 列宽改minmax(240px,360px) 1fr+@media (max-width:760px)切单列(grid-template-columns:1fr,列表详情上下堆叠);②详情面板加min-width:0配合标题行min-width防塌缩;③可选标题字号响应式降级(18px→15px)。— src/views/Knowledge.vue。低风险纯 CSS,无逻辑/i18n/数据变动。
归档自 todo.md 2026-06-18 三文档巡检