rightkit_agent_engine_protocol/event/
durability.rs1use super::ProtocolEvent;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum EventDurability {
8 DurableFact,
9 LiveProjection,
10}
11
12impl ProtocolEvent {
13 pub fn durability(&self) -> EventDurability {
17 match self {
18 Self::AssistantDelta { .. }
19 | Self::ToolOutputDelta { .. }
20 | Self::StreamResyncRequired { .. }
21 | Self::PersistenceFailed { .. } => EventDurability::LiveProjection,
22 _ => EventDurability::DurableFact,
23 }
24 }
25
26 pub fn is_durable_fact(&self) -> bool {
27 self.durability() == EventDurability::DurableFact
28 }
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34 use crate::TranscriptMessage;
35
36 #[test]
37 fn token_delta_and_resync_are_live_projections() {
38 assert_eq!(
39 ProtocolEvent::AssistantDelta {
40 session_id: "s".into(),
41 seq: 1,
42 created_at: "t".into(),
43 text: "x".into(),
44 is_reasoning: false,
45 }
46 .durability(),
47 EventDurability::LiveProjection
48 );
49 assert_eq!(
50 ProtocolEvent::StreamResyncRequired {
51 session_id: "s".into(),
52 seq: 2,
53 created_at: "t".into(),
54 after_seq: 0,
55 oldest_available_seq: 1,
56 high_water_mark: 1,
57 }
58 .durability(),
59 EventDurability::LiveProjection
60 );
61 }
62
63 #[test]
64 fn persistence_failed_is_live_only() {
65 let event = ProtocolEvent::PersistenceFailed {
66 session_id: "s".into(),
67 seq: 0,
68 created_at: "t".into(),
69 reason: "disk full".into(),
70 };
71 assert_eq!(event.durability(), EventDurability::LiveProjection);
72 assert!(!event.is_durable_fact());
73 }
74
75 #[test]
76 fn settled_assistant_message_is_durable_truth() {
77 let message = TranscriptMessage::Assistant {
78 id: "m".into(),
79 created_at: "t".into(),
80 content: "done".into(),
81 reasoning_content: None,
82 tool_calls: Vec::new(),
83 pinned: false,
84 };
85 assert!(ProtocolEvent::AssistantMessageCompleted {
86 session_id: "s".into(),
87 seq: 3,
88 created_at: "t".into(),
89 message,
90 }
91 .is_durable_fact());
92 }
93}