//! 工作流类 AI 工具声明式注册(register_workflow_tools 1 个:run_workflow 迁入)。 //! //! 迁自 `tool_registry.rs::register_workflow_tools`(原 1 个 run_workflow),改用 `declare_tool!` 宏。 //! //! 迁移策略(handler 逻辑零变更): //! - handler body 逐字照搬原 async move 块(防御兜底返 Err,正常流程不可达),仅闭包包装改由 //! `declare_tool!` 宏生成。 //! - name/desc/schema/risk 与原手写定义逐字一致。 //! - 无捕获:CR-52 删死代码后 handler 不 clone db(防御兜底,run_workflow 真正执行经 //! ai_approve → execute_run_workflow_for_tool → workflow.rs::run_workflow_inner),用占位 //! `Arc<()>` 捕获(宏要求 capture 形参)。 //! //! 等价性验证:基线测试 `test_build_ai_tool_registry_baseline_tool_count` 仍断言 48 总量 + //! 工具名集合稳定(防 rename / 漏注册)。 use std::sync::Arc; use df_ai::ai_tools::{object_schema, AiToolRegistry, GoalMeta, GoalStyle, RiskLevel, ToolMeta}; use df_ai::declare_tool; /// 注册 run_workflow 工具到 `$registry`(无 db 捕获,防御兜底)。 /// /// 与原手写 register(name, desc, schema, risk, handler) 语义 1:1: /// - name/desc/schema 字符串与 JSON Schema 逐字照搬原定义 /// - risk=High(触发工作流引擎执行,须人工批准) /// - handler body 与原 async move 块逐字一致(逻辑零变更,仅返 Err 兜底) /// /// 唯一差异:闭包包装改由 `declare_tool!` 宏生成,handler body 直接写业务逻辑。 pub fn register(registry: &mut AiToolRegistry) { // 无捕获:占位 Arc<()>(CR-52 后 handler 不持 db,仅返 Err 防御)。 let dummy: Arc<()> = Arc::new(()); declare_tool!( registry, dummy: Arc<()>, "run_workflow", "按任务 target_status 推进对应工作流(含 AiNode 自审 / HumanNode 核对闸门)。参数 task_id + target_status 同时提供才联动任务推进(完成后按 target_status 推进任务,失败按退回态回滚)。属高风险操作(触发工作流引擎执行),须人工批准。审批通过后由后端直接执行工作流引擎并联动推进任务,返回 execution_id", RiskLevel::High, meta: ToolMeta { approval_hint: Some(("触发工作流:任务{} 推进到 {}", &["task_id", "target_status"])), display_verb: Some("触发工作流"), goal: Some(GoalMeta { verb: "执行工作流", keys: &[], style: GoalStyle::Raw, fallback: Some("执行工作流") }), ..Default::default() }, schema: object_schema(vec![("task_id", "string", true), ("target_status", "string", true)]), args => { let task_id = args["task_id"].as_str().ok_or_else(|| anyhow::anyhow!("缺少 task_id"))?; let target_status = args["target_status"].as_str() .ok_or_else(|| anyhow::anyhow!("缺少 target_status"))?; // 防御兜底(正常流程不可达):run_workflow 经 ai_approve 分支执行,不经此 handler。 // 误入此路径说明调用方异常(非 ai_approve 直接 execute),返回明确错误勿盲目重试 // (对齐 run_command 超时标注模式 L700-712),High risk 去重缓存会断 LLM 重试循环。 Err(anyhow::anyhow!( "run_workflow 须经人工审批后由后端 ai_approve 分支执行(转调 run_workflow_inner,\ 持完整 State)。本 handler 经 ai_tools.execute 调用属异常路径(无 AppHandle/State),\ 勿盲目重试同调用(task_id={}, target_status={});\ 若需推进任务,重新发起 run_workflow tool_call 走审批流程。", task_id, target_status )) } ); }