pi-usage-ledger

Tracks the agent's own token/cost usage per provider request and renders a /usage overlay dashboard. Self-contained: hooks the provider-response lifecycle (message_end) and persists records as session custom entries, so the ledger survives /reload, compac

Packages

Package details

extension

Install pi-usage-ledger from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:pi-usage-ledger
Package
pi-usage-ledger
Version
1.0.0
Published
Aug 29, 2026
Downloads
159/mo · 159/wk
Author
nickybc
License
MIT
Types
extension
Size
24.8 KB
Dependencies
0 dependencies · 2 peers
Pi manifest JSON
{
  "extensions": [
    "./dist/index.js"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-usage-ledger

A self-contained pi coding-agent extension that tracks the agent's own token and cost usage and renders it as a /usage overlay dashboard.

No core modifications, no auth-broker access, no external services. The plugin hooks the provider-response lifecycle itself and persists every request as a session custom entry, so the ledger survives /reload, compaction, and restarts.

Features

  • Total tokens (input / output / cache-read / cache-write, plus reasoning tokens when the provider reports them)
  • Total cost in USD — computed by pi itself from the catalog model pricing (no price table is invented by this plugin)
  • Per-model breakdown (request count, tokens, cost)
  • Per-provider breakdown
  • Time windows: 24h / 7d / all
  • Daily sparkline (last 14 days)
  • Works headless: outside the TUI, /usage falls back to a one-line notification summary

Install

Load as an extension file

No install step needed — point the extension loader at the compiled entry (or the TypeScript source directly; pi loads .ts extensions natively):

pi -e ./pi-usage/dist/index.js
# or, from source:
pi -e ./pi-usage/src/index.ts

(-e/--extension is repeatable.)

Auto-discovery

Copy the plugin into a trusted extension location and reload:

  • ~/.pi/agent/extensions/ (global)
  • .pi/extensions/ (project-local)
mkdir -p ~/.pi/agent/extensions/pi-usage-ledger
cp -r pi-usage/dist ~/.pi/agent/extensions/pi-usage-ledger/

Package / marketplace

package.json declares the extension under pi.extensions (./dist/index.js), so the directory is a valid pi package. To install from npm or git, see packages.md.

Usage

Run /usage. An overlay dashboard opens (TUI mode):

Key Action
1 / 2 / 3 Switch window: 24h / 7d / all
/ Cycle window
esc / ctrl+c / enter Close

How it works

Event hook: message_end

The extension event after_provider_response does not carry token or cost data — its payload is only the HTTP status and response headers. The authoritative per-request usage arrives on the finished assistant message: the agent loop emits message_end with an AgentMessage snapshot whose usage field (from @earendil-works/pi-ai) carries the full token breakdown (input, output, cacheRead, cacheWrite, totalTokens, reasoning) and usage.cost (input/output/cacheRead/cacheWrite/total in USD) — pi computes cost from catalog model pricing. This plugin hooks pi.on("message_end").

Persistence: session custom entries

Each qualified request is appended as a session custom entry:

pi.appendEntry("pi-usage.record", record);

Custom entries (CustomEntry) are excluded from LLM context and are kept across reloads and compaction. The /usage command rebuilds the full ledger from the session branch:

for (const entry of ctx.sessionManager.getBranch()) {
  if (entry.type === "custom" && entry.customType === "pi-usage.record") { … }
}

Record shape

{
  v: 1,                       // schema version
  ts: number,                 // request start (Unix ms)
  provider: string,           // e.g. "anthropic", "openai", "openrouter"
  model: string,              // e.g. "anthropic/claude-sonnet-4-5"
  stopReason?: string,        // e.g. "stop" | "length" | "toolUse"
  usage:  { input, output, cacheRead, cacheWrite, totalTokens, reasoningTokens? },
  cost:   { input, output, cacheRead, cacheWrite, total }   // USD
}

What is (and is not) counted

  • Every finished assistant message with stopReason !== "error" and reported totalTokens > 0 is recorded — including truncated (length) and aborted responses that consumed tokens.
  • Requests with zero reported usage (error placeholders, providers without usage reporting) are not recorded: the plugin never fabricates token or cost numbers.
  • Cost shows $0.00 (pricing n/a) when tokens were reported but pi had no pricing for the model; the plugin does not invent a price table.
  • The ledger is per session: each session file accumulates its own records (subagent sessions run their own extension runners against their own session files).

Build from source

npm install        # devDeps: @earendil-works/pi-coding-agent, @earendil-works/pi-tui
npm run build      # tsc → dist/index.js + dist/index.d.ts
npm run typecheck

License

MIT