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