walrus_core/protocol/message/
server.rs1use compact_str::CompactString;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct SendResponse {
9 pub agent: CompactString,
11 pub content: String,
13 pub session: u64,
15}
16
17#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct ToolCallInfo {
20 pub name: CompactString,
22 pub arguments: String,
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
28pub enum StreamEvent {
29 Start {
31 agent: CompactString,
33 session: u64,
35 },
36 Chunk {
38 content: String,
40 },
41 Thinking {
43 content: String,
45 },
46 ToolStart {
48 calls: Vec<ToolCallInfo>,
50 },
51 ToolResult {
53 call_id: CompactString,
55 output: String,
57 },
58 ToolsComplete,
60 End {
62 agent: CompactString,
64 },
65}
66
67#[derive(Debug, Clone, Serialize, Deserialize)]
69pub enum DownloadEvent {
70 Start {
72 model: CompactString,
74 },
75 FileStart {
77 model: CompactString,
79 filename: String,
81 size: u64,
83 },
84 Progress {
86 model: CompactString,
88 bytes: u64,
90 },
91 FileEnd {
93 model: CompactString,
95 filename: String,
97 },
98 End {
100 model: CompactString,
102 },
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize)]
107pub enum HubEvent {
108 Start {
110 package: CompactString,
112 },
113 Step {
115 message: String,
117 },
118 End {
120 package: CompactString,
122 },
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize)]
127pub struct SessionInfo {
128 pub id: u64,
130 pub agent: CompactString,
132 pub created_by: CompactString,
134 pub message_count: usize,
136 pub alive_secs: u64,
138}
139
140#[derive(Debug, Clone, Serialize, Deserialize)]
142pub struct TaskInfo {
143 pub id: u64,
145 #[serde(default, skip_serializing_if = "Option::is_none")]
147 pub parent_id: Option<u64>,
148 pub agent: CompactString,
150 pub status: String,
152 pub description: String,
154 #[serde(default, skip_serializing_if = "Option::is_none")]
156 pub result: Option<String>,
157 #[serde(default, skip_serializing_if = "Option::is_none")]
159 pub error: Option<String>,
160 pub created_by: CompactString,
162 pub prompt_tokens: u64,
164 pub completion_tokens: u64,
166 pub alive_secs: u64,
168 #[serde(default, skip_serializing_if = "Option::is_none")]
170 pub blocked_on: Option<String>,
171}
172
173#[derive(Debug, Clone, Serialize, Deserialize)]
175#[serde(tag = "type", rename_all = "snake_case")]
176pub enum ServerMessage {
177 Response(SendResponse),
179 Stream(StreamEvent),
181 Download(DownloadEvent),
183 Error {
185 code: u16,
187 message: String,
189 },
190 Pong,
192 Hub(HubEvent),
194 Sessions(Vec<SessionInfo>),
196 Tasks(Vec<TaskInfo>),
198}
199
200impl From<SendResponse> for ServerMessage {
201 fn from(r: SendResponse) -> Self {
202 Self::Response(r)
203 }
204}
205
206impl From<StreamEvent> for ServerMessage {
207 fn from(e: StreamEvent) -> Self {
208 Self::Stream(e)
209 }
210}
211
212impl From<DownloadEvent> for ServerMessage {
213 fn from(e: DownloadEvent) -> Self {
214 Self::Download(e)
215 }
216}
217
218impl From<HubEvent> for ServerMessage {
219 fn from(e: HubEvent) -> Self {
220 Self::Hub(e)
221 }
222}
223
224fn error_or_unexpected(msg: ServerMessage) -> anyhow::Error {
225 match msg {
226 ServerMessage::Error { code, message } => {
227 anyhow::anyhow!("server error ({code}): {message}")
228 }
229 other => anyhow::anyhow!("unexpected response: {other:?}"),
230 }
231}
232
233impl TryFrom<ServerMessage> for SendResponse {
234 type Error = anyhow::Error;
235 fn try_from(msg: ServerMessage) -> anyhow::Result<Self> {
236 match msg {
237 ServerMessage::Response(r) => Ok(r),
238 other => Err(error_or_unexpected(other)),
239 }
240 }
241}
242
243impl TryFrom<ServerMessage> for StreamEvent {
244 type Error = anyhow::Error;
245 fn try_from(msg: ServerMessage) -> anyhow::Result<Self> {
246 match msg {
247 ServerMessage::Stream(e) => Ok(e),
248 other => Err(error_or_unexpected(other)),
249 }
250 }
251}
252
253impl TryFrom<ServerMessage> for DownloadEvent {
254 type Error = anyhow::Error;
255 fn try_from(msg: ServerMessage) -> anyhow::Result<Self> {
256 match msg {
257 ServerMessage::Download(e) => Ok(e),
258 other => Err(error_or_unexpected(other)),
259 }
260 }
261}
262
263impl TryFrom<ServerMessage> for HubEvent {
264 type Error = anyhow::Error;
265 fn try_from(msg: ServerMessage) -> anyhow::Result<Self> {
266 match msg {
267 ServerMessage::Hub(e) => Ok(e),
268 other => Err(error_or_unexpected(other)),
269 }
270 }
271}