fix: comprehensive cross-provider tool calling and history fixes
- Fix DeepSeek R1 (reasoner) 400 errors by ensuring assistant messages with tool_calls in history always have non-null 'content' and 'reasoning_content'. - Implement deterministic tool call ID truncation (max 40 chars) for OpenAI compatibility (fixes errors when history contains long Gemini signatures). - Automatic transition from 'max_tokens' to 'max_completion_tokens' for newer OpenAI models (o1, o3, gpt-5-nano). - Added 'reasoning' and 'thought' aliases to reasoning_content for robust deserialization from various clients.
This commit is contained in:
@@ -72,7 +72,7 @@ pub async fn messages_to_openai_json(messages: &[UnifiedMessage]) -> Result<Vec<
|
||||
msg["reasoning_content"] = serde_json::json!(reasoning);
|
||||
}
|
||||
|
||||
// For assistant messages with tool_calls, content can be null
|
||||
// For assistant messages with tool_calls, content can be empty string
|
||||
if let Some(tool_calls) = &m.tool_calls {
|
||||
// Sanitize tool call IDs for OpenAI compatibility (max 40 chars)
|
||||
let sanitized_calls: Vec<_> = tool_calls.iter().map(|tc| {
|
||||
@@ -84,7 +84,7 @@ pub async fn messages_to_openai_json(messages: &[UnifiedMessage]) -> Result<Vec<
|
||||
}).collect();
|
||||
|
||||
if parts.is_empty() {
|
||||
msg["content"] = serde_json::Value::Null;
|
||||
msg["content"] = serde_json::json!("");
|
||||
} else {
|
||||
msg["content"] = serde_json::json!(parts);
|
||||
}
|
||||
@@ -165,7 +165,7 @@ pub async fn messages_to_openai_json_text_only(
|
||||
msg["reasoning_content"] = serde_json::json!(reasoning);
|
||||
}
|
||||
|
||||
// For assistant messages with tool_calls, content can be null
|
||||
// For assistant messages with tool_calls, content can be empty string
|
||||
if let Some(tool_calls) = &m.tool_calls {
|
||||
// Sanitize tool call IDs for OpenAI compatibility (max 40 chars)
|
||||
let sanitized_calls: Vec<_> = tool_calls.iter().map(|tc| {
|
||||
@@ -177,7 +177,7 @@ pub async fn messages_to_openai_json_text_only(
|
||||
}).collect();
|
||||
|
||||
if parts.is_empty() {
|
||||
msg["content"] = serde_json::Value::Null;
|
||||
msg["content"] = serde_json::json!("");
|
||||
} else {
|
||||
msg["content"] = serde_json::json!(parts);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user