Skip to main content

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}