Skip to main content

yoagent_state/
event.rs

1use crate::{EventId, StateError};
2use chrono::Utc;
3use serde::{Deserialize, Serialize};
4use serde_json::Value as JsonValue;
5
6pub const CURRENT_EVENT_SCHEMA_VERSION: u32 = 1;
7
8#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
9pub struct ActorRef {
10    pub kind: String,
11    pub id: String,
12}
13
14impl ActorRef {
15    pub fn new(kind: impl Into<String>, id: impl Into<String>) -> Self {
16        Self {
17            kind: kind.into(),
18            id: id.into(),
19        }
20    }
21
22    pub fn agent(id: impl Into<String>) -> Self {
23        Self::new("agent", id)
24    }
25
26    pub fn user(id: impl Into<String>) -> Self {
27        Self::new("user", id)
28    }
29
30    pub fn system(id: impl Into<String>) -> Self {
31        Self::new("system", id)
32    }
33
34    pub fn tool(id: impl Into<String>) -> Self {
35        Self::new("tool", id)
36    }
37}
38
39#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
40pub struct Event {
41    pub id: EventId,
42    pub schema_version: u32,
43    pub ts_ms: i64,
44    pub actor: ActorRef,
45    pub kind: String,
46    pub payload: JsonValue,
47    pub causation_id: Option<EventId>,
48    pub correlation_id: Option<String>,
49}
50
51impl Event {
52    pub fn new(actor: ActorRef, kind: impl Into<String>, payload: JsonValue) -> Self {
53        Self {
54            id: EventId::generate(),
55            schema_version: CURRENT_EVENT_SCHEMA_VERSION,
56            ts_ms: now_ms(),
57            actor,
58            kind: kind.into(),
59            payload,
60            causation_id: None,
61            correlation_id: None,
62        }
63    }
64
65    pub fn with_causation(mut self, event_id: EventId) -> Self {
66        self.causation_id = Some(event_id);
67        self
68    }
69
70    pub fn with_correlation(mut self, correlation_id: impl Into<String>) -> Self {
71        self.correlation_id = Some(correlation_id.into());
72        self
73    }
74
75    pub fn payload_as<T>(&self) -> Result<T, StateError>
76    where
77        T: for<'de> Deserialize<'de>,
78    {
79        serde_json::from_value(self.payload.clone()).map_err(|source| {
80            StateError::InvalidEventPayload {
81                kind: self.kind.clone(),
82                source,
83            }
84        })
85    }
86}
87
88pub fn now_ms() -> i64 {
89    Utc::now().timestamp_millis()
90}