mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
centralize openai responses alias handling
This commit is contained in:
@@ -90,10 +90,7 @@ pub(super) async fn maybe_handle(
|
||||
let endpoint = match normalized_provider_type.as_str() {
|
||||
"codex" => endpoints.into_iter().find(|endpoint| {
|
||||
endpoint.is_active
|
||||
&& matches!(
|
||||
endpoint.api_format.trim().to_ascii_lowercase().as_str(),
|
||||
"openai:responses" | "openai:cli"
|
||||
)
|
||||
&& crate::ai_pipeline::is_openai_responses_format(&endpoint.api_format)
|
||||
}),
|
||||
"antigravity" => endpoints.into_iter().find(|endpoint| {
|
||||
endpoint.is_active
|
||||
|
||||
@@ -227,10 +227,7 @@ pub(super) async fn handle_admin_provider_oauth_complete_key(
|
||||
.await?;
|
||||
if let Some(endpoint) = endpoints.into_iter().find(|endpoint| {
|
||||
endpoint.is_active
|
||||
&& matches!(
|
||||
endpoint.api_format.trim().to_ascii_lowercase().as_str(),
|
||||
"openai:responses" | "openai:cli"
|
||||
)
|
||||
&& crate::ai_pipeline::is_openai_responses_format(&endpoint.api_format)
|
||||
}) {
|
||||
let refreshed_key = state
|
||||
.read_provider_catalog_keys_by_ids(std::slice::from_ref(&key_id))
|
||||
|
||||
@@ -19,10 +19,7 @@ pub(crate) fn provider_oauth_runtime_endpoint_for_provider(
|
||||
.iter()
|
||||
.find(|endpoint| {
|
||||
endpoint.is_active
|
||||
&& matches!(
|
||||
endpoint.api_format.trim().to_ascii_lowercase().as_str(),
|
||||
"openai:responses" | "openai:cli"
|
||||
)
|
||||
&& crate::ai_pipeline::is_openai_responses_format(&endpoint.api_format)
|
||||
})
|
||||
.cloned(),
|
||||
"antigravity" => endpoints
|
||||
|
||||
@@ -289,11 +289,7 @@ fn provider_query_key_supports_endpoint(
|
||||
}
|
||||
|
||||
fn provider_query_normalize_api_format_alias(value: &str) -> String {
|
||||
match value.trim().to_ascii_lowercase().as_str() {
|
||||
"openai:cli" => "openai:responses".to_string(),
|
||||
"openai:compact" => "openai:responses:compact".to_string(),
|
||||
other => other.to_string(),
|
||||
}
|
||||
crate::ai_pipeline::normalize_legacy_openai_format_alias(value)
|
||||
}
|
||||
|
||||
fn provider_query_transport_supports_standard_test_execution(
|
||||
@@ -301,11 +297,11 @@ fn provider_query_transport_supports_standard_test_execution(
|
||||
transport: &AdminGatewayProviderTransportSnapshot,
|
||||
api_format: &str,
|
||||
) -> bool {
|
||||
match api_format {
|
||||
match crate::ai_pipeline::normalize_legacy_openai_format_alias(api_format).as_str() {
|
||||
"openai:chat" => {
|
||||
crate::provider_transport::policy::supports_local_openai_chat_transport(transport)
|
||||
}
|
||||
"openai:responses" | "openai:cli" => {
|
||||
"openai:responses" => {
|
||||
crate::provider_transport::policy::supports_local_standard_transport_with_network(
|
||||
transport, api_format,
|
||||
)
|
||||
@@ -933,7 +929,9 @@ async fn provider_query_execute_standard_test_candidate(
|
||||
}
|
||||
|
||||
let provider_api_format = candidate.endpoint.api_format.as_str();
|
||||
let provider_request_body = match provider_api_format {
|
||||
let normalized_provider_api_format =
|
||||
crate::ai_pipeline::normalize_legacy_openai_format_alias(provider_api_format);
|
||||
let provider_request_body = match normalized_provider_api_format.as_str() {
|
||||
"openai:chat" => {
|
||||
let Some(mut provider_request_body) =
|
||||
crate::ai_pipeline::build_local_openai_chat_request_body(
|
||||
@@ -964,7 +962,7 @@ async fn provider_query_execute_standard_test_candidate(
|
||||
crate::ai_pipeline::build_cross_format_openai_chat_request_body(
|
||||
&request_body,
|
||||
&candidate.effective_model,
|
||||
provider_api_format,
|
||||
normalized_provider_api_format.as_str(),
|
||||
false,
|
||||
)
|
||||
else {
|
||||
@@ -985,12 +983,12 @@ async fn provider_query_execute_standard_test_candidate(
|
||||
}
|
||||
provider_request_body
|
||||
}
|
||||
"openai:responses" | "openai:cli" => {
|
||||
"openai:responses" => {
|
||||
let Some(mut provider_request_body) =
|
||||
crate::ai_pipeline::build_cross_format_openai_chat_request_body(
|
||||
&request_body,
|
||||
&candidate.effective_model,
|
||||
provider_api_format,
|
||||
normalized_provider_api_format.as_str(),
|
||||
false,
|
||||
)
|
||||
else {
|
||||
@@ -1037,13 +1035,19 @@ async fn provider_query_execute_standard_test_candidate(
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let oauth_auth = match provider_api_format {
|
||||
"openai:chat" | "openai:responses" | "openai:cli" | "claude:chat" | "claude:cli"
|
||||
| "gemini:chat" | "gemini:cli" => state.resolve_local_oauth_header_auth(&transport).await?,
|
||||
let oauth_auth = match crate::ai_pipeline::normalize_legacy_openai_format_alias(
|
||||
provider_api_format,
|
||||
)
|
||||
.as_str()
|
||||
{
|
||||
"openai:chat" | "openai:responses" | "claude:chat" | "claude:cli" | "gemini:chat"
|
||||
| "gemini:cli" => state.resolve_local_oauth_header_auth(&transport).await?,
|
||||
_ => None,
|
||||
};
|
||||
let auth = match provider_api_format {
|
||||
"openai:chat" | "openai:responses" | "openai:cli" => {
|
||||
let auth = match crate::ai_pipeline::normalize_legacy_openai_format_alias(provider_api_format)
|
||||
.as_str()
|
||||
{
|
||||
"openai:chat" | "openai:responses" => {
|
||||
crate::provider_transport::auth::resolve_local_openai_bearer_auth(&transport)
|
||||
.or(oauth_auth)
|
||||
}
|
||||
@@ -1104,7 +1108,7 @@ async fn provider_query_execute_standard_test_candidate(
|
||||
Some("application/json"),
|
||||
)
|
||||
}
|
||||
"openai:responses" | "openai:cli" => {
|
||||
"openai:responses" => {
|
||||
crate::provider_transport::auth::build_complete_passthrough_headers_with_auth(
|
||||
&parts.headers,
|
||||
auth_header.as_deref().unwrap_or_default(),
|
||||
@@ -1158,10 +1162,7 @@ async fn provider_query_execute_standard_test_candidate(
|
||||
response_body: None,
|
||||
});
|
||||
}
|
||||
if matches!(
|
||||
provider_api_format.trim().to_ascii_lowercase().as_str(),
|
||||
"openai:responses" | "openai:cli"
|
||||
) {
|
||||
if crate::ai_pipeline::is_openai_responses_format(provider_api_format) {
|
||||
crate::ai_pipeline::apply_codex_openai_responses_special_headers(
|
||||
&mut request_headers,
|
||||
&provider_request_body,
|
||||
@@ -1266,8 +1267,8 @@ fn provider_query_prefers_chat_standard_test_api_format(api_format: &str) -> boo
|
||||
|
||||
fn provider_query_supports_cli_standard_test_api_format(api_format: &str) -> bool {
|
||||
matches!(
|
||||
api_format,
|
||||
"openai:responses" | "openai:cli" | "claude:cli" | "gemini:cli"
|
||||
crate::ai_pipeline::normalize_legacy_openai_format_alias(api_format).as_str(),
|
||||
"openai:responses" | "claude:cli" | "gemini:cli"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -350,11 +350,7 @@ fn endpoint_matches_fixed_provider_template(
|
||||
}
|
||||
|
||||
fn normalize_api_format_alias(value: &str) -> String {
|
||||
match value.trim().to_ascii_lowercase().as_str() {
|
||||
"openai:cli" => "openai:responses".to_string(),
|
||||
"openai:compact" => "openai:responses:compact".to_string(),
|
||||
other => other.to_string(),
|
||||
}
|
||||
crate::ai_pipeline::normalize_legacy_openai_format_alias(value)
|
||||
}
|
||||
|
||||
fn api_format_matches(left: &str, right: &str) -> bool {
|
||||
|
||||
@@ -313,14 +313,7 @@ impl<'a> AdminAppState<'a> {
|
||||
|
||||
let provider_type = provider.provider_type.trim().to_ascii_lowercase();
|
||||
if provider_type == "codex"
|
||||
&& matches!(
|
||||
existing_endpoint
|
||||
.api_format
|
||||
.trim()
|
||||
.to_ascii_lowercase()
|
||||
.as_str(),
|
||||
"openai:responses" | "openai:cli"
|
||||
)
|
||||
&& crate::ai_pipeline::is_openai_responses_format(&existing_endpoint.api_format)
|
||||
{
|
||||
let has_config_in_payload = fields.contains("config");
|
||||
let config_payload = if has_config_in_payload {
|
||||
|
||||
@@ -458,15 +458,13 @@ fn aggregate_sync_sse_response_for_client(
|
||||
.as_deref()
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty());
|
||||
match api_format {
|
||||
match api_format.map(crate::ai_pipeline::normalize_legacy_openai_format_alias) {
|
||||
Some(value) if value.eq_ignore_ascii_case("openai:chat") => {
|
||||
aggregate_openai_chat_stream_sync_response(body)
|
||||
}
|
||||
Some(value)
|
||||
if value.eq_ignore_ascii_case("openai:responses")
|
||||
|| value.eq_ignore_ascii_case("openai:responses:compact")
|
||||
|| value.eq_ignore_ascii_case("openai:cli")
|
||||
|| value.eq_ignore_ascii_case("openai:compact") =>
|
||||
|| value.eq_ignore_ascii_case("openai:responses:compact") =>
|
||||
{
|
||||
aggregate_openai_responses_stream_sync_response(body)
|
||||
}
|
||||
@@ -531,18 +529,10 @@ fn resolve_affinity_forward_client_api_format(
|
||||
.as_deref()
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty());
|
||||
match api_format {
|
||||
match api_format.map(crate::ai_pipeline::normalize_legacy_openai_format_alias) {
|
||||
Some(value) if value.eq_ignore_ascii_case("openai:chat") => Some("openai:chat"),
|
||||
Some(value)
|
||||
if value.eq_ignore_ascii_case("openai:responses")
|
||||
|| value.eq_ignore_ascii_case("openai:cli") =>
|
||||
{
|
||||
Some("openai:responses")
|
||||
}
|
||||
Some(value)
|
||||
if value.eq_ignore_ascii_case("openai:responses:compact")
|
||||
|| value.eq_ignore_ascii_case("openai:compact") =>
|
||||
{
|
||||
Some(value) if value.eq_ignore_ascii_case("openai:responses") => Some("openai:responses"),
|
||||
Some(value) if value.eq_ignore_ascii_case("openai:responses:compact") => {
|
||||
Some("openai:responses:compact")
|
||||
}
|
||||
Some(value) if value.eq_ignore_ascii_case("claude:chat") => Some("claude:chat"),
|
||||
|
||||
@@ -12,10 +12,10 @@ pub(crate) fn models_api_format(request_context: &GatewayPublicRequestContext) -
|
||||
.and_then(|decision| decision.auth_endpoint_signature.as_deref())
|
||||
.map(str::trim)
|
||||
.filter(|signature| !signature.is_empty())?;
|
||||
match signature.to_ascii_lowercase().as_str() {
|
||||
match crate::ai_pipeline::normalize_legacy_openai_format_alias(signature).as_str() {
|
||||
"openai:chat" => Some("openai:chat"),
|
||||
"openai:responses" | "openai:cli" => Some("openai:responses"),
|
||||
"openai:responses:compact" | "openai:compact" => Some("openai:responses:compact"),
|
||||
"openai:responses" => Some("openai:responses"),
|
||||
"openai:responses:compact" => Some("openai:responses:compact"),
|
||||
"openai:image" => Some("openai:image"),
|
||||
"claude:chat" => Some("claude:chat"),
|
||||
"gemini:chat" => Some("gemini:chat"),
|
||||
@@ -37,12 +37,10 @@ const MODELS_CROSS_FORMAT_QUERY_API_FORMATS: &[&str] = &[
|
||||
];
|
||||
|
||||
pub(super) fn models_query_api_formats(api_format: &str) -> &'static [&'static str] {
|
||||
match api_format.trim().to_ascii_lowercase().as_str() {
|
||||
match crate::ai_pipeline::normalize_legacy_openai_format_alias(api_format).as_str() {
|
||||
"openai:chat"
|
||||
| "openai:responses"
|
||||
| "openai:responses:compact"
|
||||
| "openai:cli"
|
||||
| "openai:compact"
|
||||
| "claude:chat"
|
||||
| "gemini:chat" => MODELS_CROSS_FORMAT_QUERY_API_FORMATS,
|
||||
"openai:image" => &["openai:image"],
|
||||
|
||||
@@ -209,17 +209,17 @@ fn users_me_usage_api_format_defaults_to_non_stream(item: &StoredRequestUsageAud
|
||||
.or(item.endpoint_api_format.as_deref())
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty());
|
||||
let Some(value) = api_format else {
|
||||
return false;
|
||||
};
|
||||
matches!(
|
||||
api_format,
|
||||
Some(value)
|
||||
if value.eq_ignore_ascii_case("openai:chat")
|
||||
|| value.eq_ignore_ascii_case("openai:responses")
|
||||
|| value.eq_ignore_ascii_case("openai:responses:compact")
|
||||
|| value.eq_ignore_ascii_case("openai:cli")
|
||||
|| value.eq_ignore_ascii_case("openai:compact")
|
||||
|| value.eq_ignore_ascii_case("openai:image")
|
||||
|| value.eq_ignore_ascii_case("claude:chat")
|
||||
|| value.eq_ignore_ascii_case("claude:cli")
|
||||
crate::ai_pipeline::normalize_legacy_openai_format_alias(value).as_str(),
|
||||
"openai:chat"
|
||||
| "openai:responses"
|
||||
| "openai:responses:compact"
|
||||
| "openai:image"
|
||||
| "claude:chat"
|
||||
| "claude:cli"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user