feat: return reasoning_content with tool_calls for DeepSeek models (#2543)

* feat: return reasoning_content with tool_calls for DeepSeek models

* fix: correct reasoning_content handling for DeepSeek tool_calls

* test: cover DeepSeek reasoning content round trip

---------

Co-authored-by: Jason <farion1231@gmail.com>
This commit is contained in:
bling-yshs
2026-05-07 23:03:07 +08:00
committed by GitHub
parent 1d44b1ba41
commit f5fbcd0493
3 changed files with 104 additions and 8 deletions
+39 -4
View File
@@ -82,9 +82,9 @@ pub fn claude_api_format_needs_transform(api_format: &str) -> bool {
)
}
fn is_moonshot_or_kimi_identifier(value: &str) -> bool {
fn is_reasoning_content_compatible_identifier(value: &str) -> bool {
let value = value.to_ascii_lowercase();
value.contains("moonshot") || value.contains("kimi")
value.contains("moonshot") || value.contains("kimi") || value.contains("deepseek")
}
fn should_preserve_reasoning_content_for_openai_chat(
@@ -94,7 +94,7 @@ fn should_preserve_reasoning_content_for_openai_chat(
if body
.get("model")
.and_then(|m| m.as_str())
.is_some_and(is_moonshot_or_kimi_identifier)
.is_some_and(is_reasoning_content_compatible_identifier)
{
return true;
}
@@ -113,7 +113,7 @@ fn should_preserve_reasoning_content_for_openai_chat(
base_urls
.into_iter()
.flatten()
.any(is_moonshot_or_kimi_identifier)
.any(is_reasoning_content_compatible_identifier)
}
pub fn transform_claude_request_for_api_format(
@@ -1673,4 +1673,39 @@ mod tests {
assert_eq!(msg["reasoning_content"], "I should call the tool.");
assert!(msg.get("tool_calls").is_some());
}
#[test]
fn test_transform_openai_chat_preserves_reasoning_content_for_deepseek_provider() {
let provider = create_provider_with_meta(
json!({
"env": {
"ANTHROPIC_BASE_URL": "https://api.deepseek.com/v1",
"ANTHROPIC_API_KEY": "test-key"
}
}),
ProviderMeta {
api_format: Some("openai_chat".to_string()),
..Default::default()
},
);
let body = json!({
"model": "deepseek-v4-flash",
"max_tokens": 64,
"messages": [{
"role": "assistant",
"content": [
{"type": "thinking", "thinking": "I should call the tool."},
{"type": "tool_use", "id": "call_123", "name": "get_weather", "input": {"location": "Tokyo"}}
]
}]
});
let transformed =
transform_claude_request_for_api_format(body, &provider, "openai_chat", None, None)
.unwrap();
let msg = &transformed["messages"][0];
assert_eq!(msg["reasoning_content"], "I should call the tool.");
assert!(msg.get("tool_calls").is_some());
}
}