@agentoom/pi-spending-guard
Track LLM spending per task and pause when a configurable threshold is reached — continue, refine the prompt, or stop. Pi extension by agentoom.com.
Package details
Install @agentoom/pi-spending-guard from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@agentoom/pi-spending-guard- Package
@agentoom/pi-spending-guard- Version
1.2.1- Published
- Jul 31, 2026
- Downloads
- 671/mo · 620/wk
- Author
- agentoom
- License
- MIT
- Types
- extension
- Size
- 43.1 KB
- Dependencies
- 0 dependencies · 5 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
@agentoom/pi-spending-guard
Track LLM spending per task and pause when a configurable threshold is reached for pi by agentoom.com.
When your spending limit is hit, spending-guard pauses the task and asks you to choose: continue (double the limit or reset the counter), refine the prompt, or stop entirely — so you never lose control of your API costs.
Beyond per-session limits, spending-guard now tracks project-level and global cumulative spending that persists across sessions and auto-updates on every cost received.
New in 1.2: Tool execution tracking (all extensions) + compaction tracking (summary LLM calls cost money).
Fixed in 1.2.1: Session accumulated cost no longer carries over across sessions, and tool tracking state is now persisted immediately (see Changelog).
Install
pi install npm:@agentoom/pi-spending-guard
Quick start
Out of the box, spending-guard is enabled with a $3.00 default limit. Start pi and spend away — it'll pause automatically at $3.00.
Project, global, and tool cumulative tracking are also enabled by default.
Usage
Commands
| Command | Description |
|---|---|
/spending |
Show current spending, all totals, tool stats, compactions, and enabled state |
/spending limit [amount] |
Set or view the session spending limit (e.g. /spending limit 5) |
/spending toggle [on|off] |
Enable/disable session threshold tracking; no argument toggles |
/spending track project [on|off] |
Enable/disable project-level cumulative tracking |
/spending track global [on|off] |
Enable/disable global cumulative tracking |
/spending track tools [on|off] |
Enable/disable tool execution tracking |
/spending tools |
Show per-tool execution stats (calls + nested costs) |
/spending project |
Show project-level cumulative total |
/spending global |
Show global cumulative total |
/spending reset [project|global|session|tools|meta] |
Reset a total (default: session counter) |
/spending-limit [amount] |
Shortcut: set or view the limit |
/spending-toggle [on|off] |
Shortcut: enable/disable |
/spending-status |
Shortcut: show all status including tool stats + compactions |
Threshold dialog
When accumulated cost reaches the configured limit, spending-guard pauses and presents a 4-option dialog:
| Option | Behaviour |
|---|---|
| Continue (double the limit) | Raises the cap to 2× the current limit and keeps going |
| Continue (reset counter) | Keeps the same limit, resets accumulated cost to $0.00 |
| Refine the prompt | Opens an input field so you can write a more focused prompt |
| Stop the task | Gracefully shuts down pi |
Cost display
While any tracking is enabled, current spending is shown live in the footer status bar:
💵 $1.23 / $3.00 📁 $10.50 🌍 $45.00 🗜️ 3c 🔧 17 calls $0.015
| Icon | Meaning |
|---|---|
| 💵 | Current session spending / limit |
| 📁 | Project-level cumulative total (across all sessions in this project) |
| 🌍 | Global cumulative total (across all projects) |
| 🗜️ | Session compaction count (each compaction costs a summary LLM call) |
| 🔧 | Tool execution count + nested LLM costs (across all extensions) |
What's tracked (comprehensive)
Always tracked (costs flow through all totals)
| Source | Event | What's captured |
|---|---|---|
| Assistant messages | message_end |
event.message.usage.cost.total — the primary LLM cost |
| Tool nested LLM calls | tool_result |
event.usage.cost.total — costs from LLM calls made inside tools (any extension) |
| Compaction summaries | session_compact |
Compaction count (manual vs auto) — each compaction fires a summary LLM call whose cost flows through message_end |
Always tracked (metadata, no direct cost)
| Source | Event | What's captured |
|---|---|---|
| Tool invocations | tool_execution_start |
Call count per tool name (any extension, built-in or third-party) |
Not tracked (pi's event system doesn't expose this data)
| What | Why it's invisible |
|---|---|
| Direct HTTP calls from extensions | If an extension calls fetch("https://paid-api.com/...") directly, bypassing pi's agent, no cost event is emitted. Pi has no network interception layer at the extension level. |
| MCP server-side billing | If an MCP server charges per call or per token, that cost is on the server side and never reaches pi's event stream. Only the LLM usage that invoked the MCP tool is visible. |
| Extension background work | File watchers, sockets, timers, periodic fetches started by extensions don't emit cost events. |
| Provider-specific billing nuances | Some providers charge differently for cache reads/writes, tool-use tokens, or thinking tokens. Pi only surfaces cost.total — if the provider doesn't report it, it's invisible. |
| Retry costs as a separate category | Retries generate additional LLM calls whose costs flow through message_end and are tracked, but there's no built-in event to label them as "retry" vs "initial attempt." |
Key limitation: Everything that flows through
pi's agent (LLM calls + tool usage from those calls) is fully tracked. Only costs incurred outside pi's agent event pipe are invisible.
Tool execution tracking
Spending-guard monitors every tool call made by the LLM — including tools registered by third-party extensions — and tracks:
- Call count per tool (incremented on
tool_execution_start) - Nested LLM costs incurred during tool runs (captured from
tool_result.usage)
This means if a third-party extension's tool makes its own LLM calls through pi's agent, those costs are tracked and counted against your session, project, and global spending totals.
What's tracked:
- Built-in tools (
bash,read,write,edit,grep,find,ls, etc.) - Custom tools registered by any extension
- All third-party extension tools
View per-tool stats with /spending tools:
🔧 Tool Execution Stats
bash: 14 calls
read: 8 calls
write: 4 calls
edit: 3 calls
my_search_tool: 2 calls $0.0032
code_review: 1 call $0.0120
─────────────────────
Total: 32 calls across 6 tools, $0.0152 nested cost
Enable/disable tracking with /spending track tools on|off. Reset per-session tool stats with /spending reset tools.
Compaction tracking
Each session compaction fires a summary LLM call (costs money). Spending-guard tracks:
- Total compactions this session
- Manual vs auto breakdown (
/compactvs threshold/overflow triggered)
The compaction count is shown in the footer (🗜️ 3c) and in /spending status. Reset with /spending reset meta.
Compaction summary costs already flow through
message_endand are counted in your totals. The compaction tracker just surfaces how many happened so you can spot runaway compaction loops.
Project & global cumulative tracking
Beyond per-session limits, spending-guard persists cumulative totals to disk so you can see how much you've spent over time:
- Project total →
.pi/spending-guard-project-total.json(one per project) - Global total →
~/.pi/agent/spending-guard-global-total.json(shared across all projects)
Both totals auto-update on every LLM cost received and persist across sessions, restarts, and reloads.
View them with /spending project, /spending global, or /spending-status. Reset them with /spending reset project or /spending reset global.
Configuration
Spending-guard reads from these files (project takes priority):
.pi/spending-guard.json— project-local~/.pi/agent/spending-guard.json— global
If neither file exists, it defaults to enabled with a $3.00 limit.
Config format
{
"enabled": true,
"limit": 5.00,
"trackProject": true,
"trackGlobal": true,
"trackTools": true
}
| Key | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
true |
Whether session threshold tracking starts active |
limit |
number |
3.00 |
Session spending threshold in USD |
trackProject |
boolean |
true |
Persist cumulative project-level total to disk |
trackGlobal |
boolean |
true |
Persist cumulative global total to disk |
trackTools |
boolean |
true |
Track tool executions (calls + nested LLM costs) |
Per-project vs global
- Place the extension globally to track spending across all projects:
pi install npm:@agentoom/pi-spending-guard - Place a
.pi/spending-guard.jsonin a specific project to override the default for that project only.
Development
spending/
├── package.json
├── index.ts # Extension entry point
├── .gitignore
└── README.md
Run against a local path:
pi install ./spending
Changelog
1.2.1
- Fix: session accumulated cost carryover. The per-session
accumulatedCostcounter is now reset to zero on session start/restart, matching the behaviour oftoolSpendingandsessionMeta. Previously, when pi auto-resumed a session on startup, the previous session's accumulated cost was restored from entries and new spending was added on top, inflating the displayed session total. - Fix: tool execution state not persisted immediately.
persist()is now called in bothtool_execution_start(call counts) andtool_result(nested costs). Previously, tool tracking data was only persisted when the nextmessage_endfired — if no assistant message followed, tracked calls and nested costs were lost. Thetool_resulthandler also now persists state even when the session guard is paused or disabled, so tool cost tracking works regardless of guard state.
1.2.0
- Tool execution tracking (all extensions): call counts + nested LLM costs.
- Compaction tracking (manual vs auto).
- Project-level and global cumulative spending totals persisted to disk.
1.0.x
- Initial release: per-session spending limit with threshold dialog.