fix: handle dict type for server_tool_use in Usage model

Fix Pydantic serialization warning when API responses contain
server_tool_use as a dict instead of ServerToolUse object.

Some API providers (e.g., NEXUS, custom Anthropic-compatible endpoints)
return server_tool_use as a plain dict with fields like:
{
  "web_search_requests": 0,
  "tool_search_requests": null
}

This caused Pydantic serialization warnings:
  PydanticSerializationUnexpectedValue(Expected `ServerToolUse` -
  serialized value may not be as expected)

Changes:
- Modified Usage.__init__ to accept Union[ServerToolUse, dict] for server_tool_use
- Added conversion logic to transform dict to ServerToolUse object
- Follows same pattern as prompt_tokens_details and completion_tokens_details

This maintains backward compatibility while supporting API responses
that return dict format for server_tool_use field.
This commit is contained in:
chris258-123 2026-02-10 02:26:15 +08:00
parent 9bb7f18795
commit 270220dac9

View file

@ -1428,7 +1428,7 @@ class Usage(SafeAttributeModel, CompletionUsage):
completion_tokens_details: Optional[
Union[CompletionTokensDetailsWrapper, dict]
] = None,
server_tool_use: Optional[ServerToolUse] = None,
server_tool_use: Optional[Union[ServerToolUse, dict]] = None,
cost: Optional[float] = None,
**params,
):
@ -1521,6 +1521,14 @@ class Usage(SafeAttributeModel, CompletionUsage):
"cache_creation_input_tokens"
]
# Handle server_tool_use - convert dict to ServerToolUse object if needed
_server_tool_use: Optional[ServerToolUse] = None
if server_tool_use is not None:
if isinstance(server_tool_use, dict):
_server_tool_use = ServerToolUse(**server_tool_use)
elif isinstance(server_tool_use, ServerToolUse):
_server_tool_use = server_tool_use
super().__init__(
prompt_tokens=prompt_tokens or 0,
completion_tokens=completion_tokens or 0,
@ -1529,8 +1537,8 @@ class Usage(SafeAttributeModel, CompletionUsage):
prompt_tokens_details=_prompt_tokens_details or None,
)
if server_tool_use is not None:
self.server_tool_use = server_tool_use
if _server_tool_use is not None:
self.server_tool_use = _server_tool_use
else: # maintain openai compatibility in usage object if possible
del self.server_tool_use