@agimon-ai/po-loop
Session-scoped recurring prompt scheduler and loop controls for Pi coding agents.
Package details
Install @agimon-ai/po-loop from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@agimon-ai/po-loop- Package
@agimon-ai/po-loop- Version
0.0.0-alpha.20- Published
- Oct 18, 2026
- Downloads
- 1,100/mo · 1,100/wk
- Author
- agiflow-ai
- License
- MIT
- Types
- extension
- Size
- 217.3 KB
- Dependencies
- 7 dependencies · 4 peers
Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
@agimon-ai/po-loop
Send a prompt now, then repeat it at a bounded interval for the current session.
Part of the Po distribution.
Several loops can coexist. Loop is a minor mode and remains active while at least one scheduled prompt belongs to the current session.
Alpha: launcher and scheduling contracts may change between releases.
Requirements
- Node.js 24 or newer
Install
The seeded modes.yaml selects Loop in default.packages. Keep it there or select it through a
layer; it is not fixed host infrastructure.
Start and manage loops
Activate the Loop minor mode, then ask the agent to set an interval loop or a cron job; it uses the
loop_start tool. The Activity Loops section lists the session's loops whether or not the mode is
active, and each row has a stop control. /loops lists loops and /loops stop <instanceId> stops
one.
The default interval is 300 seconds. Accepted intervals range from 30 to 3600 seconds. A loop runs its prompt once immediately, then schedules later passes.
If Pi is busy, a due pass waits for the shared agent to become idle. Multiple due signals can coalesce rather than creating overlapping model turns. Stopping a loop prevents future passes but does not rewind side effects from a pass already sent.
Lifecycle and cost
Loop state belongs to the session's po/loop-launchers service; it is not a durable queue.
Replacing or shutting down the session aborts pending launches and stops active timers. Resuming a
transcript does not restart old loops.
Every pass can start another model turn and repeat tool or external side effects. Choose conservative intervals, make prompts idempotent where possible, and stop loops when the recurring work is complete.
Web extension slots
The Loop Activity section declares loop.registration for start controls and loop.items for
session-scoped instance rows. Other web plugins may fill either slot; Loop owns the section shell and
renders all registered fills without requiring a feature-specific dependency.
Extension authors: cross-extension launchers
Launcher definitions use the shared Cordis service. A consumer registers a launcher and returns its cleanup callback. Cordis removes that launcher when either package or the session unloads, then registers it again when the provider returns.
import { PO_LOOP_LAUNCHERS_SERVICE, requirePoLoopLaunchers } from '@agimon-ai/po-loop/loop-launchers';
import type { Context } from '@deepseek-ai/cordis';
export function myLoopPlugin(ctx: Context): void {
ctx.inject([PO_LOOP_LAUNCHERS_SERVICE], (sessionContext) => {
const registration = requirePoLoopLaunchers(sessionContext).register({
id: 'example.recurring-check',
source: '@example/po-recurring-check',
label: 'Recurring check',
async launch({ instanceId, signal }) {
signal.throwIfAborted();
// Start session work. The returned stop callback owns cleanup.
return { instanceId, stop: () => undefined };
},
});
return () => registration.dispose('Contributor unloaded.');
});
}
Mount that plugin on the runner's shared Po Cordis root. Loop owns the registry and default
launcher. Consumers depend only on
@agimon-ai/po-loop/loop-launchers; there is no process-global registry or
session-ID lookup API.
The package root exports the service contract types.
Development
pnpm build
pnpm typecheck
pnpm test
pnpm lint
Maintained by Agimon.
License
MIT
Server entries live directly in src/extensions/. They declare commands, minor mode owners, and optional services. The helpers own registration and cleanup; onDispose clears UI state, while session service disposal stops pending launches and timers. Services live in named folders and public exports remain flat.