gproxy_protocol/transform/generate/gemini_responses/stream/
context.rs1use super::super::GeminiResponseContext;
2use super::common::{StreamLimits, invalid, limit, measure};
3use crate::{transform::TransformError, wire::DeclaredFields};
4
5pub struct GeminiToResponsesContext {
6 pub response: GeminiResponseContext,
7 pub actual_model: Option<String>,
9 pub final_thinking_tokens: Option<i64>,
11}
12
13#[derive(Default)]
14pub struct ResponsesToGeminiContext {
15 pub response_modalities: Option<Vec<crate::wire::gemini::Modality>>,
16 pub image_mime: Option<crate::wire::gemini::ImageMimeType>,
17}
18
19pub(super) fn clean_context(
20 mut c: GeminiToResponsesContext,
21 limits: StreamLimits,
22) -> Result<GeminiToResponsesContext, TransformError> {
23 if c.response.created_at < 0
24 || c.actual_model.as_ref().is_some_and(|v| v.trim().is_empty())
25 || [
26 c.response.usage.cache_write_tokens,
27 c.response.usage.cached_tokens,
28 c.final_thinking_tokens,
29 ]
30 .into_iter()
31 .flatten()
32 .any(|v| v < 0)
33 {
34 return Err(invalid("negative facts or empty actual model"));
35 }
36 c.response.request = c.response.request.into_declared();
37 c.response.effective_tool_choice = c.response.effective_tool_choice.into_declared();
38 c.response.effective_prompt_cache_options =
39 c.response.effective_prompt_cache_options.into_declared();
40 let bytes = measure(&c.response.request, limits.max_bytes)?
41 .checked_add(measure(
42 &c.response.effective_tool_choice,
43 limits.max_bytes,
44 )?)
45 .and_then(|v| v.checked_add(c.actual_model.as_ref().map_or(0, String::len)))
46 .ok_or_else(limit)?;
47 if bytes > limits.max_bytes {
48 return Err(limit());
49 }
50 measure(
51 &c.response.effective_prompt_cache_options,
52 limits.max_bytes.saturating_sub(bytes),
53 )?;
54 Ok(c)
55}
56
57pub(super) fn clone_response(c: &GeminiResponseContext) -> GeminiResponseContext {
58 GeminiResponseContext {
59 request: c.request.clone(),
60 effective_parallel_tool_calls: c.effective_parallel_tool_calls,
61 effective_tool_choice: c.effective_tool_choice.clone(),
62 usage: c.usage,
63 created_at: c.created_at,
64 effective_prompt_cache_options: c.effective_prompt_cache_options.clone(),
65 }
66}