codex_mobile_bridge/bridge_protocol/
envelopes.rs1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4use super::directory::{DirectoryBookmarkRecord, DirectoryHistoryRecord};
5use super::runtime::{ApiError, RuntimeStatusSnapshot, RuntimeSummary};
6use super::thread::PendingServerRequestRecord;
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct PersistedEvent {
11 pub seq: i64,
12 pub event_type: String,
13 pub runtime_id: Option<String>,
14 pub thread_id: Option<String>,
15 pub payload: Value,
16 pub created_at_ms: i64,
17}
18
19#[derive(Debug, Deserialize)]
20#[serde(tag = "kind", rename_all = "snake_case")]
21pub enum ClientEnvelope {
22 Hello {
23 device_id: String,
24 last_ack_seq: Option<i64>,
25 },
26 Request {
27 request_id: String,
28 action: String,
29 #[serde(default)]
30 payload: Value,
31 },
32 AckEvents {
33 last_seq: i64,
34 },
35 Ping,
36}
37
38#[derive(Debug, Serialize)]
39#[serde(tag = "kind", rename_all = "snake_case")]
40pub enum ServerEnvelope {
41 Hello {
42 bridge_version: String,
43 protocol_version: u32,
44 runtime: RuntimeStatusSnapshot,
45 runtimes: Vec<RuntimeSummary>,
46 directory_bookmarks: Vec<DirectoryBookmarkRecord>,
47 directory_history: Vec<DirectoryHistoryRecord>,
48 pending_requests: Vec<PendingServerRequestRecord>,
49 },
50 Response {
51 request_id: String,
52 success: bool,
53 #[serde(skip_serializing_if = "Option::is_none")]
54 data: Option<Value>,
55 #[serde(skip_serializing_if = "Option::is_none")]
56 error: Option<ApiError>,
57 },
58 Event {
59 seq: i64,
60 event_type: String,
61 #[serde(skip_serializing_if = "Option::is_none")]
62 runtime_id: Option<String>,
63 #[serde(skip_serializing_if = "Option::is_none")]
64 thread_id: Option<String>,
65 payload: Value,
66 },
67 Pong {
68 server_time_ms: i64,
69 },
70}
71
72pub fn ok_response(request_id: String, data: Value) -> ServerEnvelope {
73 ServerEnvelope::Response {
74 request_id,
75 success: true,
76 data: Some(data),
77 error: None,
78 }
79}
80
81pub fn event_envelope(event: PersistedEvent) -> ServerEnvelope {
82 ServerEnvelope::Event {
83 seq: event.seq,
84 event_type: event.event_type,
85 runtime_id: event.runtime_id,
86 thread_id: event.thread_id,
87 payload: event.payload,
88 }
89}