Skip to content

[FEATURE]: Show live input/output token counts and rolling TPS in the footer #29909

@Proton1917

Description

@Proton1917

Feature hasn't been suggested before.

  • I searched existing issues and found related/partial requests. This is intended as a concrete, footer-scoped version of the token/TPS request, not a generic progress indicator.

Related issues:

Describe the enhancement you want to request

Please add a Claude Code-style live token meter to the OpenCode TUI footer/status line while an assistant turn is running.

The key request is not just showing a spinner or a phase label. The footer should expose live usage/performance signals such as:

in 42.1k · out 318 · 58 tok/s

or, when cache detail is useful:

in 2.1k + cache 40k · out 318 · 58 tok/s

Reference behavior

Claude Code's documented statusLine mechanism exposes token usage data to the bottom status bar. Its status line JSON includes fields such as:

  • context_window.total_input_tokens
  • context_window.total_output_tokens
  • context_window.current_usage.input_tokens
  • context_window.current_usage.output_tokens
  • context_window.current_usage.cache_creation_input_tokens
  • context_window.current_usage.cache_read_input_tokens
  • cost.total_api_duration_ms

Docs: https://code.claude.com/docs/en/statusline

For Anthropic streaming, the Messages API also provides the raw ingredients: message_start includes initial usage, and message_delta.usage.output_tokens is cumulative. That makes exact output-token deltas possible when the provider streams usage. Docs: https://platform.claude.com/docs/en/build-with-claude/streaming

This issue is not asking OpenCode to clone Claude Code's configurable statusLine hook. The request is to bring the same always-visible usage feel into OpenCode's existing footer.

Desired behavior

While the assistant turn is running, show:

  • Current request input tokens as soon as known, including cache read/write tokens when available.
  • Output tokens generated so far, updating while the response streams.
  • Current/rolling TPS (tok/s) during generation, calculated from output-token deltas over a short recent window.

After the turn completes:

  • Keep the final provider-reported input/output token counts where OpenCode already shows usage/cost.
  • Optionally keep the final or recent average TPS for the completed response.
  • Do not replace or distort accurate provider-reported usage/cost once it arrives.

Why this matters

A spinner only says that something is running. A live token/TPS meter shows whether the model is actually producing output and how fast it is moving.

This is useful for:

  • long reasoning turns
  • slow providers and local models
  • comparing actual throughput across providers/models
  • noticing stalled generations before waiting indefinitely
  • distinguishing prompt/context processing time from output generation time
  • understanding context pressure without opening a separate panel

Implementation notes

OpenCode already has most of the data path needed for a small first pass:

  • packages/llm/src/schema/events.ts defines normalized Usage with input, output, cache, reasoning, and provider metadata fields.
  • Anthropic parsing already maps message_start and message_delta usage, with right-biased merge semantics for cumulative usage.
  • OpenAI Chat requests already set stream_options: { include_usage: true } and map provider usage into normalized Usage.
  • Session.getUsage(...) already converts normalized usage into OpenCode's existing token/cost shape.
  • The run footer already has FooterState.usage and renders it in the footer.

A possible first pass:

  1. Track an in-progress per-turn usage snapshot separately from final persisted billing usage.
  2. Update the footer usage string while the turn is running.
  3. Prefer provider-reported usage deltas when available.
  4. If a provider only reports final usage, estimate output tokens from streamed text/reasoning/tool-input deltas until final usage arrives.
  5. Compute rolling TPS from output-token deltas and elapsed time.
  6. Replace estimates with final provider-reported usage/cost on completion.

This keeps billing/cost accounting unchanged and limits the UX change to the existing footer/status line.

Non-goals

  • Not asking for full stdout/stderr streaming.
  • Not asking for a generic MCP/tool progress indicator.
  • Not asking for a large billing dashboard.
  • Not asking for plan/quota reset tracking.
  • Not asking to redesign the sidebar.
  • Not asking for a plugin API in this first step.

The goal is a low-footprint, always-visible footer indicator for live input/output tokens and current TPS, in the same spirit as Claude Code's token-aware status line.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions