systemprompt_models/notifications/
event.rs1use chrono::{DateTime, Utc};
7use schemars::JsonSchema;
8use serde::{Deserialize, Serialize};
9use systemprompt_identifiers::{AgentName, NotificationStreamId, UserId};
10
11use super::attention::Attention;
12use super::kind::NotificationKind;
13use super::subject::SubjectRef;
14
15pub const NOTIFICATIONS_CONSUMER: &str = "notifications";
16pub const NOTIFICATION_EVENT_VERSION: u32 = 1;
17
18#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
20pub struct DirectRecipient {
21 pub user: UserId,
22 pub attention: Option<Attention>,
23}
24
25#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
27pub struct NotificationEvent {
28 pub kind: NotificationKind,
29 pub actor: UserId,
30 pub actor_is_agent: bool,
31 pub via_agent: Option<AgentName>,
32 pub subjects: Vec<SubjectRef>,
33 pub stream: Option<NotificationStreamId>,
34 pub direct_recipients: Vec<DirectRecipient>,
35 pub sender_attention: Option<Attention>,
36 pub title: Option<String>,
37 pub body: Option<String>,
38 pub payload: serde_json::Value,
40 pub occurred_at: DateTime<Utc>,
41}
42
43impl NotificationEvent {
44 #[must_use]
45 pub const fn new(kind: NotificationKind, actor: UserId, occurred_at: DateTime<Utc>) -> Self {
46 Self {
47 kind,
48 actor,
49 actor_is_agent: false,
50 via_agent: None,
51 subjects: Vec::new(),
52 stream: None,
53 direct_recipients: Vec::new(),
54 sender_attention: None,
55 title: None,
56 body: None,
57 payload: serde_json::Value::Null,
58 occurred_at,
59 }
60 }
61
62 #[must_use]
63 pub const fn with_actor_is_agent(mut self, actor_is_agent: bool) -> Self {
64 self.actor_is_agent = actor_is_agent;
65 self
66 }
67
68 #[must_use]
69 pub fn with_via_agent(mut self, via_agent: AgentName) -> Self {
70 self.via_agent = Some(via_agent);
71 self
72 }
73
74 #[must_use]
75 pub fn with_subject(mut self, subject: SubjectRef) -> Self {
76 self.subjects.push(subject);
77 self
78 }
79
80 #[must_use]
81 pub fn with_subjects(mut self, subjects: impl IntoIterator<Item = SubjectRef>) -> Self {
82 self.subjects.extend(subjects);
83 self
84 }
85
86 #[must_use]
87 pub fn with_stream(mut self, stream: NotificationStreamId) -> Self {
88 self.stream = Some(stream);
89 self
90 }
91
92 #[must_use]
93 pub fn with_direct_recipient(mut self, user: UserId, attention: Option<Attention>) -> Self {
94 self.direct_recipients
95 .push(DirectRecipient { user, attention });
96 self
97 }
98
99 #[must_use]
100 pub fn with_direct_recipients(
101 mut self,
102 recipients: impl IntoIterator<Item = DirectRecipient>,
103 ) -> Self {
104 self.direct_recipients.extend(recipients);
105 self
106 }
107
108 #[must_use]
109 pub const fn with_sender_attention(mut self, attention: Attention) -> Self {
110 self.sender_attention = Some(attention);
111 self
112 }
113
114 #[must_use]
115 pub fn with_title(mut self, title: impl Into<String>) -> Self {
116 self.title = Some(title.into());
117 self
118 }
119
120 #[must_use]
121 pub fn with_body(mut self, body: impl Into<String>) -> Self {
122 self.body = Some(body.into());
123 self
124 }
125
126 #[must_use]
127 pub fn with_payload(mut self, payload: serde_json::Value) -> Self {
129 self.payload = payload;
130 self
131 }
132}