Skip to content

feat(ai): show running $ spend — per-run cost + credits left in the response bar - #17

Merged
ndemianc merged 1 commit into
developfrom
feat/editor-running-spend
Jul 17, 2026
Merged

feat(ai): show running $ spend — per-run cost + credits left in the response bar#17
ndemianc merged 1 commit into
developfrom
feat/editor-running-spend

Conversation

@ndemianc

Copy link
Copy Markdown
Contributor

Editor half of M5 / top-bet #2"turn BYO-key into a trust weapon: real token/cost accounting." Pairs with thin.ly #367 (which emits the data).

Why

The response bar has always had a slot for credits, but agent.js hands back credits: nullnothing ever told it. Your own plan's argument: "Cost opacity is the #1 criticism of BOTH Cursor and Windsurf" — and now that prompt caching is live and verified (~87% cache-read discount), the number is genuinely worth showing.

What

  • openaiCompat.js — parse the gateway's namespaced levelcode frame into usage.{cost_micros, credits_remaining_micros}. No choices, and no other provider sends it → inert everywhere else.
  • agent.js — accumulate the run's cost across turns, keep the latest balance, report both on agentDone (and in the 🐛 debug line next to cacheRead).
  • chat.html — render money, not a count.

One bug this avoids

The bar did String(credits) + ' credit' + (credits === 1 ? '' : 's') — a count. Handing it a micro-$ figure would have printed "9876543 credits". It now renders:

· $0.02 · $9.88 left

And money() floors sub-cent turns at <$0.01 rather than rounding to $0.00 — with caching live, sub-cent turns are common and "$0.00" reads as free/broken.

BYOK runs send neither figure, so the bar is unchanged there — this is a gateway-only affordance, and the "🖥 Local · Direct · BYO key" story stays literally true.

All 5 extension test files pass.

🤖 Generated with Claude Code

…esponse bar

M5/bet-#2 ("turn BYO-key into a trust weapon"). The response bar has always had
a slot for credits, but agent.js hands back `credits: null` because nothing ever
told it. The gateway now emits a final `levelcode` SSE frame (thin.ly #367) with
what the turn cost and what's left, in retail micro-$.

- openaiCompat: parse the gateway's namespaced `levelcode` frame into
  usage.{cost_micros, credits_remaining_micros}. It carries no `choices`, and no
  other provider sends it, so this is inert everywhere else.
- agent.js: accumulate the RUN's cost across turns and keep the latest balance;
  report both on agentDone (and in the 🐛 debug line next to cacheRead).
- chat.html: render money, not a count. The bar previously did
  `String(credits) + ' credits'`, which would have printed "9876543 credits" for
  a micro-$ figure. Now: `· $0.02 · $9.88 left`.

`money()` floors sub-cent turns at "<$0.01" rather than rounding to "$0.00" —
with prompt caching live, sub-cent turns are common and "$0.00" reads as
free/broken.

BYOK runs send neither figure, so the bar is unchanged there — this is a
gateway-only affordance.

All 5 extension test files pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ndemianc
ndemianc merged commit ba4f454 into develop Jul 17, 2026
1 check passed
@ndemianc
ndemianc deleted the feat/editor-running-spend branch July 19, 2026 02:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant