Repository navigation
feat(pi): show Pi agents' usage on the Usage page - #1442
Conversation
Pi agents get a `usage` hook, as Claude, Codex and goose have. For each of the agent's Buzz conversations, it reads the conversation's Pi entries and reports each answer's tokens, model and cost as pi-ai recorded them. The channel and thread come from the conversation's key, the title from its first prompt. Only agents running on this computer are read, as for their sessions, since reading opens their storage. The host no longer drops `usage` from the messages it sends; that was the only place the counts were lost. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Salman Mohammed <smohammed@squareup.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| /** A conversation's model requests, its entries oldest first. pi-ai counts a | ||
| * request's input without its cached part, and prices the models it knows. */ | ||
| export function conversationUsage( |
There was a problem hiding this comment.
Keep the conversion helper private
conversationUsage has no production caller outside this module; it is exported solely so the first two tests can bypass the actual readUsage boundary. This creates a test-only production API and couples coverage to an implementation detail, so behavior-preserving refactors must retain the export. Keep the helper private and exercise these conversion cases through readUsage with the existing fake request boundary instead.
AGENTS.md reference: AGENTS.md:L131-L134
Useful? React with 👍 / 👎.


Stacked on #1420, which adds the Pi agent type. Review that first.
Why
The Usage page shows what each agent cost, by harness. It gets its numbers from each agent type's
usagehook. Claude, Codex and goose have one. Pi does not, so Pi agents are missing from the page.Pi records every answer's token counts and cost in the agent's Pi durable storage, through pi-ai's
usage. But the Pi host dropsusagefrom each message before sending it to the app, so the app never sees those counts.What
src/bundled/pi/usage.ts(new) turns the agent's Pi conversations into the Usage plugin'sSessionUsage, one per Buzz conversation.registergetsusage:, ascodex/usage.tsandgoose/usage.tsare wired in. The Usage plugin does not change.host.mjskeepsusageon the messages itsentriesrequest returns.How
places, which are its Buzz conversations by channel or thread. The channel and thread root come from the conversation's key. The title comes from the first prompt'sContent:line.since. It is then read in full, so the snapshot is complete.responseId, model, and tokens. pi-ai'sinputalready leaves out cached tokens, so it maps straight to Buzz'sinput.cacheWrite1his kept too.cost.totalis the recorded cost. pi-ai prices a model it has no rates for at $0, so $0 counts as no recorded cost. The Usage plugin then estimates it or lists the model as unpriced.sessionsfollows.Risk
Low. Pi is new in #1420 and ships off until it is turned on in Settings → Plugins. The host change only adds a field to
entriesreplies; the Activity tab ignores it.Known gaps:
sinceis skipped, even if a long turn kept running pastsince.Testing
In the desktop app (
BUZZ_DEV_VIEWER= just desktop, macOS), Usage page, last 30 days, with one Pi agent (Pip) that ran 4 conversations today:usagehook): 4 agents, 43 sessions, 3 harnesses, no Pi.Real storage: a copy of Pip's storage, served by the real host on Pi durable 1.3.0. All 31 answers came back with usage.
readUsageturned them into 4 sessions whose costs add up to the $2.40 above.Live host test on the real 1.3.0 packages:
PI_DEPS=<folder pi.sh installed> bin/pnpm exec vitest run src/bundled/pi/host.live.test.ts. It now checks that answers keep their usage, and it fails with the old host.Not checked: Linux and Windows, light theme and narrow widths of the Usage page, and the Harness filter set to Pi. The Usage page itself has no changes.
Bigger picture
This is the Usage follow-up named in #1420. The other follow-up, Harness defaults for Pi on the agent settings page, is still to come.
🤖 Generated with Claude Code