修正 raw image edit 的 provider 归属

created_raw_image_edit 用 settings.provider 统一驱动审计、日志与错误构造

invalid_request / invalid_input / request_error 增加 provider 参数,不再写死 vector-engine
This commit is contained in:
2026-09-19 13:22:20 +08:00
parent 5cba2dbeb7
commit 89587c9e9e
@@ -7,11 +7,11 @@ use serde::Deserialize;
use crate::image_provider::{
constants::{
GPT_IMAGE_2_5_EDIT_MODEL, GPT_IMAGE_2_DIMENSION_ALIGNMENT, GPT_IMAGE_2_MAX_EDGE,
GPT_IMAGE_2_MAX_PIXELS, GPT_IMAGE_2_MIN_PIXELS, VECTOR_ENGINE_PROVIDER,
GPT_IMAGE_2_MAX_PIXELS, GPT_IMAGE_2_MIN_PIXELS,
},
images_edit_url,
runtime::{
ImageProviderSettings, PlatformImageError, build_failure_audit,
ImageProvider, ImageProviderSettings, PlatformImageError, build_failure_audit,
effective_request_timeout_ms, request_budget_exhausted_error, truncate_raw,
},
};
@@ -124,8 +124,9 @@ pub async fn create_raw_image_edit(
options: RawImageEditOptions,
failure_context: &str,
) -> Result<RawImageEditResult, PlatformImageError> {
let provider_label = settings.provider.as_str();
validate_raw_image_edit_dimensions(options.width, options.height)
.map_err(|error| invalid_input(failure_context, error.to_string()))?;
.map_err(|error| invalid_input(settings.provider, failure_context, error.to_string()))?;
let url = images_edit_url(settings);
let started_at = Instant::now();
let prompt_chars = Some(prompt.chars().count());
@@ -161,7 +162,9 @@ pub async fn create_raw_image_edit(
Part::stream(reqwest::Body::from(image_bytes))
.file_name(image_file_name)
.mime_str(image_mime_type.as_str())
.map_err(|error| invalid_request(failure_context, error.to_string()))?,
.map_err(|error| {
invalid_request(settings.provider, failure_context, error.to_string())
})?,
);
if let Some(value) = options.quality {
form = form.text("quality", value);
@@ -178,7 +181,9 @@ pub async fn create_raw_image_edit(
Part::stream(reqwest::Body::from(mask.bytes))
.file_name(mask.file_name)
.mime_str(mask.mime_type.as_str())
.map_err(|error| invalid_request(failure_context, error.to_string()))?,
.map_err(|error| {
invalid_request(settings.provider, failure_context, error.to_string())
})?,
);
}
@@ -191,6 +196,7 @@ pub async fn create_raw_image_edit(
.await
.map_err(|error| {
request_error(
settings.provider,
&url,
failure_context,
"request_send",
@@ -202,7 +208,7 @@ pub async fn create_raw_image_edit(
})?;
let status = response.status();
tracing::info!(
provider = VECTOR_ENGINE_PROVIDER,
provider = provider_label,
endpoint = %url,
status = status.as_u16(),
prompt_chars,
@@ -213,6 +219,7 @@ pub async fn create_raw_image_edit(
);
let body = response.text().await.map_err(|error| {
request_error(
settings.provider,
&url,
failure_context,
"response_read",
@@ -229,7 +236,7 @@ pub async fn create_raw_image_edit(
);
let raw_excerpt = truncate_raw(body.as_str());
let audit = build_failure_audit(
VECTOR_ENGINE_PROVIDER,
provider_label,
url.as_str(),
failure_context,
"upstream_status",
@@ -246,7 +253,7 @@ pub async fn create_raw_image_edit(
Some(GPT_IMAGE_2_5_EDIT_MODEL),
);
return Err(PlatformImageError::Upstream {
provider: VECTOR_ENGINE_PROVIDER,
provider: provider_label,
message,
upstream_status: status.as_u16(),
raw_excerpt,
@@ -259,7 +266,7 @@ pub async fn create_raw_image_edit(
let message = format!("{failure_context}:上游响应不是 JSON{error}");
let raw_excerpt = truncate_raw(body.as_str());
let audit = build_failure_audit(
VECTOR_ENGINE_PROVIDER,
provider_label,
url.as_str(),
failure_context,
"response_parse",
@@ -276,7 +283,7 @@ pub async fn create_raw_image_edit(
Some(GPT_IMAGE_2_5_EDIT_MODEL),
);
return Err(PlatformImageError::ResponseParse {
provider: VECTOR_ENGINE_PROVIDER,
provider: provider_label,
message,
raw_excerpt,
audit: Some(audit),
@@ -287,7 +294,7 @@ pub async fn create_raw_image_edit(
if b64_images.is_empty() {
let message = format!("{failure_context}:上游未返回 b64_json 图片");
let audit = build_failure_audit(
VECTOR_ENGINE_PROVIDER,
provider_label,
url.as_str(),
failure_context,
"missing_image",
@@ -304,7 +311,7 @@ pub async fn create_raw_image_edit(
Some(GPT_IMAGE_2_5_EDIT_MODEL),
);
return Err(PlatformImageError::MissingImage {
provider: VECTOR_ENGINE_PROVIDER,
provider: provider_label,
message,
audit: Some(audit),
});
@@ -319,21 +326,22 @@ fn collect_b64_images(data: Vec<RawImageEditResponseEntry>) -> Vec<String> {
.collect()
}
fn invalid_request(context: &str, message: String) -> PlatformImageError {
fn invalid_request(provider: ImageProvider, context: &str, message: String) -> PlatformImageError {
PlatformImageError::InvalidRequest {
provider: VECTOR_ENGINE_PROVIDER,
provider: provider.as_str(),
message: format!("{context}:构造上游请求失败:{message}"),
}
}
fn invalid_input(context: &str, message: String) -> PlatformImageError {
fn invalid_input(provider: ImageProvider, context: &str, message: String) -> PlatformImageError {
PlatformImageError::InvalidRequest {
provider: VECTOR_ENGINE_PROVIDER,
provider: provider.as_str(),
message: format!("{context}:请求参数无效:{message}"),
}
}
fn request_error(
provider: ImageProvider,
url: &str,
context: &str,
failure_stage: &'static str,
@@ -342,12 +350,13 @@ fn request_error(
prompt_chars: Option<usize>,
reference_image_count: Option<usize>,
) -> PlatformImageError {
let provider_label = provider.as_str();
let timeout = error.is_timeout();
let connect = error.is_connect();
let source = error.to_string();
let message = format!("{context}:上游请求失败:{source}");
tracing::warn!(
provider = VECTOR_ENGINE_PROVIDER,
provider = provider_label,
endpoint = %url,
failure_stage,
timeout,
@@ -360,7 +369,7 @@ fn request_error(
"ImageProvider Raw 图片编辑请求失败"
);
let audit = build_failure_audit(
VECTOR_ENGINE_PROVIDER,
provider_label,
url,
context,
failure_stage,
@@ -377,7 +386,7 @@ fn request_error(
Some(GPT_IMAGE_2_5_EDIT_MODEL),
);
PlatformImageError::Request {
provider: VECTOR_ENGINE_PROVIDER,
provider: provider_label,
message,
endpoint: Some(url.to_string()),
timeout,
@@ -466,7 +475,11 @@ mod tests {
#[test]
fn dimension_validation_error_identifies_client_input() {
let error = invalid_input("raw_image_edit", "尺寸无效".to_string());
let error = invalid_input(
ImageProvider::Tiantoken,
"raw_image_edit",
"尺寸无效".to_string(),
);
assert_eq!(error.to_string(), "raw_image_edit:请求参数无效:尺寸无效");
}