fix(cli): preserve output budget for encrypted reasoning - #13349
Merged
Conversation
Contributor
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (4 files)
Reviewed by grok-4.6 · Input: 67.3K · Output: 7.2K · Cached: 489.3K Review guidance: REVIEW.md from base branch |
marius-kilocode
enabled auto-merge
August 24, 2026 09:16
WebReflection
approved these changes
Aug 24, 2026
WebReflection
left a comment
Contributor
There was a problem hiding this comment.
Curious to learn where "[opaque reasoning state]" strings comes from (I imagine cloud) but this looks good to me.
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Long-running Luna sessions sometimes sent a much smaller
max_output_tokensvalue than the configured 32,000-token cap. Luna then consumed the entire reduced budget in reasoning and returned no actionable assistant output.The reduced values were not random gateway behavior. They were calculated by the CLI before the request was sent.
Investigation Findings
The affected requests used
openai/gpt-5.6-lunathrough the Kilo Gateway. The live model metadata reported:maxThe CLI's output budget calculation is:
The old normalized estimate serialized the entire message history. It excluded encoded media, but treated provider continuation metadata as ordinary text. In particular, OpenAI's
reasoningEncryptedContentwas counted according to its encoded character length.That value is opaque reasoning continuation state. Its serialized byte length is not equivalent to the provider's tokenized context length. In the affected sessions, the ciphertext was large enough to inflate the local estimate to approximately 1.04 million tokens.
The provider-reported context was lower, but the old implementation intentionally selected the larger value with
Math.max. Therefore, the inflated local estimate overrode the accurate provider usage.Incident Evidence
The five explicit output-limit cases identified in the local response and request records were:
2026-08-21_08-26-29.071841+00_7361789response.incomplete,max_output_tokens2026-08-21_10-18-49.896391+00_7365221response.incomplete,max_output_tokens2026-08-21_10-26-34.680182+00_7365690response.incomplete,max_output_tokens2026-08-21_14-04-09.383612+00_7385561response.incomplete,max_output_tokens2026-08-21_14-19-32.427317+00_7386101response.incomplete,max_output_tokensThe corresponding request records explicitly contained the reduced caps. The last two request records have identical hashes. The second request was a retry after a client-side stream timeout, not an independent cap decision.
The old client estimates can be inferred directly from the sent caps:
These values exactly satisfy the CLI formula. The gateway did not need to rewrite the cap to produce the observed behavior.
Ciphertext Contribution
The affected histories contained large encrypted reasoning values:
The encrypted values were the decisive source of the estimate inflation. Replacing them with a fixed marker reduces their contribution to a small structural metadata cost while preserving the visible reasoning text, tool arguments, tool results, and ordinary message content.
Before And After Reproduction
Using the same Luna context limit, provider usage, and an incident-shaped reasoning continuation value:
The provider-reported context for this reproduction was 490,972 tokens. Before the fix, the inflated local estimate won the
Math.maxcomparison. After the fix, the normalized estimate no longer includes the ciphertext size, so the provider-reported context remains the relevant baseline and the configured 32,000-token output budget is retained.The raw estimate remains intentionally available for diagnostics. It represents serialized payload size, not a token estimate suitable for output budgeting.
Root Cause
The root cause was a mismatch between serialized request size and provider token usage:
Math.max(reported, estimated)selected the inflated estimate over the provider-reported context.max_output_tokensvalue between 1,822 and 8,854.reasoning.effort: "max"consumed the reduced budget in reasoning before producing an actionable response.Max reasoning effort made the failure visible because reasoning tokens are included in the output budget. It did not cause the reduced cap.
Implementation
The estimator now replaces
reasoningEncryptedContentwith a fixed opaque-state marker for normalized token accounting. This matches the existing treatment of encoded media:providerMetadataand legacyproviderOptionsmessage shapes are covered.The output-cap documentation now explicitly describes both excluded categories.
Scope And Limitations
This change fixes the identified Luna failure mode. It does not make character-based estimates equivalent to provider tokenization for all possible providers. Genuine large visible context, oversized tool schemas, media input, or incorrect model metadata can still require a lower output cap.
The live Luna catalog does not expose a separate input-token limit. The CLI therefore continues to use the model context window and provider-reported usage for this calculation. Adding an input limit would require upstream catalog metadata and separate handling; it is not part of this focused fix.
Release Note
The CLI changeset prevents encrypted reasoning state from incorrectly reducing the output token budget in long-running sessions.