Skip to content

bug: call_model_stream_raw never requests stream_options.include_usage; cost tracking silent in production #118

Description

@rdwj

Summary

LLMClient.call_model_stream_raw in fipsagents.baseagent.llm does not set stream_options={\"include_usage\": True} when issuing streaming chat completions. vLLM (and other OpenAI-compat servers) only emit a usage chunk on streaming responses when this flag is explicitly opted into. Without the flag, StreamMetrics.prompt_tokens / completion_tokens stay None for the entire stream, and OpenAIChatServer._persist_cost_data (added in #117 / #116) returns early — meaning cost tracking is a no-op in real deployments.

The unit tests in tests/test_server_openai.py synthesise StreamMetrics with populated prompt_tokens / completion_tokens, so they exercise the persistence path correctly but bypass the gap in the LLM client.

Reproduction

Cluster smoke against fipsagents 0.14.0 + fipsagents-platform 0.2.0, gpt-oss-20b on RHPDS:

  1. POST two /v1/chat/completions with the same session_id.
  2. Both calls return content correctly; the response's usage block is {prompt_tokens: null, completion_tokens: null, total_tokens: null}.
  3. Inspect the platform's session row: messages populated (204 bytes), cost_data empty {}.

Direct curl against the same vLLM endpoint with stream_options.include_usage=true confirms the model happily emits a final usage chunk: {prompt_tokens:70, total_tokens:75, completion_tokens:5, prompt_tokens_details:{cached_tokens:64}}. The endpoint isn't broken — the client never asks.

Fix

In LLMClient.call_model_stream_raw, after call_kwargs[\"stream\"] = True:

call_kwargs.setdefault(\"stream_options\", {\"include_usage\": True})

setdefault so callers can opt out by passing stream_options={\"include_usage\": False} (or pass other stream options).

Tests

  • Regression: assert _client.chat.completions.create is called with stream_options={\"include_usage\": True} when streaming. Mock the OpenAI client; check the kwargs.
  • E2E coverage already exists for the persistence path; once the flag is forwarded, the existing usage-driven tests prove the loop closes.

Impact

  • Affects every fipsagents 0.14.0 deployment that depends on cost_data accumulation.
  • No data loss — sessions persistence is unaffected; only the cost accumulator is empty.
  • Patch-level fix: cut 0.14.1.

Related

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions