1use std::sync::Arc;
2
3use async_trait::async_trait;
4
5use super::TextAgent;
6use crate::error::AgentError;
7use crate::state::State;
8
9pub struct RouteRule {
11 predicate: Box<dyn Fn(&State) -> bool + Send + Sync>,
12 agent: Arc<dyn TextAgent>,
13}
14
15impl RouteRule {
16 pub fn new(
18 predicate: impl Fn(&State) -> bool + Send + Sync + 'static,
19 agent: Arc<dyn TextAgent>,
20 ) -> Self {
21 Self {
22 predicate: Box::new(predicate),
23 agent,
24 }
25 }
26}
27
28pub struct RouteTextAgent {
31 name: String,
32 rules: Vec<RouteRule>,
33 default: Arc<dyn TextAgent>,
34}
35
36impl RouteTextAgent {
37 pub fn new(
39 name: impl Into<String>,
40 rules: Vec<RouteRule>,
41 default: Arc<dyn TextAgent>,
42 ) -> Self {
43 Self {
44 name: name.into(),
45 rules,
46 default,
47 }
48 }
49}
50
51#[async_trait]
52impl TextAgent for RouteTextAgent {
53 fn name(&self) -> &str {
54 &self.name
55 }
56
57 async fn run(&self, state: &State) -> Result<String, AgentError> {
58 for rule in &self.rules {
59 if (rule.predicate)(state) {
60 return rule.agent.run(state).await;
61 }
62 }
63 self.default.run(state).await
64 }
65}