Skip to main content

mofa_kernel/agent/types/
event.rs

1//! 全局事件系统
2//!
3//! 本模块提供全局事件系统,用于替代分散的 AgentEvent 和 PluginEvent 定义。
4//!
5//! # 设计目标
6//!
7//! - 提供单一的事件类型,避免多处重复定义
8//! - 支持事件的发布-订阅模式
9//! - 支持事件携带任意数据
10//! - 提供清晰的事件来源和类型标识
11
12use serde::{Deserialize, Serialize};
13use std::collections::HashMap;
14
15// ============================================================================
16// GlobalEvent - 全局事件类型
17// ============================================================================
18
19/// 全局事件类型
20///
21/// 替代 `AgentEvent` 和 `PluginEvent`,提供全局事件抽象。
22///
23/// # 事件类型
24///
25/// 常见的事件类型包括:
26/// - `lifecycle:*` - 生命周期事件(created, initialized, started, stopped, shutdown)
27/// - `execution:*` - 执行事件(started, completed, failed, interrupted)
28/// - `message:*` - 消息事件(sent, received, delivered)
29/// - `plugin:*` - 插件事件(loaded, unloaded, error)
30/// - `state:*` - 状态变更事件(changed, error)
31/// - `custom:*` - 自定义事件
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct GlobalEvent {
34    /// 事件 ID(唯一标识)
35    pub event_id: String,
36
37    /// 事件类型
38    ///
39    /// 使用命名空间格式,如 "lifecycle:initialized"
40    pub event_type: String,
41
42    /// 事件源(触发事件的 Agent 或组件 ID)
43    pub source: String,
44
45    /// 时间戳(毫秒)
46    pub timestamp: u64,
47
48    /// 事件数据(负载)
49    pub data: serde_json::Value,
50
51    /// 元数据(额外属性)
52    pub metadata: HashMap<String, String>,
53}
54
55impl GlobalEvent {
56    /// 创建新事件
57    pub fn new(event_type: impl Into<String>, source: impl Into<String>) -> Self {
58        let timestamp = std::time::SystemTime::now()
59            .duration_since(std::time::UNIX_EPOCH)
60            .unwrap()
61            .as_millis() as u64;
62
63        Self {
64            event_id: uuid::Uuid::new_v4().to_string(),
65            event_type: event_type.into(),
66            source: source.into(),
67            timestamp,
68            data: serde_json::Value::Null,
69            metadata: HashMap::new(),
70        }
71    }
72
73    /// 创建带数据的事件
74    pub fn with_data(mut self, data: impl Into<serde_json::Value>) -> Self {
75        self.data = data.into();
76        self
77    }
78
79    /// 添加元数据
80    pub fn with_metadata(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
81        self.metadata.insert(key.into(), value.into());
82        self
83    }
84
85    /// 获取特定数据字段
86    pub fn get_data<T: for<'de> Deserialize<'de>>(&self) -> Option<T> {
87        serde_json::from_value(self.data.clone()).ok()
88    }
89
90    /// 检查事件是否为指定类型
91    pub fn is_type(&self, event_type: &str) -> bool {
92        self.event_type == event_type
93    }
94
95    /// 检查事件是否来自指定源
96    pub fn is_from(&self, source: &str) -> bool {
97        self.source == source
98    }
99
100    /// 检查事件类型是否匹配前缀
101    pub fn matches_prefix(&self, prefix: &str) -> bool {
102        self.event_type.starts_with(prefix)
103    }
104}
105
106// ============================================================================
107// EventBuilder - 事件构建器
108// ============================================================================
109
110/// 事件构建器
111///
112/// 提供流式 API 来构建事件。
113pub struct EventBuilder {
114    event: GlobalEvent,
115}
116
117impl EventBuilder {
118    /// 创建新构建器
119    pub fn new(event_type: impl Into<String>, source: impl Into<String>) -> Self {
120        Self {
121            event: GlobalEvent::new(event_type, source),
122        }
123    }
124
125    /// 设置事件 ID
126    pub fn id(mut self, id: impl Into<String>) -> Self {
127        self.event.event_id = id.into();
128        self
129    }
130
131    /// 设置事件数据
132    pub fn data(mut self, data: impl Into<serde_json::Value>) -> Self {
133        self.event.data = data.into();
134        self
135    }
136
137    /// 添加元数据
138    pub fn metadata(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
139        self.event.metadata.insert(key.into(), value.into());
140        self
141    }
142
143    /// 设置时间戳
144    pub fn timestamp(mut self, timestamp: u64) -> Self {
145        self.event.timestamp = timestamp;
146        self
147    }
148
149    /// 构建事件
150    pub fn build(self) -> GlobalEvent {
151        self.event
152    }
153}
154
155// ============================================================================
156// 预定义事件类型常量
157// ============================================================================
158
159/// 生命周期事件类型
160pub mod lifecycle {
161    pub const CREATED: &str = "lifecycle:created";
162    pub const INITIALIZED: &str = "lifecycle:initialized";
163    pub const STARTED: &str = "lifecycle:started";
164    pub const STOPPED: &str = "lifecycle:stopped";
165    pub const SHUTDOWN: &str = "lifecycle:shutdown";
166    pub const DESTROYED: &str = "lifecycle:destroyed";
167}
168
169/// 执行事件类型
170pub mod execution {
171    pub const STARTED: &str = "execution:started";
172    pub const COMPLETED: &str = "execution:completed";
173    pub const FAILED: &str = "execution:failed";
174    pub const INTERRUPTED: &str = "execution:interrupted";
175    pub const TIMEOUT: &str = "execution:timeout";
176}
177
178/// 消息事件类型
179pub mod message {
180    pub const SENT: &str = "message:sent";
181    pub const RECEIVED: &str = "message:received";
182    pub const DELIVERED: &str = "message:delivered";
183    pub const FAILED: &str = "message:failed";
184}
185
186/// 插件事件类型
187pub mod plugin {
188    pub const LOADED: &str = "plugin:loaded";
189    pub const UNLOADED: &str = "plugin:unloaded";
190    pub const ERROR: &str = "plugin:error";
191}
192
193/// 状态事件类型
194pub mod state {
195    pub const CHANGED: &str = "state:changed";
196    pub const ERROR: &str = "state:error";
197    pub const PAUSED: &str = "state:paused";
198    pub const RESUMED: &str = "state:resumed";
199}
200
201// ============================================================================
202// 辅助函数:快速创建常见事件
203// ============================================================================
204
205/// 创建生命周期事件
206pub fn lifecycle_event(event_type: &str, source: &str) -> GlobalEvent {
207    GlobalEvent::new(event_type, source)
208}
209
210/// 创建执行事件
211pub fn execution_event(event_type: &str, source: &str, data: serde_json::Value) -> GlobalEvent {
212    GlobalEvent::new(event_type, source).with_data(data)
213}
214
215/// 创建状态变更事件
216pub fn state_changed_event(source: &str, old_state: &str, new_state: &str) -> GlobalEvent {
217    GlobalEvent::new(state::CHANGED, source).with_data(serde_json::json!({
218        "old_state": old_state,
219        "new_state": new_state
220    }))
221}
222
223/// 创建错误事件
224pub fn error_event(source: &str, error: &str) -> GlobalEvent {
225    GlobalEvent::new("error", source).with_data(serde_json::json!({
226        "error": error
227    }))
228}
229
230// ============================================================================
231// Tests
232// ============================================================================
233
234#[cfg(test)]
235mod tests {
236    use super::*;
237
238    #[test]
239    fn test_event_creation() {
240        let event = GlobalEvent::new("test:event", "agent1");
241        assert_eq!(event.event_type, "test:event");
242        assert_eq!(event.source, "agent1");
243        assert!(!event.event_id.is_empty());
244    }
245
246    #[test]
247    fn test_event_with_data() {
248        let data = serde_json::json!({ "key": "value" });
249        let event = GlobalEvent::new("test:event", "agent1").with_data(data.clone());
250
251        assert_eq!(event.data, data);
252    }
253
254    #[test]
255    fn test_event_builder() {
256        let event = EventBuilder::new("test:event", "agent1")
257            .id("custom-id")
258            .data(serde_json::json!({ "test": true }))
259            .metadata("meta1", "value1")
260            .timestamp(12345)
261            .build();
262
263        assert_eq!(event.event_id, "custom-id");
264        assert_eq!(event.timestamp, 12345);
265        assert_eq!(event.metadata.get("meta1"), Some(&"value1".to_string()));
266    }
267
268    #[test]
269    fn test_event_type_checks() {
270        let event = GlobalEvent::new("lifecycle:initialized", "agent1");
271
272        assert!(event.is_type("lifecycle:initialized"));
273        assert!(event.is_from("agent1"));
274        assert!(event.matches_prefix("lifecycle:"));
275        assert!(!event.matches_prefix("execution:"));
276    }
277
278    #[test]
279    fn test_helper_functions() {
280        let event = state_changed_event("agent1", "ready", "executing");
281
282        assert!(event.is_type(state::CHANGED));
283        assert_eq!(event.source, "agent1");
284
285        let data: serde_json::Value = event.data;
286        assert_eq!(data["old_state"], "ready");
287        assert_eq!(data["new_state"], "executing");
288    }
289}