Skip to main content

gproxy_transform/transform/count_tokens/
openai_to_gemini.rs

1//! OpenAI -> Gemini count-token transforms.
2
3use 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}