修复: DeepSeek reasoning_content 全链路透传(跨6 crate补字段+映射+agentic loop累积回传)
This commit is contained in:
@@ -44,6 +44,9 @@ struct OpenAiRequest {
|
||||
/// 流式时请求末 chunk 携带 usage(OpenAI 官方 + 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];
|
||||
|
||||
Reference in New Issue
Block a user