pi-agent-foreman
Send Pi agents back to work when they stop before the job is done.
Package details
Install pi-agent-foreman from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-agent-foreman- Package
pi-agent-foreman- Version
0.5.2- Published
- Sep 17, 2026
- Downloads
- 1,323/mo · 1,323/wk
- Author
- alexshpunt
- License
- MIT
- Types
- extension
- Size
- 652.7 KB
- Dependencies
- 1 dependency · 4 peers
Pi manifest JSON
{
"image": "https://raw.githubusercontent.com/alexshpunt/pi-agent-foreman/main/assets/foreman-gallery.webp",
"extensions": [
"./src/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
Your agent finished early.
The tests are still waiting. The implementation has a "small follow-up." The agent has helpfully explained what somebody should do next.
Foreman sends it back to work.
Pi Agent Foreman watches the final exchange after every settled Pi run. If the agent openly admits that it stopped before finishing required work, a small second model gives it one firm instruction: finish the job now.
The foreman sees the last user message and the agent activity that followed it, then either calls veto or stays quiet. The activity includes every assistant text, compact tool-call arguments, and success or error statuses. Private thinking and full tool results stay out. This keeps enough context for background updates without turning the review into tool-call archaeology.
Install
pi install npm:pi-agent-foreman
Requires Pi 0.83 or newer. Foreman uses the Node.js runtime bundled with your Pi installation.
Cost and privacy
When enabled, Foreman makes one extra review request after each settled Pi run. auto uses
TypeSafe when a key is configured and the selected Pi model otherwise. If TypeSafe is
unavailable, Foreman falls back to the model judge.
The reviewer receives the last user message plus the assistant's text, compact tool arguments,
and success or error statuses. It does not receive private thinking or full tool results.
TypeSafe decisions are stored locally in <agent dir>/agent-foreman/decisions.jsonl.
Set up the foreman
Run:
/agent-foreman
The menu lets you:
- turn Back to Work on or off;
- choose a foreman from the models already available in Pi;
- choose its reasoning level;
- choose the Judge:
auto,model, ortypesafe.
Back to Work is on by default. Until you choose a dedicated foreman, it uses the current session model and reasoning level. Choosing a model automatically enables the mode.
The selection is stored globally in Pi's settings.json:
{
"agentForeman": {
"enabled": true,
"model": "openai-codex/gpt-5.6-luna",
"thinking": "low"
}
}
You do not need to edit this file yourself.
The two judges
There are two ways to judge a settled run.
The model judge asks a nested model to call a veto tool. It writes the instruction it
sends back, in the language of the assistant message.
The TypeSafe judge asks a TypeSafe System One model for probabilities instead and decides in code: one request, one answer per question, no tool call and no generated prose. The instruction is built from the answer, so it does not name the unfinished work in detail; the agent still has the turn in its context.
agentForeman.judge selects one:
| Value | Behaviour |
|---|---|
auto |
The TypeSafe judge when a key is configured, the model judge otherwise. This is the default. |
model |
Always the model judge. |
typesafe |
The TypeSafe judge, falling back to the model judge when TypeSafe cannot answer. |
The fallback is what keeps the feature safe to leave on: a missing key, a refused request, or a service that is down all end with the model judge doing the review, and the session shows one warning about it.
Give the TypeSafe judge a key in one of two places. Either the environment of the Pi process:
export TYPESAFE_API_KEY=...
Or Pi's own credential file, which is read through Pi's public helper:
{
"typesafe": { "type": "api_key", "key": "..." }
}
The environment wins. The /agent-foreman menu shows which of the two the judge is using.
{
"agentForeman": {
"enabled": true,
"judge": "auto",
"threshold": 0.5
}
}
One request asks about the settled exchange: whether required work is still unfinished, whether
the agent put it off, the four reasons a stop can be legitimate, what kind of work is left, and
which language the request is in. threshold is the minimum probability that required work is
unfinished. The instruction goes back in the language of the request.
Both judges follow the same policy, written once in src/policy.ts: the model judge reads it
as prose, the TypeSafe judge asks about it as typed questions, so the two cannot drift apart on
what counts as a legitimate stop.
Every TypeSafe decision is appended to <agent dir>/agent-foreman/decisions.jsonl, one JSON
line per settled run, with every answer, the decision and its reason, and the instruction when
one was sent. The instruction itself also lands in the session file; the numbers behind it only
exist in this log.
Tuning the judge
npm run bench sends a set of invented exchanges to the real judge and compares each
decision with the intended behaviour in bench/cases.ts. The cases cover lazy stops, the
legitimate reasons to stop, and the cases that are already known to be hard. Every case is
written for that file: no case is taken from a real session, and none names a real
repository, commit, or log. A failing case is a tuning target, not a broken build.
npm run bench # all cases, one run each
npm run bench -- --repeat 3 # stability: three runs per case
npm run bench -- --group lazy,target # only some groups
npm run bench -- --case todo-in-reply # one case
npm run bench -- --threshold 0.7 # the tuning knobs
This costs real API calls and is not part of npm test or CI. Every run writes the full
result to bench/.results/last.json (ignored by git) and exits non-zero when a case fails.
Custom prompt
Create either a project prompt:
.pi/agent-foreman/prompt.md
.pi/agent-foreman/config.json
or a global prompt:
~/.pi/agent/agent-foreman/prompt.md
~/.pi/agent/agent-foreman/config.json
A trusted project prompt takes precedence over the global prompt. The project file is ignored when the project is not trusted.
Without config.json, prompt.md completely replaces the built-in reviewer prompt. To append your instructions instead, add:
{
"mode": "append"
}
The supported modes are override and append. If the prompt or configuration cannot be read, Foreman shows a warning and uses its built-in prompt.
What it looks like
When the foreman catches an unfinished answer:
⛑ Foreman sent the agent back to work
The instruction itself is delivered as a normal user message. The main agent does not receive a foreman wrapper or hidden transcript.
Pressing Esc to abort a run never summons the foreman. Research answers, genuinely completed work, and agents waiting for background work or sub-agents they already started are left alone.
Development
git clone https://github.com/alexshpunt/pi-agent-foreman.git
cd pi-agent-foreman
npm install
npm test
License
MIT
