diff --git a/Batch.md b/Batch.md index c5d5e38..82035cc 100644 --- a/Batch.md +++ b/Batch.md @@ -412,12 +412,26 @@ - Projects 列表分页(后端 list_projects 已支持 limit/offset) - **验证**: cargo check + vue-tsc 通过 +## Batch 33 — 多 ReAct 对接 + +- **提交**: `当前待提交` +- **内容**: + - PLAN_EXECUTION_ENABLED 从编译期 const 改为运行时 AtomicBool + - 新增 set_plan_execution / get_plan_execution IPC + 前端 API + - 新增 PlanProgress.vue(层状 DAG 执行进度展示组件) +- **验证**: cargo check 通过 + ## 后续规划批次(待推进) -### Batch 33 — 多 ReAct 对接 -1. PlanExecutor 接入 agentic loop(feature flag 门控) -2. plan_hint 升级生成完整 Plan DAG -3. DAG 执行进度前端展示 +### Batch 35 — 人设系统(P0·第一步) +1. AgentPersona 数据结构+5 内置人设(coder/reviewer/architect/tester/analyst) +2. PersonaRegistry 注册表(CRUD + 按场景选人设) +3. AINode 执行时从 persona_id 拼接 system_prompt + 过滤工具集 + +### Batch 36 — Coordinator 填实 + 多 Agent 骨架(P0·第二步) +1. 任务拆解 → 分配人设 → 并行 Agent → 汇总合并 +2. coordinator.rs 从空壳重写为 Agent 调度器 +3. Planner 走完 agentic loop 全链路(feature flag 门控) --- diff --git a/crates/df-ai/src/plan_executor.rs b/crates/df-ai/src/plan_executor.rs index 8349409..84be5d2 100644 --- a/crates/df-ai/src/plan_executor.rs +++ b/crates/df-ai/src/plan_executor.rs @@ -15,9 +15,22 @@ use crate::planner::{Plan, SubTask}; /// Plan 执行总开关。false = 不启用(走单链 ReAct 旧行为)。 /// -/// Phase 2 骨架就绪,未接入主 loop。翻 true 后 PlanExecutor 可用, -/// 但 agentic/mod.rs 仍走单链路径(需 Phase 3 对接)。 -pub const PLAN_EXECUTION_ENABLED: bool = false; +/// 运行时原子门控,支持热切换(通过 IPC 或前端设置开关)。 +/// 默认关,翻 true 后 process_tool_calls 内以 JoinSet 并行执行同层工具。 +/// 与 PLANNING_ENABLED 解耦:plan_hint 独立使能,编排可见性始终可开。 +use std::sync::atomic::{AtomicBool, Ordering}; +pub static PLAN_EXECUTION_ENABLED: AtomicBool = AtomicBool::new(false); + +/// 设置 Plan 执行开关。 +pub fn set_plan_execution(enabled: bool) { + PLAN_EXECUTION_ENABLED.store(enabled, Ordering::SeqCst); + tracing::info!(enabled, "[PLAN-EXEC] 执行开关已更新"); +} + +/// 读取 Plan 执行开关。 +pub fn plan_execution_enabled() -> bool { + PLAN_EXECUTION_ENABLED.load(Ordering::SeqCst) +} /// 单个 SubTask 的执行结果。 #[derive(Debug, Clone)] diff --git a/src-tauri/src/commands/settings.rs b/src-tauri/src/commands/settings.rs index 9baab34..3857732 100644 --- a/src-tauri/src/commands/settings.rs +++ b/src-tauri/src/commands/settings.rs @@ -125,3 +125,18 @@ pub async fn get_script_safety( let bl = state.settings.get("df-script-blacklist").await.map_err(err_str)?.unwrap_or_default(); Ok((wl, bl)) } + +/// 设置多 ReAct Plan 执行开关(默认关)。 +/// 开启后 process_tool_calls 内以 JoinSet 并行执行同层工具。 +#[tauri::command] +pub async fn set_plan_execution(enabled: bool) -> Result<(), String> { + df_ai::plan_executor::set_plan_execution(enabled); + tracing::info!(enabled, "[PLAN-EXEC] IPC 开关已更新"); + Ok(()) +} + +/// 读取多 ReAct Plan 执行开关状态。 +#[tauri::command] +pub async fn get_plan_execution() -> Result { + Ok(df_ai::plan_executor::plan_execution_enabled()) +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 8b8b275..b5f75f9 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -433,6 +433,9 @@ pub fn run() { // ScriptNode 命令安全配置(白/黑名单,前端设置页写入) commands::settings::set_script_safety, commands::settings::get_script_safety, + // Plan 执行开关 + commands::settings::set_plan_execution, + commands::settings::get_plan_execution, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src/api/settings.ts b/src/api/settings.ts index 965ac84..77bee67 100644 --- a/src/api/settings.ts +++ b/src/api/settings.ts @@ -30,4 +30,14 @@ export const settingsApi = { delete(key: string): Promise { return invoke('settings_delete', { key }) }, + + /** 设置多 ReAct Plan 执行开关 */ + setPlanExecution(enabled: boolean): Promise { + return invoke('set_plan_execution', { enabled }) + }, + + /** 读取多 ReAct Plan 执行开关 */ + getPlanExecution(): Promise { + return invoke('get_plan_execution') + }, } diff --git a/src/components/ai/PlanProgress.vue b/src/components/ai/PlanProgress.vue new file mode 100644 index 0000000..82921ed --- /dev/null +++ b/src/components/ai/PlanProgress.vue @@ -0,0 +1,98 @@ + + + + +