Skip to main content

walrus_core/protocol/message/
server.rs

1//! Messages sent by the gateway to the client.
2
3use compact_str::CompactString;
4use serde::{Deserialize, Serialize};
5
6/// Complete response from an agent.
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct SendResponse {
9    /// Source agent identifier.
10    pub agent: CompactString,
11    /// Response content.
12    pub content: String,
13}
14
15/// Events emitted during a streamed agent response.
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub enum StreamEvent {
18    /// Stream has started.
19    Start {
20        /// Source agent identifier.
21        agent: CompactString,
22    },
23    /// A chunk of streamed content.
24    Chunk {
25        /// Chunk content.
26        content: String,
27    },
28    /// Stream has ended.
29    End {
30        /// Source agent identifier.
31        agent: CompactString,
32    },
33}
34
35/// Events emitted during a model download.
36#[derive(Debug, Clone, Serialize, Deserialize)]
37pub enum DownloadEvent {
38    /// Download has started.
39    Start {
40        /// Model being downloaded.
41        model: CompactString,
42    },
43    /// A file download has started.
44    FileStart {
45        /// Model being downloaded.
46        model: CompactString,
47        /// Filename within the repo.
48        filename: String,
49        /// Total size in bytes.
50        size: u64,
51    },
52    /// Download progress for current file (delta, not cumulative).
53    Progress {
54        /// Model being downloaded.
55        model: CompactString,
56        /// Bytes downloaded in this chunk.
57        bytes: u64,
58    },
59    /// A file download has completed.
60    FileEnd {
61        /// Model being downloaded.
62        model: CompactString,
63        /// Filename within the repo.
64        filename: String,
65    },
66    /// All downloads complete.
67    End {
68        /// Model that was downloaded.
69        model: CompactString,
70    },
71}
72
73/// Events emitted during a hub install or uninstall operation.
74#[derive(Debug, Clone, Serialize, Deserialize)]
75pub enum HubEvent {
76    /// Operation has started.
77    Start {
78        /// Package being operated on.
79        package: CompactString,
80    },
81    /// A progress step message.
82    Step {
83        /// Human-readable step description.
84        message: String,
85    },
86    /// Operation has completed.
87    End {
88        /// Package that was operated on.
89        package: CompactString,
90    },
91}
92
93/// Messages sent by the gateway to the client.
94#[derive(Debug, Clone, Serialize, Deserialize)]
95#[serde(tag = "type", rename_all = "snake_case")]
96pub enum ServerMessage {
97    /// Complete response from an agent.
98    Response(SendResponse),
99    /// A streamed response event.
100    Stream(StreamEvent),
101    /// A model download event.
102    Download(DownloadEvent),
103    /// Error response.
104    Error {
105        /// Error code.
106        code: u16,
107        /// Error message.
108        message: String,
109    },
110    /// Pong response to client ping.
111    Pong,
112    /// A hub install/uninstall event.
113    Hub(HubEvent),
114}
115
116impl From<SendResponse> for ServerMessage {
117    fn from(r: SendResponse) -> Self {
118        Self::Response(r)
119    }
120}
121
122impl From<StreamEvent> for ServerMessage {
123    fn from(e: StreamEvent) -> Self {
124        Self::Stream(e)
125    }
126}
127
128impl From<DownloadEvent> for ServerMessage {
129    fn from(e: DownloadEvent) -> Self {
130        Self::Download(e)
131    }
132}
133
134impl From<HubEvent> for ServerMessage {
135    fn from(e: HubEvent) -> Self {
136        Self::Hub(e)
137    }
138}
139
140fn error_or_unexpected(msg: ServerMessage) -> anyhow::Error {
141    match msg {
142        ServerMessage::Error { code, message } => {
143            anyhow::anyhow!("server error ({code}): {message}")
144        }
145        other => anyhow::anyhow!("unexpected response: {other:?}"),
146    }
147}
148
149impl TryFrom<ServerMessage> for SendResponse {
150    type Error = anyhow::Error;
151    fn try_from(msg: ServerMessage) -> anyhow::Result<Self> {
152        match msg {
153            ServerMessage::Response(r) => Ok(r),
154            other => Err(error_or_unexpected(other)),
155        }
156    }
157}
158
159impl TryFrom<ServerMessage> for StreamEvent {
160    type Error = anyhow::Error;
161    fn try_from(msg: ServerMessage) -> anyhow::Result<Self> {
162        match msg {
163            ServerMessage::Stream(e) => Ok(e),
164            other => Err(error_or_unexpected(other)),
165        }
166    }
167}
168
169impl TryFrom<ServerMessage> for DownloadEvent {
170    type Error = anyhow::Error;
171    fn try_from(msg: ServerMessage) -> anyhow::Result<Self> {
172        match msg {
173            ServerMessage::Download(e) => Ok(e),
174            other => Err(error_or_unexpected(other)),
175        }
176    }
177}
178
179impl TryFrom<ServerMessage> for HubEvent {
180    type Error = anyhow::Error;
181    fn try_from(msg: ServerMessage) -> anyhow::Result<Self> {
182        match msg {
183            ServerMessage::Hub(e) => Ok(e),
184            other => Err(error_or_unexpected(other)),
185        }
186    }
187}