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
71 lines
2.6 KiB
Python
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
|