gproxy_protocol/transform/openai/create_image/gemini/
request.rs1use crate::gemini::count_tokens::types as gt;
2use crate::gemini::generate_content::request::{
3 GeminiGenerateContentRequest, PathParameters, QueryParameters, RequestBody, RequestHeaders,
4};
5use crate::gemini::stream_generate_content::request::{
6 GeminiStreamGenerateContentRequest,
7 PathParameters as GeminiStreamGenerateContentPathParameters,
8 QueryParameters as GeminiStreamGenerateContentQueryParameters,
9 RequestHeaders as GeminiStreamGenerateContentRequestHeaders,
10};
11use crate::gemini::types::HttpMethod as GeminiHttpMethod;
12use crate::openai::create_image::request::{
13 OpenAiCreateImageRequest, RequestBody as CreateImageRequestBody,
14};
15use crate::openai::create_image::types as it;
16use crate::transform::gemini::model_get::utils::ensure_models_prefix;
17use crate::transform::openai::create_image::gemini::utils::gemini_image_config_from_create_image_size;
18use crate::transform::openai::create_image::utils::create_image_model_to_string;
19use crate::transform::utils::TransformError;
20
21fn validate_create_image_request(body: &CreateImageRequestBody) -> Result<(), TransformError> {
22 if matches!(
23 body.response_format,
24 Some(it::OpenAiImageResponseFormat::Url)
25 ) {
26 return Err(TransformError::not_implemented(
27 "cannot convert OpenAI image request with response_format=url to Gemini generateContent request",
28 ));
29 }
30
31 Ok(())
32}
33
34impl TryFrom<OpenAiCreateImageRequest> for GeminiGenerateContentRequest {
35 type Error = TransformError;
36
37 fn try_from(value: OpenAiCreateImageRequest) -> Result<Self, TransformError> {
38 let headers = RequestHeaders {
39 extra: value.headers.extra,
40 };
41 let body = value.body;
42 validate_create_image_request(&body)?;
43
44 let image_config = gemini_image_config_from_create_image_size(body.size)?;
45 let model = ensure_models_prefix(
46 &body
47 .model
48 .as_ref()
49 .map(create_image_model_to_string)
50 .unwrap_or_default(),
51 );
52
53 Ok(GeminiGenerateContentRequest {
54 method: GeminiHttpMethod::Post,
55 path: PathParameters { model },
56 query: QueryParameters::default(),
57 headers,
58 body: RequestBody {
59 contents: vec![gt::GeminiContent {
60 parts: vec![gt::GeminiPart {
61 text: Some(body.prompt),
62 ..gt::GeminiPart::default()
63 }],
64 role: Some(gt::GeminiContentRole::User),
65 }],
66 tools: None,
67 tool_config: None,
68 safety_settings: None,
69 system_instruction: None,
70 generation_config: Some(gt::GeminiGenerationConfig {
71 response_modalities: Some(vec![gt::GeminiModality::Image]),
72 candidate_count: body.n,
73 image_config,
74 ..gt::GeminiGenerationConfig::default()
75 }),
76 cached_content: None,
77 store: None,
78 },
79 })
80 }
81}
82
83impl TryFrom<&OpenAiCreateImageRequest> for GeminiStreamGenerateContentRequest {
84 type Error = TransformError;
85
86 fn try_from(value: &OpenAiCreateImageRequest) -> Result<Self, TransformError> {
87 let output = GeminiGenerateContentRequest::try_from(value.clone())?;
88
89 Ok(Self {
90 method: GeminiHttpMethod::Post,
91 path: GeminiStreamGenerateContentPathParameters {
92 model: output.path.model,
93 },
94 query: GeminiStreamGenerateContentQueryParameters::default(),
95 headers: GeminiStreamGenerateContentRequestHeaders {
96 extra: output.headers.extra,
97 },
98 body: output.body,
99 })
100 }
101}
102
103impl TryFrom<OpenAiCreateImageRequest> for GeminiStreamGenerateContentRequest {
104 type Error = TransformError;
105
106 fn try_from(value: OpenAiCreateImageRequest) -> Result<Self, TransformError> {
107 GeminiStreamGenerateContentRequest::try_from(&value)
108 }
109}