fix: align image generation checks

This commit is contained in:
fawney19
2026-05-21 00:45:02 +08:00
parent 4d0c654822
commit 923515ab28
8 changed files with 41 additions and 20 deletions

View File

@@ -1516,12 +1516,11 @@ fn provider_query_standard_execution_response_body(
provider_api_format: &str,
result: &aether_contracts::ExecutionResult,
) -> Option<Value> {
let body = provider_query_execution_json_body(result)
.or_else(|| {
provider_query_decode_execution_body(result).and_then(|body| {
provider_query_aggregate_standard_stream_sync_response(provider_api_format, &body)
})
})?;
let body = provider_query_execution_json_body(result).or_else(|| {
provider_query_decode_execution_body(result).and_then(|body| {
provider_query_aggregate_standard_stream_sync_response(provider_api_format, &body)
})
})?;
if result.status_code < 400
&& provider_query_normalize_api_format_alias(provider_api_format)
== "gemini:generate_content"

View File

@@ -100,9 +100,8 @@ fn provider_query_execution_json_body_decodes_stream_encoded_json_response() {
"url": "https://example.test/image.png"
}]
});
let encoded_body = base64::engine::general_purpose::STANDARD.encode(
serde_json::to_vec(&body).expect("test body should serialize"),
);
let encoded_body = base64::engine::general_purpose::STANDARD
.encode(serde_json::to_vec(&body).expect("test body should serialize"));
let result = aether_contracts::ExecutionResult {
request_id: "request-1".to_string(),
candidate_id: None,
@@ -119,7 +118,10 @@ fn provider_query_execution_json_body_decodes_stream_encoded_json_response() {
error: None,
};
assert_eq!(provider_query_execution_json_body(&result), Some(body.clone()));
assert_eq!(
provider_query_execution_json_body(&result),
Some(body.clone())
);
assert_eq!(
provider_query_standard_execution_response_body("openai:image", &result),
Some(body)

View File

@@ -1102,7 +1102,10 @@ async fn gateway_routes_openai_responses_stream_image_intent_to_openai_image_pla
);
assert_eq!(seen_plan.client_api_format, "openai:responses");
assert_eq!(seen_plan.provider_api_format, "openai:image");
assert_eq!(seen_plan.url, "https://images.example.com/v1/responses");
assert_eq!(
seen_plan.url,
"https://images.example.com/v1/images/generations"
);
assert!(seen_plan.plan_stream);
assert_eq!(seen_plan.auth_header, "Bearer sk-upstream-image-bridge");
assert_eq!(seen_plan.body_json["stream"], true);

View File

@@ -712,7 +712,7 @@ async fn gateway_converts_gemini_image_sync_to_openai_image_provider() {
);
assert_eq!(
seen_execution_runtime_request.url,
"https://api.openai.com/v1/responses"
"https://api.openai.com/v1/images/generations"
);
assert_eq!(
seen_execution_runtime_request.authorization,

View File

@@ -40,7 +40,7 @@ use aether_data_contracts::repository::global_models::StoredProviderActiveGlobal
use aether_data_contracts::repository::provider_catalog::ProviderCatalogReadRepository;
use aether_data_contracts::repository::usage::{StoredRequestUsageAudit, UsageRepository};
use axum::response::IntoResponse;
use chrono::Utc;
use chrono::{TimeZone, Utc};
#[path = "public_support/dashboard.rs"]
mod dashboard;
@@ -2372,6 +2372,20 @@ fn sample_auth_wallet(user_id: &str, now: chrono::DateTime<chrono::Utc>) -> Stor
.expect("wallet should build")
}
fn wallet_today_usage_test_time() -> chrono::DateTime<chrono::Utc> {
let offset =
chrono::FixedOffset::east_opt(8 * 3600).expect("Asia/Shanghai test offset should be valid");
let local_today = Utc::now().with_timezone(&offset).date_naive();
let local_noon = local_today
.and_hms_opt(12, 0, 0)
.expect("wallet today test noon should be valid");
offset
.from_local_datetime(&local_noon)
.single()
.expect("fixed offset local noon should be unambiguous")
.with_timezone(&Utc)
}
fn sample_auth_session(
user_id: &str,
session_id: &str,
@@ -4378,7 +4392,7 @@ async fn gateway_handles_wallet_balance_locally_without_proxying_upstream() {
#[tokio::test]
async fn gateway_handles_wallet_today_cost_locally_without_proxying_upstream() {
let auth_now = Utc::now();
let usage_now = auth_now;
let usage_now = wallet_today_usage_test_time();
let user = sample_auth_user(auth_now);
let access_token = build_test_auth_token(
"access",
@@ -4453,6 +4467,7 @@ async fn gateway_handles_wallet_today_cost_locally_without_proxying_upstream() {
#[tokio::test]
async fn gateway_wallet_flow_today_entry_uses_live_settled_usage() {
let auth_now = Utc::now();
let usage_now = wallet_today_usage_test_time();
let user = sample_auth_user(auth_now);
let access_token = build_test_auth_token(
"access",
@@ -4475,7 +4490,7 @@ async fn gateway_wallet_flow_today_entry_uses_live_settled_usage() {
"gpt-4.1",
"OpenAI",
"completed",
auth_now - chrono::Duration::minutes(5),
usage_now,
),
]));
let (gateway_url, upstream_hits, gateway_handle, upstream_handle) =

View File

@@ -1191,10 +1191,10 @@ mod tests {
use serde_json::json;
use super::{
build_chatgpt_web_image_request_body, build_openai_image_provider_request_body,
is_openai_image_stream_request, normalize_openai_image_request,
normalize_openai_image_request_with_options, openai_image_operation_from_path,
OpenAiImageNormalizeOptions, OpenAiImageOperation,
build_chatgpt_web_image_request_body, build_openai_image_api_provider_request_body,
build_openai_image_provider_request_body, is_openai_image_stream_request,
normalize_openai_image_request, normalize_openai_image_request_with_options,
openai_image_operation_from_path, OpenAiImageNormalizeOptions, OpenAiImageOperation,
};
use crate::formats::openai::image::spec::{resolve_stream_spec, resolve_sync_spec};
use crate::formats::openai::responses::codex::{

View File

@@ -356,6 +356,7 @@ pub fn build_openai_chat_usage_chunk(
)
}
#[allow(clippy::too_many_arguments)]
pub fn build_openai_chat_usage_chunk_with_cache(
id: &str,
model: &str,

View File

@@ -1338,13 +1338,14 @@ mod tests {
let output = utf8(outcome.sse_body);
assert!(output.contains("event: message_start"));
assert!(output.contains("event: message_stop"));
assert!(output.contains("\"stop_reason\":\"end_turn\""));
assert!(!output.contains("status_code"));
assert_eq!(
outcome
.terminal_summary
.as_ref()
.and_then(|summary| summary.finish_reason.as_deref()),
Some("end_turn")
Some("stop")
);
}