gemini_adk_rs/text/
race.rs1use std::sync::Arc;
2
3use async_trait::async_trait;
4
5use super::TextAgent;
6use crate::context::AgentEvent;
7use crate::error::AgentError;
8use crate::middleware::MiddlewareChain;
9use crate::state::State;
10
11pub struct RaceTextAgent {
13 name: String,
14 agents: Vec<Arc<dyn TextAgent>>,
15 middleware: MiddlewareChain,
16}
17
18impl RaceTextAgent {
19 pub fn new(name: impl Into<String>, agents: Vec<Arc<dyn TextAgent>>) -> Self {
21 Self {
22 name: name.into(),
23 agents,
24 middleware: MiddlewareChain::new(),
25 }
26 }
27
28 pub fn with_middleware_chain(mut self, chain: MiddlewareChain) -> Self {
33 self.middleware = chain;
34 self
35 }
36}
37
38#[async_trait]
39impl TextAgent for RaceTextAgent {
40 fn name(&self) -> &str {
41 &self.name
42 }
43
44 async fn run(&self, state: &State) -> Result<String, AgentError> {
45 if self.agents.is_empty() {
46 return Err(AgentError::Other("No agents in race".into()));
47 }
48
49 for agent in &self.agents {
50 let _ = self
51 .middleware
52 .run_on_event(&AgentEvent::AgentStarted {
53 name: agent.name().to_string(),
54 })
55 .await;
56 }
57 let (tx, mut rx) = tokio::sync::mpsc::channel::<(String, Result<String, AgentError>)>(1);
58 let cancel = tokio_util::sync::CancellationToken::new();
59
60 let mut handles = Vec::with_capacity(self.agents.len());
61 for agent in &self.agents {
62 let agent = agent.clone();
63 let state = state.clone();
64 let tx = tx.clone();
65 let cancel = cancel.clone();
66
67 handles.push(tokio::spawn(async move {
68 tokio::select! {
69 result = agent.run(&state) => {
70 let _ = tx.send((agent.name().to_string(), result)).await;
71 }
72 _ = cancel.cancelled() => {}
73 }
74 }));
75 }
76 drop(tx); let (winner, result) = rx.recv().await.unwrap_or((
79 String::new(),
80 Err(AgentError::Other("All race agents failed".into())),
81 ));
82
83 cancel.cancel();
85 for handle in handles {
86 handle.abort();
87 }
88
89 if result.is_ok() {
90 let _ = self
91 .middleware
92 .run_on_event(&AgentEvent::AgentCompleted { name: winner })
93 .await;
94 }
95 result
96 }
97}