gproxy_protocol/transform/generate/gemini_responses/
identity.rs1use crate::{
2 transform::{
3 TransformError,
4 identity::{IdentityFlow, IdentityRole, IdentityTarget, SourceIdentity, TargetIdPolicy},
5 },
6 wire::{gemini as g, openai::responses::input as r},
7};
8
9pub(crate) fn id(
10 flow: &mut IdentityFlow,
11 policy: &TargetIdPolicy,
12 role: IdentityRole,
13 to: IdentityRole,
14 source: Option<String>,
15 index: u64,
16) -> Result<String, TransformError> {
17 flow.resolve_as(
18 role,
19 to,
20 SourceIdentity::new(crate::Dialect::Gemini, source, index),
21 policy,
22 )
23 .map(|v| v.emitted_id)
24 .map_err(|e| TransformError::shape("identity", e.to_string()))
25}
26
27#[derive(Debug, Default, Clone)]
31pub struct GeminiReplayContext {
32 pub target: Option<IdentityTarget>,
33}
34
35pub(crate) fn function(call: r::FunctionCall) -> Result<g::Part, TransformError> {
38 if call.namespace.is_some()
39 || call
40 .caller
41 .flatten()
42 .is_some_and(|v| matches!(v, r::Caller::Program(_)))
43 {
44 return Err(TransformError::unsupported(
45 "function.scope",
46 "Gemini native tool caller requires adapter",
47 ));
48 }
49 let args: serde_json::Map<String, serde_json::Value> = serde_json::from_str(&call.arguments)
50 .map_err(|e| TransformError::shape("function.arguments", e.to_string()))?;
51 Ok(g::Part::builder()
52 .function_call(
53 g::FunctionCall::builder(call.name)
54 .id(call.call_id)
55 .args(args)
56 .build(),
57 )
58 .build())
59}
60
61pub(crate) fn reasoning_text(value: &r::ReasoningItem) -> String {
63 match &value.content {
64 Some(content) => content.iter().map(|v| v.text.as_str()).collect(),
65 None => value.summary.iter().map(|v| v.text.as_str()).collect(),
66 }
67}