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) -> Result<&AgentConfig, AgentError>;
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) -> Result<&AgentConfig, AgentError> {
151 self.data().config.as_ref().ok_or(AgentError::NoConfig)
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_agent_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 _ => return Err(AgentError::UnknownDefKind(def.kind.to_string()).into()),
238 }
239}