From cac30067ef6b3c0a1e1994981121abf78f842b52 Mon Sep 17 00:00:00 2001 From: Nikketryhard Date: Mon, 16 Feb 2026 19:57:18 -0600 Subject: [PATCH] feat: add structured output to Gemini endpoint Gemini endpoint now accepts responseMimeType and responseSchema fields, injected into Google's generationConfig via MITM. Supports both snake_case and camelCase aliases. --- src/api/gemini.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/api/gemini.rs b/src/api/gemini.rs index 15e861f..80110d2 100644 --- a/src/api/gemini.rs +++ b/src/api/gemini.rs @@ -67,6 +67,14 @@ pub(crate) struct GeminiRequest { /// When true, injects {"googleSearch": {}} into tools via MITM. #[serde(default, alias = "googleSearch")] pub google_search: bool, + /// Response MIME type for structured output, e.g. "application/json". + /// Injected as generationConfig.responseMimeType via MITM. + #[serde(default, alias = "responseMimeType")] + pub response_mime_type: Option, + /// Response schema for structured output (JSON Schema object). + /// Injected as generationConfig.responseSchema via MITM. + #[serde(default, alias = "responseSchema")] + pub response_schema: Option, } fn default_timeout() -> u64 { @@ -257,8 +265,8 @@ pub(crate) async fn handle_gemini( frequency_penalty: None, presence_penalty: None, reasoning_effort: body.thinking_level.clone(), - response_mime_type: None, - response_schema: None, + response_mime_type: body.response_mime_type.clone(), + response_schema: body.response_schema.clone(), google_search: body.google_search, }; if gp.temperature.is_some() @@ -267,6 +275,8 @@ pub(crate) async fn handle_gemini( || gp.max_output_tokens.is_some() || gp.stop_sequences.is_some() || gp.reasoning_effort.is_some() + || gp.response_mime_type.is_some() + || gp.response_schema.is_some() || gp.google_search { state.mitm_store.set_generation_params(gp).await;