@asm3r96/pi-loops
v0.1.1
Published
A reusable Pi extension that adds a supervised loop harness around the normal Pi coding agent. Supports bounded LLM nodes, deterministic gates, steering, evidence collection, and composable workflow definitions.
Maintainers
Readme
pi-loops
A reusable Pi extension that adds a supervised loop harness around the Pi coding agent.
The agent still works as normal — it thinks, investigates, edits files, runs tools, and writes code. The loop extension owns the workflow around the agent: state, node order, tool scope, steering, evidence, validation, approvals, and completion.
This extension ships with no pre-built loops. It gives you the runtime and tooling to build your own workflows. Add your loops in src/loops/ and the agent will help you design them.
Features
- Generic loop runtime — sequence typed nodes (code, LLM, gate, approval, finalizer)
- Bounded LLM nodes — each node has scoped tools, timeout, model assignment, and steering rules
- Deterministic gates — validate artifacts and evidence without LLM cost
- Evidence collection — every tool call, command, and file change tracked automatically
- Steering — the loop detects stalls, over-research, repeated failures and nudges the agent
- Context cleaning — sanitize tool-call noise between nodes via code handlers
- Session persistence — loop state survives Pi session restarts
- Per‑node model routing — assign different models and thinking levels to different nodes
loop_reporttool — structured agent-to-loop handoff
Installation
# Install for all projects
pi install npm:@asm3r96/pi-loops
# Or install from git
pi install git:github.com/Asm3r96/pi-loops
# Or load directly
pi -e ./src/index.tsAfter install, the extension auto-loads on Pi startup. The agent will also discover the bundled pi-loops skill from skills/pi-loops/, so it can guide users through designing and creating their own loops.
Quick start — build your first loop
After installing, ask the agent:
Help me build a loop that does X.The agent will read the bundled skill and walk you through creating:
- A loop definition in
src/loops/my-loop/definition.ts - Optional code handlers in
src/loops/my-loop/handlers.ts - Registration in
src/loops/index.ts - Reload and run
The skill also includes a plain-text design reference at skills/pi-loops/references/github-issue.md. This is not runnable loop code; it is a walkthrough the agent can read to understand how a real multi-node loop can be structured.
Available commands
| Command | Description |
|---------|-------------|
| /loop start <definition> [input...] | Start a new loop |
| /loop status | Show current run state |
| /loop list | List available loop definitions |
| /loop cancel | Cancel active run |
| /loop pause | Pause active run |
| /loop resume | Resume paused/idle loop |
Architecture
src/
├── index.ts Extension entry: commands, events, tool registration
├── types.ts Loop/workflow type definitions
├── runtime.ts Generic loop runtime engine
├── nodes.ts Code handler registry + gate/LLM execution
├── state.ts Session persistence (save/restore via Pi session entries)
├── evidence.ts Tool observation + steering triggers
├── tools.ts loop_report custom tool
└── loops/
└── index.ts Add your loops hereKey node types
| Type | Description |
|------|-------------|
| code | Deterministic logic (fetch, transform, validate, side-effect) |
| llm | Agent works inside bounded scope, reports via loop_report |
| gate | Validates artifacts and evidence deterministically |
| approval | Pauses for user decision |
| finalizer | Writes final result |
The loop_report tool
LLM nodes signal completion by calling loop_report. The report includes a summary, artifacts, changed files, and confidence. It is a proposal — the next gate decides whether to pass, request a retry, or fail.
Adding a new loop
src/loops/my-loop/definition.ts— export aLoopDefinitionsrc/loops/my-loop/handlers.ts— write code handlers and register themsrc/loops/index.ts— import and register
// loops/index.ts
import { createMyLoopDefinition } from "./my-loop/definition.ts";
import { registerMyLoopHandlers } from "./my-loop/handlers.ts";
export function registerLoopPackages(registerDefinition) {
registerDefinition(createMyLoopDefinition());
registerMyLoopHandlers();
}Reload Pi and run:
/reload
/loop start my-loop input=valueLicense
MIT
Built with Pi.
