From d3c9b4ad477417918dec286525782f7a68ae19a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BB=9D=E5=B0=98?= <237809796@qq.com> Date: Tue, 16 Jun 2026 22:45:46 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96:=20AiNode=E8=87=AA=E5=AE=A1?= =?UTF-8?q?=E9=98=B6=E6=AE=B52=E8=BF=9B=E5=BA=A6=E7=99=BB=E8=AE=B0+P0=20pr?= =?UTF-8?q?ovider=E6=B3=A8=E5=85=A5=E5=BE=85=E5=86=B3+CR-43=E5=AE=A1?= =?UTF-8?q?=E6=9F=A5=E9=98=9F=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/todo.md | 15 ++++++++------- docs/待决策.md | 13 ++++++++++++- docs/待审查.md | 10 ++++++++++ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/docs/todo.md b/docs/todo.md index b964acc..1a0edee 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -136,13 +136,14 @@ - **实施顺序**:④-1→②-1→②-5→②-2→②-3→②-4→②-6→①-1/①-3。**最小里程碑**(④-1+②-1+②-2+②-3):run_workflow 单 task_advance 节点 DAG 端到端推进 todo→in_progress - [ ] F-260616-07 阶段3 AI 执行闭环 — **F-03 收口三件 ✅ 本批完成**(batch64), AiNode 自审闸门 ⏳ 待后续批 - [x] ✅(batch64·2026-06-16·workflow wii1u1lnm) **F-03 收口三件** — ①advance_task 注册 AI 工具(tool_registry.rs:395,handler L407 调 `df_nodes::task_advance_node::advance_task_atomic` 与 IPC `commands::task::advance_task:165` 同源) ②run_workflow 注册 AI 工具(:428,handler 架构约束无 AppHandle/State 报错引导走 IPC,ToolDefinition+审批文案 L1260-1261/1286-1287 注册让 LLM 可产出 tool_call) ③update_task handler guard 拒 status(L374 `field=="status"` bail,schema 通用 field/value 故 guard 拦非 schema 改)+ df-storage tasks 白名单移 status+review_rounds(crud.rs:331-347,advance_status_atomic CAS L848 独立路径不经白名单)。同步落地防 AI 工具行为不一致。**主代独立核查全过**:cargo check --workspace EXIT 0(5 pre-existing warnings 无关)+ df-storage 11 集成测试(含新 `update_field_rejects_tasks_status`)。文件锁:tool_registry.rs + crud.rs + project_soft_delete.rs。**审查登记 CR-260616-41**(待审查.md 当前队列) - - [ ] AiNode 自审闸门(阶段3 核心,✅ 决策a 已定 2026-06-16:TaskRecord 加 output_json) — 待后续批 - - [ ] df-storage: TaskRecord 加 `output_json: Option` 字段 + V18 迁移(ALTER TABLE tasks ADD COLUMN output_json TEXT) + Repo update 方法 - - [ ] df-nodes: ai_node.rs ai_execute 执行后写产出到 task.output_json(通过 NodeContext 拿 task_id + DB 句柄) - - [ ] df-nodes: ai_node.rs ai_self_review 读 task.output_json 构建自审 prompt(需求符合度+产出完整性 → 通过/不通过+理由+建议) + 自审结果写回 output_json - - [ ] df-workflow: run_workflow 注入 task 数据到 NodeContext(config 注入 task_id + provider 配置,④-1 deep_merge 已就绪) - - [ ] df-nodes: human_node.rs human_review 读 task.output_json 展示产出+自审结果给人核 - - [ ] 前端: TaskDetail.vue 展示 output_json(产出+自审结果) + - [x] ✅ AiNode 自审闸门(阶段3 核心,决策a) — **阶段1迁移+方案✅(539b5ed+25409e5) + 阶段2②③④⑤✅(c10adaf ai 侧+741b0b9 前端)**,⑥联调阻塞 P0 provider 注入(F-260616-07c 待决)。cargo df-nodes 73 passed + workspace EXIT 0 + vue-tsc EXIT 0 + - [x] ✅(539b5ed) ①df-storage: TaskRecord 加 `output_json: Option` + V17 迁移(幂等补列) + crud 白名单+SELECT/INSERT/UPDATE 全链路 + - [x] ✅(c10adaf) ②df-nodes ai_node.rs: AiNode 持 db(Arc)+execute 后 config[task_id] 存在则 update_field 落 output_json + - [x] ✅(c10adaf) ③df-nodes ai_node.rs: AiSelfReviewNode 独立节点(prompt 四维度+parse_review_json 兜底 verdict=unknown+写回 review 子字段)+ state.rs 注册 + testing 模板 ai→ai_self_review + - [ ] ④df-workflow: run_workflow 注入 task 数据到 NodeContext(④-1 deep_merge 已就绪,**但 provider 配置注入阻塞 P0 F-260616-07c**) + - [x] ✅(c10adaf) human_review: 经 DAG inputs["ai_self_review"].data 透传 verdict/summary(HumanNode 零改动,方案④更优路径) + - [x] ✅(741b0b9) ⑤前端: TaskDetail.vue 展示 output_json(parsedOutput+review 红绿标+产出 markdown)+ types.ts+i18n 双语 + - [ ] ⑥端到端联调 — **阻塞 P0 provider 注入**(F-260616-07c secret 下沉待决)+ 实测类待用户(tauri dev) - [ ] run_workflow handler 注入 AppState(当前报错引导走 IPC) — 后续批扩展 build_ai_tool_registry 签名注入 AppState 句柄让 AI 直驱 - [x] ⏸️(待决策.md已决b暂缓·2026-06-16) F-260616-08 阶段4 Git 集成(kind+git闸门+worktree) - [x] ✅ **CR-260616-01 代码审查完成** → 审查登记已迁 [待审查.md](./待审查.md)(职责分离:审查队列独立,不进 todo)。结论 🔴0 🟡6 ⚪4 质量优,8 维度全过。**待修项 CR-01-A~I 见下方推进区**。 diff --git a/docs/待决策.md b/docs/待决策.md index fbd8dc6..ad81516 100644 --- a/docs/待决策.md +++ b/docs/待决策.md @@ -139,7 +139,18 @@ - d: 等 git 集成(阶段4 F-260616-08 暂缓),自审代码改动 diff。最贴切(自审代码)但阻塞于阶段4。 - **推荐**:**a**(task 中心,最直接解锁自审闭环+人核,数据模型变更小:TaskRecord 加 output_json+迁移+run_workflow 注入 task 到 NodeContext+自审 prompt 模板,中等工作量)。c 通用但 executor 改动大,b 语义弱,d 阻塞阶段4。 - **关联**:todo F-260616-07 阶段3(AiNode 自审 ⏳ 子条) / task_workflow_templates.rs:57-72(testing 模板) / ai_node.rs(AiNode 通用执行) / memory aichat-arch-extensibility(AiNode 空壳架构债) -- **状态**:✅ 已决(2026-06-16)— **决策:a**。TaskRecord 加 `output_json` 产出字段,ai_execute 写 / ai_self_review 读 / human_review 展示。task 中心,产出跟着 task 走,跨工作流执行可传递。 +- **状态**:✅ 已决(2026-06-16)— **决策:a**。TaskRecord 加 `output_json` 产出字段,ai_execute 写 / ai_self_review 读 / human_review 展示。task 中心,产出跟着 task 走,跨工作流执行可传递。**阶段1迁移+方案✅(539b5ed+25409e5) 阶段2②③④⑤✅(c10adaf ai 侧 + 741b0b9 前端),⑥联调阻塞 P0 provider 注入见 F-260616-07c**。 + +#### F-260616-07c AiNode provider 注入安全(FR-S1 api_key 下沉) +- **背景**:AiNode 自审闭环②③④⑤已实施(c10adaf+741b0b9),provider 配置注入阻塞⑥联调。根因:secret 解析(ensure_resolved_key)在 src-tauri/commands/ai/secret.rs(app crate),df-nodes 不可依赖 src-tauri(单向 app→df-nodes),AiNode/AiSelfReviewNode 只能从 config 读明文 api_key,违背 FR-S1 mask 设计(前端/LLM tool_call schema 可拿明文 key)。 +- **决策点**:secret 解析下沉方式? +- **选项**: + - a: 完整下沉 secret.rs → df-storage(新建 df-storage/src/secret.rs,src-tauri 改调 df-storage::secret) + - b: df-storage 加薄 secret 查询方法(AiProviderRepo::resolve_api_key(id) 封装 mask/env 解析,df-nodes 调此) + - c: provider_id 注入 config + df-nodes 直查 ai_providers.api_key(不走 secret.rs,df-nodes 自实现解析) +- **推荐**:**待 secret 下沉调研方案定**(workflow wf_94cf4cad 产出 docs/02-架构设计/secret下沉与provider注入方案-2026-06-16.md) +- **关联**:todo F-260616-07 阶段3(⑥联调阻塞此) / secret.rs / FR-S1 / memory FR-S1 api_key IPC mask +- **状态**:🟡 待决(2026-06-16)— secret 下沉方向待调研方案定。AiNode 自审闭环功能通(②③④⑤),⑥阻塞此 P0 安全债。 --- diff --git a/docs/待审查.md b/docs/待审查.md index 13a7b1b..9c5d7ea 100644 --- a/docs/待审查.md +++ b/docs/待审查.md @@ -148,6 +148,16 @@ --- +### CR-260616-43 AiNode 自审阶段2(AiNode持db+ai_self_review节点+DAG透传+前端展示) — 🟡 待审 + +- **范围**: F-260616-07 阶段3 AiNode 自审闭环②③④⑤(3 commit:539b5ed 迁移 + c10adaf ai 侧 + 741b0b9 前端)。①**①迁移**(539b5ed):TaskRecord 加 `output_json: Option` + V17 迁移(幂等补列) + crud 白名单加 output_json(L346)+SELECT/INSERT/UPDATE 全链路 + 5 构造点补 None。②**ai_node.rs②③④**(c10adaf):AiNode 持 db(`Arc`,对齐 TaskAdvanceNode:98-110 先例)+ execute 后 `config["task_id"]` 存在则 `update_field` 落 output_json(产出 schema {text,model,usage},落库失败只 warn 不阻断)+ AiSelfReviewNode 独立节点(parse_review_json 兜底 verdict=unknown + build_review_prompt 四维度 + 写回 review 子字段不覆盖 text)+ state.rs L269-270 注册 ai_self_review + ai 工厂 L262 `AiNode::new(db)` + testing 模板 L61 ai_self_review + L72 edge(ai_self_review→human_review)+ NodeOutput.data 平铺透传 + HumanNode 零改动。③**前端⑤**(741b0b9):types.ts output_json?(schema 注释)+ TaskDetail.vue parsedOutput computed(try/catch 兜底)+review-card 红绿标+renderedOutput 复用 useRendered + i18n zh/en taskDetail.output/review 双语。 +- **维度**: ①AiSelfReviewNode prompt 四维度+JSON 兜底完备性(parse_review_json 各路径 verdict 覆盖,代码块 fence 剥离重试) ②写回 output_json review 子字段(读现有合并不覆盖 text,reviewed_at/reviewer_model) ③DAG 透传(NodeOutput.data 平铺,human_review 经 inputs 读,HumanNode 零改动核验) ④state.rs 注册+工厂闭包 move db.clone() ⑤testing 模板节点类型对齐 ⑥前端 schema 契约一致(types.ts 与 ai_node.rs 写回 schema 字段名对齐 verdict/summary/suggestions) ⑦i18n 特殊字符转义 ⑧**P0 安全债登记**(api_key 明文 config 注入违背 FR-S1,跨 crate 阻塞,F-260616-07c 待决) ⑨主代亲跑 cargo df-nodes 73 passed + workspace EXIT 0 + vue-tsc EXIT 0。 +- **commit**: 539b5ed + c10adaf + 741b0b9。 +- **主代独立核查**: ✅ 全过(human_node.rs 零改动 git diff 确认 / state.rs L262 AiNode::new(ai_db)+L269-270 AiSelfReviewNode::new(review_db) / templates L61 ai_self_review+L72 edge / ai_node.rs AiNode 持 db@L119+execute 写@L184+AiSelfReviewNode@L292+parse_review_json@L258 / cargo test -p df-nodes 73 passed 亲跑 / cargo check --workspace EXIT 0 / vue-tsc EXIT 0 / 前端 schema 对齐)。 +- **审查 agent 待复审重点**: ①AiSelfReviewNode.execute 完整 mock LlmProvider 单测(本次降级 parse_review_json+update_field 单测,P3 待补) ②parse_review_json 兜底各路径(verdict=unknown 覆盖非 Object/数组/缺 verdict/JSON 解析失败/fence 剥离) ③写回 output_json 读现有合并的并发安全(同一 task 多次自审竞态) ④human_review 审批卡 description 拼自审摘要未实现(P2,透传链通但卡片未拼,HumanNode 只读 config 不读 inputs) ⑤P0 api_key config 注入(F-260616-07c 阻塞⑥联调)。 + +--- + ### CR-260616-35 batch59 CR-34-1 守卫 + CR-30 流式重试对齐决策a1 + UX-2025-04 断线保文 — ✅ 已审(PASS) - **范围**: 3 agent 合并批(workflow wdlt0xfl6,主代独立核查全过)。①**CR-34-1** useAiPanel.ts:102 守卫加有效性检查 `|| !list.some(p=>p.id===activeProvider)`(deleted provider 残留回落 DB is_default) ②**CR-30-1/CR-30-2 + UX-2025-04 合并**:stream_recv.rs `StreamResult` enum(Complete/Partial/InitFailed 三分支) + `classify_status_or_class`(4xx Fatal/5xx+429+timeout Retryable 镜像 retry::is_status_retryable) + agentic.rs 重试对齐决策 a1(Init 失败重试复用 retry::backoff_delay 1s→2s→4s±20%jitter + 30s 总预算 retry_deadline + Fatal 分类 4xx 立即放弃; MidStream Partial 不重试保文→入库 + AiCompleted(incomplete=true) + 系统提示「响应因网络中断不完整」) + 删 3 处误导注释(agentic.rs:12/commands.rs/state.rs) + retry.rs `pub mod` + `backoff_delay`/`is_status_retryable` 改 `pub` 暴露供 src-tauri 复用 + useAiEvents.ts:177 补 `case 'AiStreamRetry'`(消除死事件穿透) + AiCompleted case 处理 incomplete + types.ts:204/mod.rs `incomplete?:boolean` 字段(所有 emit 点补 None 向后兼容) + i18n aiStreamRetry/responseIncomplete 双语。