Count reasoning, images and fixed overhead in the context estimate (dirge-qobx.1) - #840
Merged
Conversation
yogthos
force-pushed
the
fix/qobx-1-estimator
branch
from
September 2, 2026 08:51
487be96 to
22b8ad0
Compare
…irge-qobx.1) The fold trigger reads the provider's prompt count; the fold's own accounting read chars/4 over messages, counting only text blocks and tool-call arguments. Three things that ship with every request counted zero: replayed reasoning (echoed back for every provider but OpenAI, never stripped), images (a reference in the transcript, ~1.5k tokens on the wire), and the system prompt plus tool schemas, which are not in messages at all. A request the provider charged 82% of the window for read as 25% at the turn-start tier, so the 0.90 fold never fired, and a fold could report 63800 -> 63479 on a 204,320-token request. block_chars now prices thinking text and images. The fixed overhead is re-derived after each response as prompt_total - estimate(messages sent) and added back at the two pre-send tiers that compare an estimate against ctx_max. Also dirge-qobx.6: on Anthropic input_tokens is the uncached remainder, not the prompt, so a warm cache left every tier under-reading by the cached prefix. TokenUsage::prompt_total normalizes the two provider conventions and every decision site reads it; the session gauge follows the same convention so it keeps describing the fold it warns about.
yogthos
force-pushed
the
fix/qobx-1-estimator
branch
from
September 2, 2026 08:56
22b8ad0 to
c2d9fde
Compare
yogthos
pushed a commit
that referenced
this pull request
Sep 2, 2026
dirge-qobx and children .1-.6, all closed by #840-#843. Plus dirge-57hu: CI runs nextest with no timeout, so the looping test those PRs surfaced held ten runners for 5h29m instead of failing. Also gitignores .beads/.auto-import-issues.jsonl, a per-machine staging marker that has been showing up untracked.
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.
The fold trigger reads the provider's prompt count. The fold's own accounting read
chars / 4overmessages, counting only text blocks and tool-call arguments. Three things that ship with every request counted zero:thinkingblock is echoed back inside the assistant turn for every provider except OpenAI (provider_rejects_reasoning_echo), and nothing ever strips a stale one. On a long reasoning-heavy run it is the largest single term in the prompt.compact_schema), and not inmessagesat all.So a request the provider charged 82% of the window for read as 25% at the turn-start tier: the 0.90 fold never fired on anything, the 0.60 result-cap tier tightened late, and a fold could report
context compacted: 63800 → 63479against a 204,320-token request — which is what a live run did, one turn before stopping mid-task.block_charspricesthinkingtext andimageblocks (IMAGE_TOKENS_ESTIMATE, a flat 1.5k — the transcript records no dimensions).prompt_total − estimate(messages we sent)and added back at the two pre-send tiers. Last observed, not a running maximum: the tool surface changes with/model, an MCP server connecting, or a prompt-layer swap.Also dirge-qobx.6, because the derivation above depends on it: on Anthropic
input_tokensis the uncached remainder, not the prompt (TokenUsage's own doc says so). With a warm prompt cache every tier under-read the prompt by the entire cached prefix — no fold at 0.75, none at 0.78, no exit-with-summary at 0.80, and the first sign of trouble was the provider refusing the request.TokenUsage::prompt_totalnormalizes the two conventions, every decision site reads it, andSession::record_token_usagefollows the same convention so the gauge keeps describing the fold it warns about.Follow-ups in the epic (dirge-qobx): strip stale reasoning at the provider boundary (qobx.2), stop ending the run on a prune-only fold (qobx.3), fold when an autonomous stretch has no user turn (qobx.4), log the silent skip (qobx.5).