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/// Partial audio-transcription update from the server.
64///
65/// Vertex AI `v1` marks both fields as optional. The server may send a
66/// terminal transcription marker with `finished=true` and no `text`, so the
67/// client must not require text to be present on every update.
68#[derive(Debug, Clone, PartialEq, Deserialize)]
69pub struct Transcription {
70    #[serde(default)]
71    pub text: Option<String>,
72    #[serde(default)]
73    pub finished: Option<bool>,
74}
75
76// ── Tool call ────────────────────────────────────────────────────────────────
77
78#[derive(Debug, Clone, Deserialize)]
79#[serde(rename_all = "camelCase")]
80pub struct ToolCallMessage {
81    pub function_calls: Vec<FunctionCallRequest>,
82}
83
84/// A function the server wants the client to execute.
85#[derive(Debug, Clone, Deserialize)]
86#[serde(rename_all = "camelCase")]
87pub struct FunctionCallRequest {
88    /// Server-assigned call ID — must be echoed back in [`FunctionResponse`](super::client_message::FunctionResponse).
89    pub id: String,
90    pub name: String,
91    /// Arguments as a JSON object matching the function's declared schema.
92    pub args: serde_json::Value,
93}
94
95#[derive(Debug, Clone, Deserialize)]
96pub struct ToolCallCancellation {
97    pub ids: Vec<String>,
98}
99
100// ── Session lifecycle ────────────────────────────────────────────────────────
101
102/// Sent when the server is about to terminate the connection.
103/// The client should reconnect (with a session resumption handle if available).
104#[derive(Debug, Clone, Deserialize)]
105#[serde(rename_all = "camelCase")]
106pub struct GoAway {
107    /// Remaining time before disconnect, as a protobuf Duration string (e.g. `"30s"`).
108    pub time_left: Option<String>,
109}
110
111/// Periodic update with a fresh session resumption handle.
112#[derive(Debug, Clone, Deserialize)]
113#[serde(rename_all = "camelCase")]
114pub struct SessionResumptionUpdate {
115    pub new_handle: Option<String>,
116    #[serde(default)]
117    pub resumable: Option<bool>,
118}
119
120// ── Usage metadata ───────────────────────────────────────────────────────────
121
122/// Token usage statistics.  Accompanies many server messages.
123#[derive(Debug, Clone, PartialEq, Deserialize)]
124#[serde(rename_all = "camelCase")]
125pub struct UsageMetadata {
126    #[serde(default)]
127    pub prompt_token_count: u32,
128    #[serde(default)]
129    pub cached_content_token_count: u32,
130    #[serde(default)]
131    pub response_token_count: u32,
132    #[serde(default)]
133    pub tool_use_prompt_token_count: u32,
134    #[serde(default)]
135    pub thoughts_token_count: u32,
136    #[serde(default)]
137    pub total_token_count: u32,
138    #[serde(default)]
139    pub prompt_tokens_details: Option<Vec<ModalityTokenCount>>,
140    #[serde(default)]
141    pub response_tokens_details: Option<Vec<ModalityTokenCount>>,
142}
143
144#[derive(Debug, Clone, PartialEq, Deserialize)]
145#[serde(rename_all = "camelCase")]
146pub struct ModalityTokenCount {
147    pub modality: String,
148    pub token_count: u32,
149}
150
151/// An error returned by the API.
152#[derive(Debug, Clone, PartialEq, Deserialize)]
153pub struct ApiError {
154    pub message: String,
155}
156
157// ── Semantic event (application-facing) ──────────────────────────────────────
158
159/// High-level event produced by decomposing a [`ServerMessage`].
160///
161/// One wire message may yield **multiple** events (e.g. transcription + model
162/// text + usage stats arrive in the same JSON frame).  The
163/// [`codec::into_events`](crate::codec::into_events) function performs this
164/// decomposition.
165#[derive(Debug, Clone)]
166pub enum ServerEvent {
167    /// The server accepted the `setup` message.
168    SetupComplete,
169
170    /// A chunk of model-generated text.
171    ModelText(String),
172    /// A chunk of model-generated audio (base64-decoded raw PCM bytes, 24 kHz).
173    ModelAudio(Vec<u8>),
174
175    /// The model finished generating (turn may still be open for metadata).
176    GenerationComplete,
177    /// The model's turn is fully complete.
178    TurnComplete,
179    /// The model's generation was interrupted by user activity.
180    Interrupted,
181
182    /// Transcription of the user's spoken input.
183    InputTranscription(String),
184    /// Transcription of the model's spoken output.
185    OutputTranscription(String),
186
187    /// The server requests one or more function calls.
188    ToolCall(Vec<FunctionCallRequest>),
189    /// The server cancels previously requested function calls.
190    ToolCallCancellation(Vec<String>),
191
192    /// Updated session resumption state.
193    SessionResumption {
194        new_handle: Option<String>,
195        resumable: bool,
196    },
197
198    /// The server will disconnect soon — the client should reconnect.
199    GoAway { time_left: Option<Duration> },
200
201    /// Token usage statistics.
202    Usage(UsageMetadata),
203
204    /// The WebSocket connection was closed.
205    Closed { reason: String },
206
207    /// An API-level error.
208    Error(ApiError),
209}