mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
test: stabilize merged PR checks
This commit is contained in:
@@ -138,3 +138,80 @@ pub(crate) fn aggregate_claude_stream_sync_response(body: &[u8]) -> Option<serde
|
||||
pub(crate) fn aggregate_gemini_stream_sync_response(body: &[u8]) -> Option<serde_json::Value> {
|
||||
aether_ai_formats::api::aggregate_gemini_stream_sync_response(body)
|
||||
}
|
||||
|
||||
pub(crate) fn gemini_generate_content_response_has_visible_output(
|
||||
body: &serde_json::Value,
|
||||
) -> bool {
|
||||
if aether_ai_formats::formats::gemini::generate_content::response::from_raw(body).is_some() {
|
||||
return true;
|
||||
}
|
||||
|
||||
openai_chat_response_has_visible_output(body) || openai_responses_body_has_visible_output(body)
|
||||
}
|
||||
|
||||
fn openai_chat_response_has_visible_output(body: &serde_json::Value) -> bool {
|
||||
body.get("choices")
|
||||
.and_then(serde_json::Value::as_array)
|
||||
.is_some_and(|choices| {
|
||||
choices.iter().any(|choice| {
|
||||
choice
|
||||
.get("message")
|
||||
.or_else(|| choice.get("delta"))
|
||||
.is_some_and(message_like_value_has_visible_output)
|
||||
|| value_has_non_empty_text(choice.get("text"))
|
||||
|| choice
|
||||
.get("finish_reason")
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.is_some_and(|value| !value.trim().is_empty() && value != "length")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn openai_responses_body_has_visible_output(body: &serde_json::Value) -> bool {
|
||||
body.get("output")
|
||||
.and_then(serde_json::Value::as_array)
|
||||
.is_some_and(|items| {
|
||||
items.iter().any(|item| {
|
||||
item.get("type")
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.is_some_and(|kind| matches!(kind, "function_call" | "image_generation_call"))
|
||||
|| item
|
||||
.get("content")
|
||||
.and_then(serde_json::Value::as_array)
|
||||
.is_some_and(|content| {
|
||||
content.iter().any(response_content_has_visible_output)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn message_like_value_has_visible_output(value: &serde_json::Value) -> bool {
|
||||
value_has_non_empty_text(value.get("content"))
|
||||
|| value
|
||||
.get("tool_calls")
|
||||
.and_then(serde_json::Value::as_array)
|
||||
.is_some_and(|items| !items.is_empty())
|
||||
}
|
||||
|
||||
fn response_content_has_visible_output(value: &serde_json::Value) -> bool {
|
||||
value_has_non_empty_text(value.get("text"))
|
||||
|| value
|
||||
.get("type")
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.is_some_and(|kind| matches!(kind, "function_call" | "output_image"))
|
||||
}
|
||||
|
||||
fn value_has_non_empty_text(value: Option<&serde_json::Value>) -> bool {
|
||||
match value {
|
||||
Some(serde_json::Value::String(text)) => !text.trim().is_empty(),
|
||||
Some(serde_json::Value::Array(items)) => items.iter().any(|item| {
|
||||
value_has_non_empty_text(item.get("text"))
|
||||
|| value_has_non_empty_text(item.get("content"))
|
||||
|| item
|
||||
.get("type")
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.is_some_and(|kind| matches!(kind, "image_url" | "input_image"))
|
||||
}),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ use crate::{usage::GatewaySyncReportRequest, AppState, GatewayError};
|
||||
pub(crate) use self::adaptation::{
|
||||
maybe_build_provider_private_stream_normalizer, ProviderPrivateStreamNormalizer,
|
||||
};
|
||||
pub(crate) use self::api::gemini_generate_content_response_has_visible_output;
|
||||
pub(crate) use self::finalize::common::LocalCoreSyncFinalizeOutcome;
|
||||
pub(crate) use self::finalize::internal::{
|
||||
maybe_bridge_standard_sync_json_to_stream, maybe_build_stream_response_rewriter,
|
||||
|
||||
@@ -1249,49 +1249,6 @@ fn chatgpt_web_image_internal_url(base_url: &str) -> String {
|
||||
format!("{base_url}/__aether/chatgpt-web-image")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn chatgpt_web_chat_image_bridge_body_uses_internal_web_shape() {
|
||||
let body_json = json!({
|
||||
"model": "gpt-image-2",
|
||||
"messages": [
|
||||
{"role": "system", "content": "Use crisp vector-like shapes."},
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "text", "text": "Draw a glass city"},
|
||||
{"type": "image_url", "image_url": {"url": "https://example.com/ref.png"}}
|
||||
]
|
||||
}
|
||||
],
|
||||
"size": "1536x1024",
|
||||
"output_format": "webp",
|
||||
"web_model": "gpt-5-image-test"
|
||||
});
|
||||
|
||||
let (provider_body, summary) =
|
||||
build_chatgpt_web_image_provider_body_from_openai_chat_body(&body_json, "gpt-image-2")
|
||||
.expect("chat image body should convert");
|
||||
|
||||
assert_eq!(provider_body["operation"], "edit");
|
||||
assert_eq!(provider_body["model"], "gpt-image-2");
|
||||
assert_eq!(provider_body["web_model"], "gpt-5-image-test");
|
||||
assert_eq!(
|
||||
provider_body["prompt"],
|
||||
"Use crisp vector-like shapes.\nDraw a glass city"
|
||||
);
|
||||
assert_eq!(provider_body["size"], "1536x1024");
|
||||
assert_eq!(provider_body["ratio"], "3:2");
|
||||
assert_eq!(provider_body["output_format"], "webp");
|
||||
assert_eq!(provider_body["images"][0], "https://example.com/ref.png");
|
||||
assert_eq!(summary["operation"], "edit");
|
||||
assert_eq!(summary["output_format"], "webp");
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn build_kiro_openai_chat_cross_format_payload_parts(
|
||||
state: &AppState,
|
||||
@@ -1515,3 +1472,46 @@ fn redaction_mask_error_to_gateway_error(error: RedactionMaskError) -> GatewayEr
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn chatgpt_web_chat_image_bridge_body_uses_internal_web_shape() {
|
||||
let body_json = json!({
|
||||
"model": "gpt-image-2",
|
||||
"messages": [
|
||||
{"role": "system", "content": "Use crisp vector-like shapes."},
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "text", "text": "Draw a glass city"},
|
||||
{"type": "image_url", "image_url": {"url": "https://example.com/ref.png"}}
|
||||
]
|
||||
}
|
||||
],
|
||||
"size": "1536x1024",
|
||||
"output_format": "webp",
|
||||
"web_model": "gpt-5-image-test"
|
||||
});
|
||||
|
||||
let (provider_body, summary) =
|
||||
build_chatgpt_web_image_provider_body_from_openai_chat_body(&body_json, "gpt-image-2")
|
||||
.expect("chat image body should convert");
|
||||
|
||||
assert_eq!(provider_body["operation"], "edit");
|
||||
assert_eq!(provider_body["model"], "gpt-image-2");
|
||||
assert_eq!(provider_body["web_model"], "gpt-5-image-test");
|
||||
assert_eq!(
|
||||
provider_body["prompt"],
|
||||
"Use crisp vector-like shapes.\nDraw a glass city"
|
||||
);
|
||||
assert_eq!(provider_body["size"], "1536x1024");
|
||||
assert_eq!(provider_body["ratio"], "3:2");
|
||||
assert_eq!(provider_body["output_format"], "webp");
|
||||
assert_eq!(provider_body["images"][0], "https://example.com/ref.png");
|
||||
assert_eq!(summary["operation"], "edit");
|
||||
assert_eq!(summary["output_format"], "webp");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user