Removed all argument conversion code to see what DeepSeek actually returns.
This will help identify if the problem is with our conversion or with the
original API response format.
Phase 1 continued - gathering evidence about original response structure.
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added detailed logging to patched_create_chat_result to investigate why
invalid_tool_calls.args conversion is not working. This will show:
- Response structure and keys
- Whether invalid_tool_calls exists
- Type and value of args before/after conversion
- Whether conversion is actually executing
This is Phase 1 (Root Cause Investigation) of systematic debugging.
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
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>
Added ToolCallArgsParsingWrapper to handle AI providers (like DeepSeek)
that return tool_calls.args as JSON strings instead of dictionaries.
The wrapper monkey-patches ChatOpenAI's _create_chat_result method to
parse string arguments before AIMessage construction, preventing
Pydantic validation errors.
Changes:
- New: agent/chat_model_wrapper.py - Wrapper implementation
- Modified: agent/base_agent/base_agent.py - Wrap model during init
- Modified: CHANGELOG.md - Document fix as v0.4.1
- New: tests/unit/test_chat_model_wrapper.py - Unit tests
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>