[PR #12721] feat(tui): add tokens per second to response footer #14336

Open
opened 2026-02-16 18:19:08 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/12721

State: open
Merged: No


Fixes #5374
Closes #6096

Adds a tok/s (TPS) counter to assistant message footers. Shows up right after duration, like: 18.3s · 131 tok/s

Why

I've been switching between providers a lot lately and wanted a quick way to see which models are actually fast vs which just feel fast. Kimi K2.5 clocks ~130 tok/s. Having the number right there makes the difference obvious without needing external tooling.

Screenshot

TPS in action with Kimi K2.5

Kimi K2.5 Free hitting 198 tok/s on a real response

Prior art

#5497 by @edlsh tackled this back in December. It's been sitting for 2+ months now with merge conflicts and CI failures, and a few people in the comments are asking for it to land. Rather than try to rebase that PR, I reimplemented it cleanly on current dev with a different structure: TPS logic lives in core/tokens/ instead of tui/util/ so the SDK and other consumers can use it later without pulling in TUI code.

How it works

processor.ts records a firstToken timestamp when the first output-delta arrives during streaming. TPS is then calculated as generatedTokens / ((completed - firstToken) / 1000), where generatedTokens includes both output and reasoning tokens. Responses shorter than 250ms, tool calls, and errored responses are filtered out.

What I left out

Average/aggregate TPS across a session. Both issues mention it but it felt like scope creep for a first pass. The per-message timestamps are all persisted, so adding a session-level summary later is straightforward.

Testing

34 unit tests cover calculation, edge cases, and filtering. All CI checks pass: typecheck, unit, e2e (linux), pr-standards.

**Original Pull Request:** https://github.com/anomalyco/opencode/pull/12721 **State:** open **Merged:** No --- Fixes #5374 Closes #6096 Adds a tok/s (TPS) counter to assistant message footers. Shows up right after duration, like: `18.3s · 131 tok/s` ### Why I've been switching between providers a lot lately and wanted a quick way to see which models are actually fast vs which just feel fast. Kimi K2.5 clocks ~130 tok/s. Having the number right there makes the difference obvious without needing external tooling. ### Screenshot ![TPS in action with Kimi K2.5](https://raw.githubusercontent.com/JohnC0de/opencode/feat/tokens-per-second-display/docs/assets/tps-screenshot.png) *Kimi K2.5 Free hitting 198 tok/s on a real response* ### Prior art #5497 by @edlsh tackled this back in December. It's been sitting for 2+ months now with merge conflicts and CI failures, and a few people in the comments are asking for it to land. Rather than try to rebase that PR, I reimplemented it cleanly on current `dev` with a different structure: TPS logic lives in `core/tokens/` instead of `tui/util/` so the SDK and other consumers can use it later without pulling in TUI code. ### How it works `processor.ts` records a `firstToken` timestamp when the first `output-delta` arrives during streaming. TPS is then calculated as `generatedTokens / ((completed - firstToken) / 1000)`, where generatedTokens includes both output and reasoning tokens. Responses shorter than 250ms, tool calls, and errored responses are filtered out. ### What I left out Average/aggregate TPS across a session. Both issues mention it but it felt like scope creep for a first pass. The per-message timestamps are all persisted, so adding a session-level summary later is straightforward. ### Testing 34 unit tests cover calculation, edge cases, and filtering. All CI checks pass: typecheck, unit, e2e (linux), pr-standards.
yindo added the pull-request label 2026-02-16 18:19:08 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#14336