Skip to main content

lash_remote_protocol/protocol/
observations.rs

1#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
2pub struct RemoteSessionCursor {
3    pub protocol_version: u32,
4    pub cursor: String,
5}
6
7impl RemoteSessionCursor {
8    pub fn new(cursor: impl Into<String>) -> Self {
9        Self {
10            protocol_version: REMOTE_PROTOCOL_VERSION,
11            cursor: cursor.into(),
12        }
13    }
14
15    pub fn validate(&self) -> Result<(), RemoteProtocolError> {
16        ensure_protocol_version(self.protocol_version)?;
17        require_non_empty("RemoteSessionCursor", "cursor", &self.cursor)
18    }
19}
20
21#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
22pub struct RemoteSessionObservationEvent {
23    pub protocol_version: u32,
24    pub session_id: String,
25    pub revision: u64,
26    pub cursor: String,
27    #[serde(flatten)]
28    pub event: RemoteSessionObservationEventPayload,
29}
30
31impl RemoteSessionObservationEvent {
32    pub fn validate(&self) -> Result<(), RemoteProtocolError> {
33        ensure_protocol_version(self.protocol_version)?;
34        require_non_empty(
35            "RemoteSessionObservationEvent",
36            "session_id",
37            &self.session_id,
38        )?;
39        require_non_empty("RemoteSessionObservationEvent", "cursor", &self.cursor)?;
40        if let RemoteSessionObservationEventPayload::TurnActivity { activity } = &self.event {
41            activity.validate()?;
42            if activity.protocol_version != self.protocol_version {
43                return Err(RemoteProtocolError::MismatchedNestedProtocolVersion {
44                    parent: "RemoteSessionObservationEvent",
45                    child: "activity",
46                    parent_version: self.protocol_version,
47                    child_version: activity.protocol_version,
48                });
49            }
50        }
51        Ok(())
52    }
53}
54
55#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
56#[serde(tag = "type", rename_all = "snake_case")]
57pub enum RemoteSessionObservationEventPayload {
58    TurnActivity {
59        activity: RemoteTurnActivity,
60    },
61    Committed,
62    AgentFrameSwitched {
63        frame_id: String,
64    },
65    QueueChanged {
66        kind: RemoteSessionQueueEventKind,
67        batch_ids: Vec<String>,
68    },
69    ProcessChanged {
70        kind: RemoteSessionProcessEventKind,
71        process_ids: Vec<String>,
72    },
73}
74
75#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
76#[serde(rename_all = "snake_case")]
77pub enum RemoteSessionQueueEventKind {
78    Enqueued,
79    Cancelled,
80}
81
82#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
83#[serde(rename_all = "snake_case")]
84pub enum RemoteSessionProcessEventKind {
85    Started,
86    Cancelled,
87}
88
89#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
90pub struct RemoteLiveReplayGap {
91    pub protocol_version: u32,
92    pub session_id: String,
93    pub requested_cursor: String,
94    pub latest_cursor: String,
95    pub latest_revision: u64,
96    pub reason: RemoteLiveReplayGapReason,
97}
98
99impl RemoteLiveReplayGap {
100    pub fn validate(&self) -> Result<(), RemoteProtocolError> {
101        ensure_protocol_version(self.protocol_version)?;
102        require_non_empty("RemoteLiveReplayGap", "session_id", &self.session_id)?;
103        require_non_empty(
104            "RemoteLiveReplayGap",
105            "requested_cursor",
106            &self.requested_cursor,
107        )?;
108        require_non_empty("RemoteLiveReplayGap", "latest_cursor", &self.latest_cursor)
109    }
110}
111
112#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
113#[serde(rename_all = "snake_case")]
114pub enum RemoteLiveReplayGapReason {
115    Trimmed,
116    Unavailable,
117}
118
119impl RemoteTurnResult {
120    pub fn validate(&self) -> Result<(), RemoteProtocolError> {
121        ensure_protocol_version(self.protocol_version)?;
122        require_non_empty("RemoteTurnResult", "session_id", &self.session_id)?;
123        require_non_empty("RemoteTurnResult", "turn_id", &self.turn_id)?;
124        for activity in &self.activities {
125            if activity.protocol_version != self.protocol_version {
126                return Err(RemoteProtocolError::MismatchedNestedProtocolVersion {
127                    parent: "RemoteTurnResult",
128                    child: "activities",
129                    parent_version: self.protocol_version,
130                    child_version: activity.protocol_version,
131                });
132            }
133            activity.validate()?;
134        }
135        Ok(())
136    }
137}