gemini_genai_rs/protocol/messages/
client.rs1use serde::{Deserialize, Serialize};
4
5use crate::protocol::types::*;
6
7#[derive(Debug, Clone, Serialize)]
9pub struct SetupMessage {
10 pub setup: SetupPayload,
12}
13
14#[derive(Debug, Clone, Serialize)]
16#[serde(rename_all = "camelCase")]
17pub struct SetupPayload {
18 pub model: String,
20 #[serde(skip_serializing_if = "Option::is_none")]
22 pub generation_config: Option<GenerationConfig>,
23 #[serde(skip_serializing_if = "Option::is_none")]
25 pub system_instruction: Option<Content>,
26 #[serde(skip_serializing_if = "Vec::is_empty")]
28 pub tools: Vec<Tool>,
29 #[serde(skip_serializing_if = "Option::is_none")]
31 pub tool_config: Option<ToolConfig>,
32 #[serde(skip_serializing_if = "Option::is_none")]
34 pub input_audio_transcription: Option<InputAudioTranscription>,
35 #[serde(skip_serializing_if = "Option::is_none")]
37 pub output_audio_transcription: Option<OutputAudioTranscription>,
38 #[serde(skip_serializing_if = "Option::is_none")]
40 pub realtime_input_config: Option<RealtimeInputConfig>,
41 #[serde(skip_serializing_if = "Option::is_none")]
43 pub session_resumption: Option<SessionResumptionConfig>,
44 #[serde(skip_serializing_if = "Option::is_none")]
46 pub context_window_compression: Option<ContextWindowCompressionConfig>,
47 #[serde(skip_serializing_if = "Option::is_none")]
49 pub proactivity: Option<ProactivityConfig>,
50}
51
52impl SessionConfig {
53 pub fn to_setup_message(&self) -> SetupMessage {
58 let tools = if self.supports_async_tools() {
59 self.tools.clone()
60 } else {
61 self.tools
62 .iter()
63 .map(|tool| {
64 let mut t = tool.clone();
65 if let Some(ref mut decls) = t.function_declarations {
66 for d in decls.iter_mut() {
67 d.behavior = None;
68 }
69 }
70 t
71 })
72 .collect()
73 };
74
75 let generation_config = if self.supports_async_tools() {
76 self.generation_config.clone()
77 } else {
78 let mut gc = self.generation_config.clone();
79 gc.thinking_config = None;
80 gc
81 };
82
83 SetupMessage {
84 setup: SetupPayload {
85 model: self.model_uri(),
86 generation_config: Some(generation_config),
87 system_instruction: self.system_instruction.clone(),
88 tools,
89 tool_config: self.tool_config.clone(),
90 input_audio_transcription: self.input_audio_transcription.clone(),
91 output_audio_transcription: self.output_audio_transcription.clone(),
92 realtime_input_config: self.realtime_input_config.clone(),
93 session_resumption: self.session_resumption.clone(),
94 context_window_compression: self.context_window_compression.clone(),
95 proactivity: self.proactivity.clone(),
96 },
97 }
98 }
99
100 pub fn to_setup_json(&self) -> String {
102 serde_json::to_string(&self.to_setup_message())
103 .expect("setup message serialization is infallible for valid config")
104 }
105}
106
107#[derive(Debug, Clone, Serialize)]
109#[serde(rename_all = "camelCase")]
110pub struct RealtimeInputMessage {
111 pub realtime_input: RealtimeInputPayload,
113}
114
115#[derive(Debug, Clone, Serialize)]
117#[serde(rename_all = "camelCase")]
118pub struct RealtimeInputPayload {
119 #[serde(skip_serializing_if = "Vec::is_empty")]
121 pub media_chunks: Vec<MediaChunk>,
122 #[serde(skip_serializing_if = "Option::is_none")]
124 pub audio: Option<Blob>,
125 #[serde(skip_serializing_if = "Option::is_none")]
127 pub video: Option<Blob>,
128 #[serde(skip_serializing_if = "Option::is_none")]
130 pub audio_stream_end: Option<bool>,
131 #[serde(skip_serializing_if = "Option::is_none")]
133 pub text: Option<String>,
134}
135
136#[derive(Debug, Clone, Serialize)]
138#[serde(rename_all = "camelCase")]
139pub struct MediaChunk {
140 pub mime_type: String,
142 pub data: String, }
145
146#[derive(Debug, Clone, Serialize)]
148#[serde(rename_all = "camelCase")]
149pub struct ClientContentMessage {
150 pub client_content: ClientContentPayload,
152}
153
154#[derive(Debug, Clone, Serialize)]
156#[serde(rename_all = "camelCase")]
157pub struct ClientContentPayload {
158 pub turns: Vec<Content>,
160 #[serde(skip_serializing_if = "Option::is_none")]
162 pub turn_complete: Option<bool>,
163}
164
165#[derive(Debug, Clone, Serialize)]
167#[serde(rename_all = "camelCase")]
168pub struct ToolResponseMessage {
169 pub tool_response: ToolResponsePayload,
171}
172
173#[derive(Debug, Clone, Serialize)]
175#[serde(rename_all = "camelCase")]
176pub struct ToolResponsePayload {
177 pub function_responses: Vec<FunctionResponse>,
179}
180
181#[derive(Debug, Clone, Serialize)]
183#[serde(rename_all = "camelCase")]
184pub struct ActivitySignalMessage {
185 pub realtime_input: ActivitySignalPayload,
187}
188
189#[derive(Debug, Clone, Serialize)]
191#[serde(rename_all = "camelCase")]
192pub struct ActivitySignalPayload {
193 #[serde(skip_serializing_if = "Option::is_none")]
195 pub activity_start: Option<ActivityStart>,
196 #[serde(skip_serializing_if = "Option::is_none")]
198 pub activity_end: Option<ActivityEnd>,
199}
200
201#[derive(Debug, Clone, Serialize, Deserialize)]
203pub struct ActivityStart {}
204
205#[derive(Debug, Clone, Serialize, Deserialize)]
207pub struct ActivityEnd {}