mirror of
https://github.com/Xe138/AI-Trader.git
synced 2026-04-01 17:17:24 -04:00
fix: handle invalid_tool_calls args normalization for DeepSeek
Extended ToolCallArgsParsingWrapper to handle both tool_calls and invalid_tool_calls args formatting inconsistencies from DeepSeek: - tool_calls.args: string -> dict (for successful calls) - invalid_tool_calls.args: dict -> string (for failed calls) The wrapper now normalizes both types before AIMessage construction, preventing Pydantic validation errors in both success and error cases. Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
## [0.4.1] - 2025-11-05
|
||||
|
||||
### Fixed
|
||||
- Fixed Pydantic validation error for tool_calls when using DeepSeek and other AI providers that return `args` as JSON strings instead of dictionaries. Added `ToolCallArgsParsingWrapper` that monkey-patches ChatOpenAI's `_create_chat_result` method to parse string arguments before AIMessage construction.
|
||||
- Fixed Pydantic validation errors for both `tool_calls` and `invalid_tool_calls` when using DeepSeek and other AI providers:
|
||||
- `tool_calls.args`: Converts JSON strings to dictionaries (for successful tool calls)
|
||||
- `invalid_tool_calls.args`: Converts dictionaries to JSON strings (for failed tool calls)
|
||||
- Added `ToolCallArgsParsingWrapper` that monkey-patches ChatOpenAI's `_create_chat_result` method to normalize arguments before AIMessage construction.
|
||||
|
||||
## [0.4.0] - 2025-11-05
|
||||
|
||||
|
||||
@@ -50,10 +50,14 @@ class ToolCallArgsParsingWrapper:
|
||||
|
||||
if 'choices' in response_dict:
|
||||
for choice in response_dict['choices']:
|
||||
if 'message' in choice and 'tool_calls' in choice['message']:
|
||||
tool_calls = choice['message']['tool_calls']
|
||||
if tool_calls:
|
||||
for tool_call in tool_calls:
|
||||
if 'message' not in choice:
|
||||
continue
|
||||
|
||||
message = choice['message']
|
||||
|
||||
# Fix regular tool_calls: string args -> dict
|
||||
if 'tool_calls' in message and message['tool_calls']:
|
||||
for tool_call in message['tool_calls']:
|
||||
if 'function' in tool_call and 'arguments' in tool_call['function']:
|
||||
args = tool_call['function']['arguments']
|
||||
# Parse string arguments to dict
|
||||
@@ -64,6 +68,19 @@ class ToolCallArgsParsingWrapper:
|
||||
# Keep as string if parsing fails
|
||||
pass
|
||||
|
||||
# Fix invalid_tool_calls: dict args -> string
|
||||
if 'invalid_tool_calls' in message and message['invalid_tool_calls']:
|
||||
for invalid_call in message['invalid_tool_calls']:
|
||||
if 'args' in invalid_call:
|
||||
args = invalid_call['args']
|
||||
# Convert dict arguments to JSON string
|
||||
if isinstance(args, dict):
|
||||
try:
|
||||
invalid_call['args'] = json.dumps(args)
|
||||
except (TypeError, ValueError):
|
||||
# Keep as-is if serialization fails
|
||||
pass
|
||||
|
||||
# Call original method with fixed response
|
||||
return original_create_chat_result(response_dict, generation_info)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user