Skip to main content

gproxy_protocol/adapt/generate/stream/prepare/
claude_gemini.rs

1use super::super::super::{
2    GenerationResources, GenerationStateAccess,
3    claude_gemini::{ClaudeViaGemini, GeminiViaClaude},
4};
5use super::super::{StreamInvocation, StreamSettings, StreamTarget};
6use super::RequestMode;
7use crate::{
8    capability::{ResourceAccess, StateStore},
9    transform::{
10        TransformError,
11        generate::{claude_gemini as pair, claude_gemini::stream as p},
12    },
13    wire::{DeclaredFields, claude::generate_content as c, gemini as g},
14};
15
16pub struct ClaudeViaGeminiStreamFacts {
17    pub request: pair::ClaudeGeminiRequestContext,
18    pub response: p::GeminiToClaudeContext,
19}
20
21pub struct GeminiViaClaudeStreamFacts {
22    pub max_tokens: Option<i64>,
23    pub response: p::ClaudeToGeminiContext,
24}
25
26impl ClaudeViaGemini {
27    pub async fn prepare_stream<S: StateStore>(
28        input: c::GenerateContentRequestBody,
29        mut target: StreamTarget,
30        context: ClaudeViaGeminiStreamFacts,
31        settings: StreamSettings,
32        state: &GenerationStateAccess<'_, S>,
33    ) -> Result<StreamInvocation<p::GeminiToClaudeStream>, TransformError> {
34        let original = input.into_declared();
35        let prepared = Self::prepare_with_state(
36            original.clone().buffered(),
37            target.endpoint.clone(),
38            target.identities.clone(),
39            state,
40            context.request,
41        )
42        .await?;
43        target.identities = prepared.identities().clone();
44        let bridge = p::GeminiToClaudeStream::new_with_policy(
45            context.response,
46            target.identities.response.clone(),
47            settings.events.into(),
48            target.identities.response_policy.clone(),
49        )?;
50        StreamInvocation::new(
51            original,
52            prepared.target_request().clone().streaming(),
53            target,
54            settings,
55            bridge,
56            prepared.report().clone(),
57            state,
58        )
59        .await
60    }
61    pub async fn prepare_stream_with_capabilities<S: StateStore, R: ResourceAccess>(
62        input: c::GenerateContentRequestBody,
63        mut target: StreamTarget,
64        context: ClaudeViaGeminiStreamFacts,
65        settings: StreamSettings,
66        state: &GenerationStateAccess<'_, S>,
67        resources: &GenerationResources<'_, R>,
68    ) -> Result<StreamInvocation<p::GeminiToClaudeStream>, TransformError> {
69        let original = input.into_declared();
70        let prepared = Self::prepare_with_capabilities(
71            original.clone().buffered(),
72            target.endpoint.clone(),
73            target.identities.clone(),
74            state,
75            resources,
76            context.request,
77        )
78        .await?;
79        target.identities = prepared.identities().clone();
80        let bridge = p::GeminiToClaudeStream::new_with_policy(
81            context.response,
82            target.identities.response.clone(),
83            settings.events.into(),
84            target.identities.response_policy.clone(),
85        )?;
86        StreamInvocation::new(
87            original,
88            prepared.target_request().clone().streaming(),
89            target,
90            settings,
91            bridge,
92            prepared.report().clone(),
93            state,
94        )
95        .await
96    }
97}
98
99impl GeminiViaClaude {
100    pub async fn prepare_stream<S: StateStore>(
101        input: g::GenerateContentRequestBody,
102        mut target: StreamTarget,
103        mut context: GeminiViaClaudeStreamFacts,
104        settings: StreamSettings,
105        state: &GenerationStateAccess<'_, S>,
106    ) -> Result<StreamInvocation<p::ClaudeToGeminiStream>, TransformError> {
107        let original = input.into_declared();
108        let prepared = Self::prepare_with_state(
109            original.clone().buffered(),
110            target.endpoint.clone(),
111            target.identities.clone(),
112            state,
113            context.max_tokens,
114        )
115        .await?;
116        target.identities = prepared.identities().clone();
117        context.response.usage = prepared.usage_facts(context.response.usage);
118        let bridge = p::ClaudeToGeminiStream::new_with_policy(
119            context.response,
120            target.identities.response.clone(),
121            settings.events.into(),
122            target.identities.response_policy.clone(),
123        )?;
124        StreamInvocation::new(
125            original,
126            prepared.target_request().clone().streaming(),
127            target,
128            settings,
129            bridge,
130            prepared.report().clone(),
131            state,
132        )
133        .await
134    }
135    pub async fn prepare_stream_with_capabilities<S: StateStore, R: ResourceAccess>(
136        input: g::GenerateContentRequestBody,
137        mut target: StreamTarget,
138        mut context: GeminiViaClaudeStreamFacts,
139        settings: StreamSettings,
140        state: &GenerationStateAccess<'_, S>,
141        resources: &GenerationResources<'_, R>,
142    ) -> Result<StreamInvocation<p::ClaudeToGeminiStream>, TransformError> {
143        let original = input.into_declared();
144        let prepared = Self::prepare_with_capabilities(
145            original.clone().buffered(),
146            target.endpoint.clone(),
147            target.identities.clone(),
148            state,
149            resources,
150            context.max_tokens,
151        )
152        .await?;
153        target.identities = prepared.identities().clone();
154        context.response.usage = prepared.usage_facts(context.response.usage);
155        let bridge = p::ClaudeToGeminiStream::new_with_policy(
156            context.response,
157            target.identities.response.clone(),
158            settings.events.into(),
159            target.identities.response_policy.clone(),
160        )?;
161        StreamInvocation::new(
162            original,
163            prepared.target_request().clone().streaming(),
164            target,
165            settings,
166            bridge,
167            prepared.report().clone(),
168            state,
169        )
170        .await
171    }
172}