Thinking Meter
OpenCode TUI plugin: counts the turns cut off mid-thought, says whether the output cap or the context window did it, and shows what thinking costs per turn and after which tool.
0
141
近 7 天 141
33.2
生态多维模型
7 天前
2026-09-05
快速安装与配置
opencode.json写入当前项目的 opencode.json,只对这个仓库生效。
opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-thinking-meter@0.1.0"]
}写入 ~/.config/opencode/opencode.json,对所有项目生效。
~/.config/opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-thinking-meter@0.1.0"]
}若你要在本地改造这个插件,先装到项目里再从本地路径引用。
shell
pnpm add -D opencode-thinking-meterOpenCode 启动时会通过内嵌运行时自动加载 npm 依赖并缓存至本地目录,无需手动在全局环境执行安装。
When a local reasoning model stops mid-thought, opencode shows you nothing. The response just ends, short and useless, and the next turn starts. This plugin counts those turns, says which setting cut them — the per-response output cap, or the context window filling up — and shows what the thinking is costing per turn and after which tool.
It is not another token panel. Half a dozen plugins already show tokens, cost, cache hit rate and TPS in the sidebar, and one of them (@mtayfur/opencode-cache-view) even estimates reasoning tokens. None of them look at finish reasons, which is where the expensive failure hides.
On my own sessions, over three that had any cutoffs at all: 21 responses finished on length, 18 of them with the model still thinking, and those turns account for a quarter of every output token generated. That is what this measures.
What you see
Under the sidebar's Context block, headerless, so it reads as three more lines of it:
Context
14,231 tokens
34% used
$0.00 spent
11 cut off · 77k lost
10 mid-thought · cap 7 · wall 4
think 39s · ~2.1k per turn
room 1.8k · turns want ~2.1k
The last line is the useful one, and it only appears when it is a problem: the room left for a response, against what a turn of thinking has actually been taking. The prompt gets longer every turn, so that number only falls — it tells you a cutoff is coming before it happens.
Prompt row, right side: cut 11 · 77k, or ✂11 under 80 columns. A toast fires when a cutoff happens live, naming the cause.
/thinking opens the whole picture:
cut off 11 turns · 10 mid-thought
cause output cap 7 · context wall 4
lost 76,598 tokens · 19m
thinking 45m over 69 turns · ~2,117 tokens each
after prompt 42× · 41s · ~2.3k each
after read 14× · 52s · ~2.7k each
after edit 8× · 5s · ~243 each
after bash 2× · 47s · ~2.7k each
after grep 2× · 1s · ~33 each
after write 1× · 1m · ~5.6k each
room left 15,002 of 33k (observed)
a turn wants ~2,066 tokens of it
Thinking is attributed to whatever the model had just seen — your prompt, or the result of a specific tool. Reads costing more thought than edits is the sort of thing you can act on; a single global average is not.
The two causes
Both make a response end with finish: "length", and they want opposite fixes:
- output cap — the response hit the per-response token limit. The generation stops at a round number (
8192,16384). Fix it by raisinglimit.outputfor the model, ornum_predicton the ollama side. - context wall — prompt and response together filled the window, so the real cap was whatever the prompt left over. Total tokens land on a 4k boundary rather than on a round output number, and the cap shrinks every turn as the prompt grows. Fix it by compacting sooner, pruning harder, or raising
num_ctx.
The second is the one worth knowing about, and it is invisible over ollama's OpenAI-compatible route: num_ctx is not a concept in that API, so the value in your opencode config never reaches the server and the catalog's context number is fiction. This plugin learns the real window by watching where responses actually die, and says (observed) when it is using that instead of the catalog.
Counting thinking without reasoning tokens
tokens.reasoning was zero on every one of the 331 assistant messages I checked. That is not a bug: Anthropic folds extended thinking into output_tokens and reports no separate count (opencode's own packages/llm/src/schema/events.ts documents it), and llama.cpp and ollama report none either.
So thinking is measured in seconds (from each reasoning part's own start and end times, always available) and in characters at 4 per token, and the estimate is only used when the provider is silent — if a provider does report reasoning tokens, that number wins and the parts are scaled to it.
Cost in dollars appears in the report only when the model has a price. Local models are free, which is exactly why the interesting unit here is time and room, not money.
Install
opencode plugin opencode-thinking-meter -g
That installs the package into your global OpenCode config and adds it to tui.json. Drop -g for the current project only. Restart OpenCode afterwards; plugins load at startup.
Without npm
TUI plugins are not auto-discovered, so a file install needs both steps:
mkdir -p ~/.config/opencode/tui-plugins
curl -fsSL https://raw.githubusercontent.com/tannerbruhn/opencode-thinking-meter/main/src/tui.tsx \
-o ~/.config/opencode/tui-plugins/thinking-meter.tsx
curl -fsSL https://raw.githubusercontent.com/tannerbruhn/opencode-thinking-meter/main/src/analyse.js \
-o ~/.config/opencode/tui-plugins/analyse.js
Then add it to ~/.config/opencode/tui.json:
{
"$schema": "https://opencode.ai/tui.json",
"plugin": ["./tui-plugins/thinking-meter.tsx"]
}
Do not put the files in ~/.config/opencode/plugin/. That directory is auto-discovered for server plugins and will load them the wrong way.
Options
"plugin": [["opencode-thinking-meter", { "place": "block", "warn": 2 }]]
| Option | Default | Meaning |
|---|---|---|
place |
"context" |
Headerless, directly under the Context block. "block" gives it its own Thinking heading, below the compaction meter. |
warn |
1.5 |
Show the room line when what is left is under this many turns' worth of thinking. |
badge |
"✂" |
Glyph in front of the count on terminals under 80 columns. |
toast |
true |
Toast when a cutoff happens. |
Status
node --test test/ covers it: 15 tests, including a replay over three of my real sessions with every string stripped out (test/session.json — token counts, finish reasons, part types, tool names, reasoning lengths and durations only, under synthetic ids, with timestamps rebased to the start of each session). The replay pins the numbers this plugin exists to produce: 21 cutoffs, 18 mid-thought, 14 attributed to the context wall and 7 to the output cap, none unattributed. The sidebar lines are asserted to fit 37 columns.
What the tests do not cover is how it looks in a terminal, which needs a real one. The sidebar placement in particular: opencode puts a blank line between sidebar slots, so "headerless, under Context" means one line of gap, not a seamless continuation of that block.
License
MIT
同类生态推荐
Compaction Meter
opencode-compaction-meter
OpenCode TUI plugin: how many times the session has compacted, tool calls per cycle, room after each restart, and whether the last summary was cut off. Spots compaction thrash while you work.
Usage Panel
opencode-usage-panel
Sidebar token-usage and cost panel for the opencode TUI. Breaks a session down by model with per-model cost, context usage, and configurable peak/off-peak pricing.
Dcp Dynamic Limits
opencode-dcp-dynamic-limits
OpenCode plugin that syncs DCP context limits to the active model and quiets chat reminder spam.