修复: OpenAI SSE error 识别 + 条件引擎 warn + MidStream stop_flag 优先 + 双窗口 listener 时序加固
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
//! 零行为变更(纯搬迁)。结构对齐 `anthropic_helpers.rs`。
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::debug;
|
||||
use tracing::{debug, error};
|
||||
|
||||
use crate::provider::{StreamChunk, TokenUsage, ToolCallDelta};
|
||||
|
||||
@@ -111,6 +111,11 @@ pub(crate) struct OpenAiStreamChunk {
|
||||
/// 末 chunk(choices 为空)携带的累计 usage
|
||||
#[serde(default)]
|
||||
pub usage: Option<OpenAiUsage>,
|
||||
/// 流中途 error 事件(OpenAI 兼容协议:`{"error":{"message":..,"type":..}}`)。
|
||||
/// 部分中转站按 OpenAI 协议在流中途发 error 帧而非走 HTTP 非 200,
|
||||
/// serde default + Value 兜底:旧响应无此字段不受影响,且对 error 载荷形态不敏感。
|
||||
#[serde(default)]
|
||||
pub error: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
@@ -170,6 +175,25 @@ pub(crate) fn apply_openai_sse(data: &str, usage_accum: &mut Option<TokenUsage>)
|
||||
|
||||
match serde_json::from_str::<OpenAiStreamChunk>(data) {
|
||||
Ok(chunk) => {
|
||||
// 流中途 error 事件(中转站按 OpenAI 协议在流中途发 error 帧)。
|
||||
// 不走 finished 完成路径(避免残缺响应被当正常完成入库),由 stream_llm
|
||||
// 识别 error 非空 → 发 AiError + 丢弃残缺(对齐 anthropic_helpers 215-219)。
|
||||
if let Some(err_val) = chunk.error {
|
||||
let msg = err_val
|
||||
.get("message")
|
||||
.and_then(|m| m.as_str())
|
||||
.unwrap_or("stream error")
|
||||
.to_string();
|
||||
error!(%msg, raw = %err_val, "OpenAI 流式错误事件");
|
||||
return StreamChunk {
|
||||
delta: String::new(),
|
||||
finished: false,
|
||||
tool_calls: None,
|
||||
usage: None,
|
||||
error: Some(msg),
|
||||
reasoning_content: None,
|
||||
};
|
||||
}
|
||||
// 提取 usage(带 include_usage 时末段 chunk 携带,覆盖累积)
|
||||
if let Some(u) = chunk.usage {
|
||||
*usage_accum = Some(TokenUsage {
|
||||
|
||||
Reference in New Issue
Block a user