pi Cost Tracking — There's No Native Hook, So Cost Comes From the Proxy
Just want the answer? pi has no cost hook to attach to — you have to move where the model traffic goes. Install the tool-call extension, then add a provider for the cost X-ray:
curl -sf https://agenticcontrolplane.com/install.sh | bash
# ~/.pi/agent/models.json
{
"providers": {
"acp": {
"baseUrl": "https://api.agenticcontrolplane.com/v1",
"api": "openai-completions",
"apiKey": "!cat ~/.acp/credentials",
"compat": { "supportsDeveloperRole": false, "supportsReasoningEffort": false },
"models": [{ "id": "gemini-3.5-flash" }]
}
}
}
# then: pi --model acp/gemini-3.5-flash
Full pi install guide → · pi's control model, explained → · free up to 5 agents
pi’s minimalism is the whole design — four tools, no permission system, extend it yourself. That same minimalism means there’s no cost hook to extend, either. The two typed events an extension gets, tool_call and tool_result, dispatch on tools: they see arguments and results, never a token count or a model’s usage fields. There is no seam inside pi where an extension could intercept a model call the way it intercepts a tool call, because pi doesn’t route model calls through its extension pipeline at all.
That makes pi’s cost story different in kind from Hermes’s, which has an in-process hook on every LLM request, and closer in shape to Codex CLI’s: the only way to see what a call cost is to change where it goes.
Why the extension can’t do this
The ACP extension for pi is genuinely comprehensive for what it covers — tool_call fires before every bash, read, write, edit, or custom tool call and can deny or rewrite it; tool_result fires after and can redact or rewrite what the model reads back. Because pi has no MCP layer and no second tool-dispatch path, that pair of events sees everything the agent does. It just never sees what the agent’s model calls cost, because pi’s core loop talks to the model provider directly, outside the extension pipeline both events are wired to.
So adding the extension gets you policy and an audit trail on tool calls — deny, ask, allow, redact — with nothing about spend. Cost needs a second, separate mechanism.
The config
pi’s model calls can route through the ACP proxy the same way any OpenAI-compatible client’s can. Add a provider entry in ~/.pi/agent/models.json:
{
"providers": {
"acp": {
"baseUrl": "https://api.agenticcontrolplane.com/v1",
"api": "openai-completions",
"apiKey": "!cat ~/.acp/credentials",
"compat": { "supportsDeveloperRole": false, "supportsReasoningEffort": false },
"models": [{ "id": "gemini-3.5-flash" }]
}
}
}
Then launch pi against it:
pi --model acp/gemini-3.5-flash
The proxy is multi-provider — it routes gpt-*, claude-*, and gemini-* model ids to the matching upstream and forwards the request unchanged. Same response back; the difference is the usage fields on the way through get read and priced, and the call lands as a row joined to the tool-audit rows for the same session, in the console.
What you get once it’s routed
Once a model in models.json points at the proxy, calling pi with --model acp/... gives you the same per-call cost picture documented for turning on the cost X-ray generally:
- Per-call cost — tokens in and out, priced to dollars, rolled up per run
- Prompt-cache hit rate — so a cold cache doesn’t silently double a session’s cost before anyone notices
- The loop-vs-leaf split — how much of the spend is the agent re-reading its own context to decide the next step, versus doing the work
- A policy check on the tool calls the model emits — the proxy sees the
tool_useblocks in the model’s response, which is a second, coarser layer than the extension’s owntool_callinterception, not a replacement for it
None of that shows up if pi is still pointed at its default provider. The extension and the provider entry are independent: you can run the extension alone (policy, no cost), the provider alone (cost, no tool-call policy), or both together, which is the configuration that gets you the full picture in one console.
Budget limits
Once model traffic is routed through the proxy, workspace-billed traffic is subject to your workspace’s daily LLM cost cap, enforced at the gateway before the call goes upstream — the session fails rather than runs up a bill past the limit. Bring-your-own-key traffic is billed by whichever provider you’re calling; ACP meters it but can’t cap an account it doesn’t hold. Without the provider entry in models.json, there’s no cap at all, because there’s nothing in pi’s path to enforce one.
Troubleshooting
I added the provider but see nothing in the console. Check you actually launched with --model acp/<id> — adding the provider block to models.json doesn’t change pi’s default model selection, it just makes the option available.
apiKey": "!cat ~/.acp/credentials" fails. That syntax shells out to read the file at launch; confirm the file exists and holds a workspace key (gsk_...), which the install script writes when you sign in. A missing or malformed file means pi can’t authenticate the request, not that the proxy is unreachable.
Tool-call policy rows show up but cost rows don’t, or vice versa. That’s expected if only one of the two pieces is installed — the extension and the provider entry are unrelated integrations that happen to write to the same console.
Frequently asked questions
Does pi track cost natively?
No. pi ships four tools and two typed events for extensions — tool_call and tool_result — and neither carries token usage or pricing data. There’s no /usage command, no status-line dollar figure, no cost metric. pi’s own minimalism, which is deliberate for the permission model too, extends to cost: nothing native computes or shows it.
If pi has no cost hook, how does ACP show cost for it?
Not through the extension. The ACP pi extension covers tool-call policy and audit — it never sees a model call, so it can’t price one. Cost requires a second, separate step: adding a provider entry in ~/.pi/agent/models.json whose baseUrl points at the ACP proxy, so pi’s model traffic itself passes through a point that can read token usage off the response.
Does routing model calls through the proxy change what pi does?
No. The proxy is multi-provider and forwards requests unchanged — same model, same response — while reading the usage fields to price the call. You select it by model id (pi –model acp/gemini-3.5-flash), so it’s an explicit choice per run, not a silent redirect.
Can I get both tool-call policy and cost from pi in one setup?
Yes, but they’re two independent pieces you add separately: the extension (tool_call / tool_result) for policy and audit on everything pi runs, and the models.json provider entry for cost on the model calls you route through it. Installing one doesn’t install the other, and neither depends on the other being present.
Where to read more
- pi’s control model, explained — what the extension covers natively, and where its two typed events end
- Prime Agent cost tracking — the same proxy pattern on pi’s hard fork, with its own provider seam
- Hermes Agent cost tracking — the in-process hook alternative, for comparison
- Claude Code cost tracking reference and Codex CLI cost tracking — the sibling references for the other coding agents