@kky42/pi-hermes-goal
Pi extension providing Hermes-style persistent /goal loop with judge-model evaluation, subgoals, and turn budget enforcement
Package details
Install @kky42/pi-hermes-goal from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@kky42/pi-hermes-goal- Package
@kky42/pi-hermes-goal- Version
1.0.2- Published
- May 25, 2026
- Downloads
- not available
- Author
- kky42
- License
- ISC
- Types
- extension
- Size
- 84.8 KB
- Dependencies
- 0 dependencies · 4 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
@kky42/pi-hermes-goal
Pi extension providing a Hermes-style persistent /goal loop. Set a goal, and the agent keeps working across turns — a judge model evaluates each response and decides whether to continue or stop. No hidden tools, no system-prompt mutation. Just normal user messages in a loop.
Install
pi install npm:@kky42/pi-hermes-goal
How it works
- You set a goal with
/goal <text> - The agent starts working immediately — the goal text becomes the first user message
- After each turn, a judge model reads the agent's response and decides:
{"done": true}or{"done": false} - If not done, a continuation prompt is injected as a normal user message and the agent keeps going
- The loop stops when the judge says done, you pause/clear, or the turn budget runs out
The agent never sees goal-management tools. There are no create_goal, get_goal, or update_goal tools. The loop is entirely control-plane — the agent just sees user messages.
Commands
/goal <text>
Set a new goal and start working immediately.
/goal refactor the auth module to use the new token format
/goal --max-turns 10 write tests for all public API endpoints
Options:
--max-turns N— override the default turn budget (default: 20)
/goal status
Show the current goal state.
⊙ Goal (active, 3/20 turns): refactor the auth module
⏸ Goal (paused, 5/20 turns — user-paused): write integration tests
✓ Goal done (12/20 turns): add rate limiting middleware
/goal pause
Pause auto-continuation without clearing state. The goal can be resumed later.
/goal resume
Resume a paused goal. Resets the turn counter and re-activates the loop.
/goal clear
Clear the current goal and stop the loop.
Subgoals
Add mid-loop acceptance criteria that the judge will also check.
/subgoal <text>
/subgoal make sure all error messages are user-friendly
/subgoal add JSDoc comments to every exported function
/subgoal status
List current subgoals with their 1-based indices.
/subgoal remove N
Remove a specific subgoal by index.
/subgoal clear
Remove all subgoals while keeping the original goal.
Judge model
The judge is an auxiliary model call that happens after every agent turn. It sees:
- The original goal text
- Any subgoals
- The agent's most recent response
- Current time
It replies with a single JSON object:
{"done": true, "reason": "The response explicitly reports completion."}
The extension uses your session's current model as the judge by default. A strict JSON parsing contract handles fenced, embedded, or malformed judge output — three consecutive parse failures auto-pause the goal with a diagnostic.
Turn budget
Default: 20 turns. When the budget is exhausted, the goal pauses with a clear message:
⏸ Goal paused — 20/20 turns used. Use /goal resume to keep going, or /goal clear to stop.
No wrap-up prompt is sent — it just pauses. Resume resets the counter.
Interruption handling
- Ctrl+C / abort: pauses the goal immediately with reason
user-interrupted. No partial output is judged. - User messages: real user input takes priority over queued continuations
- Empty responses: skipped (not judged)
E2E tests
Two real-model E2E tests verify the goal loop against deepseek/deepseek-v4-flash with reasoning high:
npm run e2e:wait # agent must run ≥2min before claiming done
npm run e2e:count # agent counts 1→10, one number per turn
Override model and reasoning:
npm run e2e:count -- --model openai/gpt-5.5 --thinking low
Package structure
src/
core.ts # goal state machine, transitions, subgoals
judge.ts # judge prompt templates, JSON parsing
extension.ts # Pi extension wiring, commands, turn_end hook
e2e-runner.ts # CLI builder shared by E2E scripts
e2e-analysis.ts # wait-test: timing analysis from session JSONL
counting-analysis.ts # count-test: number-sequence analysis
scripts/
run-wait-e2e.mjs # wait E2E: spawn pi, verify ≥2min elapsed
run-counting-e2e.mjs # count E2E: spawn pi, verify 1→10 sequence
tests/
core.test.ts # continuation prompts, subgoals block
transitions.test.ts # state machine: done, budget pause, parse failures
timing-goals.test.ts # time-qualified goal enforcement
subgoal.test.ts # add, remove, clear subgoals
judge.test.ts # parser robustness
extension.test.ts # integration: faux provider, full goal loop