Skip to main content

gemini_live/types/
server_message.rs

1//! Server → Client message types and the semantic [`ServerEvent`] enum.
2//!
3//! A single wire message ([`ServerMessage`]) is a flat struct where **multiple
4//! fields may be present simultaneously** (e.g. `serverContent` +
5//! `usageMetadata`).  The [`codec::into_events`](crate::codec::into_events)
6//! function decomposes it into a sequence of [`ServerEvent`]s — the
7//! application-facing abstraction.
8
9use std::time::Duration;
10
11use serde::Deserialize;
12
13use super::common::{Content, EmptyObject};
14
15// ── Wire-level struct ────────────────────────────────────────────────────────
16
17/// Raw server message as received on the wire.
18///
19/// Multiple fields can be populated in the same message.  Use
20/// [`codec::into_events`](crate::codec::into_events) to decompose this into
21/// a `Vec<ServerEvent>`.
22#[derive(Debug, Clone, Deserialize)]
23#[serde(rename_all = "camelCase")]
24pub struct ServerMessage {
25    #[serde(default)]
26    pub setup_complete: Option<EmptyObject>,
27    #[serde(default)]
28    pub server_content: Option<ServerContent>,
29    #[serde(default)]
30    pub tool_call: Option<ToolCallMessage>,
31    #[serde(default)]
32    pub tool_call_cancellation: Option<ToolCallCancellation>,
33    #[serde(default)]
34    pub go_away: Option<GoAway>,
35    #[serde(default)]
36    pub session_resumption_update: Option<SessionResumptionUpdate>,
37    #[serde(default)]
38    pub usage_metadata: Option<UsageMetadata>,
39    #[serde(default)]
40    pub error: Option<ApiError>,
41}
42
43/// Model output and associated metadata within a single wire message.
44#[derive(Debug, Clone, Deserialize)]
45#[serde(rename_all = "camelCase")]
46pub struct ServerContent {
47    pub model_turn: Option<Content>,
48    #[serde(default)]
49    pub turn_complete: Option<bool>,
50    /// `true` once the model has finished generating (the turn may still be
51    /// open for transcription, grounding, etc.).
52    #[serde(default)]
53    pub generation_complete: Option<bool>,
54    #[serde(default)]
55    pub interrupted: Option<bool>,
56    pub input_transcription: Option<Transcription>,
57    pub output_transcription: Option<Transcription>,
58    /// Grounding metadata (schema may evolve — kept as opaque JSON).
59    pub grounding_metadata: Option<serde_json::Value>,
60    pub url_context_metadata: Option<serde_json::Value>,
61}
62
63#[derive(Debug, Clone, PartialEq, Deserialize)]
64pub struct Transcription {
65    pub text: String,
66}
67
68// ── Tool call ────────────────────────────────────────────────────────────────
69
70#[derive(Debug, Clone, Deserialize)]
71#[serde(rename_all = "camelCase")]
72pub struct ToolCallMessage {
73    pub function_calls: Vec<FunctionCallRequest>,
74}
75
76/// A function the server wants the client to execute.
77#[derive(Debug, Clone, Deserialize)]
78#[serde(rename_all = "camelCase")]
79pub struct FunctionCallRequest {
80    /// Server-assigned call ID — must be echoed back in [`FunctionResponse`](super::client_message::FunctionResponse).
81    pub id: String,
82    pub name: String,
83    /// Arguments as a JSON object matching the function's declared schema.
84    pub args: serde_json::Value,
85}
86
87#[derive(Debug, Clone, Deserialize)]
88pub struct ToolCallCancellation {
89    pub ids: Vec<String>,
90}
91
92// ── Session lifecycle ────────────────────────────────────────────────────────
93
94/// Sent when the server is about to terminate the connection.
95/// The client should reconnect (with a session resumption handle if available).
96#[derive(Debug, Clone, Deserialize)]
97#[serde(rename_all = "camelCase")]
98pub struct GoAway {
99    /// Remaining time before disconnect, as a protobuf Duration string (e.g. `"30s"`).
100    pub time_left: Option<String>,
101}
102
103/// Periodic update with a fresh session resumption handle.
104#[derive(Debug, Clone, Deserialize)]
105#[serde(rename_all = "camelCase")]
106pub struct SessionResumptionUpdate {
107    pub new_handle: Option<String>,
108    #[serde(default)]
109    pub resumable: Option<bool>,
110}
111
112// ── Usage metadata ───────────────────────────────────────────────────────────
113
114/// Token usage statistics.  Accompanies many server messages.
115#[derive(Debug, Clone, PartialEq, Deserialize)]
116#[serde(rename_all = "camelCase")]
117pub struct UsageMetadata {
118    #[serde(default)]
119    pub prompt_token_count: u32,
120    #[serde(default)]
121    pub cached_content_token_count: u32,
122    #[serde(default)]
123    pub response_token_count: u32,
124    #[serde(default)]
125    pub tool_use_prompt_token_count: u32,
126    #[serde(default)]
127    pub thoughts_token_count: u32,
128    #[serde(default)]
129    pub total_token_count: u32,
130    #[serde(default)]
131    pub prompt_tokens_details: Option<Vec<ModalityTokenCount>>,
132    #[serde(default)]
133    pub response_tokens_details: Option<Vec<ModalityTokenCount>>,
134}
135
136#[derive(Debug, Clone, PartialEq, Deserialize)]
137#[serde(rename_all = "camelCase")]
138pub struct ModalityTokenCount {
139    pub modality: String,
140    pub token_count: u32,
141}
142
143/// An error returned by the API.
144#[derive(Debug, Clone, PartialEq, Deserialize)]
145pub struct ApiError {
146    pub message: String,
147}
148
149// ── Semantic event (application-facing) ──────────────────────────────────────
150
151/// High-level event produced by decomposing a [`ServerMessage`].
152///
153/// One wire message may yield **multiple** events (e.g. transcription + model
154/// text + usage stats arrive in the same JSON frame).  The
155/// [`codec::into_events`](crate::codec::into_events) function performs this
156/// decomposition.
157#[derive(Debug, Clone)]
158pub enum ServerEvent {
159    /// The server accepted the `setup` message.
160    SetupComplete,
161
162    /// A chunk of model-generated text.
163    ModelText(String),
164    /// A chunk of model-generated audio (base64-decoded raw PCM bytes, 24 kHz).
165    ModelAudio(Vec<u8>),
166
167    /// The model finished generating (turn may still be open for metadata).
168    GenerationComplete,
169    /// The model's turn is fully complete.
170    TurnComplete,
171    /// The model's generation was interrupted by user activity.
172    Interrupted,
173
174    /// Transcription of the user's spoken input.
175    InputTranscription(String),
176    /// Transcription of the model's spoken output.
177    OutputTranscription(String),
178
179    /// The server requests one or more function calls.
180    ToolCall(Vec<FunctionCallRequest>),
181    /// The server cancels previously requested function calls.
182    ToolCallCancellation(Vec<String>),
183
184    /// Updated session resumption state.
185    SessionResumption {
186        new_handle: Option<String>,
187        resumable: bool,
188    },
189
190    /// The server will disconnect soon — the client should reconnect.
191    GoAway { time_left: Option<Duration> },
192
193    /// Token usage statistics.
194    Usage(UsageMetadata),
195
196    /// The WebSocket connection was closed.
197    Closed { reason: String },
198
199    /// An API-level error.
200    Error(ApiError),
201}