opencode-token-min plugin overview: context trimming pipeline, honest Context sidebar, 80-99% savings goal

opencode-token-min: a plugin that stops long AI sessions from re-billing your whole conversation

Most of the cost of a long interactive AI session is not the model. It is your
own conversation being re-invoiced on every single step.

Every step in a chat re-sends the full context — system prompt, every history
message, every tool dump — even if only the last exchange changed. A 20-step
task with 50,000 tokens of context isn’t 50,000 tokens; by the end it is
roughly a million. That is the bill you actually watch climb while you work.

opencode-token-min is a plugin for opencode that stops
it. One hook, one ledger, one honest sidebar box — and the goal of cutting the
re-sent-context cost by 80–99% per task. Published on npm.

What it does

opencode exposes an experimental.chat.messages.transform hook that runs
before every model call. The plugin uses it to rewrite the context before it
shipps:

  • Trim per-role budgets — only so much history survives as a tail, and the
    instructions always stay.
  • Digest oversized tool outputs into short summaries, so the tail of the
    conversation stays useful instead of just small.
  • Cache-aware — while the session’s cache state is unknown, budgets are
    loosened so trimming can never silently break a warm prompt cache.

The default auto mode trims and digests from day one. Prefer to measure
first? Set MODE = "watch" — it only records savings numbers without touching
a single token. Sessions that confirm an active cache widen the budgets
(cached) instead of forcing a rewrite:

MODE        what happens
------      -------------------------------
auto        trim + digest every step (default)
watch       measure only, nothing is touched
cached      trims, widens budgets unconditionally

A per-task ledger records one row per step:

{"ts":"2026-09-18T17:00:00Z","sessionID":"s_ab3…","taskID":"msg_u4…",
 "model":"provider/model","cost":0.0004,
 "tokens":{"input":8460,"output":1300,"reasoning":900,
           "cacheRead":4200,"cacheWrite":0,"estSaved":175000,
           "beforeTok":178000,"afterTok":3000}}

Every row is tagged with the originating user message (taskID), so “how much
did that last task cost and save” is a real number — not a blurry lifetime
ballpark.

What you see

A TUI plugin turns that ledger into a Context box in the sidebar:

Context
8,460 tokens
7% used
$1.23 spent
~3,063,221 tokens saved
81% saved
~622,254 tokens saved · last task
93% saved

Tokens, % used and $ spent reflect the last step as the API reports them. The
rest comes from the ledger, summed per originating task. The two rows that
matter mid-session: how much the whole session has saved, and how much your
most recent attempt
just saved.

Why these numbers are honest: input / output / reasoning / cacheRead
and $ are provider-truth, copied verbatim from the step-finish report — the
same figures an invoice would use. Only the saved lines are an estimate
(chars ÷ 4, conservative, floored at 0), because there is no invoice for the
tokens you didn’t re-send. That part is for watching the trend, not for
accounting.

Why 80–99%?

That is the target from the LLM token-optimization playbook: re-cut what you
re-send until “costs stay flat” is a habit, not a shock. History re-billing is
the largest single lever, and the plugin makes the effect visible — and
enforceable — without a billing panel.

Where the untrimmed case shipped ~178k tokens per step, the trimmed case sends
~3k, so the ledger logs ~175k saved per step — a ~98% cut.

Real sessions (GLM-5.3, auto mode, names kept out of it)

Two long-running sessions this week, straight from the ledger (provider
billing numbers, not estimates), names and plan details kept out. One session
started on a local non-billable model before being switched back to GLM; those
rows are excluded, so the table counts GLM steps only. Both ran from an
afternoon into the next day.

Session Timeframe (UTC) GLM steps GLM cost input sent cache-read est. tokens saved est. $ saved* % saved†
Private site + API + apps build Sep 20–21, 16:06–17:11 3,022 $92.17 52.5M 49.1M 1,511.4M $435.82 ~97.5%
App modernisation session Sep 20–21, 18:09–17:11 945 $27.54 15.8M 14.1M 416.5M $101.84 ~96.5%
Both combined 48.1 h total‡ 3,967 $119.71 68.3M 63.2M 1,927.9M $537.66 ~97.3%

*est. $ saved = est. saved tokens × that session’s fitted GLM cache-read rate
(~$0.29/M and ~$0.25/M) — the cheapest possible re-send, so the figures are
conservative. At each session’s actual blended billed rate (~$0.90/M) the same
tokens are ~$1,363 and ~$380; at full input price (~$1.43/M), ~$2,161 and
~$603.

†% saved = ΣestSaved ÷ ΣbeforeTok, zero-trim rows included, so this is
conservative.
Combined, the sessions billed ~132M effective tokens (input +
cache-read) while the same steps would have re-sent ~1,982M context tokens —
~97% of the re-sent context never reached the API, and the
context that did ship was only ~54M tokens.

‡Sum of each session’s elapsed span — the two ran partly in parallel and
include idle time, so the per-hour rates below are diluted (conservative).

Scaled to a full-time agent

Take those two sessions — 48 h of session time combined, $119.71 billed,
~$538–2,763 of context not re-sent — and run them like a job: 8-hour day,
7-day week, 4-week month, 12-month year. That’s 2,688 hours, about 29% more
than a standard 40-h-week year (2,080 h). Linear extrapolation from two real
sessions (elapsed spans include idle time), so treat it as the shape of the
number, not a quote:

Period Hours Billed with token-min $ saved (floor*) $ saved (blended) $ saved (full input)
One day (8 h) 8 $20 $89 $290 $460
One week (7 days) 56 $139 $626 $2,029 $3,217
One month (4 weeks) 224 $557 $2,503 $8,115 $12,866
One year (12 months) 2,688 ~$6,700 ~$30,000 ~$97,000 ~$154,000

*Floor / blended / full input reuse the per-session rates from the table
above: the trimmed context priced at each session’s fitted cache-read
(~$0.25–0.29/M), at the sessions’ actual blended billed rate (~$0.90/M), and at
full input price (~$1.43/M) — the cheapest, the likely, and the no-cache worst
case. Savings scale with context weight: tool-heavy agentic sessions like these
trim the most; chat-shaped sessions save less. The honest year-end comparison:
~$6.7k billed with token-min against ~$30k–154k of context that was never
re-sent.

Install

Published on npm, install in one line:

opencode plugin opencode-token-min --global

Prefer not to use the plugin manager? Same files, by hand:

mkdir -p ~/.config/opencode/plugins ~/.config/opencode/tui
cp plugins/token-min.ts   ~/.config/opencode/plugins/
cp tui/token-min.tsx      ~/.config/opencode/tui/

Restart opencode, or /tui --dev to hot-reload the sidebar. Zero config,
conservative defaults.

Note: if you pin a specific version (e.g. opencode plugin
[email protected] --global
) and later want the newest, the npm cache
keeps what you installed — install the exact new version, or clear
~/.cache/opencode/packages/opencode-token-min* first.

Caveats

  • Savings are estimates (a chars→tokens heuristic plus a tool-digest
    heuristic), for watching the trend — not invoicing. Usage and $ are
    provider-truth.
  • watch mode proves the numbers before it ever touches a token.
  • Cache safety is measured, not guaranteed — the plugin errs on the side of
    smaller context, which is never wrong on cost.

Built by Big Pickle, directed by the boss (Tommy Miland). This post was
written with AI assistance. Repo:
tmiland-lab/opencode-token-min.

Share and Enjoy !

Shares

Comments (via GitHub)