pi-agent
claude_code
1 companion file
SKILL.md
---
name: pi-agent
description: >-
Offload cheap, bulk, or parallelizable work from Claude Code to `pi` β a
headless coding-agent CLI running on near-free Cloudflare Workers AI. Use when
you (Claude Code) want to fan out mechanical edits, read-only recon,
long-context digestion, or test/boilerplate generation onto cheap models
instead of spending Opus tokens; or when the user says "use pi", "spawn pi",
"offload to pi", "run this on the cheap models / Workers AI". Covers safe
headless invocation, cost-verified model routing, output parsing, RPC
steering, and parallel fan-out.
---
# pi-agent β offload work to pi on near-free Workers AI
`pi` (`@earendil-works/pi-coding-agent`, at `/root/.bun/bin/pi`) is a headless
coding-agent CLI with `read/bash/edit/write/grep/find/ls` tools. It is wired to
**Cloudflare Workers AI via an AI Gateway OpenAI-compatible endpoint**.
Cloudflare's catalog lists every model below as tool-capable, but the
piβgatewayβmodel *tool loop* does not always work in practice (see below).
Availability, context, ceilings, and price all change β confirm the current set
with `pi --list-models` (shows context Β· max-output Β· tool-calling Β· vision) and
read Cloudflare's Workers AI pricing page when a decision hinges on exact cost.
**Strategic frame:** Opus (Claude Code) is the scarce, high-IQ orchestrator; pi
is cheap muscle on capacity the user already pays for. Route token-wasteful,
parallelizable, or low-judgment work to pi. **The binding constraint is a small,
shared daily free-Neuron pool.** On Workers Paid, overage is a cheap soft cap
rather than a hard failure β but the pool is small, so favor the cheapest model
that clears the task's quality bar, reserve flagship models for escalation, and
keep every run bounded.
## β οΈ Tested behavior (smoke tests, 2026-07-07) β read this first
Doc-level "function calling: Yes" is NOT the same as tool loops working through
the pi β AI-Gateway β model path. Actual results:
| Model | Pure text (no `-t`) | Tool loop (`-t read,β¦`) | Verdict |
|---|---|---|---|
| `gpt-oss-120b` | β
| β
executed first try | **reliable tool driver** |
| `gpt-oss-20b` | β
clean | β οΈ prompt-sensitive: "Read X" leaked the call into its reasoning channel and did nothing; **"Use the read tool to open X" executed cleanly** | text-first; tools OK **with explicit tool phrasing** |
| `glm-4.7-flash` | untested | β timed out at 100s, 0 tools | **don't use headless** until it passes a smoke test |
**Consequences for routing:**
- For work that needs pi to **use tools** (explore repo, edit files itself),
default to **`gpt-oss-120b`**. If you use `gpt-oss-20b` to save cost, phrase
the prompt with an explicit *"use the read/edit/grep tool"* instruction.
- The most robust and cheapest pattern is **text-in / text-out with NO tools**
(`-nt`): pipe the file(s) in via `@file` or stdin, get the answer or the full
new file content out, and let **Opus apply the change** with Write/Edit. This
sidesteps gateway tool-calling entirely and lets you use the cheapest models.
Prefer it for edits over pi's own `edit`/`write` tool.
## When to offload vs. keep
**Keep on Opus:** architecture, ambiguous debugging, API-contract design, D1/DO
schema migrations, anything irreversible or judgment-heavy.
**Offload to pi:** bulk mechanical edits (as text-out, Opus applies), read-only
recon, long-context digestion into a brief, test/boilerplate generation from a
spec Opus wrote, cheap second-opinion reviews, scratch exploration, drafting.
## Model routing (by role β confirm current models with `pi --list-models`)
Route on tool-loop *reliability* first (see the tested table above), then on
cost. Names below are today's picks, not permanent β prices and the catalog
change, so keep the cheap-vs-flagship split as the durable signal and verify the
specifics against `pi --list-models` and the pricing page.
| Task | Model | Why |
|---|---|---|
| **Pure text-in/out** β digest, summarize, draft, classify, review, generate file content | `@cf/openai/gpt-oss-20b` | Cheap and tested-clean on pure text; no tool loop means no gateway flakiness |
| Long-context digest / vision (text-out) | `@cf/google/gemma-4-26b-a4b-it` | Largest-context cheap model, and has vision |
| Recon-scale input (text-out, small scope) | `@cf/qwen/qwen3-30b-a3b-fp8` | Cheapest input; recon is input-heavy so it barely dents the pool |
| **Agentic / tool-using** β pi explores or edits files itself | `@cf/openai/gpt-oss-120b` | The one model with a tested-reliable gateway tool loop |
| Tool-using on the cheap | `@cf/openai/gpt-oss-20b` | Works **only with explicit "use the X tool" prompts** β cheaper but finicky |
| Coding-flavored alt | `@cf/zai-org/glm-4.7-flash` | β οΈ timed out in testing β smoke-test before any headless use |
| Vision | `@cf/google/gemma-4-26b-a4b-it` / `@cf/moonshotai/kimi-k2.7-code` | Only these two confirm vision |
| **Escalation only** (never default) | `@cf/zai-org/glm-5.2`, `@cf/moonshotai/kimi-k2.7-code` | The flagship, most-expensive models β one fat run can eat a big slice of the daily pool |
Model IDs resolve under pi's default provider (`cloudflare-workers-ai`), so the
short `@cf/...` form works. Full form: `cloudflare-workers-ai/@cf/openai/gpt-oss-20b`.
## Core invocation patterns
**Sandbox tools with `-t` (or `-nt` for none), and use `--no-session` for
ephemeral offload.**
```bash
# BEST for edits: text-out, no tools, Opus applies the result.
# Pipe the current file in; get the full new file content back.
pi -p -nt --no-session --model @cf/openai/gpt-oss-20b \
"Here is src/schemas/income.ts:\n$(cat src/schemas/income.ts)\n\nAdd an optional \`source\` field mirroring src/schemas/expense.ts. Output the COMPLETE new file, nothing else." \
> /tmp/income.new.ts # then Opus reviews + writes it
# Pure-text digest via stdin
cat taskNotes/accounts-balance-formula/*.md | \
pi -p -nt --model @cf/google/gemma-4-26b-a4b-it \
"Summarize the open decisions in <=300 words."
# Read-only recon β let pi use tools; use gpt-oss-120b for reliability,
# or gpt-oss-20b with EXPLICIT tool phrasing.
pi -p --no-session --model @cf/openai/gpt-oss-120b \
-t read,grep,find,ls \
"Use grep/find to list every file under src/routes that references org memberships. Return paths only."
# Structured output when you need to parse tool calls / final text
pi -p --mode json --no-session --model @cf/openai/gpt-oss-120b \
-t read,edit,write "<task>" 2>/dev/null \
| jq -rc 'select(.type=="message_end")'
```
- **Text mode (`pi -p`)** prints the final assistant text to stdout. If the model
emits no final message (e.g. it "thought" a tool call but never issued one),
stdout is **empty** β check `--mode json` for what happened. **JSON mode**
streams LF-delimited events (`session`, `agent_start`, `message_*`,
`tool_execution_*`, `agent_end{messages}`); a `tool_execution_start` count of
0 on a tool task means the tool loop failed. Non-zero exit / exit 124
(timeout) = failure; stderr carries diagnostics.
- Add `-a` / `--approve` to trust project-local `.pi/` extensions, skills, and
agents for the run.
- Sandbox tighter with `--no-builtin-tools` (keep only custom/extension tools)
or `--no-tools`/`-nt` (all off). Deny specific tools with `-xt bash`.
## Parallel fan-out (the flagship pattern)
Opus writes a precise per-file changeset, then dispatches one pi run **per file
in parallel** β each isolated in context and cost β then reviews and applies.
Prefer the **text-out variant** so cheap models work and Opus stays in control
of what lands on disk:
```bash
for f in src/routes/income.ts src/routes/expense.ts src/routes/reports.ts; do
( pi -p -nt --no-session --model @cf/openai/gpt-oss-20b \
"File $f:\n$(cat $f)\n\n<scoped change>. Output the COMPLETE new file only." \
> /tmp/pi.$(basename $f) ) &
done
wait
# Opus now diffs each /tmp/pi.* against the original, sanity-checks, and Writes it.
```
If you instead let pi edit files directly (`-t read,edit,write`), use
`gpt-oss-120b` for a reliable tool loop, and typecheck the aggregate diff.
## RPC mode β long-lived, steerable worker
When you want to steer or abort mid-run and watch spend, spawn a persistent
worker instead of one-shot print:
```bash
pi --mode rpc --no-session --model @cf/openai/gpt-oss-120b
```
Write JSON commands one-per-line to stdin (`prompt`, `steer`, `follow_up`,
`abort`, `set_model`, `get_session_stats` β tokens+cost, `get_last_assistant_text`,
`fork`, `get_messages`); read the same streamed events back. **Framing is strict
LF-only JSONL** β split on `\n`, strip trailing `\r`, and do **not** use Node
`readline` (it breaks on U+2028/U+2029). `get_session_stats` lets Opus watch cost
and `abort` a runaway.
## Guardrails
- **Never default to a flagship / most-expensive model** (`glm-5.2`,
`kimi-k2.7-code`) β a single fat run can burn a big slice of the daily pool.
Escalate to them by hand only.
- **Tool loops are the flaky part, not the models.** Prefer text-out (`-nt`) and
let Opus apply edits. When you do need tools, use `gpt-oss-120b`; only use
`gpt-oss-20b` with explicit "use the X tool" phrasing; smoke-test any other
model's 3-tool loop before trusting it headlessly (`glm-4.7-flash` timed out).
- **Always pass `-t` or `-nt`** to scope tools; never hand a broad task write
access it doesn't need.
- **Keep every run bounded** β a looping or tool-failed run still spends input
tokens against the shared pool. Fan out over many small, scoped runs rather
than one open-ended one. If a gateway dynamic route is already configured,
target it with `--model dynamic/<route>` to inherit its budget and rate limits.
## Quick reference
```
pi -p one-shot, prints final text, exits
--mode json|rpc machine-readable events / bidirectional protocol
--model @cf/... pick the model (short form uses default provider)
-t a,b -xt a,b allow / deny tools
-nt -nbt no tools / no builtin tools (prefer -nt for text-out)
--no-session ephemeral (don't save)
-c -r --session <id> continue / resume / target a session
--fork <id> branch a session non-destructively
-a trust project-local .pi resources
--list-models [q] list available models
@file... attach files as context
```
Companion Files
references/usecases.md
7 KB
text/markdown
Danger Zone
Deleting this skill will remove all associated files. This action cannot be undone.
Owner
Prasham Trivedi
Created
7/9/2026, 6:35:50 PM
Last Updated
7/9/2026, 6:35:50 PM
π Skill ID
119lnvd-atQvUdyVYo1WQ