objectiveai_sdk/viewer/
events.rs1use schemars::JsonSchema;
13use serde::{Deserialize, Serialize};
14use tokio::sync::mpsc;
15
16#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
26#[serde(tag = "type", rename_all = "snake_case")]
27#[schemars(rename = "viewer.Event")]
28pub enum Event {
29 #[schemars(title = "Inbound")]
36 Inbound {
37 destination: String,
38 sub_type: String,
39 value: serde_json::Value,
40 },
41 #[schemars(title = "CliCommand")]
47 CliCommand {
48 destination: String,
49 value: serde_json::Value,
50 },
51}
52
53impl Event {
54 pub fn destination(&self) -> &str {
57 match self {
58 Event::Inbound { destination, .. } => destination,
59 Event::CliCommand { destination, .. } => destination,
60 }
61 }
62}
63
64pub type EventReceiver = mpsc::UnboundedReceiver<Event>;
65pub type EventSender = mpsc::UnboundedSender<Event>;
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70 use serde_json::json;
71
72 #[test]
73 fn inbound_serializes_with_tag_and_sub_type() {
74 let e = Event::Inbound {
75 destination: "objectiveai".to_string(),
76 sub_type: "agent_completions".to_string(),
77 value: json!({"id": "abc"}),
78 };
79 let s = serde_json::to_string(&e).unwrap();
80 let v: serde_json::Value = serde_json::from_str(&s).unwrap();
81 assert_eq!(v["type"], "inbound");
82 assert_eq!(v["destination"], "objectiveai");
83 assert_eq!(v["sub_type"], "agent_completions");
84 assert_eq!(v["value"], json!({"id": "abc"}));
85
86 let back: Event = serde_json::from_str(&s).unwrap();
87 match back {
88 Event::Inbound {
89 destination,
90 sub_type,
91 value,
92 } => {
93 assert_eq!(destination, "objectiveai");
94 assert_eq!(sub_type, "agent_completions");
95 assert_eq!(value, json!({"id": "abc"}));
96 }
97 _ => panic!("expected Inbound"),
98 }
99 }
100
101 #[test]
102 fn cli_command_serializes_with_tag_and_no_sub_type() {
103 let e = Event::CliCommand {
104 destination: "my_plugin".to_string(),
105 value: json!({"type": "notification", "value": {"x": 1}}),
106 };
107 let s = serde_json::to_string(&e).unwrap();
108 let v: serde_json::Value = serde_json::from_str(&s).unwrap();
109 assert_eq!(v["type"], "cli_command");
110 assert_eq!(v["destination"], "my_plugin");
111 assert!(v.get("sub_type").is_none());
112 assert_eq!(v["value"]["type"], "notification");
113 }
114
115 #[test]
116 fn destination_accessor() {
117 let i = Event::Inbound {
118 destination: "d1".to_string(),
119 sub_type: "s".to_string(),
120 value: json!(null),
121 };
122 let c = Event::CliCommand {
123 destination: "d2".to_string(),
124 value: json!(null),
125 };
126 assert_eq!(i.destination(), "d1");
127 assert_eq!(c.destination(), "d2");
128 }
129}