mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
feat(codex-image): 封装 GPT Image 2 图片接口并收紧错误处理
- 新增 openai:image 路由、planner 与 finalize,内部通过 Codex responses image_generation tool 执行生图 - 补充 Codex OAuth/header 兼容、图片 success report 本地处理与相关前后端/集成测试 - 禁止 chat/completions 使用 gpt-image-2,图片接口限制 n=1,并移除 Provider 模型页的图片能力开关
This commit is contained in:
@@ -40,6 +40,9 @@ const CLIENT_ERROR_PATTERNS: &[&str] = &[
|
||||
"validationexception",
|
||||
];
|
||||
|
||||
const STRICT_CLIENT_ERROR_PATTERNS: &[&str] =
|
||||
&["unknown parameter", "invalid model for this endpoint"];
|
||||
|
||||
const COMPATIBILITY_ERROR_PATTERNS: &[&str] = &[
|
||||
"unsupported parameter",
|
||||
"unsupported model",
|
||||
@@ -154,6 +157,10 @@ pub(crate) fn classify_local_failover(
|
||||
return LocalFailoverClassification::RetrySemanticThinkingError;
|
||||
}
|
||||
|
||||
if is_strict_semantic_client_error(input.status_code, &parsed_error) {
|
||||
return LocalFailoverClassification::StopSemanticClientError;
|
||||
}
|
||||
|
||||
if is_semantic_compatibility_error(input.status_code, &parsed_error) {
|
||||
return LocalFailoverClassification::RetrySemanticCompatibilityError;
|
||||
}
|
||||
@@ -324,6 +331,18 @@ fn is_semantic_client_error(status_code: u16, parsed: &ParsedLocalErrorResponse)
|
||||
.any(|pattern| search_text.contains(&pattern.to_ascii_lowercase()))
|
||||
}
|
||||
|
||||
fn is_strict_semantic_client_error(status_code: u16, parsed: &ParsedLocalErrorResponse) -> bool {
|
||||
if status_code < 400 {
|
||||
return false;
|
||||
}
|
||||
|
||||
let search_text = semantic_search_text(parsed);
|
||||
!search_text.is_empty()
|
||||
&& STRICT_CLIENT_ERROR_PATTERNS
|
||||
.iter()
|
||||
.any(|pattern| search_text.contains(&pattern.to_ascii_lowercase()))
|
||||
}
|
||||
|
||||
fn is_semantic_compatibility_error(status_code: u16, parsed: &ParsedLocalErrorResponse) -> bool {
|
||||
if status_code < 400 {
|
||||
return false;
|
||||
@@ -462,6 +481,34 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifier_stops_unknown_parameter_errors_before_compatibility_retry() {
|
||||
assert_eq!(
|
||||
classify_local_failover(
|
||||
&LocalFailoverPolicy::default(),
|
||||
LocalFailoverInput::new(
|
||||
400,
|
||||
Some("{\"error\":{\"message\":\"Unknown parameter: 'tools[0].n'.\"}}")
|
||||
)
|
||||
),
|
||||
LocalFailoverClassification::StopSemanticClientError
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifier_stops_invalid_model_for_endpoint_errors_before_compatibility_retry() {
|
||||
assert_eq!(
|
||||
classify_local_failover(
|
||||
&LocalFailoverPolicy::default(),
|
||||
LocalFailoverInput::new(
|
||||
400,
|
||||
Some("{\"error\":{\"message\":\"invalid model for this endpoint\"}}")
|
||||
)
|
||||
),
|
||||
LocalFailoverClassification::StopSemanticClientError
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifier_retries_semantic_thinking_errors() {
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user