Skip to content

fix: report full prompt length in OpenAI usage - #729

Open
Javinator9889 wants to merge 3 commits into
ROCm:mainfrom
Javinator9889:fix/openai-usage-prompt-tokens
Open

Javinator9889 wants to merge 3 commits into
ROCm:mainfrom
Javinator9889:fix/openai-usage-prompt-tokens

Conversation

@Javinator9889

@Javinator9889 Javinator9889 commented Sep 17, 2026

Copy link
Copy Markdown

Motivation

In OpenCode and similar OpenAPI-compatible-endpoint applications, the current context usage is wrongly reported, as it just takes into account the newly evaluated suffix/prompt rather than the cumulative count of tokens in the context.

This causes these tools to fail at certain point, receiving an error message stating that "the context was cleared" with no time to react. Built-in tools such as context compression that specifically prevent this problem for happening never run, and the conversation is re-fed again by the third party tool to the FLM model, causing a subsequent context overflow, and that in a loop.

Technical Details

The prompt cache erases the matching prefix from tokens before prefill, so meta_info.prompt_tokens = tokens.size() recorded only the newly evaluated suffix. The first turn of a conversation has no cache and looked correct, but every later turn reused the whole history as a cached prefix and reported just the new message.

OpenAI defines usage.prompt_tokens as the entire input, with cached tokens counted inside it and broken out separately. Reporting the delta instead made the context appear to reset on every request, so clients that size the context from usage never learn how full it is -- an agent front-end deciding when to compact from that figure never compacts.

Add the erased prefix back into prompt_tokens, carry the cached count on chat_meta_info_t, and expose it as usage.prompt_tokens_details.cached_tokens on the OpenAI endpoints. prefill_speed_tps now divides by the tokens actually evaluated, so a cache hit no longer inflates it.

The Ollama-compatible prompt_eval_count is left reporting evaluated tokens only, matching upstream Ollama.

Test Plan

The testing is hard to automate as it requires a real model running on a real NPU and a third party tool (such as OpenCode) to be running to see lively how the context increases with every conversation exchange.

Test Result

Verified locally running OpenCode against Qwen3.5:9b, in a multi-turn conversation where the context was growing as new messages were exchanged

Submission Checklist

Closes #730

The prompt cache erases the matching prefix from `tokens` before prefill, so
`meta_info.prompt_tokens = tokens.size()` recorded only the newly evaluated
suffix. The first turn of a conversation has no cache and looked correct, but
every later turn reused the whole history as a cached prefix and reported just
the new message.

OpenAI defines usage.prompt_tokens as the entire input, with cached tokens
counted inside it and broken out separately. Reporting the delta instead made
the context appear to reset on every request, so clients that size the context
from usage never learn how full it is -- an agent front-end deciding when to
compact from that figure never compacts.

Add the erased prefix back into prompt_tokens, carry the cached count on
chat_meta_info_t, and expose it as usage.prompt_tokens_details.cached_tokens on
the OpenAI endpoints. prefill_speed_tps now divides by the tokens actually
evaluated, so a cache hit no longer inflates it.

The Ollama-compatible prompt_eval_count is left reporting evaluated tokens
only, matching upstream Ollama.
Two-turn check, streaming and non-streaming, that prompt_tokens counts
the cached prefix and cached_tokens reports it. Needs a live server.
@Javinator9889

Copy link
Copy Markdown
Author

Hey @zaneni6 this PR should be ready to be reviewed :)

Single-turn models reject conversation history, so the two-turn shape
does not apply. Detect the server's rejection and check the pinned
system prefix across two one-shot requests instead.
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.

[Issue]: usage.prompt_tokens on the OpenAI-compatible endpoints reports only the tokens prefilled on the current turn

1 participant