gproxy_transform/transform/count_tokens/
openai_to_gemini.rs1use crate::protocol::{gemini, openai};
4use crate::transform::{TransformContext, TransformError};
5
6use super::common;
7
8pub fn request(
9 input: openai::ResponseInputTokensRequest,
10 _: &TransformContext,
11) -> Result<gemini::CountTokensRequest, TransformError> {
12 let model = common::openai_model_string(input.model);
13 let contents = common::text_to_gemini_contents(common::openai_input_to_text(input.input));
14 let system_instruction = input
15 .instructions
16 .filter(|text| !text.is_empty())
17 .map(|text| {
18 common::text_to_gemini_content(
19 text,
20 Some(gemini::ContentRole::Known(gemini::ContentRoleKnown::System)),
21 )
22 });
23 let tools = common::openai_tools_to_gemini(input.tools);
24 let tool_config = common::openai_tool_config_to_gemini(input.tool_choice);
25 let generation_config = common::openai_generation_config_to_gemini(input.reasoning, input.text);
26 let service_tier = common::openai_service_tier_to_gemini(input.service_tier);
27
28 Ok(crate::protocol::wire!(gemini::CountTokensRequest {
29 model: Some(model.clone()),
30 contents: Vec::new(),
31 generate_content_request: Some(crate::protocol::wire!(gemini::GenerateContentRequest {
32 model: Some(model),
33 contents,
34 tools,
35 tool_config,
36 safety_settings: Vec::new(),
37 system_instruction,
38 generation_config,
39 cached_content: None,
40 service_tier,
41 store: None,
42 extra: Default::default(),
43 })),
44 extra: Default::default(),
45 }))
46}
47
48pub fn response(
49 input: openai::ResponseInputTokensResponse,
50 _: &TransformContext,
51) -> gemini::CountTokensResponse {
52 crate::protocol::wire!(gemini::CountTokensResponse {
53 total_tokens: Some(common::u32_to_i32(input.input_tokens)),
54 cached_content_token_count: None,
55 prompt_tokens_details: Vec::new(),
56 cache_tokens_details: Vec::new(),
57 extra: Default::default(),
58 })
59}