Skip to content

Bedrock GPT-5.6: usage total counts cached input twice, so auto-compaction fires after every message #47296

Description

@joaomj

On amazon-bedrock/us.openai.gpt-5.6-luna, auto-compaction runs after almost every message. A ~150k prompt is recorded as ~300k, because Bedrock's usage total for this model counts the cached input tokens a second time. isOverflow trusts that total, so the session compacts, drops to ~40k, climbs back over the threshold in three or four tool calls, and compacts again. 9 compactions in 18 minutes in one session. Anthropic models on the same provider and same session are unaffected.

Stored usage for one turn (message.data in opencode.db):

total: 303459   input: 151411   output: 639
cache: { read: 132976, write: 18433 }

input is the non-cached remainder, so the value Bedrock reported was 151411 + 132976 + 18433 = 302820, which is exactly twice 151410. Cache read plus cache write is the other half. Across consecutive turns each cache.read equals the previous turn's stored input (106736 follows an input of 106738), which only holds if the real prompt is the ~151k figure and the cache was added on top of it a second time.

Effect on the threshold: overflow.usable gives limit.input - min(20_000, output cap) = 180000 for a declared 200k window. isOverflow prefers tokens.total, and ProviderShared.totalTokens passes the provider total straight through, so 303459 is compared against 180000 while the true prompt is ~152k. Every turn overflows.

Anthropic models do not trip it: input stays at 2 with cache.read at 170k on Opus in the same session, and the total stays truthful.

Possibly the same class of problem as #45368 (compaction re-triggering per step), but that one was an output-limit fallback, not the usage total. I have not tested us.openai.gpt-5.6-sol.

Workaround: declare a doubled window (limit.context and limit.input at 400000) so the inflated total lands near the real ceiling.

Steps to reproduce

  1. Configure amazon-bedrock/us.openai.gpt-5.6-luna with limit: { context: 200000, input: 200000, output: 64000 } and compaction: { auto: true }.
  2. Run a session with a large system prompt and a few tool calls that return several thousand tokens each, until the prompt passes ~90k.
  3. Every subsequent message triggers compaction. Confirm in ~/.local/share/opencode/opencode.db: select json_extract(data,'$.tokens') from message where session_id = '<id>' shows total at roughly twice input + output + cache.read + cache.write minus the cache, and summary messages between every turn.

Expected

The recorded total reflects the real prompt size, so compaction fires when the context is genuinely near the window.

OpenCode version

1.18.27

Operating System

Linux 7.0.0-29-generic (x64)

Terminal

Zed 1.15.1

Activity

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

Metadata

Metadata

Assignees

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