Skip to main content

gproxy_protocol/adapt/generate/stream/event/
gemini.rs

1use super::*;
2use crate::{
3    transform::generate::stream::gemini::{GeminiStreamCollector, GeminiStreamLimits},
4    wire::gemini as g,
5};
6
7impl sealed::Event for g::GenerateContentResponseBody {}
8impl NativeEvent for g::GenerateContentResponseBody {
9    type Full = Self;
10    type Collector = GeminiStreamCollector;
11    const DIALECT: Dialect = Dialect::Gemini;
12    fn collector(_: IdentityFlow, _: TargetIdPolicy, limits: EventLimits) -> Self::Collector {
13        GeminiStreamCollector::new(GeminiStreamLimits {
14            max_bytes: limits.max_bytes,
15        })
16    }
17    fn collect(collector: &mut Self::Collector, event: Self) -> Result<(), TransformError> {
18        collector.push(event)
19    }
20    fn collected(
21        collector: Self::Collector,
22    ) -> Result<Converted<Collected<Self::Full>>, TransformError> {
23        let value = collector.finish()?;
24        Ok(Converted {
25            value: Collected::native(value.value),
26            report: value.report,
27        })
28    }
29    fn event_name(&self) -> Option<&'static str> {
30        None
31    }
32    fn is_terminal(&self) -> bool {
33        self.candidates
34            .iter()
35            .flatten()
36            .any(|v| v.finish_reason.is_some())
37    }
38    fn tool_declarations(
39        &self,
40        _complete_tool_names: bool,
41    ) -> Vec<(String, ToolCallKind, Option<String>)> {
42        self.candidates
43            .iter()
44            .flatten()
45            .flat_map(|c| c.content.iter())
46            .flat_map(|c| c.parts.iter().flatten())
47            .filter_map(|p| p.function_call.as_ref())
48            .filter_map(|f| {
49                f.id.as_ref()
50                    .map(|id| (id.clone(), ToolCallKind::Function, Some(f.name.clone())))
51            })
52            .collect()
53    }
54}