gemini_genai_rs/protocol/messages/
server.rs1use serde::{Deserialize, Serialize};
4
5use crate::protocol::types::*;
6
7#[derive(Debug, Clone, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct SetupCompleteMessage {
11 pub setup_complete: SetupCompletePayload,
13}
14
15#[derive(Debug, Clone, Deserialize)]
17#[serde(rename_all = "camelCase")]
18pub struct SetupCompletePayload {
19 #[serde(default)]
21 pub session_resumption: Option<SessionResumptionResult>,
22}
23
24#[derive(Debug, Clone, Deserialize)]
26#[serde(rename_all = "camelCase")]
27pub struct SessionResumptionResult {
28 #[serde(default)]
30 pub handle: Option<String>,
31 #[serde(default)]
33 pub resumed: Option<bool>,
34}
35
36#[derive(Debug, Clone, Deserialize)]
38#[serde(rename_all = "camelCase")]
39pub struct ServerContentMessage {
40 pub server_content: ServerContentPayload,
42 #[serde(default)]
44 pub usage_metadata: Option<UsageMetadata>,
45}
46
47#[derive(Debug, Clone, Deserialize)]
49#[serde(rename_all = "camelCase")]
50pub struct ServerContentPayload {
51 #[serde(default)]
53 pub model_turn: Option<Content>,
54 #[serde(default)]
56 pub turn_complete: Option<bool>,
57 #[serde(default)]
59 pub generation_complete: Option<bool>,
60 #[serde(default)]
62 pub interrupted: Option<bool>,
63 #[serde(default)]
65 pub input_transcription: Option<TranscriptionPayload>,
66 #[serde(default)]
68 pub output_transcription: Option<TranscriptionPayload>,
69 #[serde(default)]
71 pub grounding_metadata: Option<GroundingMetadata>,
72 #[serde(default)]
74 pub url_context_metadata: Option<UrlContextMetadata>,
75 #[serde(default)]
77 pub turn_complete_reason: Option<String>,
78 #[serde(default)]
80 pub waiting_for_input: Option<bool>,
81}
82
83#[derive(Debug, Clone, Deserialize)]
85pub struct TranscriptionPayload {
86 #[serde(default)]
88 pub text: Option<String>,
89}
90
91#[derive(Debug, Clone, Deserialize)]
93#[serde(rename_all = "camelCase")]
94pub struct ToolCallMessage {
95 pub tool_call: ToolCallPayload,
97}
98
99#[derive(Debug, Clone, Deserialize)]
101#[serde(rename_all = "camelCase")]
102pub struct ToolCallPayload {
103 pub function_calls: Vec<FunctionCall>,
105}
106
107#[derive(Debug, Clone, Deserialize)]
109#[serde(rename_all = "camelCase")]
110pub struct ToolCallCancellationMessage {
111 pub tool_call_cancellation: ToolCallCancellationPayload,
113}
114
115#[derive(Debug, Clone, Deserialize)]
117#[serde(rename_all = "camelCase")]
118pub struct ToolCallCancellationPayload {
119 pub ids: Vec<String>,
121}
122
123#[derive(Debug, Clone, Deserialize)]
125#[serde(rename_all = "camelCase")]
126pub struct GoAwayMessage {
127 pub go_away: GoAwayPayload,
129}
130
131#[derive(Debug, Clone, Deserialize)]
133#[serde(rename_all = "camelCase")]
134pub struct GoAwayPayload {
135 #[serde(default)]
137 pub time_left: Option<String>,
138}
139
140#[derive(Debug, Clone, Deserialize)]
142#[serde(rename_all = "camelCase")]
143pub struct SessionResumptionUpdateMessage {
144 pub session_resumption_update: SessionResumptionUpdatePayload,
146}
147
148#[derive(Debug, Clone, Deserialize)]
150#[serde(rename_all = "camelCase")]
151pub struct SessionResumptionUpdatePayload {
152 #[serde(default)]
154 pub new_handle: Option<String>,
155 #[serde(default)]
157 pub resumable: Option<bool>,
158 #[serde(default)]
160 pub last_consumed_client_message_index: Option<String>,
161}
162
163#[derive(Debug, Clone, Serialize, Deserialize)]
165#[serde(rename_all = "camelCase")]
166pub struct VoiceActivityMessage {
167 pub voice_activity: VoiceActivityPayload,
169}
170
171#[derive(Debug, Clone, Serialize, Deserialize)]
173#[serde(rename_all = "camelCase")]
174pub struct VoiceActivityPayload {
175 #[serde(skip_serializing_if = "Option::is_none")]
177 pub voice_activity_type: Option<VoiceActivityType>,
178}
179
180#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
182pub enum VoiceActivityType {
183 #[serde(rename = "VOICE_ACTIVITY_START")]
185 VoiceActivityStart,
186 #[serde(rename = "VOICE_ACTIVITY_END")]
188 VoiceActivityEnd,
189}
190
191#[derive(Debug, Clone, Deserialize)]
193#[serde(rename_all = "camelCase")]
194pub struct ServerMessageWrapper {
195 #[serde(default)]
197 pub usage_metadata: Option<UsageMetadata>,
198}
199
200#[derive(Debug, Clone)]
206pub enum ServerMessage {
207 SetupComplete(SetupCompleteMessage),
209 ServerContent(Box<ServerContentMessage>),
211 ToolCall(ToolCallMessage),
213 ToolCallCancellation(ToolCallCancellationMessage),
215 GoAway(GoAwayMessage),
217 SessionResumptionUpdate(SessionResumptionUpdateMessage),
219 VoiceActivity(VoiceActivityMessage),
221 Unknown(serde_json::Value),
223}
224
225#[derive(Deserialize)]
230#[serde(rename_all = "camelCase")]
231struct RawServerMessage {
232 setup_complete: Option<SetupCompletePayload>,
233 server_content: Option<ServerContentPayload>,
234 usage_metadata: Option<UsageMetadata>,
235 tool_call: Option<ToolCallPayload>,
236 tool_call_cancellation: Option<ToolCallCancellationPayload>,
237 go_away: Option<GoAwayPayload>,
238 session_resumption_update: Option<SessionResumptionUpdatePayload>,
239 voice_activity: Option<VoiceActivityPayload>,
240}
241
242impl ServerMessage {
243 pub fn parse(text: &str) -> Result<Self, serde_json::Error> {
249 let raw: RawServerMessage = match serde_json::from_str(text) {
250 Ok(raw) => raw,
251 Err(e) => {
255 return if text.trim_start().starts_with('{') {
256 Err(e)
257 } else {
258 serde_json::from_str::<serde_json::Value>(text).map(ServerMessage::Unknown)
259 };
260 }
261 };
262
263 if let Some(setup_complete) = raw.setup_complete {
264 Ok(ServerMessage::SetupComplete(SetupCompleteMessage {
265 setup_complete,
266 }))
267 } else if let Some(tool_call_cancellation) = raw.tool_call_cancellation {
268 Ok(ServerMessage::ToolCallCancellation(
269 ToolCallCancellationMessage {
270 tool_call_cancellation,
271 },
272 ))
273 } else if let Some(tool_call) = raw.tool_call {
274 Ok(ServerMessage::ToolCall(ToolCallMessage { tool_call }))
275 } else if let Some(server_content) = raw.server_content {
276 Ok(ServerMessage::ServerContent(Box::new(
277 ServerContentMessage {
278 server_content,
279 usage_metadata: raw.usage_metadata,
280 },
281 )))
282 } else if let Some(go_away) = raw.go_away {
283 Ok(ServerMessage::GoAway(GoAwayMessage { go_away }))
284 } else if let Some(session_resumption_update) = raw.session_resumption_update {
285 Ok(ServerMessage::SessionResumptionUpdate(
286 SessionResumptionUpdateMessage {
287 session_resumption_update,
288 },
289 ))
290 } else if let Some(voice_activity) = raw.voice_activity {
291 Ok(ServerMessage::VoiceActivity(VoiceActivityMessage {
292 voice_activity,
293 }))
294 } else {
295 serde_json::from_str::<serde_json::Value>(text).map(ServerMessage::Unknown)
297 }
298 }
299}