Skip to main content

gproxy_protocol/transform/openai/model_list/gemini/
utils.rs

1use http::StatusCode;
2
3use crate::gemini::types::{GeminiApiErrorResponse, GeminiModelInfo};
4use crate::openai::types::{
5    OpenAiApiError, OpenAiApiErrorResponse, OpenAiModel, OpenAiModelObject,
6};
7
8pub fn strip_models_prefix(value: &str) -> String {
9    value.strip_prefix("models/").unwrap_or(value).to_string()
10}
11
12fn openai_error_type_from_google_status(status: &str) -> Option<&'static str> {
13    match status {
14        "INVALID_ARGUMENT" => Some("invalid_request_error"),
15        "UNAUTHENTICATED" => Some("authentication_error"),
16        "PERMISSION_DENIED" => Some("permission_error"),
17        "NOT_FOUND" => Some("not_found_error"),
18        "RESOURCE_EXHAUSTED" => Some("rate_limit_error"),
19        "DEADLINE_EXCEEDED" => Some("timeout_error"),
20        "FAILED_PRECONDITION" => Some("invalid_request_error"),
21        "ABORTED" | "INTERNAL" | "UNAVAILABLE" => Some("api_error"),
22        _ => None,
23    }
24}
25
26fn openai_error_type_from_http_status(status_code: StatusCode) -> &'static str {
27    match status_code.as_u16() {
28        400 | 413 => "invalid_request_error",
29        401 => "authentication_error",
30        403 => "permission_error",
31        404 => "not_found_error",
32        429 => "rate_limit_error",
33        504 => "timeout_error",
34        _ => "api_error",
35    }
36}
37
38pub fn openai_model_from_gemini_model(model: GeminiModelInfo) -> OpenAiModel {
39    let id = model
40        .base_model_id
41        .as_deref()
42        .map(str::trim)
43        .filter(|value| !value.is_empty())
44        .map(ToOwned::to_owned)
45        .unwrap_or_else(|| strip_models_prefix(&model.name));
46
47    OpenAiModel {
48        id,
49        created: 0,
50        object: OpenAiModelObject::Model,
51        owned_by: "google".to_string(),
52    }
53}
54
55pub fn openai_error_response_from_gemini(
56    status_code: StatusCode,
57    body: GeminiApiErrorResponse,
58) -> OpenAiApiErrorResponse {
59    let error = body.error;
60    let type_ = error
61        .status
62        .as_deref()
63        .and_then(openai_error_type_from_google_status)
64        .unwrap_or_else(|| openai_error_type_from_http_status(status_code));
65
66    OpenAiApiErrorResponse {
67        error: OpenAiApiError {
68            message: error.message,
69            type_: type_.to_string(),
70            param: None,
71            code: error.status.or(Some(error.code.to_string())),
72        },
73    }
74}