Skip to content

fix(inference): tolerate null token counts in streamed usage - #6596

Open
VihaanAgarwal wants to merge 1 commit into
livekit:mainfrom
VihaanAgarwal:fix/inference-null-usage-tokens
Open

fix(inference): tolerate null token counts in streamed usage#6596
VihaanAgarwal wants to merge 1 commit into
livekit:mainfrom
VihaanAgarwal:fix/inference-null-usage-tokens

Conversation

@VihaanAgarwal

Copy link
Copy Markdown

Fixes #6595

What breaks

On the OpenAI-compatible path (livekit.agents.inference.llm.LLMStream), a provider can send a final streaming chunk where usage is present but individual counts are null. We only guard on if chunk.usage is not None:, then pass the fields straight into CompletionUsage, where completion_tokens, prompt_tokens and total_tokens are all required int.

The pydantic ValidationError gets caught by the generic except Exception at the bottom of _run and re-raised as APIConnectionError(retryable=False). Because it's non-retryable it surfaces as an unrecoverable llm_error and terminates the AgentSession, so a malformed usage payload drops a live call.

The reporter hits this behind a proxy in front of a custom model that occasionally omits completion_tokens.

Fix

Coerce the three counts with or 0. That's what prompt_cached_tokens on the adjacent line already does, so this keeps the block internally consistent rather than introducing a new pattern. Complete payloads are unaffected.

Same shape as #5404, which fixed the other half of this (usage present but not reached).

Tests

tests/test_inference_llm_usage.py drives LLMStream with a fake OpenAI stream, so it needs no network or credentials:

  • a chunk with completion_tokens=None yields usage with 0 and does not raise
  • a chunk with prompt_tokens/total_tokens null is coerced the same way
  • a fully-populated chunk passes through untouched

The first two fail on main with APIConnectionError and pass with the change.

Full unit gate: 1175 passed, 4 skipped. make type-check, make lint and make format-check are clean. The 9 errors in the pytest summary are a pre-existing OTLP metrics-exporter teardown issue that reproduces identically on a clean checkout.

An OpenAI-compatible provider can send a final chunk where usage is
present but individual counts are null. CompletionUsage requires ints,
so the pydantic error was wrapped as a non-retryable APIConnectionError
and tore down the whole AgentSession mid-call.

Coerce the three counts to 0, matching what prompt_cached_tokens
already does on the adjacent line.
@VihaanAgarwal
VihaanAgarwal requested a review from a team as a code owner July 29, 2026 01:03
@CLAassistant

CLAassistant commented Jul 29, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CompletionUsage validation crashes session when provider returns usage.completion_tokens=None mid-stream (OpenAI-compatible path)

2 participants