agent_stream_kit/
agent.rs

1use async_trait::async_trait;
2
3use super::askit::ASKit;
4use super::config::AgentConfig;
5use super::context::AgentContext;
6use super::data::AgentData;
7use super::error::AgentError;
8use super::runtime::runtime;
9
10#[derive(Debug, Default, Clone, PartialEq)]
11pub enum AgentStatus {
12    #[default]
13    Init,
14    Start,
15    Stop,
16}
17
18pub enum AgentMessage {
19    Input { ctx: AgentContext, data: AgentData },
20    Config { config: AgentConfig },
21    Stop,
22}
23
24#[async_trait]
25pub trait Agent {
26    fn new(
27        askit: ASKit,
28        id: String,
29        def_name: String,
30        config: Option<AgentConfig>,
31    ) -> Result<Self, AgentError>
32    where
33        Self: Sized;
34
35    fn askit(&self) -> &ASKit;
36
37    fn id(&self) -> &str;
38
39    fn status(&self) -> &AgentStatus;
40
41    fn def_name(&self) -> &str;
42
43    fn config(&self) -> Option<&AgentConfig>;
44
45    fn set_config(&mut self, config: AgentConfig) -> Result<(), AgentError>;
46
47    fn get_global_config(&self) -> Option<AgentConfig> {
48        self.askit().get_global_config(self.def_name())
49    }
50
51    fn flow_name(&self) -> &str;
52
53    fn set_flow_name(&mut self, flow_name: String);
54
55    fn start(&mut self) -> Result<(), AgentError>;
56
57    fn stop(&mut self) -> Result<(), AgentError>;
58
59    async fn process(&mut self, ctx: AgentContext, data: AgentData) -> Result<(), AgentError>;
60
61    fn runtime(&self) -> &tokio::runtime::Runtime {
62        runtime()
63    }
64}
65
66pub struct AsAgentData {
67    pub askit: ASKit,
68
69    pub id: String,
70    pub status: AgentStatus,
71    pub def_name: String,
72    pub flow_name: String,
73    pub config: Option<AgentConfig>,
74}
75
76impl AsAgentData {
77    pub fn new(askit: ASKit, id: String, def_name: String, config: Option<AgentConfig>) -> Self {
78        Self {
79            askit,
80            id,
81            status: AgentStatus::Init,
82            def_name,
83            flow_name: String::new(),
84            config,
85        }
86    }
87}
88
89#[async_trait]
90pub trait AsAgent {
91    fn new(
92        askit: ASKit,
93        id: String,
94        def_name: String,
95        config: Option<AgentConfig>,
96    ) -> Result<Self, AgentError>
97    where
98        Self: Sized + Send + Sync;
99
100    fn data(&self) -> &AsAgentData;
101
102    fn mut_data(&mut self) -> &mut AsAgentData;
103
104    fn set_config(&mut self, _config: AgentConfig) -> Result<(), AgentError> {
105        Ok(())
106    }
107
108    fn start(&mut self) -> Result<(), AgentError> {
109        Ok(())
110    }
111
112    fn stop(&mut self) -> Result<(), AgentError> {
113        Ok(())
114    }
115
116    async fn process(&mut self, _ctx: AgentContext, _data: AgentData) -> Result<(), AgentError> {
117        Ok(())
118    }
119}
120
121#[async_trait]
122impl<T: AsAgent + Send + Sync> Agent for T {
123    fn new(
124        askit: ASKit,
125        id: String,
126        def_name: String,
127        config: Option<AgentConfig>,
128    ) -> Result<Self, AgentError> {
129        let mut agent = T::new(askit, id, def_name, config)?;
130        agent.mut_data().status = AgentStatus::Init;
131        Ok(agent)
132    }
133
134    fn askit(&self) -> &ASKit {
135        &self.data().askit
136    }
137
138    fn id(&self) -> &str {
139        &self.data().id
140    }
141
142    fn status(&self) -> &AgentStatus {
143        &self.data().status
144    }
145
146    fn def_name(&self) -> &str {
147        self.data().def_name.as_str()
148    }
149
150    fn config(&self) -> Option<&AgentConfig> {
151        self.data().config.as_ref()
152    }
153
154    fn set_config(&mut self, config: AgentConfig) -> Result<(), AgentError> {
155        self.mut_data().config = Some(config.clone());
156        self.set_config(config)
157    }
158
159    fn flow_name(&self) -> &str {
160        &self.data().flow_name
161    }
162
163    fn set_flow_name(&mut self, flow_name: String) {
164        self.mut_data().flow_name = flow_name.clone();
165    }
166
167    fn start(&mut self) -> Result<(), AgentError> {
168        self.mut_data().status = AgentStatus::Start;
169
170        if let Err(e) = self.start() {
171            self.askit()
172                .emit_error(self.id().to_string(), e.to_string());
173            return Err(e);
174        }
175
176        Ok(())
177    }
178
179    fn stop(&mut self) -> Result<(), AgentError> {
180        self.mut_data().status = AgentStatus::Stop;
181        self.stop()?;
182        self.mut_data().status = AgentStatus::Init;
183        Ok(())
184    }
185
186    async fn process(&mut self, ctx: AgentContext, data: AgentData) -> Result<(), AgentError> {
187        if let Err(e) = self.process(ctx, data).await {
188            self.askit()
189                .emit_error(self.id().to_string(), e.to_string());
190            return Err(e);
191        }
192        Ok(())
193    }
194
195    fn get_global_config(&self) -> Option<AgentConfig> {
196        self.askit().get_global_config(self.def_name())
197    }
198}
199
200pub fn new_boxed<T: Agent + Send + Sync + 'static>(
201    askit: ASKit,
202    id: String,
203    def_name: String,
204    config: Option<AgentConfig>,
205) -> Result<Box<dyn Agent + Send + Sync>, AgentError> {
206    Ok(Box::new(T::new(askit, id, def_name, config)?))
207}
208
209pub fn agent_new(
210    askit: ASKit,
211    agent_id: String,
212    def_name: &str,
213    config: Option<AgentConfig>,
214) -> Result<Box<dyn Agent + Send + Sync>, AgentError> {
215    let def;
216    {
217        let defs = askit.defs.lock().unwrap();
218        def = defs
219            .get(def_name)
220            .ok_or_else(|| AgentError::UnknownDefName(def_name.to_string()))?
221            .clone();
222    }
223
224    if let Some(new_boxed) = def.new_boxed {
225        return new_boxed(askit, agent_id, def_name.to_string(), config);
226    }
227
228    match def.kind.as_str() {
229        // "Command" => {
230        //     return new_boxed::<super::builtins::CommandAgent>(
231        //         askit,
232        //         agent_id,
233        //         def_name.to_string(),
234        //         config,
235        //     );
236        // }
237        _ => return Err(AgentError::UnknownDefKind(def.kind.to_string()).into()),
238    }
239}