potato_agent/agents/orchestration/
sequential.rs1use crate::agents::{
2 error::AgentError,
3 run_context::ResumeContext,
4 runner::{AgentRunOutcome, AgentRunResult, AgentRunner},
5 session::SessionState,
6};
7use async_trait::async_trait;
8use potato_util::create_uuid7;
9use std::fmt::Debug;
10use std::sync::Arc;
11
12#[derive(Debug)]
15pub struct SequentialAgent {
16 id: String,
17 agents: Vec<Arc<dyn AgentRunner>>,
18 pass_output: bool,
19}
20
21impl SequentialAgent {
22 pub fn id(&self) -> &str {
23 &self.id
24 }
25}
26
27#[async_trait]
28impl AgentRunner for SequentialAgent {
29 fn id(&self) -> &str {
30 &self.id
31 }
32
33 async fn run(
34 &self,
35 input: &str,
36 session: &mut SessionState,
37 ) -> Result<AgentRunOutcome, AgentError> {
38 let mut current_input = input.to_string();
39 let mut last_result: Option<AgentRunResult> = None;
40
41 for agent in &self.agents {
42 match agent.run(¤t_input, session).await? {
43 AgentRunOutcome::Complete(result) => {
44 if self.pass_output {
45 current_input = result.final_response.response_text();
46 }
47 last_result = Some(*result);
48 }
49 AgentRunOutcome::NeedsInput {
50 question,
51 resume_context,
52 } => {
53 return Ok(AgentRunOutcome::NeedsInput {
55 question,
56 resume_context,
57 });
58 }
59 }
60 }
61
62 match last_result {
63 Some(result) => Ok(AgentRunOutcome::complete(result)),
64 None => Err(AgentError::Error(
65 "SequentialAgent has no agents".to_string(),
66 )),
67 }
68 }
69
70 async fn resume(
71 &self,
72 user_answer: &str,
73 ctx: ResumeContext,
74 session: &mut SessionState,
75 ) -> Result<AgentRunOutcome, AgentError> {
76 for agent in &self.agents {
78 if agent.id() == ctx.agent_id {
79 return agent.resume(user_answer, ctx, session).await;
80 }
81 }
82 Err(AgentError::Error(format!(
83 "No agent with id '{}' found in sequential pipeline",
84 ctx.agent_id
85 )))
86 }
87}
88
89#[derive(Default)]
91pub struct SequentialAgentBuilder {
92 agents: Vec<Arc<dyn AgentRunner>>,
93 pass_output: bool,
94}
95
96impl SequentialAgentBuilder {
97 pub fn new() -> Self {
98 Self::default()
99 }
100
101 pub fn then(mut self, agent: Arc<dyn AgentRunner>) -> Self {
102 self.agents.push(agent);
103 self
104 }
105
106 pub fn pass_output(mut self, yes: bool) -> Self {
108 self.pass_output = yes;
109 self
110 }
111
112 pub fn build(self) -> Arc<SequentialAgent> {
113 Arc::new(SequentialAgent {
114 id: create_uuid7(),
115 agents: self.agents,
116 pass_output: self.pass_output,
117 })
118 }
119}