mirror of
https://github.com/hwchase17/langchain.git
synced 2026-06-09 10:17:00 +00:00
fix(openai,groq,openrouter): use is-not-None checks in usage metadata token extraction (#36500)
Python's `or` operator treats `0` as falsy, so
`token_usage.get("total_tokens") or fallback` silently replaces a
provider-reported `total_tokens=0` with the computed sum of input +
output tokens. Providers can legitimately report zero tokens (e.g.,
cached responses, empty completions).
The same pattern exists in the dual-key lookups for
`input_tokens`/`output_tokens` in Groq and OpenRouter. While current
APIs don't return both key formats simultaneously (making the `or`-chain
functionally correct today), the semantics are still wrong; `0` should
not fall through to a fallback.
## Changes
- Replace `x.get(key) or fallback` with explicit `is not None` checks in
`_create_usage_metadata` across `langchain-openai`, `langchain-groq`,
and `langchain-openrouter` for `input_tokens`, `output_tokens`, and
`total_tokens`
- Fix a concrete bug in the `total_tokens` path: a provider-reported `0`
was silently replaced by the computed sum
- Harden dual-key lookups in Groq and OpenRouter to correctly preserve
zero values from the preferred key, should both key formats ever coexist
- Update OpenAI's single-key extraction for consistency — the old `or 0`
pattern happened to produce correct results (`0 or 0 == 0`) but was
semantically wrong
This commit is contained in:
@@ -3837,9 +3837,12 @@ class OpenAIRefusalError(Exception):
|
||||
def _create_usage_metadata(
|
||||
oai_token_usage: dict, service_tier: str | None = None
|
||||
) -> UsageMetadata:
|
||||
input_tokens = oai_token_usage.get("prompt_tokens") or 0
|
||||
output_tokens = oai_token_usage.get("completion_tokens") or 0
|
||||
total_tokens = oai_token_usage.get("total_tokens") or input_tokens + output_tokens
|
||||
_input = oai_token_usage.get("prompt_tokens")
|
||||
input_tokens = _input if _input is not None else 0
|
||||
_output = oai_token_usage.get("completion_tokens")
|
||||
output_tokens = _output if _output is not None else 0
|
||||
_total = oai_token_usage.get("total_tokens")
|
||||
total_tokens = _total if _total is not None else input_tokens + output_tokens
|
||||
if service_tier not in {"priority", "flex"}:
|
||||
service_tier = None
|
||||
service_tier_prefix = f"{service_tier}_" if service_tier else ""
|
||||
|
||||
Reference in New Issue
Block a user