oc_chat
Loading...
Searching...
No Matches
providers.openai_compat.usage Namespace Reference

Functions

dict _as_dict (Any value)
int _as_int (Any value)
UsageStats normalise_usage (Any usage)

Detailed Description

Usage-block normalisation across the OpenAI-compatible dialect variants.

Purpose
-------
:func:`normalise_usage` folds the ``usage`` block every lane returns into
one :class:`UsageStats`. The lanes all claim the OpenAI chat-completions
dialect, but they differ in which optional sub-blocks they populate:
Groq and Cerebras report ``completion_tokens_details.reasoning_tokens``;
OpenRouter adds a top-level ``cost`` (USD, ignored here — pricing is
``oc_pricing``'s job) and may report ``prompt_tokens_details``; Bitdeer
and NVIDIA NIM report neither and leave the optional blocks absent.

Responsibilities
----------------
- :func:`normalise_usage` — total, defensive dict → :class:`UsageStats`.
- :func:`_as_dict` — coerce a pydantic sub-block (or anything else) to a
  plain dict so ``isinstance(x, dict)`` checks in callers hold.
- :func:`_as_int` — coerce a reported count to a non-negative int.

Diagnostics
-----------
Domain: OC_CHAT.CLIENT
Levels:
    L2 — lifecycle events
    L3 — semantic details
    L4 — deep tracing

Contracts
---------
- Total: any input — ``None``, a non-dict, a partial block, a block with
  string counts — yields a :class:`UsageStats` rather than raising. A
  usage block is telemetry; a malformed one must never abort a turn.
- Absent fields normalise to 0, which callers read as "no data" (the
  contract's own zero-hit-zero-miss convention).
- ``total_tokens`` is derived as prompt+completion ONLY when the lane did
  not report it; a reported total is never overwritten.
- ``cache_hit_tokens`` comes from ``prompt_tokens_details.cached_tokens``
  (the OpenAI-standard prefix-cache field). The miss side is the reported
  prompt total minus the hit, floored at 0 — never negative on a lane
  that reports a cached count larger than its own prompt count.
- Money is NOT parsed here. ``usage.cost`` (OpenRouter/Vercel) is
  deliberately dropped: plan 202's fail-closed pricing path owns cost,
  and a provider-asserted figure entering by this door would bypass it.

Dependencies
------------
- oc_diagnostics (structured debug logging via _dbg)
- option_c_agent_contracts (UsageStats)

Function Documentation

◆ _as_dict()

dict providers.openai_compat.usage._as_dict ( Any value)
protected
Return *value* as a plain dict, or ``{}`` when it is not dict-like.

Definition at line 66 of file usage.py.

Here is the caller graph for this function:

◆ _as_int()

int providers.openai_compat.usage._as_int ( Any value)
protected
Return *value* as a non-negative int, or 0 when it is not a count.

Definition at line 76 of file usage.py.

Here is the caller graph for this function:

◆ normalise_usage()

UsageStats providers.openai_compat.usage.normalise_usage ( Any usage)
Fold a lane's ``usage`` block into :class:`UsageStats`.

Handles the dialect variants named in the module docstring; unknown
extra keys are ignored, so a lane that grows a field does not break
this parser.

Definition at line 91 of file usage.py.

Here is the call graph for this function: