Skip to content

Per-session cost readout, behind a flag, for API billing #121

Closed

Description

@omartelo

The footer shows the model and how much of the context window the last turn left
occupied (ContextRing.tsx, SessionModel.tsx), fed by the session-usage
event (internal/terminal/usage.go). What it never shows is what the session
cost.

Worth stating who this is for before any of it is built: on a subscription the
number is noise.
It only means anything on API billing. So it ships off,
behind a setting, and when the flag is off the readout is absent — not zeroed,
not greyed. Nobody on a plan should have to look at a running total that does
not apply to them.

What exists

internal/terminal/usage_claude.go:124 already tails Claude's transcript and
reads input_tokens, cache_read_input_tokens and
cache_creation_input_tokens off the last assistant line. Three things are
missing for cost:

  • output_tokens is not parsed at all.
  • The reader answers how full is the context right now, so it reads the tail.
    Cost is a sum across every assistant line of the transcript — a different
    traversal, and it has to keep meaning something when /clear starts a new
    transcript mid-session.
  • A price table per model. That is a maintenance tail with a known failure: a
    model lich has never heard of prices at nothing.

Open

  • Per session only, or a project / daily total as well?
  • Price table baked into the binary (goes stale between releases) or a setting?
  • Claude only at first — it is the only provider reporting a session id today
    (see the emitUsage doc) — or hold until a second reader exists?
  • Where it renders: beside the context ring in the footer, or on the card?

Activity

  1. added
    enhancementNew capability or improvement
    needs-shapingOpen questions to settle before implementing
    on Jul 28, 2026
  2. omartelo commented on Jul 29, 2026

    @omartelo
    CollaboratorAuthor

    Shipped in #127. The four open questions, as they were decided:

    • Per session only. One total per lich session, summed across every conversation it ran.
    • Baked table with a remote refresh. internal/pricing ships the prices this binary knows and refreshes itself from LiteLLM's published table the first time a session runs a model it has never heard of, caching that under the config dir. On-miss, never on a schedule; with the setting off, no request is made at all.
    • Claude only, structure ready for the rest. The table is keyed by model id and keeps every provider's prices, so a second reader prices off it unchanged. What stays Claude-only is the transcript read.
    • Beside the context ring, in the footer.

    The failure this issue named — a model lich has never heard of pricing at nothing — is answered by stopping the count at that line rather than skipping it: the readout goes absent until a price lands. A total silently missing a turn is worse than no total.

    Still open, if either is ever wanted: a project or daily total, and the second provider's reader.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew capability or improvement

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions