From e4d70fbe1b7260377788e9770449813e8b7d597e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Sat, 12 Sep 2026 13:50:25 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=20Raw=20=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=97=A0=E6=95=88=E6=81=A2=E5=A4=8D=E5=AE=A1=E8=AE=A1=E5=AD=97?= =?UTF-8?q?=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RawImageEditResult 仅保留实际透传的 b64_images 删除 raw-edit 不会产生的恢复审计转发与文档描述 补充 PreparedRawImageEdit 的 Debug 派生以通过现有测试 --- ...术方案】Raw GPT Image 2图片编辑代理-2026-09-07.md | 2 +- .../api-server/src/openai_image_generation.rs | 2 +- server-rs/crates/api-server/src/raw_image.rs | 14 ++++---------- .../platform-image/src/vector_engine/raw_edit.rs | 13 +------------ 4 files changed, 7 insertions(+), 24 deletions(-) diff --git a/docs/technical/【技术方案】Raw GPT Image 2图片编辑代理-2026-09-07.md b/docs/technical/【技术方案】Raw GPT Image 2图片编辑代理-2026-09-07.md index c6a4cd3e1..393eb6fb4 100644 --- a/docs/technical/【技术方案】Raw GPT Image 2图片编辑代理-2026-09-07.md +++ b/docs/technical/【技术方案】Raw GPT Image 2图片编辑代理-2026-09-07.md @@ -85,7 +85,7 @@ raw 操作使用独立的 operation / ledger 命名空间,例如 `raw-image-ed `platform-image` 保留 VectorEngine 协议细节。raw handler 只负责:认证、multipart 字段解析、PNG 预检查、计费编排和响应映射。provider 请求仍由 `platform-image` 统一构造,并携带 `model`、`n`、`quality`、`background`、`output_format`、尺寸及图片参考字节。 -provider 响应只提取并透传 `data[].b64_json` 字符串,不在服务端解码图片 base64,也不读取或回传 provider 的 `output_format`(该字段只是请求参数回显)。GPT-Image-2 原生只返回 `b64_json`,因此不发送 `response_format` 参数,也不实现 URL 响应下载或兼容分支。发送、响应读取、上游状态、响应解析和缺图失败必须生成 `PlatformImageFailureAudit`,由 api-server 写入现有外部 API 失败审计链;成功结果同时写入统一的 `external_generation_run` 追踪事件。raw handler 只将上游 `b64_json` 原样写入 `data[].b64_json`。`RawImageEditResult.recovered_failure_audits` 保留共享结果契约,但 raw-edit 当前只有一次同步 provider 调用、没有 fallback,因此成功结果该列表恒为空;若后续增加 fallback,api-server 必须先落库其中的每条失败审计,再写成功运行摘要。 +provider 响应只提取并透传 `data[].b64_json` 字符串,不在服务端解码图片 base64,也不读取或回传 provider 的 `output_format`(该字段只是请求参数回显)。GPT-Image-2 原生只返回 `b64_json`,因此不发送 `response_format` 参数,也不实现 URL 响应下载或兼容分支。发送、响应读取、上游状态、响应解析和缺图失败必须生成 `PlatformImageFailureAudit`,由 api-server 写入现有外部 API 失败审计链;成功结果同时写入统一的 `external_generation_run` 追踪事件。raw handler 只将上游 `b64_json` 原样写入 `data[].b64_json`。 ## 代码拆分 diff --git a/server-rs/crates/api-server/src/openai_image_generation.rs b/server-rs/crates/api-server/src/openai_image_generation.rs index e1debf606..f0fa7591c 100644 --- a/server-rs/crates/api-server/src/openai_image_generation.rs +++ b/server-rs/crates/api-server/src/openai_image_generation.rs @@ -492,7 +492,7 @@ pub(crate) async fn record_openai_image_failure_if_configured( record_openai_image_failure_audit_if_configured(settings, audit).await; } -pub(crate) async fn record_openai_image_failure_audit_if_configured( +async fn record_openai_image_failure_audit_if_configured( settings: &OpenAiImageSettings, audit: &platform_image::PlatformImageFailureAudit, ) { diff --git a/server-rs/crates/api-server/src/raw_image.rs b/server-rs/crates/api-server/src/raw_image.rs index 873b0398c..a39aca114 100644 --- a/server-rs/crates/api-server/src/raw_image.rs +++ b/server-rs/crates/api-server/src/raw_image.rs @@ -21,8 +21,8 @@ use crate::{ auth::AuthenticatedAccessToken, http_error::AppError, openai_image_generation::{ - map_platform_image_error, record_openai_image_failure_audit_if_configured, - record_openai_image_failure_if_configured, require_openai_image_settings, + map_platform_image_error, record_openai_image_failure_if_configured, + require_openai_image_settings, }, request_context::RequestContext, state::AppState, @@ -125,10 +125,6 @@ pub(crate) async fn edit_raw_image( return Err(map_platform_image_error(error)); } }; - for audit in &generated.recovered_failure_audits { - record_openai_image_failure_audit_if_configured(&audit_settings, audit).await; - } - let recovered_failure_count = generated.recovered_failure_audits.len(); let data: Vec = generated .b64_images .into_iter() @@ -145,10 +141,7 @@ pub(crate) async fn edit_raw_image( true, None, Some("raw-image-edit".to_string()), - Some(json!({ - "imageCount": data.len(), - "recoveredFailureCount": recovered_failure_count, - })), + Some(json!({ "imageCount": data.len() })), ) .await; } @@ -168,6 +161,7 @@ pub(crate) async fn edit_raw_image( Ok(Json(result)) } +#[derive(Debug)] struct PreparedRawImageEdit { image: RawImageEditImage, prompt: String, 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 ea944a190..6061f885b 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 @@ -34,16 +34,8 @@ pub struct RawImageEditImage { } #[derive(Clone, Debug)] -/// Successful response from the synchronous raw GPT Image 2 edit call. pub struct RawImageEditResult { pub b64_images: Vec, - /// Failure audits recovered by an internal fallback attempt. - /// - /// Raw-edit currently performs one provider call and has no fallback, so - /// this is empty on every successful result. The field remains part of the - /// shared result contract so adding a fallback later cannot silently drop - /// its audit trail from callers that already handle recovered failures. - pub recovered_failure_audits: Vec, } const GPT_IMAGE_2_MIN_PIXELS: u64 = 655_360; @@ -319,10 +311,7 @@ pub async fn create_vector_engine_raw_image_edit( audit: Some(audit), }); } - Ok(RawImageEditResult { - b64_images, - recovered_failure_audits: Vec::new(), - }) + Ok(RawImageEditResult { b64_images }) } fn collect_b64_images(data: Vec) -> Vec {