opencode/packages
Kit Langton d4ff331052 refactor(llm): inclusive total + non-overlapping breakdown for Usage
Final shape after considering ecosystem conventions:

  inputTokens             — inclusive total (matches AI SDK / OpenAI / LangChain)
  outputTokens            — inclusive total (includes reasoning)
  nonCachedInputTokens    — breakdown: fresh prompt
  cacheReadInputTokens    — breakdown: cache hit
  cacheWriteInputTokens   — breakdown: cache write
  reasoningTokens         — subset of outputTokens

Invariant:
  nonCached + cacheRead + cacheWrite = inputTokens
  reasoningTokens <= outputTokens

Why this shape:

- `inputTokens` keeps its AI-SDK / OpenAI semantics, so a reader from any
  major ecosystem sees the number they expect.
- The non-overlapping breakdown fields are populated alongside the
  inclusive totals — consumers read whichever they need without
  subtracting. This eliminates the underflow bug class (opencode#26620)
  structurally without diverging on naming.
- Aligns with the AI SDK v3 spec proposal (vercel/ai#9921), which adds
  exactly this kind of non-overlapping breakdown to address the active
  ecosystem bugs around cache token double-counting and underflow
  (pydantic-ai#4364, langfuse#12306/#11979, vercel/ai#8349,
  langchain#32818, langchainjs#10249).

Mappers:

- OpenAI Chat / Responses / Bedrock: provider reports inclusive totals
  natively; mapper derives `nonCachedInputTokens` via
  `ProviderShared.subtractTokens`.
- Gemini: `promptTokenCount` is inclusive; `candidatesTokenCount` is
  *exclusive* of `thoughtsTokenCount`, so mapper sums those to produce
  the inclusive `outputTokens`. Only computes the total when the visible
  component is reported (avoids fabricating an inclusive number from a
  partial breakdown).
- Anthropic: `input_tokens` is *non-cached* natively; mapper sums it with
  cache reads/writes to produce the inclusive `inputTokens`.
  `output_tokens` is inclusive (Anthropic doesn't break thinking out, so
  `reasoningTokens` stays undefined).

Added a `visibleOutputTokens` getter (clamped `outputTokens - reasoningTokens`)
as the one safe escape hatch for consumers wanting the non-reasoning view.

Added `ProviderShared.sumTokens` to derive an inclusive total from a
non-overlapping breakdown, returning `undefined` when every input is
undefined (so we don't fabricate a 0).
2026-05-10 20:39:22 -04:00
..
app sync release versions for v1.14.46 2026-05-10 02:34:36 +00:00
console zen: fix usage css on mobile 2026-05-10 12:14:11 -04:00
containers chore: bump Bun to 1.3.13 (#23791) 2026-04-23 00:25:36 -04:00
core sync release versions for v1.14.46 2026-05-10 02:34:36 +00:00
desktop sync release versions for v1.14.46 2026-05-10 02:34:36 +00:00
docs
enterprise sync release versions for v1.14.46 2026-05-10 02:34:36 +00:00
extensions/zed sync release versions for v1.14.46 2026-05-10 02:34:36 +00:00
function sync release versions for v1.14.46 2026-05-10 02:34:36 +00:00
http-recorder chore: generate 2026-05-10 16:44:40 +00:00
identity
llm refactor(llm): inclusive total + non-overlapping breakdown for Usage 2026-05-10 20:39:22 -04:00
opencode Use Effect timeout in compaction test (#26728) 2026-05-10 12:45:54 -04:00
plugin sync release versions for v1.14.46 2026-05-10 02:34:36 +00:00
script
sdk chore: generate 2026-05-10 16:22:29 +00:00
slack sync release versions for v1.14.46 2026-05-10 02:34:36 +00:00
storybook feat(prompt): add shell mode UI with cancel button, custom icon, and example placeholder (#24105) 2026-04-24 14:04:55 +08:00
ui sync release versions for v1.14.46 2026-05-10 02:34:36 +00:00
web Zen: add Ring 2.6 1T 2026-05-10 03:51:34 -04:00