From a59feb23c426bc543cf2dd9316e2dfbcdf779943 Mon Sep 17 00:00:00 2001 From: asepharyana Date: Sun, 12 Jul 2026 17:50:38 +0700 Subject: [PATCH] feat: add turn_events to ToolCtx and implement live state updates in spawn tool --- src/app/runtime/actions/mod.rs | 3 +++ src/app/state/rest.rs | 1 + src/tool/mod.rs | 4 ++++ src/tool/spawn.rs | 36 ++++++++++++++++++++++++++++++++-- 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/app/runtime/actions/mod.rs b/src/app/runtime/actions/mod.rs index 1efc080..7ca9971 100644 --- a/src/app/runtime/actions/mod.rs +++ b/src/app/runtime/actions/mod.rs @@ -536,6 +536,9 @@ pub fn apply_action(state: &mut AppStateRest, action: Action) { status, }); } + if state.misc.overlay != Overlay::Workflow { + state.misc.overlay = Overlay::Workflow; + } state.dirty = true; } } diff --git a/src/app/state/rest.rs b/src/app/state/rest.rs index e018671..0c48ada 100644 --- a/src/app/state/rest.rs +++ b/src/app/state/rest.rs @@ -268,6 +268,7 @@ impl AppStateRest { origin, graduated_checks: Vec::new(), lsp_manager: self.lsp_manager.clone(), + turn_events: Some(self.turn_events.clone()), } } } diff --git a/src/tool/mod.rs b/src/tool/mod.rs index b6eca9d..8934725 100644 --- a/src/tool/mod.rs +++ b/src/tool/mod.rs @@ -50,6 +50,7 @@ pub struct ToolCtx { pub origin: crate::app::state::types::Origin, pub graduated_checks: Vec, pub lsp_manager: Arc>, + pub turn_events: Option>>>, } /// Find which graduated checks apply to a given file path/content pair. @@ -86,6 +87,7 @@ pub struct ToolCtxBuilder { pub origin: crate::app::state::types::Origin, pub graduated_checks: Vec, pub lsp_manager: Arc>, + pub turn_events: Option>>>, } impl Default for ToolCtxBuilder { @@ -100,6 +102,7 @@ impl Default for ToolCtxBuilder { origin: crate::app::state::types::Origin::Main, graduated_checks: Vec::new(), lsp_manager: Arc::new(Mutex::new(crate::app::lsp::LspManager::new())), + turn_events: None, } } } @@ -124,6 +127,7 @@ impl ToolCtxBuilder { origin: self.origin, graduated_checks: self.graduated_checks, lsp_manager: self.lsp_manager, + turn_events: self.turn_events, } } } diff --git a/src/tool/spawn.rs b/src/tool/spawn.rs index 4e8f4ba..91b5404 100644 --- a/src/tool/spawn.rs +++ b/src/tool/spawn.rs @@ -88,12 +88,28 @@ impl Tool for SpawnAgents { }, }; + use std::sync::Arc; + let live: Option = _ctx.turn_events.as_ref().map(|turn_events| { + let turn_events = turn_events.clone(); + let f: crate::app::workflow::engine::LiveStateFn = Arc::new(move |agent_id: String, status| { + let name = agent_id.chars().take(30).collect::(); + if let Ok(mut q) = turn_events.lock() { + q.push_back(crate::app::state::runtime::TurnEvent::WorkflowAgentUpdate { + agent_id, + agent_name: name, + status, + }); + } + }); + f + }); + let results = crate::app::workflow::engine::execute_primitive( &wf.script, &HashMap::new(), max_concurrency, true, - None, + live.as_ref(), )?; format_results(results, "parallel") } @@ -155,12 +171,28 @@ impl Tool for SpawnPipeline { }, }; + use std::sync::Arc; + let live: Option = _ctx.turn_events.as_ref().map(|turn_events| { + let turn_events = turn_events.clone(); + let f: crate::app::workflow::engine::LiveStateFn = Arc::new(move |agent_id: String, status| { + let name = agent_id.chars().take(30).collect::(); + if let Ok(mut q) = turn_events.lock() { + q.push_back(crate::app::state::runtime::TurnEvent::WorkflowAgentUpdate { + agent_id, + agent_name: name, + status, + }); + } + }); + f + }); + let results = crate::app::workflow::engine::execute_primitive( &wf.script, &HashMap::new(), 1, false, - None, + live.as_ref(), )?; format_results(results, "pipeline") }