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
225impl ServerMessage {
226 pub fn parse(text: &str) -> Result<Self, serde_json::Error> {
231 if text.contains("\"setupComplete\"") {
232 serde_json::from_str::<SetupCompleteMessage>(text).map(ServerMessage::SetupComplete)
233 } else if text.contains("\"toolCallCancellation\"") {
234 serde_json::from_str::<ToolCallCancellationMessage>(text)
236 .map(ServerMessage::ToolCallCancellation)
237 } else if text.contains("\"toolCall\"") {
238 serde_json::from_str::<ToolCallMessage>(text).map(ServerMessage::ToolCall)
239 } else if text.contains("\"serverContent\"") {
240 serde_json::from_str::<ServerContentMessage>(text)
241 .map(|sc| ServerMessage::ServerContent(Box::new(sc)))
242 } else if text.contains("\"goAway\"") {
243 serde_json::from_str::<GoAwayMessage>(text).map(ServerMessage::GoAway)
244 } else if text.contains("\"sessionResumptionUpdate\"") {
245 serde_json::from_str::<SessionResumptionUpdateMessage>(text)
246 .map(ServerMessage::SessionResumptionUpdate)
247 } else if text.contains("\"voiceActivity\"") {
248 serde_json::from_str::<VoiceActivityMessage>(text).map(ServerMessage::VoiceActivity)
249 } else {
250 serde_json::from_str::<serde_json::Value>(text).map(ServerMessage::Unknown)
251 }
252 }
253}