Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T03:58:21.532Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

protocol.rs

209 lines · 5.6 KB · rust
1//! Framed protocol types for `openagents.omega.effectd.v1`.
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6pub const PROTOCOL_SCHEMA: &str = "openagents.omega.effectd.v1";
7pub const PROTOCOL_VERSION: u32 = 1;
8pub const SERVICE_VERSION: &str = "0.1.0";
9/// Newline-framed JSON frames must stay under this byte budget (spec §8).
10pub const MAX_FRAME_BYTES: usize = 64 * 1024;
11
12#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
13#[serde(rename_all = "snake_case")]
14pub enum ProtocolErrorCode {
15    StaleGeneration,
16    UnknownMethod,
17    InvalidRequest,
18    NotRunning,
19    RunNotFound,
20    HostUnavailable,
21    HostTimeout,
22    FrameTooLarge,
23    Internal,
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
27pub struct ProtocolError {
28    pub code: ProtocolErrorCode,
29    pub message: String,
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct RequestFrame {
34    pub schema: String,
35    pub kind: String,
36    pub id: String,
37    pub generation: u64,
38    pub method: String,
39    #[serde(default, skip_serializing_if = "Option::is_none")]
40    pub params: Option<Value>,
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct ResponseFrame {
45    pub schema: String,
46    pub kind: String,
47    pub id: String,
48    pub generation: u64,
49    pub ok: bool,
50    #[serde(default, skip_serializing_if = "Option::is_none")]
51    pub result: Option<Value>,
52    #[serde(default, skip_serializing_if = "Option::is_none")]
53    pub error: Option<ProtocolError>,
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
57#[serde(rename_all = "snake_case")]
58pub enum HostMethod {
59    ResolveWorkspace,
60    ResolveSyncSession,
61    CreateThread,
62    LaneReadiness,
63    DispatchTurn,
64    RefreshEvidence,
65    InterruptTurn,
66    AppendSystemNote,
67    SarahSessionStatus,
68    SarahBootstrap,
69    SarahRoomSnapshot,
70    SarahSendMessage,
71    SarahInterruptTurn,
72    SarahDeviceGrants,
73    SarahRenewDeviceGrant,
74    SarahRevokeDeviceGrant,
75    #[serde(other)]
76    Unsupported,
77}
78
79#[derive(Debug, Clone, Serialize, Deserialize)]
80pub struct HostRequestFrame {
81    pub schema: String,
82    pub kind: String,
83    pub id: String,
84    pub generation: u64,
85    pub method: HostMethod,
86    pub params: Value,
87}
88
89#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
90#[serde(rename_all = "snake_case")]
91pub enum HostResponseErrorCode {
92    StaleGeneration,
93    InvalidRequest,
94    Unsupported,
95    Unavailable,
96    Internal,
97}
98
99#[derive(Debug, Clone, Serialize, Deserialize)]
100pub struct HostResponseError {
101    pub code: HostResponseErrorCode,
102    pub message: String,
103}
104
105impl HostResponseError {
106    pub fn unavailable(message: impl Into<String>) -> Self {
107        Self {
108            code: HostResponseErrorCode::Unavailable,
109            message: message.into(),
110        }
111    }
112}
113
114#[derive(Debug, Clone, Serialize, Deserialize)]
115pub struct HostResponseFrame {
116    pub schema: String,
117    pub kind: String,
118    pub id: String,
119    pub generation: u64,
120    pub ok: bool,
121    #[serde(default, skip_serializing_if = "Option::is_none")]
122    pub result: Option<Value>,
123    #[serde(default, skip_serializing_if = "Option::is_none")]
124    pub error: Option<HostResponseError>,
125}
126
127impl HostResponseFrame {
128    pub fn success(request: &HostRequestFrame, result: Value) -> Self {
129        Self {
130            schema: PROTOCOL_SCHEMA.to_string(),
131            kind: "host_response".to_string(),
132            id: request.id.clone(),
133            generation: request.generation,
134            ok: true,
135            result: Some(result),
136            error: None,
137        }
138    }
139
140    pub fn failure(request: &HostRequestFrame, error: HostResponseError) -> Self {
141        Self {
142            schema: PROTOCOL_SCHEMA.to_string(),
143            kind: "host_response".to_string(),
144            id: request.id.clone(),
145            generation: request.generation,
146            ok: false,
147            result: None,
148            error: Some(error),
149        }
150    }
151}
152
153#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
154#[serde(rename_all = "camelCase")]
155pub struct RunSnapshot {
156    pub run_ref: String,
157    #[serde(default)]
158    pub thread_ref: Option<String>,
159    pub state: String,
160    pub title: String,
161    /// Formatted for display. Never re-parsed to derive a duration.
162    pub updated_at: String,
163    /// OMEGA-MOB-31-03 (omega#47): the host's own numeric record of when the
164    /// run began, in epoch milliseconds. `None` when this host never recorded
165    /// one — a run that predates the field, or one that has not started. The
166    /// mobile projection refuses such a run rather than reporting a zero
167    /// unattended duration.
168    #[serde(default)]
169    pub started_at_ms: Option<u64>,
170}
171
172#[derive(Debug, Clone, Serialize, Deserialize)]
173#[serde(rename_all = "camelCase")]
174pub struct InitializeResult {
175    pub schema: String,
176    pub protocol_version: u32,
177    pub service_version: String,
178    pub generation: u64,
179    pub capabilities: Vec<String>,
180    pub data_root: String,
181    pub active_run_limit: u32,
182}
183
184#[derive(Debug, Clone, Serialize, Deserialize)]
185#[serde(rename_all = "camelCase")]
186pub struct HealthResult {
187    pub ok: bool,
188    pub status: String,
189    pub generation: u64,
190    pub data_root: String,
191    pub active_run_count: u32,
192}
193
194pub fn request_frame(
195    id: impl Into<String>,
196    generation: u64,
197    method: impl Into<String>,
198    params: Option<Value>,
199) -> RequestFrame {
200    RequestFrame {
201        schema: PROTOCOL_SCHEMA.to_string(),
202        kind: "request".to_string(),
203        id: id.into(),
204        generation,
205        method: method.into(),
206        params,
207    }
208}
209
Served at tenant.openagents/omega Member data and write actions are omitted.