@hazrid1993/pi-advisor
A second model that peer-reviews every turn of your main pi agent and injects concise advice. Pick any model from your registry as the advisor.
Package details
Install @hazrid1993/pi-advisor from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@hazrid1993/pi-advisor- Package
@hazrid1993/pi-advisor- Version
0.7.0- Published
- Sep 2, 2026
- Downloads
- 219/mo · 20/wk
- Author
- hazrid1993
- License
- MIT
- Types
- extension
- Size
- 188.9 KB
- Dependencies
- 1 dependency · 4 peers
Pi manifest JSON
{
"extensions": [
"./advisor.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-advisor
A second model that reviews your main pi agent and injects concise, actionable advice.
[!NOTE] Official release:
@hazrid1993/pi-advisoris published on npm and listed in the Pi package catalog.
What it does
Coding agents can develop tunnel vision. pi-advisor runs a second model after each main-agent turn to catch concrete mistakes, missed constraints, fragile designs, and likely wasted work.
The advisor:
- sees recent user prompts, assistant messages, tool calls, and tool results;
- can inspect the project with isolated read-only
read,grep, andfindtools; - stays silent when the main agent is on track;
- can send one
nit,concern, orblockeradvisory; - cannot edit files, execute commands, or change session state.
Advice is framed as guidance for the main agent to weigh—not blindly obey.
Research: why a paired LLM improves coding results
The two-model design is backed by peer-reviewed research. PairCoder: Pair Programming-Inspired Two-Agent Collaboration for Code Generation (Chen et al., Findings of ACL 2026) shows that pairing two LLMs — one generating code, the other reviewing it — measurably beats single-model inference on coding tasks.
Reported results:
| Result | Detail |
|---|---|
| Higher accuracy | Up to 20.3% improvement in pass@1 over single-model inference; 91.0% pass@1 on HumanEval across eight representative backbones |
| Consistent gains | Improvements hold across 13 LLMs, so the effect is not specific to one model family |
| Cheaper than heavy multi-agent setups | 40–70% fewer tokens than multi-agent baselines while still outperforming them |
| Heterogeneous pairs shine | Many pairings of different models outperform both constituent models |
What this means for pi-advisor:
- Generator + reviewer beats a lone generator. PairCoder's two-agent split — one model writes, one reviews — is exactly the shape
pi-advisorgives pi: the main agent codes, the advisor model reviews every turn and catches what tunnel vision misses. - The reviewer can (and often should) be a different model. PairCoder found heterogeneous pairings frequently beat both constituent models — one reason
/advisorlets you pick any model rather than a copy of the main agent. - Lightweight beats heavyweight. PairCoder achieves its gains with 40–70% fewer tokens than multi-agent frameworks.
pi-advisorfollows the same deployment-conscious philosophy: a bounded advisor conversation (default 24,000 characters) sent as an append-only prefix for provider prompt-cache hits, read-only exploration, and silence when the main agent is already on track.
One honest difference: PairCoder alternates the two models between coder and reviewer roles when repeated errors signal a stalled interaction. pi-advisor keeps the roles fixed — the main agent always drives, the advisor always reviews — because in an interactive session the human decides when to change course.
Chen, Junhao, Xiang Li, Yibin Xu, Yuehan Cui, Fangsheng Weng, Hao Zhao, Fei Ma, and Qi Tian. 2026. PairCoder: Pair Programming-Inspired Two-Agent Collaboration for Code Generation. In Findings of the Association for Computational Linguistics: ACL 2026, pages 3043–3058, San Diego, California, United States. Association for Computational Linguistics. DOI: 10.18653/v1/2026.findings-acl.149. Code: yisuanwang/PairCoder.
Install and update
Install
Install the official package from npm:
pi install npm:@hazrid1993/pi-advisor
Then restart pi or run:
/reload
To install directly from the source repository instead:
pi install git:github.com/hazrid93/pi-advisor
pi install git:git@github.com:hazrid93/pi-advisor
Do not use the bare github.com/hazrid93/pi-advisor form; pi treats bare values as local paths.
Update
Use pi's package update command, then reload:
pi update --extensions
(pi update alone updates the pi CLI only — --extensions updates installed
packages; --all does both.) Unpinned installs — npm:@hazrid1993/pi-advisor
or git:github.com/hazrid93/pi-advisor — track the latest release this way.
Version-pinned installs (npm:@hazrid1993/pi-advisor@0.6.4, git tags/commits)
are deliberately skipped; re-pi install with the new version/ref to move them.
Then restart pi or run:
/reload
For a one-off local test:
git clone https://github.com/hazrid93/pi-advisor
cd pi-advisor
pi -e ./advisor.ts
Quick start
Choose an available advisor model:
/advisor
Or set one directly:
/advisor model anthropic/claude-sonnet-4-5
Check that it is active:
/advisor status
The advisor uses pi's existing model registry and provider authentication. It does not manage separate API keys.
What context the advisor sees
The advisor does not receive the main model's entire context window. It maintains a bounded, in-memory sliding transcript containing:
- each newly submitted user prompt;
- the corresponding assistant turn;
- tool calls and tool results from that turn.
New user prompts are captured once from the authoritative session branch and placed before the assistant work they triggered. This lets the advisor compare the implementation against the user's actual request instead of inferring intent from the assistant's behavior.
Default window
The default and recommended budget is:
24,000 characters (roughly 6,000 tokens)
The limit is character-based, not message-count-based. The budget bounds the advisor's persistent conversation (see Prompt-cache-friendly context below): when it is exceeded, the oldest half of past reviews is dropped at once. Cutting only at review boundaries keeps every tool result paired with its tool call, and dropping in batches (rather than one message at a time) amortizes the provider prompt-cache miss — one cold request, then many cache-hit reviews before the next trim.
Inspect or change the window at runtime:
/advisor context
/advisor context 50k
/advisor context 32000
/advisor context default
Accepted range: 512–200,000 characters. default, recommended, and reset restore 24,000.
A larger window improves long-task awareness but increases advisor input cost and latency on every review. Recommended starting points:
| Workload | Suggested value |
|---|---|
| Short fixes / low-cost advisor | 12k–24k |
| General coding work | 24k (default) |
| Long refactors / tool-heavy runs | 40k–80k |
The advisor conversation resets on session replacement, reload, compaction, tree navigation, and advisor configuration changes. Existing history is marked as seen rather than replayed; the advisor resumes with newly submitted prompts and turns.
Prompt-cache-friendly context
The advisor keeps a persistent, append-only conversation with its model across reviews. Each review sends everything that came before unchanged as the leading prefix and appends exactly one new user message (that turn's session update). Consecutive requests therefore share a byte-identical prefix — precisely what provider prompt caching matches against:
- OpenAI / Gemini-style automatic prefix caching discounts the repeated prefix with no API changes (the request just has to repeat it verbatim).
- Anthropic caches via
cache_controlbreakpoints, which pi-ai applies automatically for Anthropic-api models (system prompt, last tool definition, and the trailing conversation content). - A stable per-session id is forwarded as the provider prompt-cache key /
session-affinity id (OpenAI
prompt_cache_key, Anthropic-compatiblex-session-affinity, OpenRouterx-session-id) so cache lookups route consistently.
Without this, every review rebuilt the whole rolling transcript as a fresh single-message conversation: full input price for the entire window on every turn, and cache hits only on the system prompt + tools. With it, the uncached input per review is just the new session update — prior turns, the advisor's own notes, and its read/grep/find results are read from cache at the provider's discounted rate.
/advisor status shows per-review and session-wide token usage with the
cache split — raw totals plus the cached/written breakdown and the aggregate
hit rate, matching your provider's accounting (pi-ai reports input as
uncached-only, with cache reads/writes in separate buckets). High cache-read
on an Anthropic/OpenAI advisor model means the prefix is hitting.
Two tuning levers:
cacheRetention(config): Anthropic's default cache TTL is 5 minutes ("short"). Every-turn cadences keep it warm naturally (each hit refreshes the TTL), but sparse setups —agent_settled-only triggers, long quiet gaps — can exceed 5 minutes between reviews and cold-prefill every time."long"raises the TTL to 1 hour on models that support it."none"disables cache markers and session-affinity routing entirely.- Keep the advisor model + instructions stable mid-session: the system
prompt and tools are the head of the cached prefix; changing the advisor
model or
.pi/advisor.mdstarts a fresh cache (the runtime also resets the conversation on model/config changes, so behavior stays consistent).
Known bound: tool results larger than 10k chars are truncated in the persisted history copy (the live review saw the full result). The next request diverges at that message, so the cache falls back to the previous review's breakpoint — roughly one review cycle is re-processed, then the prefix is warm again. Rare, bounded, and the price of keeping the history budget predictable.
Project-scoped advisor instructions
Each trusted project can persist its own advisor priorities in:
<project>/.pi/advisor.md
Manage them from pi:
/advisor instructions
/advisor instructions set Focus on backwards compatibility and migration safety.
/advisor instructions show
/advisor instructions clear
/advisor instructions opens a multi-line editor. Instructions are loaded for every review in that project and survive restarts. They are ignored when pi has not trusted the project.
Project instructions refine what the advisor prioritizes. They cannot grant write/command capabilities or override higher-priority safety constraints.
Global advisor instructions (cross-repo)
A second, per-user instructions file persists across every repo:
~/.pi/agent/extensions/pi-advisor-instructions.md
Manage it from any pi session:
/advisor instructions global set Always prefer tests, avoid scope creep.
/advisor instructions global show
/advisor instructions global edit
/advisor instructions global clear
Then choose which source is active (saved to the global config):
/advisor instructions mode <project|global|none>
project is the default and opt-out of global: a fresh repo does not inherit the global file unless you switch to global. none uses neither. This lets you maintain one global guidance set and opt into it per repo without editing each project file.
Selectable review triggers
By default the advisor reviews at the end of each turn and after a turn that
contained a tool error (turn_end + tool_error). You can enable additional
review points or turn others off — capture of each finalized turn always runs
on turn_end regardless, so switching triggers never loses context.
One throttle shapes how often triggers actually start a review — work
cadence: turnInterval (default 1) reviews every N completed turns, which
self-adjusts to pacing (rapid bursts and slow thoughtful runs get the same
per-work coverage). Skipped turns coalesce rather than drop, and a run that
finishes early always flushes its final review at agent_settled with
everything coalesced — throttling never leaves a finished run unreviewed.
/advisor triggers # open the fuzzy-searchable toggle menu
/advisor triggers agent_settled # toggle one trigger by name
The menu is a keyboard-driven multi-select: type to filter, ↑/↓ to move, tab
to toggle a row, enter/ctrl+s to save (at least one must stay on), esc to
cancel. Changes persist to the global config.
| Trigger | Fires |
|---|---|
turn_end |
After every turn (default) |
tool_error |
After a turn that contained a tool error, deferred to turn_end (default) |
tool_result |
After each tool completes |
agent_settled |
Once when the whole run settles (no auto-continuation) — delivered non-interrupting |
mid_pause |
After a quiet period mid-run (debounced; at most once per input) |
input |
On user input — a prompt/intent review before the agent acts |
input only counts real user input (typed or RPC). pi also fires the
input event for messages injected by extensions — including this
extension's own <advisory> deliveries — and those are deliberately ignored,
otherwise the advisor would review its own advice or re-arm mid_pause after
every delivery (a self-triggering review loop).
agent_settled is the robust choice for "review once when done, not every
turn": it fires a single non-triggering review per run, so advice can't blast
one-by-one after completion. mid_pause is opt-in early-warning on genuine
mid-run inactivity; a fluid run that never pauses fires nothing from it.
Commands
| Command | Description |
|---|---|
/advisor |
Open the advisor model picker (fuzzy-searchable TUI) |
/advisor model <provider/id> |
Set the advisor model directly |
/advisor status |
Show configuration, backlog, and the last review result |
/advisor enable / disable |
Enable or disable reviews while keeping the selected model |
/advisor thinking <off|minimal|low|medium|high|xhigh> |
Configure advisor reasoning effort |
/advisor interrupting [on|off] |
Control whether all advice immediately triggers a main-agent turn |
/advisor sync <0-6> |
Pause the main loop when the advisor falls this many turns behind; 0 disables waiting |
/advisor context [chars|Nk|default] |
Inspect or set the advisor conversation budget |
/advisor rounds [0-12] |
Max advisor tool rounds per review (default 2; each round is an extra LLM call — lower = cheaper) |
/advisor turns [1-50|every] |
Review every N turns instead of every turn (default 1); skipped turns coalesce, and a finished run always flushes its final review |
/advisor pause [4000|4s] |
mid_pause quiet period before the once-per-run early-warning review (500ms–60s, default 4s) |
/advisor cache [short|long|none] |
Prompt-cache retention: short = 5m TTL (default), long = 1h for sparse cadences, none = disable markers + session affinity |
/advisor triggers [name] |
Toggle review triggers (default: turn_end, tool_error) |
/advisor instructions [show|set <text>|edit|clear] |
Manage project-scoped advisor guidance |
/advisor instructions global [show|set <text>|edit|clear] |
Manage global (cross-repo) advisor guidance |
/advisor instructions mode <project|global|none> |
Pick which instruction source is active (default: project) |
/advisor review |
Re-review the latest completed turn now |
/advisor help |
Show command help |
Advice delivery
| Severity | Intended use | Delivery when interrupting is off |
|---|---|---|
nit |
Cleanup, simplification, or low-risk opportunity | Non-interrupting; available at the next step boundary |
concern |
Material risk, missed constraint, or fragile direction | Interrupting steer |
blocker |
Continuing is clearly unsound or wasteful | Interrupting steer |
interrupting defaults to on, so all severities trigger a turn immediately. Set /advisor interrupting off to make only concern and blocker interrupt.
Reviews run in the background by default. /advisor sync 1 makes the main agent wait after every turn; values 2–6 allow a bounded backlog. The wait is abortable and occurs between turns, not during tool execution.
Configuration
Global configuration is stored at:
~/.pi/agent/extensions/pi-advisor.json
Example:
{
"enabled": true,
"advisorModel": "anthropic/claude-sonnet-4-5",
"thinking": false,
"thinkingLevel": "medium",
"contextChars": 24000,
"turnInterval": 1,
"maxToolRounds": 2,
"maxRetries": 3,
"interrupting": true,
"syncLag": 0,
"cacheRetention": "short"
}
| Field | Default | Description |
|---|---|---|
enabled |
true |
Master review switch |
advisorModel |
null |
Advisor model as provider/id; inactive until selected |
thinking |
false |
Enable advisor reasoning when supported by the model |
thinkingLevel |
"medium" |
Reasoning effort |
contextChars |
24000 |
Advisor conversation budget (append-only, cache-friendly; oldest half dropped at once when exceeded) |
turnInterval |
1 |
Review every N completed turns instead of every turn (work-cadence throttle — self-adjusts to slow vs rapid pacing); skipped turns coalesce; a finished run always flushes its final review; also /advisor turns |
maxToolRounds |
2 |
Maximum read-only exploration rounds per review; each round is an extra LLM call — the main per-review cost lever; hard-capped at 12 |
maxRetries |
3 |
Consecutive failures before the backlog is dropped |
interrupting |
true |
Whether every advisory immediately triggers a turn |
syncLag |
0 |
Backlog threshold before the main agent waits; 0 never waits |
midPauseMs |
4000 |
Quiet period (agent inactivity) before the once-per-run mid_pause early-warning review fires (500–60000; also /advisor pause) |
cacheRetention |
"short" |
Prompt-cache TTL preference forwarded to pi-ai: "short" (Anthropic 5m, default), "long" (1h where supported — for sparse review cadences), "none" (disable cache markers + session affinity). Unset also honors pi-ai's PI_CACHE_RETENTION env. Also /advisor cache |
systemPrompt |
built in | Optional full advisor system-prompt override |
The global config path follows pi's getAgentDir() and therefore respects PI_CODING_AGENT_DIR.
How it works
user prompt + completed main-agent turn
│
▼
staged per-turn deltas (bounded)
│
▼
persistent advisor conversation ←—— append-only prefix, re-sent verbatim
+ one new "Session update" msg (provider prompt-cache hits)
│
▼
advisor model + read/grep/find/advise
│
silence or one note
│
▼
pi.sendMessage(<advisory>)
Implementation overview:
advisor.ts— pi lifecycle hooks and/advisorcommandssrc/runtime.ts— staged deltas + persistent advisor conversation, user-prompt capture, queue, retries, resets, dedupe, and deliverysrc/transcript.ts— serialization of user, assistant, and tool-result messagessrc/agent.ts— second-modelcompleteSimpletool loop (history prefix +appendedresult)src/tools.ts— project-confined read-only tools andadvisesrc/project-instructions.ts— trusted project.pi/advisor.mdpersistencesrc/index.ts— configuration, context parsing, and advisory formatting
The queue is single-flight, so advisor reviews never overlap. Epoch guards discard stale in-flight advice after session rewrites. Repeated notes are suppressed with a recent-advice ring and normalized delivery-time dedupe.
Troubleshooting
| Symptom | Fix |
|---|---|
| Model is not found | Run /advisor and select from the live available-model list |
| No API key | Configure the provider through pi (/login or its environment variable) |
| Advisor says nothing | Silence is expected when work is on track; inspect /advisor status or try a stronger model |
| Reviews are expensive or slow | Lower context with /advisor context 12k, disable thinking, set /advisor rounds 1, or thin cadence with /advisor turns 3 |
| Advisor misses earlier requirements | Increase context with /advisor context 50k; only post-start/reload prompts are accumulated |
| Repeated review failures | Fix provider/rate-limit issues or choose another model; the backlog drops after three failures by default |
| Project instruction is ignored | Ensure the project is trusted and check /advisor instructions show |
| Read tool rejects a path | Advisor filesystem access is intentionally confined to the project root |
Development
Validated against @earendil-works/pi-* 0.84.4 (latest; handles the pi 0.84.0 breaking change where ModelRegistry.getApiKeyAndHeaders() returns ProviderHeaders with null header-deletion markers plus credential-resolved baseUrl/env, all forwarded to the advisor's pi-ai stream unchanged).
npm install
npm run typecheck
npm test
The test suite uses fake completions and requires no API key.
Uninstall
pi uninstall npm:@hazrid1993/pi-advisor
Optionally remove global configuration:
rm ~/.pi/agent/extensions/pi-advisor.json
Project-specific .pi/advisor.md files are not removed automatically.
Acknowledgements
The advisor concept, system prompt, severity ladder, advisory framing, and core runtime discipline are adapted from can1357/oh-my-pi. This project ports that behavior to stock pi's public extension API.
License
MIT