gproxy_protocol/adapt/generate/gemini_responses/image_resources/
gemini.rs1use super::*;
2
3impl GeminiViaResponses {
4 pub async fn prepare_with_image_resources<S: StateStore, R: ResourceAccess>(
7 input: g::GenerateContentRequestBody,
8 endpoint: Endpoint,
9 identities: GenerationIdentity,
10 state: &GenerationStateAccess<'_, S>,
11 resources: &GenerationResources<'_, R>,
12 ) -> Result<Self, TransformError> {
13 let original = input.into_declared();
14 let mut prepared = Self::prepare_with_capabilities(
15 inline_request(original.clone()),
16 endpoint,
17 identities,
18 state,
19 resources,
20 )
21 .await?;
22 prepared.original_request = original;
23 Ok(prepared)
24 }
25 pub async fn convert_response_with_image_resources<S: StateStore, R: ResourceAccess>(
28 &mut self,
29 native: r::GenerateContentResponseBody,
30 facts: p::GeminiReplayContext,
31 state: &GenerationStateAccess<'_, S>,
32 resources: &GenerationResources<'_, R>,
33 progress: &mut ImageResourceProgress<r::GenerateContentResponseBody, R::PublishedHandle>,
34 ) -> Result<Converted<g::GenerateContentResponseBody>, TransformError> {
35 let native = native.into_declared();
36 let mut converted = self.convert_response_inline(native.clone(), facts)?;
37 if wants_uri(&self.original_request) {
38 converted.value = progress
39 .publications
40 .publish(
41 &converted.value,
42 self.identities.response.namespace(),
43 state.expires_at,
44 resources,
45 )
46 .await?;
47 }
48 Ok(converted)
49 }
50 #[allow(clippy::too_many_arguments)]
51 pub async fn invoke_with_image_resources<U: Upstream, S: StateStore, R: ResourceAccess>(
52 &mut self,
53 upstream: &U,
54 target: &U::Target,
55 limits: CodecLimits,
56 state: &GenerationStateAccess<'_, S>,
57 resources: &GenerationResources<'_, R>,
58 progress: &mut ImageResourceProgress<r::GenerateContentResponseBody, R::PublishedHandle>,
59 facts: impl FnOnce(
60 &r::GenerateContentResponseBody,
61 ) -> Result<p::GeminiReplayContext, TransformError>,
62 ) -> Result<GenerationOutcome<g::GenerateContentResponseBody>, TransformError> {
63 transport::bind(
64 (&self.endpoint, &self.selected_model),
65 &self.identities,
66 (&self.original_request, &self.target_request),
67 state,
68 limits,
69 &mut progress.generation,
70 false,
71 )?;
72 if !transport::send(
73 upstream,
74 target,
75 self.endpoint.clone(),
76 self.target_request.clone(),
77 limits,
78 &mut progress.generation,
79 )
80 .await?
81 {
82 return Ok(transport::rejected(&progress.generation));
83 }
84 self.recover_with_image_resources(limits, state, resources, progress, facts)
85 .await
86 }
87 pub async fn recover_with_image_resources<S: StateStore, R: ResourceAccess>(
88 &mut self,
89 limits: CodecLimits,
90 state: &GenerationStateAccess<'_, S>,
91 resources: &GenerationResources<'_, R>,
92 progress: &mut ImageResourceProgress<r::GenerateContentResponseBody, R::PublishedHandle>,
93 facts: impl FnOnce(
94 &r::GenerateContentResponseBody,
95 ) -> Result<p::GeminiReplayContext, TransformError>,
96 ) -> Result<GenerationOutcome<g::GenerateContentResponseBody>, TransformError> {
97 transport::bind(
98 (&self.endpoint, &self.selected_model),
99 &self.identities,
100 (&self.original_request, &self.target_request),
101 state,
102 limits,
103 &mut progress.generation,
104 true,
105 )?;
106 if progress
107 .generation
108 .raw_response
109 .as_ref()
110 .is_none_or(|response| !response.status.is_success())
111 {
112 return Err(TransformError::invalid_result(
113 "generation.recovery",
114 "successful native response required",
115 ));
116 }
117 let native = transport::recover_native(&mut progress.generation, limits)?;
118 let facts = facts(&native)?;
119 let converted = self
120 .convert_response_with_image_resources(native, facts, state, resources, progress)
121 .await?;
122 transport::finish(
123 &mut progress.generation,
124 converted,
125 self.report.clone(),
126 limits,
127 )
128 }
129}