修复: DeepSeek reasoning_content 全链路透传(跨6 crate补字段+映射+agentic loop累积回传)

This commit is contained in:
2026-06-17 18:08:04 +08:00
parent 1cd7652a34
commit 74003bc04f
11 changed files with 251 additions and 20 deletions

View File

@@ -44,6 +44,9 @@ struct OpenAiRequest {
/// 流式时请求末 chunk 携带 usageOpenAI 官方 + DeepSeek/GLM 兼容)
#[serde(skip_serializing_if = "Option::is_none")]
stream_options: Option<serde_json::Value>,
/// DeepSeek thinking 模式
#[serde(skip_serializing_if = "Option::is_none")]
pub reasoning_content: Option<String>,
}
/// OpenAI 消息格式
@@ -58,6 +61,9 @@ struct OpenAiMessage {
tool_call_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
tool_calls: Option<Vec<serde_json::Value>>,
/// DeepSeek thinking 模式推理内容
#[serde(skip_serializing_if = "Option::is_none")]
pub reasoning_content: Option<String>,
}
/// OpenAI 同步响应
@@ -78,6 +84,9 @@ struct OpenAiChoice {
struct OpenAiMessageResp {
content: Option<String>,
tool_calls: Option<Vec<OpenAiToolCallResp>>,
/// DeepSeek thinking 模式响应中的推理内容
#[serde(default, skip_serializing_if = "Option::is_none")]
pub reasoning_content: Option<String>,
}
#[derive(Debug, Deserialize)]
@@ -120,6 +129,9 @@ struct OpenAiStreamChoice {
struct OpenAiStreamDelta {
content: Option<String>,
tool_calls: Option<Vec<OpenAiStreamToolCall>>,
/// DeepSeek thinking 模式流式推理内容
#[serde(default, skip_serializing_if = "Option::is_none")]
pub reasoning_content: Option<String>,
}
#[derive(Debug, Deserialize)]
@@ -158,6 +170,7 @@ pub(crate) fn apply_openai_sse(data: &str, usage_accum: &mut Option<TokenUsage>)
tool_calls: None,
usage: usage_accum.take(),
error: None,
reasoning_content: None,
};
}
@@ -195,6 +208,7 @@ pub(crate) fn apply_openai_sse(data: &str, usage_accum: &mut Option<TokenUsage>)
tool_calls,
usage: None,
error: None,
reasoning_content: choice.delta.reasoning_content,
}
} else {
// choices 为空 = usage-only chunk不输出文本usage 已累积)
@@ -204,6 +218,7 @@ pub(crate) fn apply_openai_sse(data: &str, usage_accum: &mut Option<TokenUsage>)
tool_calls: None,
usage: None,
error: None,
reasoning_content: None,
}
}
}
@@ -215,6 +230,7 @@ pub(crate) fn apply_openai_sse(data: &str, usage_accum: &mut Option<TokenUsage>)
tool_calls: None,
usage: None,
error: None,
reasoning_content: None,
}
}
}
@@ -371,6 +387,7 @@ impl OpenAICompatProvider {
content,
tool_call_id: m.tool_call_id,
tool_calls,
reasoning_content: m.reasoning_content,
}
})
.collect();
@@ -389,6 +406,7 @@ impl OpenAICompatProvider {
stream: req.stream,
tools,
tool_choice: req.tool_choice,
reasoning_content: req.reasoning_content,
// 流式请求末 chunk 带 usage同步调用 complete 不需要)
stream_options: if req.stream {
Some(serde_json::json!({ "include_usage": true }))
@@ -509,6 +527,7 @@ impl LlmProvider for OpenAICompatProvider {
model: body.model,
usage,
tool_calls,
reasoning_content: choice.message.reasoning_content,
})
}
})
@@ -755,6 +774,7 @@ mod tests {
stream: false,
tools: None,
tool_choice: None,
reasoning_content: None,
};
let out = provider.convert_request(req);
let msg = &out.messages[0];
@@ -783,6 +803,7 @@ mod tests {
stream: false,
tools: None,
tool_choice: None,
reasoning_content: None,
};
let out = provider.convert_request(req);
let msg = &out.messages[0];