mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-13 23:11:40 +00:00
refactor(anthropic): validate output_tokens_details with a pydantic model
This commit is contained in:
parent
bed5ab45c8
commit
0809e226df
3 changed files with 13 additions and 4 deletions
|
|
@ -5,6 +5,7 @@ from collections.abc import Mapping
|
|||
from typing import TYPE_CHECKING, Any, Final, NoReturn, cast
|
||||
|
||||
import httpx
|
||||
from pydantic import ValidationError
|
||||
|
||||
import litellm
|
||||
from litellm.constants import (
|
||||
|
|
@ -39,6 +40,7 @@ from litellm.types.llms.anthropic import (
|
|||
AnthropicMessagesTool,
|
||||
AnthropicMessagesToolChoice,
|
||||
AnthropicOutputSchema,
|
||||
AnthropicOutputTokensDetails,
|
||||
AnthropicSystemMessageContent,
|
||||
AnthropicThinkingParam,
|
||||
AnthropicWebSearchTool,
|
||||
|
|
@ -2129,10 +2131,11 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig):
|
|||
details: Final = usage_object.get("output_tokens_details")
|
||||
if not isinstance(details, Mapping):
|
||||
return None
|
||||
thinking_tokens: Final = cast(Mapping[str, object], details).get("thinking_tokens")
|
||||
if isinstance(thinking_tokens, bool) or not isinstance(thinking_tokens, (int, float)):
|
||||
try:
|
||||
parsed_details: Final = AnthropicOutputTokensDetails.model_validate(details)
|
||||
except ValidationError:
|
||||
return None
|
||||
return int(thinking_tokens)
|
||||
return parsed_details.thinking_tokens
|
||||
|
||||
def calculate_usage(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -609,6 +609,12 @@ class AnthropicResponseUsageBlock(BaseModel):
|
|||
output_tokens: int
|
||||
|
||||
|
||||
class AnthropicOutputTokensDetails(BaseModel):
|
||||
model_config = ConfigDict(extra="allow", strict=True)
|
||||
|
||||
thinking_tokens: int | None = None
|
||||
|
||||
|
||||
AnthropicFinishReason = Literal["end_turn", "max_tokens", "stop_sequence", "tool_use"]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2477,7 +2477,7 @@ def test_calculate_usage_reported_thinking_tokens_override_text_estimate():
|
|||
|
||||
@pytest.mark.parametrize(
|
||||
"output_tokens_details",
|
||||
[None, {}, {"thinking_tokens": None}],
|
||||
[None, {}, {"thinking_tokens": None}, {"thinking_tokens": "180"}, {"thinking_tokens": True}],
|
||||
)
|
||||
def test_calculate_usage_falls_back_to_estimate_without_reported_thinking_tokens(output_tokens_details):
|
||||
"""Older responses have no thinking_tokens, so the visible-text estimate must still apply."""
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue