scud/attractor/handlers/
mod.rs1pub mod codergen;
4pub mod conditional;
5pub mod exit;
6pub mod fan_in;
7pub mod human;
8pub mod manager;
9pub mod parallel;
10pub mod start;
11pub mod tool;
12
13use anyhow::Result;
14use async_trait::async_trait;
15use std::collections::HashMap;
16
17use super::context::Context;
18use super::graph::{PipelineGraph, PipelineNode};
19use super::outcome::Outcome;
20use super::run_directory::RunDirectory;
21
22#[async_trait]
24pub trait Handler: Send + Sync {
25 async fn execute(
27 &self,
28 node: &PipelineNode,
29 context: &Context,
30 graph: &PipelineGraph,
31 run_dir: &RunDirectory,
32 ) -> Result<Outcome>;
33}
34
35pub struct HandlerRegistry {
37 handlers: HashMap<String, Box<dyn Handler>>,
38 default_handler: Box<dyn Handler>,
39}
40
41impl HandlerRegistry {
42 pub fn new_with_defaults() -> Self {
44 let mut handlers: HashMap<String, Box<dyn Handler>> = HashMap::new();
45 handlers.insert("start".into(), Box::new(start::StartHandler));
46 handlers.insert("exit".into(), Box::new(exit::ExitHandler));
47 handlers.insert("conditional".into(), Box::new(conditional::ConditionalHandler));
48 handlers.insert("wait.human".into(), Box::new(human::HumanHandler));
49 handlers.insert("tool".into(), Box::new(tool::ToolHandler));
50 handlers.insert("parallel".into(), Box::new(parallel::ParallelHandler));
51 handlers.insert(
52 "parallel.fan_in".into(),
53 Box::new(fan_in::FanInHandler),
54 );
55 handlers.insert(
56 "stack.manager_loop".into(),
57 Box::new(manager::ManagerHandler),
58 );
59
60 Self {
61 handlers,
62 default_handler: Box::new(codergen::CodergenHandler::simulated()),
63 }
64 }
65
66 pub fn with_backend(backend: std::sync::Arc<dyn crate::backend::AgentBackend>) -> Self {
71 let mut registry = Self::new_with_defaults();
72 registry.handlers.insert(
73 "codergen".into(),
74 Box::new(codergen::CodergenHandler::new(backend.clone())),
75 );
76 registry.default_handler = Box::new(codergen::CodergenHandler::new(backend));
77 registry
78 }
79
80 pub fn register(&mut self, handler_type: &str, handler: Box<dyn Handler>) {
82 self.handlers.insert(handler_type.to_string(), handler);
83 }
84
85 pub fn get(&self, handler_type: &str) -> &dyn Handler {
87 self.handlers
88 .get(handler_type)
89 .map(|h| h.as_ref())
90 .unwrap_or(self.default_handler.as_ref())
91 }
92}