修正 raw image edit 的 provider 归属
created_raw_image_edit 用 settings.provider 统一驱动审计、日志与错误构造 invalid_request / invalid_input / request_error 增加 provider 参数,不再写死 vector-engine
This commit is contained in:
@@ -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:请求参数无效:尺寸无效");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user