Files
567-labs--instructor/instructor/v2/core/usage.py
T
wehub-resource-sync 97e91a83f3
Ruff / Ruff (push) Has been cancelled
Test / Core Tests (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.10) (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.11) (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.12) (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.13) (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.9) (push) Has been cancelled
Test / Full Coverage (Python 3.11) (push) Has been cancelled
Test / Core Provider Tests (OpenAI) (push) Has been cancelled
Test / Core Provider Tests (Anthropic) (push) Has been cancelled
Test / Core Provider Tests (Google) (push) Has been cancelled
Test / Core Provider Tests (Other) (push) Has been cancelled
Test / Anthropic Tests (push) Has been cancelled
Test / Gemini Tests (push) Has been cancelled
Test / Google GenAI Tests (push) Has been cancelled
Test / Vertex AI Tests (push) Has been cancelled
Test / OpenAI Tests (push) Has been cancelled
Test / Writer Tests (push) Has been cancelled
Test / Auto Client Tests (push) Has been cancelled
ty / type-check (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:36:38 +08:00

71 lines
2.6 KiB
Python

"""Usage accumulation helpers owned by the v2 runtime."""
from __future__ import annotations
import logging
from typing import TYPE_CHECKING, TypeVar
if TYPE_CHECKING:
from anthropic.types import Usage as AnthropicUsage
from openai.types import CompletionUsage as OpenAIUsage
logger = logging.getLogger("instructor")
T_Response = TypeVar("T_Response")
def update_total_usage(
response: T_Response | None,
total_usage: OpenAIUsage | AnthropicUsage,
) -> T_Response | None:
if response is None:
return None
from openai.types import CompletionUsage as _OpenAIUsage
response_usage = getattr(response, "usage", None)
if isinstance(response_usage, _OpenAIUsage) and isinstance(
total_usage, _OpenAIUsage
):
total_usage.completion_tokens += response_usage.completion_tokens or 0
total_usage.prompt_tokens += response_usage.prompt_tokens or 0
total_usage.total_tokens += response_usage.total_tokens or 0
if (rtd := response_usage.completion_tokens_details) and (
ttd := total_usage.completion_tokens_details
):
ttd.audio_tokens = (ttd.audio_tokens or 0) + (rtd.audio_tokens or 0)
ttd.reasoning_tokens = (ttd.reasoning_tokens or 0) + (
rtd.reasoning_tokens or 0
)
if (rpd := response_usage.prompt_tokens_details) and (
tpd := total_usage.prompt_tokens_details
):
tpd.audio_tokens = (tpd.audio_tokens or 0) + (rpd.audio_tokens or 0)
tpd.cached_tokens = (tpd.cached_tokens or 0) + (rpd.cached_tokens or 0)
response_usage.completion_tokens = total_usage.completion_tokens
response_usage.prompt_tokens = total_usage.prompt_tokens
response_usage.total_tokens = total_usage.total_tokens
response_usage.completion_tokens_details = (
total_usage.completion_tokens_details.model_copy(deep=True)
if total_usage.completion_tokens_details is not None
else None
)
response_usage.prompt_tokens_details = (
total_usage.prompt_tokens_details.model_copy(deep=True)
if total_usage.prompt_tokens_details is not None
else None
)
return response
try:
from instructor.v2.providers.anthropic.usage import (
update_total_usage as update_anthropic_total_usage,
)
if update_anthropic_total_usage(response_usage, total_usage):
return response
except ImportError:
pass
logger.debug("No compatible response.usage found, token usage not updated.")
return response