@pi-unipi/watchdog
Jev watchdog for long-running tool calls and background tasks — judges stuck work via TypeSafe System One and kills or warns
Package details
Install @pi-unipi/watchdog from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@pi-unipi/watchdog- Package
@pi-unipi/watchdog- Version
3.0.0-alpha.0- Published
- Sep 25, 2026
- Downloads
- 1,060/mo · 1,060/wk
- Author
- neuron-mr-white
- License
- MIT
- Types
- extension
- Size
- 35.8 KB
- Dependencies
- 2 dependencies · 2 peers
Pi manifest JSON
{
"skills": [],
"themes": [],
"prompts": [],
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
@pi-unipi/watchdog
Jev watchdog for long-running tool calls and background tasks. Uses the TypeSafe System One Decision model (the same jev model the long-horizon mode router uses) to judge whether a running tool call or background task is stuck, and kills or warns accordingly.
Off by default. Configure in /unipi:settings → Watchdog.
How it works
Every intervalMin minutes (default 5), the watchdog sends ONE jev request per watched item:
- status (choice): progressing / waiting / stuck / looping
- persistent (noul): is this a long-lived service operating normally?
A kill (or warn) fires when:
- status is stuck or looping
- confidence ≥
confidence(default 0.8) - the persistent noul is < 0.5, OR the status is
looping(an error loop is not healthy, even for a service) - for
agreeChecks(default 2) consecutive checks
The persistent veto protects dev servers, file watchers, and daemons that are operating normally. A loop that keeps printing errors is NOT healthy — it gets killed even if it looks like a service.
What gets watched
| Item | Setting | Kill mechanism |
|---|---|---|
| bash tool calls | watchBash (default on) |
process-group kill of the detected child shell |
The bash kill never overrides pi's tool: it scans pi's direct children for the command string (in its raw and shell-expanded forms — ~/$VAR, quotes stripped, since a -c shell expands and implicit-execs a simple command) and requires EXACTLY ONE match. Zero or several matches downgrade to a warning instead of guessing.
| background tasks | watchBgTasks (default on) | stopTask via the shared registry |
| other tools (web, image, mcp, subagents) | otherTools (off/warn/abort-turn) | notify / abort turn |
Never watched: ask_user (human wait), quick tools (read/write/edit/grep/find/ls), persistent servers (no completion triggers configured).
Settings
| Setting | Default | Description |
|---|---|---|
enabled |
false |
Off by default — no timers run until enabled |
intervalMin |
5 |
Check interval in minutes |
firstCheckMin |
2 |
Minutes until the first check |
confidence |
0.8 |
Minimum jev confidence to act |
agreeChecks |
2 |
Consecutive agreeing checks before acting |
action |
kill |
Kill the item, or only warn |
watchBash |
true |
Watch bash tool calls |
watchBgTasks |
true |
Watch background tasks |
otherTools |
warn |
For tools without a kill handle: warn or abort the turn |
Tool result annotation
When the watchdog kills a bash call, the tool result carries:
⚠ Killed by unipi watchdog after 95s: jev judged it stuck (confidence 0.92) on 2 consecutive checks — no new output for 95s. Do not blindly re-run; investigate or change approach.
The original output follows the warning. isError is set to true.
Debug logging
Set UNIPI_DEBUG_WATCHDOG=1 to enable debug logging to ~/.unipi/logs/watchdog.log:
2026-09-23T09:46:58Z before_agent_start mode=judged skills=37
2026-09-23T09:46:58Z judged 37 -> 12 kept=[work, fix, ...] latency=376ms failOpen=false