2026-07-11 13:16:10 +07:00
use serde_json ::{ json , Value };
use anyhow ::{ Result , anyhow };
use super ::Tool ;
use super ::ToolCtx ;
pub struct WorkflowRun ;
impl Tool for WorkflowRun {
fn name ( & self ) -> & 'static str {
"workflow_run"
}
fn description ( & self ) -> & 'static str {
2026-07-11 23:45:13 +07:00
"Execute a workflow script that can spawn multiple subagents in parallel, pipeline, or phased stages. Use when a task benefits from decomposition into independent subtasks. Simple tasks should be handled inline without this tool."
2026-07-11 13:16:10 +07:00
}
fn parameters ( & self ) -> Value {
json! ({
"type" : "object" ,
"properties" : {
"script" : {
"type" : "string" ,
2026-07-11 23:45:13 +07:00
"description" : "JSON-encoded workflow script with name, description, script (Agent/Parallel/Pipeline/Phase primitives), and options (max_concurrency, continue_on_error)"
2026-07-11 13:16:10 +07:00
},
"args" : {
"type" : "object" ,
2026-07-11 23:45:13 +07:00
"description" : "Optional string key-value arguments passed to the workflow script for template substitution ({{key}} placeholders)"
2026-07-11 13:16:10 +07:00
}
},
"required" : [ "script" ]
})
}
fn run ( & self , _ctx : & ToolCtx , args : & Value ) -> Result < String > {
2026-07-11 20:21:59 +07:00
let script_str = args . get ( "script" )
2026-07-11 13:16:10 +07:00
. and_then ( | v | v . as_str ())
. ok_or_else ( || anyhow! ( "missing required argument: script" )) ? ;
2026-07-11 20:21:59 +07:00
let workflow_script : crate ::app ::workflow ::script ::WorkflowScript =
serde_json ::from_str ( script_str )
. map_err ( | e | anyhow! ( "failed to parse workflow script: {}" , e )) ? ;
let workflow_args : std ::collections ::HashMap < String , String > = args . get ( "args" )
. and_then ( | v | v . as_object ())
. map ( | obj | {
obj . iter (). filter_map ( | ( k , v ) | {
v . as_str (). map ( | s | ( k . clone (), s . to_string ()))
}). collect ()
})
. unwrap_or_default ();
crate ::app ::workflow ::engine ::run_workflow ( & workflow_script , & workflow_args )
2026-07-11 13:16:10 +07:00
}
}
2026-07-11 23:45:13 +07:00
pub struct NoteFinding ;
impl Tool for NoteFinding {
fn name ( & self ) -> & 'static str {
"note_finding"
}
fn description ( & self ) -> & 'static str {
"Share a finding with sibling agents in the same workflow_run. Findings are ephemeral to the current run and will be prepended to other agents' next tool-round context. Does not persist to memory."
}
fn parameters ( & self ) -> Value {
json! ({
"type" : "object" ,
"properties" : {
"text" : {
"type" : "string" ,
"description" : "The finding to share with sibling agents"
}
},
"required" : [ "text" ]
})
}
fn run ( & self , _ctx : & ToolCtx , args : & Value ) -> Result < String > {
let text = args . get ( "text" )
. and_then ( | v | v . as_str ())
. ok_or_else ( || anyhow! ( "missing required argument: text" )) ? ;
crate ::app ::workflow ::engine ::note_finding ( text );
Ok ( format! ( "finding recorded: {} " , text . chars (). take ( 80 ). collect ::< String > ()))
}
}