fix(LLM 代理): Chat Completions 透传类型化错误,保留权限码
- resolve_llm_router_client 返回 Result<_, AppError> 而非 String(评审第 17 条) - load_owner_llm_catalog 的 503 + MODEL_ACCESS_UNAVAILABLE 不再被拍平成「模型目录暂不可用」 - resolve_requested_for 错误改走 agc_model_resolve_error,与 proxy_llm_responses / proxy_llm_messages 契约一致 - LlmConfig / LlmClient 构造失败按 500 返回;调用方直接 llm_error_response 透传
This commit is contained in:
@@ -187,12 +187,7 @@ pub async fn proxy_llm_chat_completions(
|
||||
let (llm_client, key_id) =
|
||||
match resolve_llm_router_client(&state, authenticated.claims().user_id()).await {
|
||||
Ok((client, key_id)) => (client, key_id),
|
||||
Err(error) => {
|
||||
return Err(llm_error_response(
|
||||
&request_context,
|
||||
AppError::from_status(StatusCode::SERVICE_UNAVAILABLE).with_message(error),
|
||||
));
|
||||
}
|
||||
Err(error) => return Err(llm_error_response(&request_context, error)),
|
||||
};
|
||||
prepare_llm_router_billing(&state, authenticated.claims().user_id())
|
||||
.await
|
||||
@@ -1518,16 +1513,20 @@ fn is_responses_terminal_sse_event(event: &str) -> bool {
|
||||
async fn resolve_llm_router_client(
|
||||
state: &AppState,
|
||||
owner_user_id: &str,
|
||||
) -> Result<(platform_llm::LlmClient, String), String> {
|
||||
let (base_url, api_key, key_id) = resolve_llm_router_credentials(state, owner_user_id).await?;
|
||||
let catalog = load_owner_llm_catalog(state, owner_user_id)
|
||||
) -> Result<(platform_llm::LlmClient, String), AppError> {
|
||||
let (base_url, api_key, key_id) = resolve_llm_router_credentials(state, owner_user_id)
|
||||
.await
|
||||
.map_err(|_| "模型目录暂不可用".to_string())?;
|
||||
.map_err(|message| {
|
||||
AppError::from_status(StatusCode::SERVICE_UNAVAILABLE).with_message(message)
|
||||
})?;
|
||||
// 目录读失败与会员权限读失败(503 + MODEL_ACCESS_UNAVAILABLE)都保留各自的类型化错误,
|
||||
// 不再拍平成一句中文,与 `proxy_llm_responses` / `proxy_llm_messages` 的契约一致。
|
||||
let catalog = load_owner_llm_catalog(state, owner_user_id).await?;
|
||||
// Chat Completions 的 `model` 恒为账号该档的默认模型,不接收客户端选择。
|
||||
let model = catalog
|
||||
.catalog
|
||||
.resolve_requested_for(None, catalog.access)
|
||||
.map_err(|error| error.message().to_string())?;
|
||||
.map_err(agc_model_resolve_error)?;
|
||||
let config = platform_llm::LlmConfig::new(
|
||||
platform_llm::LlmProvider::OpenAiCompatible,
|
||||
base_url.to_string(),
|
||||
@@ -1537,10 +1536,16 @@ async fn resolve_llm_router_client(
|
||||
state.config.llm_max_retries,
|
||||
state.config.llm_retry_backoff_ms,
|
||||
)
|
||||
.map_err(|error| error.to_string())?;
|
||||
.map_err(|error| {
|
||||
AppError::from_status(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
.with_message(format!("LLM Router 客户端配置非法:{error}"))
|
||||
})?;
|
||||
platform_llm::LlmClient::new(config)
|
||||
.map(|client| (client, key_id))
|
||||
.map_err(|error| error.to_string())
|
||||
.map_err(|error| {
|
||||
AppError::from_status(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
.with_message(format!("创建 LLM Router 客户端失败:{error}"))
|
||||
})
|
||||
}
|
||||
|
||||
async fn resolve_llm_router_credentials(
|
||||
|
||||
Reference in New Issue
Block a user