fix(provider): 修复 Windsurf PR CI 失败

This commit is contained in:
Entropy.Xu
2026-05-21 02:21:35 +08:00
parent 65c361115a
commit 4112a8b2ea
11 changed files with 38 additions and 37 deletions

View File

@@ -934,7 +934,11 @@ async fn resolve_openai_chat_to_openai_image_payload_parts(
let upstream_url = if is_chatgpt_web {
chatgpt_web_image_internal_url(&transport.endpoint.base_url)
} else {
build_openai_image_upstream_url(transport, parts.uri.query())
build_openai_image_upstream_url(
transport,
Some("/v1/images/generations"),
parts.uri.query(),
)
};
let Some(mut provider_request_headers) =
build_openai_image_headers(ProviderOpenAiImageHeadersInput {

View File

@@ -1727,7 +1727,7 @@ async fn execute_execution_runtime_sync_impl(
}
let (mut result_error_type, mut result_error_message) =
execution_error_details(result.error.as_ref(), body_json.as_ref());
if result.status_code < 400 {
if result.status_code < 400 && body_json.is_none() {
if let Some(error_body_json) =
extract_provider_private_stream_error_body(report_context.as_ref(), &body_bytes)
{

View File

@@ -25,6 +25,7 @@ use serde_json::json;
use serde_json::Value;
use thiserror::Error;
use crate::ai_serving::api::extract_provider_private_stream_error_body;
#[cfg(test)]
use crate::execution_runtime::remote_compat::execute_sync_plan_via_remote_execution_runtime;
use crate::execution_runtime::windsurf::maybe_execute_windsurf_sync;
@@ -1466,11 +1467,8 @@ pub(crate) fn build_execution_response_body(
return Ok(None);
}
if let Some(body_json) =
aether_ai_formats::api::extract_provider_private_stream_error_body(None, decoded_body_bytes)
.or_else(|| {
aether_ai_formats::api::extract_provider_private_stream_error_body(None, body_bytes)
})
if let Some(body_json) = extract_provider_private_stream_error_body(None, decoded_body_bytes)
.or_else(|| extract_provider_private_stream_error_body(None, body_bytes))
{
return Ok(Some(ResponseBody {
json_body: Some(body_json),

View File

@@ -345,7 +345,6 @@ async fn prepare_windsurf_cascade(
native_allowlist: native_bridge
.map(|bridge| bridge.native_allowlist.clone())
.unwrap_or_default(),
..SendCascadeMessageOptions::default()
};
let send_payload = build_send_cascade_message_request_with_options(
&input.api_key,
@@ -414,7 +413,7 @@ async fn read_windsurf_key_upstream_metadata(
}
match state
.read_provider_catalog_keys_by_ids(&[plan.key_id.clone()])
.read_provider_catalog_keys_by_ids(std::slice::from_ref(&plan.key_id))
.await
{
Ok(keys) => keys
@@ -1693,10 +1692,8 @@ fn build_cascade_message_with_options(
};
let text = text.trim();
match role {
"system" => {
if !text.is_empty() {
system_text.push(text.to_string());
}
"system" if !text.is_empty() => {
system_text.push(text.to_string());
}
"assistant" => {
let assistant_text = assistant_message_text_for_cascade(message, text, dialect);

View File

@@ -25,6 +25,7 @@ use crate::handlers::admin::provider::oauth::runtime::{
use crate::handlers::admin::provider::oauth::state::{
admin_provider_oauth_template, exchange_admin_provider_oauth_refresh_token,
};
use crate::handlers::admin::provider::shared::support::ADMIN_PROVIDER_OAUTH_DATA_UNAVAILABLE_DETAIL;
use crate::handlers::admin::request::{AdminAppState, AdminProviderOAuthTemplate};
use crate::GatewayError;
use aether_admin::provider::oauth::parse_admin_provider_oauth_kiro_batch_import_entries;
@@ -167,10 +168,6 @@ async fn resolve_admin_provider_oauth_batch_import_tokens(
});
}
let Some(template) = template else {
return Err(ADMIN_PROVIDER_OAUTH_DATA_UNAVAILABLE_DETAIL.to_string());
};
if let Some(refresh_token) = refresh_token {
let Some(template) = template else {
if provider_type_supports_access_token_import(provider_type) {
@@ -301,7 +298,10 @@ pub(super) async fn execute_admin_provider_oauth_batch_import(
};
let template = admin_provider_oauth_template(provider_type);
if template.is_none() && !provider_type.eq_ignore_ascii_case("windsurf") {
if template.is_none()
&& !provider_type.eq_ignore_ascii_case("windsurf")
&& !provider_type_supports_access_token_import(provider_type)
{
return Ok(AdminProviderOAuthBatchImportOutcome {
total: entries.len(),
success: 0,

View File

@@ -8,7 +8,7 @@ use super::parse::{
};
use crate::handlers::admin::provider::oauth::errors::build_internal_control_error_response;
use crate::handlers::admin::provider::oauth::state::{
build_admin_provider_oauth_backend_unavailable_response,
admin_provider_oauth_template, build_admin_provider_oauth_backend_unavailable_response,
is_fixed_provider_type_for_provider_oauth,
};
use crate::handlers::admin::provider::shared::paths::admin_provider_oauth_batch_import_provider_id;

View File

@@ -10,7 +10,7 @@ use super::progress::{
};
use crate::handlers::admin::provider::oauth::errors::build_internal_control_error_response;
use crate::handlers::admin::provider::oauth::state::{
build_admin_provider_oauth_backend_unavailable_response,
admin_provider_oauth_template, build_admin_provider_oauth_backend_unavailable_response,
is_fixed_provider_type_for_provider_oauth,
};
use crate::handlers::admin::provider::shared::paths::admin_provider_oauth_batch_import_task_provider_id;

View File

@@ -508,9 +508,6 @@ pub(super) async fn handle_admin_provider_oauth_import_refresh_token(
"Refresh Token 或 Access Token 不能为空",
));
}
let Some(template) = admin_provider_oauth_template(&provider_type) else {
return Ok(build_admin_provider_oauth_backend_unavailable_response());
};
match resolve_admin_provider_oauth_single_import_tokens(
state,
template,

View File

@@ -2880,6 +2880,7 @@ async fn gateway_completes_admin_provider_oauth_key_locally_with_trusted_admin_p
.expect("account_state_recheck_error should be string when recheck is attempted");
assert!(
account_state_recheck_error == "wham/usage API 返回状态码 401"
|| account_state_recheck_error == "wham/usage API 返回状态码 403"
|| account_state_recheck_error.starts_with("wham/usage 请求执行失败:"),
"unexpected account_state_recheck_error: {account_state_recheck_error}"
);
@@ -5351,6 +5352,7 @@ async fn gateway_refreshes_admin_provider_oauth_key_locally_with_trusted_admin_p
.expect("account_state_recheck_error should be string when attempted");
assert!(
account_state_recheck_error == "wham/usage API 返回状态码 401"
|| account_state_recheck_error == "wham/usage API 返回状态码 403"
|| account_state_recheck_error.starts_with("wham/usage 请求执行失败:"),
"unexpected account_state_recheck_error: {account_state_recheck_error}"
);
@@ -5400,6 +5402,14 @@ async fn gateway_refreshes_admin_provider_oauth_key_locally_with_trusted_admin_p
stored_key.oauth_invalid_reason.as_deref(),
Some("[OAUTH_EXPIRED] Codex Token 无效或已过期 (401)")
);
} else if account_state_recheck_attempted
&& payload["account_state_recheck_error"] == "wham/usage API 返回状态码 403"
{
assert!(stored_key.oauth_invalid_at_unix_secs.is_some());
assert!(stored_key
.oauth_invalid_reason
.as_deref()
.is_some_and(|reason| reason.contains("(403)")));
} else {
assert_eq!(stored_key.oauth_invalid_at_unix_secs, None);
assert_eq!(stored_key.oauth_invalid_reason, None);