agent_stream_kit/
agent.rs1use 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 start(&mut self) -> Result<(), AgentError>;
52
53 fn stop(&mut self) -> Result<(), AgentError>;
54
55 async fn process(&mut self, ctx: AgentContext, data: AgentData) -> Result<(), AgentError>;
56
57 fn runtime(&self) -> &tokio::runtime::Runtime {
58 runtime()
59 }
60}
61
62pub struct AsAgentData {
63 pub askit: ASKit,
64
65 pub id: String,
66 pub status: AgentStatus,
67 pub def_name: String,
68 pub config: Option<AgentConfig>,
69}
70
71impl AsAgentData {
72 pub fn new(askit: ASKit, id: String, def_name: String, config: Option<AgentConfig>) -> Self {
73 Self {
74 askit,
75 id,
76 status: AgentStatus::Init,
77 def_name,
78 config,
79 }
80 }
81}
82
83#[async_trait]
84pub trait AsAgent {
85 fn new(
86 askit: ASKit,
87 id: String,
88 def_name: String,
89 config: Option<AgentConfig>,
90 ) -> Result<Self, AgentError>
91 where
92 Self: Sized + Send + Sync;
93
94 fn data(&self) -> &AsAgentData;
95
96 fn mut_data(&mut self) -> &mut AsAgentData;
97
98 fn set_config(&mut self, _config: AgentConfig) -> Result<(), AgentError> {
99 Ok(())
100 }
101
102 fn start(&mut self) -> Result<(), AgentError> {
103 Ok(())
104 }
105
106 fn stop(&mut self) -> Result<(), AgentError> {
107 Ok(())
108 }
109
110 async fn process(&mut self, _ctx: AgentContext, _data: AgentData) -> Result<(), AgentError> {
111 Ok(())
112 }
113}
114
115#[async_trait]
116impl<T: AsAgent + Send + Sync> Agent for T {
117 fn new(
118 askit: ASKit,
119 id: String,
120 def_name: String,
121 config: Option<AgentConfig>,
122 ) -> Result<Self, AgentError> {
123 let mut agent = T::new(askit, id, def_name, config)?;
124 agent.mut_data().status = AgentStatus::Init;
125 Ok(agent)
126 }
127
128 fn askit(&self) -> &ASKit {
129 &self.data().askit
130 }
131
132 fn id(&self) -> &str {
133 &self.data().id
134 }
135
136 fn status(&self) -> &AgentStatus {
137 &self.data().status
138 }
139
140 fn def_name(&self) -> &str {
141 self.data().def_name.as_str()
142 }
143
144 fn config(&self) -> Option<&AgentConfig> {
145 self.data().config.as_ref()
146 }
147
148 fn set_config(&mut self, config: AgentConfig) -> Result<(), AgentError> {
149 self.mut_data().config = Some(config.clone());
150 self.set_config(config)
151 }
152
153 fn start(&mut self) -> Result<(), AgentError> {
154 self.mut_data().status = AgentStatus::Start;
155
156 if let Err(e) = self.start() {
157 self.askit()
158 .emit_error(self.id().to_string(), e.to_string());
159 return Err(e);
160 }
161
162 Ok(())
163 }
164
165 fn stop(&mut self) -> Result<(), AgentError> {
166 self.mut_data().status = AgentStatus::Stop;
167 self.stop()?;
168 self.mut_data().status = AgentStatus::Init;
169 Ok(())
170 }
171
172 async fn process(&mut self, ctx: AgentContext, data: AgentData) -> Result<(), AgentError> {
173 if let Err(e) = self.process(ctx, data).await {
174 self.askit()
175 .emit_error(self.id().to_string(), e.to_string());
176 return Err(e);
177 }
178 Ok(())
179 }
180
181 fn get_global_config(&self) -> Option<AgentConfig> {
182 self.askit().get_global_config(self.def_name())
183 }
184}
185
186pub fn new_boxed<T: Agent + Send + Sync + 'static>(
187 askit: ASKit,
188 id: String,
189 def_name: String,
190 config: Option<AgentConfig>,
191) -> Result<Box<dyn Agent + Send + Sync>, AgentError> {
192 Ok(Box::new(T::new(askit, id, def_name, config)?))
193}
194
195pub fn agent_new(
196 askit: ASKit,
197 agent_id: String,
198 def_name: &str,
199 config: Option<AgentConfig>,
200) -> Result<Box<dyn Agent + Send + Sync>, AgentError> {
201 let def;
202 {
203 let defs = askit.defs.lock().unwrap();
204 def = defs
205 .get(def_name)
206 .ok_or_else(|| AgentError::UnknownDefName(def_name.to_string()))?
207 .clone();
208 }
209
210 if let Some(new_boxed) = def.new_boxed {
211 return new_boxed(askit, agent_id, def_name.to_string(), config);
212 }
213
214 match def.kind.as_str() {
215 _ => return Err(AgentError::UnknownDefKind(def.kind.to_string()).into()),
224 }
225}