diff --git a/server-rs/crates/platform-image/src/vector_engine/raw_edit.rs b/server-rs/crates/platform-image/src/vector_engine/raw_edit.rs index c0d78f1e8..13f41e7e6 100644 --- a/server-rs/crates/platform-image/src/vector_engine/raw_edit.rs +++ b/server-rs/crates/platform-image/src/vector_engine/raw_edit.rs @@ -1,7 +1,7 @@ use std::time::{Duration, Instant}; use reqwest::multipart::{Form, Part}; -use serde_json::Value; +use serde::Deserialize; use super::{ audit::build_failure_audit, @@ -26,6 +26,17 @@ pub struct RawImageEditOptions { pub mask: Option, } +#[derive(Debug, Deserialize)] +struct RawImageEditResponsePayload { + id: Option, + data: Option>, +} + +#[derive(Debug, Deserialize)] +struct RawImageEditResponseEntry { + b64_json: Option, +} + pub const RAW_IMAGE_MAX_EDGE: u32 = GPT_IMAGE_2_MAX_EDGE; pub const RAW_IMAGE_DIMENSION_ALIGNMENT: u32 = GPT_IMAGE_2_DIMENSION_ALIGNMENT; pub const RAW_IMAGE_MIN_PIXELS: u64 = GPT_IMAGE_2_MIN_PIXELS; @@ -221,7 +232,7 @@ pub async fn create_vector_engine_raw_image_edit( audit: Some(audit), }); } - let payload: Value = match serde_json::from_str(body.as_str()) { + let payload: RawImageEditResponsePayload = match serde_json::from_str(body.as_str()) { Ok(payload) => payload, Err(error) => { let message = format!("{failure_context}:上游响应不是 JSON:{error}"); @@ -249,7 +260,12 @@ pub async fn create_vector_engine_raw_image_edit( }); } }; - let b64_images = extract_b64_images(&payload); + let b64_images = payload + .data + .unwrap_or_default() + .into_iter() + .filter_map(|entry| entry.b64_json) + .collect::>(); if b64_images.is_empty() { let message = format!("{failure_context}:上游未返回 b64_json 图片"); let audit = build_failure_audit( @@ -275,27 +291,12 @@ pub async fn create_vector_engine_raw_image_edit( }); } Ok(RawImageEditResult { - task_id: payload - .get("id") - .and_then(Value::as_str) - .unwrap_or("raw-image-edit") - .to_string(), + task_id: payload.id.unwrap_or_else(|| "raw-image-edit".to_string()), b64_images, recovered_failure_audits: Vec::new(), }) } -fn extract_b64_images(payload: &Value) -> Vec { - payload - .get("data") - .and_then(Value::as_array) - .into_iter() - .flatten() - .filter_map(|entry| entry.get("b64_json").and_then(Value::as_str)) - .map(str::to_string) - .collect() -} - fn invalid_request(context: &str, message: String) -> PlatformImageError { PlatformImageError::InvalidRequest { provider: VECTOR_ENGINE_PROVIDER, @@ -390,13 +391,20 @@ mod tests { #[test] fn raw_result_forwards_b64_without_decoding_or_using_output_format() { - let payload = json!({ + let payload = r#"{ "output_format": "png", "data": [{"b64_json": "not-base64-but-forwarded", "output_format": "jpeg"}] - }); + }"#; + let payload: RawImageEditResponsePayload = + serde_json::from_str(payload).expect("response envelope"); assert_eq!( - extract_b64_images(&payload), + payload + .data + .unwrap_or_default() + .into_iter() + .filter_map(|entry| entry.b64_json) + .collect::>(), vec!["not-base64-but-forwarded".to_string()] ); }