Skip to content

✨ feat: tui client estimated token cost (T28) - #5453

Merged
clubanderson merged 1 commit into
kubestellar:v4from
Danathar:feat/tui-t28-estimated-token-cost
Sep 1, 2026
Merged

✨ feat: tui client estimated token cost (T28)#5453
clubanderson merged 1 commit into
kubestellar:v4from
Danathar:feat/tui-t28-estimated-token-cost

Conversation

@Danathar

@Danathar Danathar commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Problem

The TUI token client can read token counts from GET /api/tokens, but it has no client method for the dashboard's separate GET /api/cost estimate. That leaves the Tokens pane without a source for its documented COST column: every per-agent and fleet cost remains unknown even when the dashboard has calculated an estimate.

The cost wire format also uses the numeric value 0 for both a genuine $0.00 estimate and an unpriced placeholder. Consumers therefore cannot infer whether a value is known from the number alone.

Implementation

  • Add Client.Costs(ctx) and a narrow response envelope that decodes only the estimated portion of /api/cost through the shared authenticated getJSON path.
  • Add CostSummary for total_usd, by_agent, and unpriced_models, plus CostAgentEntry for the complete per-agent token and USD breakdown.
  • Preserve the server's source value and expose CostAgentEntry.Known() so callers use the source tag rather than guessing from USD.
  • Add CostSummary.AllPriced() so a summary containing models without exact server-side prices cannot be presented as an authoritative fleet total.
  • Add a full-shaped fixture that includes ignored gateway, per-model, per-session, metadata, and repository-count siblings. This proves the TUI projection stays deliberately narrower than the dashboard payload.

The client does not calculate prices locally; the dashboard remains the sole pricing authority. Known() accepts only source: "estimated", so an unknown or future source is handled conservatively.

Regression coverage

cost_test.go verifies:

  • the authenticated GET /api/cost request and full fixture decode, including every requested per-agent field and all unpriced-model names;
  • a real $0.00 value with source: "estimated" is known, while $0.00 with source: "unpriced" is unknown;
  • a mixed priced/unpriced summary reports AllPriced() == false;
  • a zero-usage response preserves valid, non-nil empty arrays;
  • malformed JSON returns a decode error and a zero summary;
  • non-2xx responses retain the existing typed *APIError behavior, including method, path, status, and response body.

Verification

From src/:

go test ./pkg/tui/client -run 'TestCosts' -count=1
ok  github.com/kubestellar/hive/pkg/tui/client

go test ./pkg/tui/...
ok  github.com/kubestellar/hive/pkg/tui
ok  github.com/kubestellar/hive/pkg/tui/client
ok  github.com/kubestellar/hive/pkg/tui/panes
ok  github.com/kubestellar/hive/pkg/tui/theme

go build ./...
PASS

The commands used task-local GOCACHE, GOTMPDIR, and CCACHE_DIR paths because this execution environment mounts their defaults read-only; no source or test behavior was altered.

Scope

This PR intentionally does not modify the Tokens pane, application refresh loop, native gateway balances, histories, session rows, repository counts, disclaimer, or price calculations. Rendering and joining cost rows to token rows remain T30 work.

Closes #5415

— hive: backend=codex

Signed-off-by: Danathar <doug.baggett@gmail.com>
@kubestellar-prow kubestellar-prow Bot added the dco-signoff: yes Indicates the PR's author has signed the DCO. label Sep 1, 2026
@kubestellar-prow

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign hanthor for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kubestellar-prow kubestellar-prow Bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Sep 1, 2026
@clubanderson
clubanderson merged commit 06f9caf into kubestellar:v4 Sep 1, 2026
41 of 42 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dco-signoff: yes Indicates the PR's author has signed the DCO. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

✨ tui T28: client — estimated token cost

2 participants