mofa_kernel/agent/secretary/traits.rs
1//! 秘书Agent核心Traits定义
2//!
3//! 这个模块定义了秘书Agent框架的核心抽象,开发者可以通过实现这些trait
4//! 来完全自定义秘书的行为。
5//!
6//! ## 核心Traits
7//!
8//! - [`SecretaryBehavior`]: 定义秘书的完整行为
9//! - [`InputHandler`]: 处理特定类型的输入
10//! - [`PhaseHandler`]: 处理工作流中的某个阶段
11//! - [`WorkflowOrchestrator`]: 编排多阶段工作流
12
13use async_trait::async_trait;
14use serde::{Serialize, de::DeserializeOwned};
15use std::fmt::Debug;
16
17// =============================================================================
18// 消息抽象
19// =============================================================================
20
21/// 秘书输入消息Trait
22///
23/// 所有发送给秘书的消息都需要实现这个trait。
24/// 这允许开发者定义自己的输入消息类型。
25///
26/// # 示例
27///
28/// ```rust,ignore
29/// #[derive(Debug, Clone, Serialize, Deserialize)]
30/// enum MyInput {
31/// TextMessage(String),
32/// VoiceCommand { audio_url: String },
33/// FileUpload { path: String, mime_type: String },
34/// }
35///
36/// impl SecretaryInput for MyInput {}
37/// ```
38pub trait SecretaryInput:
39 Send + Sync + Clone + Debug + Serialize + DeserializeOwned + 'static
40{
41}
42
43/// 秘书输出消息Trait
44///
45/// 所有秘书发出的消息都需要实现这个trait。
46/// 这允许开发者定义自己的输出消息类型。
47///
48/// # 示例
49///
50/// ```rust,ignore
51/// #[derive(Debug, Clone, Serialize, Deserialize)]
52/// enum MyOutput {
53/// TextReply(String),
54/// ActionRequired { action: String, options: Vec<String> },
55/// Notification { level: String, message: String },
56/// }
57///
58/// impl SecretaryOutput for MyOutput {}
59/// ```
60pub trait SecretaryOutput:
61 Send + Sync + Clone + Debug + Serialize + DeserializeOwned + 'static
62{
63}
64
65// =============================================================================
66// 秘书行为定义
67// =============================================================================
68
69/// 秘书行为Trait - 核心抽象
70///
71/// 这是框架最核心的trait,定义了秘书如何响应用户输入。
72/// 开发者需要实现这个trait来创建自定义的秘书。
73///
74/// # 类型参数
75///
76/// - `Input`: 秘书接受的输入类型
77/// - `Output`: 秘书产生的输出类型
78/// - `State`: 秘书状态类型
79///
80/// # 示例
81///
82/// ```rust,ignore
83/// struct MySecretary {
84/// name: String,
85/// llm: Arc<dyn LLMProvider>,
86/// }
87///
88/// #[async_trait]
89/// impl SecretaryBehavior for MySecretary {
90/// type Input = MyInput;
91/// type Output = MyOutput;
92/// type State = MyState;
93///
94/// async fn handle_input(
95/// &self,
96/// input: Self::Input,
97/// ctx: &mut SecretaryContext<Self::State>,
98/// ) -> anyhow::Result<Vec<Self::Output>> {
99/// match input {
100/// MyInput::TextMessage(text) => {
101/// // 处理文本消息
102/// Ok(vec![MyOutput::TextReply(format!("收到: {}", text))])
103/// }
104/// _ => Ok(vec![]),
105/// }
106/// }
107///
108/// fn welcome_message(&self) -> Option<Self::Output> {
109/// Some(MyOutput::TextReply(format!("你好,我是{}!", self.name)))
110/// }
111///
112/// fn initial_state(&self) -> Self::State {
113/// MyState::new()
114/// }
115/// }
116/// ```
117#[async_trait]
118pub trait SecretaryBehavior: Send + Sync {
119 /// 秘书接受的输入类型
120 type Input: SecretaryInput;
121
122 /// 秘书产生的输出类型
123 type Output: SecretaryOutput;
124
125 /// 秘书的状态类型
126 type State: Send + Sync + 'static;
127
128 /// 处理用户输入
129 ///
130 /// 这是秘书的核心方法,当收到用户输入时会调用此方法。
131 /// 返回要发送给用户的输出消息列表。
132 ///
133 /// # 参数
134 ///
135 /// - `input`: 用户输入
136 /// - `ctx`: 秘书上下文,包含状态和共享资源
137 ///
138 /// # 返回
139 ///
140 /// 返回要发送给用户的输出消息列表
141 async fn handle_input(
142 &self,
143 input: Self::Input,
144 ctx: &mut super::context::SecretaryContext<Self::State>,
145 ) -> anyhow::Result<Vec<Self::Output>>;
146
147 /// 欢迎消息
148 ///
149 /// 当秘书启动时,可以选择发送一条欢迎消息给用户。
150 /// 返回 `None` 表示不发送欢迎消息。
151 fn welcome_message(&self) -> Option<Self::Output> {
152 None
153 }
154
155 /// 初始化状态
156 ///
157 /// 创建秘书的初始状态
158 fn initial_state(&self) -> Self::State;
159
160 /// 定时检查
161 ///
162 /// 在事件循环的每次迭代中调用(当没有用户输入时)。
163 /// 可以用来检查后台任务、发送提醒等。
164 ///
165 /// 默认实现不做任何事情。
166 async fn periodic_check(
167 &self,
168 _ctx: &mut super::context::SecretaryContext<Self::State>,
169 ) -> anyhow::Result<Vec<Self::Output>> {
170 Ok(vec![])
171 }
172
173 /// 连接断开时的清理
174 ///
175 /// 当用户连接断开时调用,可以用来保存状态、清理资源等。
176 async fn on_disconnect(
177 &self,
178 _ctx: &mut super::context::SecretaryContext<Self::State>,
179 ) -> anyhow::Result<()> {
180 Ok(())
181 }
182
183 /// 错误处理
184 ///
185 /// 当处理输入时发生错误,调用此方法生成错误响应。
186 /// 默认实现返回 `None`,表示不向用户发送错误消息。
187 fn handle_error(&self, _error: &anyhow::Error) -> Option<Self::Output> {
188 None
189 }
190}
191
192// =============================================================================
193// 阶段处理器
194// =============================================================================
195
196/// 阶段处理器Trait
197///
198/// 用于实现工作流中的单个阶段。每个阶段接收输入,处理后产生输出。
199/// 这允许将复杂的处理逻辑拆分成多个独立的阶段。
200///
201/// # 类型参数
202///
203/// - `Input`: 阶段接收的输入类型
204/// - `Output`: 阶段产生的输出类型
205/// - `State`: 秘书状态类型
206#[async_trait]
207pub trait PhaseHandler<Input, Output, State>: Send + Sync
208where
209 Input: Send + 'static,
210 Output: Send + 'static,
211 State: Send + Sync + 'static,
212{
213 /// 阶段名称(用于日志和调试)
214 fn name(&self) -> &str;
215
216 /// 处理输入
217 async fn handle(
218 &self,
219 input: Input,
220 ctx: &mut super::context::SecretaryContext<State>,
221 ) -> anyhow::Result<PhaseResult<Output>>;
222
223 /// 是否可以跳过此阶段
224 fn can_skip(&self, _input: &Input, _ctx: &super::context::SecretaryContext<State>) -> bool {
225 false
226 }
227}
228
229/// 阶段处理结果
230#[derive(Debug, Clone)]
231pub enum PhaseResult<T> {
232 /// 继续下一阶段
233 Continue(T),
234 /// 需要用户输入后继续
235 NeedInput {
236 /// 当前结果(部分完成)
237 partial_result: Option<T>,
238 /// 请求用户输入的提示
239 prompt: String,
240 },
241 /// 跳过后续阶段
242 Skip,
243 /// 终止处理
244 Abort { reason: String },
245}
246
247// =============================================================================
248// 工作流编排
249// =============================================================================
250
251/// 工作流编排器Trait
252///
253/// 用于编排多个阶段处理器,实现复杂的工作流。
254#[async_trait]
255pub trait WorkflowOrchestrator<Input, Output, State>: Send + Sync
256where
257 Input: Send + 'static,
258 Output: Send + 'static,
259 State: Send + Sync + 'static,
260{
261 /// 工作流名称
262 fn name(&self) -> &str;
263
264 /// 执行工作流
265 async fn execute(
266 &self,
267 input: Input,
268 ctx: &mut super::context::SecretaryContext<State>,
269 ) -> anyhow::Result<WorkflowResult<Output>>;
270}
271
272/// 工作流执行结果
273#[derive(Debug, Clone)]
274pub enum WorkflowResult<T> {
275 /// 工作流完成
276 Completed(T),
277 /// 需要用户输入
278 NeedInput(String),
279 /// 工作流被跳过
280 Skipped,
281 /// 工作流被终止
282 Aborted(String),
283}
284
285// =============================================================================
286// 输入处理器
287// =============================================================================
288
289/// 输入处理器Trait
290///
291/// 用于处理特定类型的用户输入。可以注册多个处理器来处理不同类型的输入。
292#[async_trait]
293pub trait InputHandler<Input, Output, State>: Send + Sync
294where
295 Input: Send + 'static,
296 Output: Send + 'static,
297 State: Send + Sync + 'static,
298{
299 /// 处理器名称
300 fn name(&self) -> &str;
301
302 /// 检查是否可以处理此输入
303 fn can_handle(&self, input: &Input) -> bool;
304
305 /// 处理输入
306 async fn handle(
307 &self,
308 input: Input,
309 ctx: &mut super::context::SecretaryContext<State>,
310 ) -> anyhow::Result<Vec<Output>>;
311}
312
313// =============================================================================
314// 事件监听器
315// =============================================================================
316
317/// 秘书内部事件
318#[derive(Debug)]
319pub enum SecretaryEvent<State> {
320 /// 秘书启动
321 Started,
322 /// 秘书停止
323 Stopped,
324 /// 收到用户输入
325 InputReceived,
326 /// 发送了输出
327 OutputSent,
328 /// 状态变更
329 StateChanged,
330 /// 自定义事件
331 Custom(String),
332 /// 占位符(用于类型约束)
333 #[doc(hidden)]
334 _Phantom(std::marker::PhantomData<State>),
335}
336
337/// 事件监听器Trait
338///
339/// 可以监听秘书的内部事件,用于日志、监控、扩展等。
340#[async_trait]
341pub trait EventListener<State>: Send + Sync
342where
343 State: Send + Sync + 'static,
344{
345 /// 监听器名称
346 fn name(&self) -> &str;
347
348 /// 处理事件
349 async fn on_event(
350 &self,
351 event: &SecretaryEvent<State>,
352 ctx: &super::context::SecretaryContext<State>,
353 );
354}
355
356// =============================================================================
357// 中间件
358// =============================================================================
359
360/// 中间件Trait
361///
362/// 可以在输入处理前后执行额外逻辑,如日志、认证、限流等。
363#[async_trait]
364pub trait Middleware<Input, Output, State>: Send + Sync
365where
366 Input: Send + Clone + 'static,
367 Output: Send + 'static,
368 State: Send + Sync + 'static,
369{
370 /// 中间件名称
371 fn name(&self) -> &str;
372
373 /// 输入预处理
374 ///
375 /// 在处理输入之前调用。返回 `None` 表示不拦截,继续处理。
376 /// 返回 `Some(outputs)` 表示拦截输入,直接返回这些输出。
377 async fn before_handle(
378 &self,
379 _input: &Input,
380 _ctx: &super::context::SecretaryContext<State>,
381 ) -> Option<Vec<Output>> {
382 None
383 }
384
385 /// 输出后处理
386 ///
387 /// 在产生输出后调用。可以修改或过滤输出。
388 async fn after_handle(
389 &self,
390 _input: &Input,
391 outputs: Vec<Output>,
392 _ctx: &super::context::SecretaryContext<State>,
393 ) -> Vec<Output> {
394 outputs
395 }
396}
397
398// =============================================================================
399// 便捷实现
400// =============================================================================
401
402/// 为所有满足约束的类型自动实现 SecretaryInput
403impl<T> SecretaryInput for T where
404 T: Send + Sync + Clone + Debug + Serialize + DeserializeOwned + 'static
405{
406}
407
408/// 为所有满足约束的类型自动实现 SecretaryOutput
409impl<T> SecretaryOutput for T where
410 T: Send + Sync + Clone + Debug + Serialize + DeserializeOwned + 'static
411{
412}
413
414// =============================================================================
415// 测试
416// =============================================================================
417
418#[cfg(test)]
419mod tests {
420 use super::*;
421 use serde::{Deserialize, Serialize};
422
423 #[derive(Debug, Clone, Serialize, Deserialize)]
424 enum TestInput {
425 Text(String),
426 }
427
428 #[derive(Debug, Clone, Serialize, Deserialize)]
429 enum TestOutput {
430 Reply(String),
431 }
432
433 // 验证自动实现的 trait
434 fn _assert_input_impl<T: SecretaryInput>() {}
435 fn _assert_output_impl<T: SecretaryOutput>() {}
436
437 #[test]
438 fn test_auto_impl() {
439 _assert_input_impl::<TestInput>();
440 _assert_output_impl::<TestOutput>();
441 }
442}