@llblab/pi-actors
Local Actor Kernel for Pi
Package details
Install @llblab/pi-actors from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@llblab/pi-actors- Package
@llblab/pi-actors- Version
0.42.0- Published
- Jul 19, 2026
- Downloads
- 1,761/mo · 412/wk
- Author
- llblab
- License
- MIT
- Types
- extension, skill
- Size
- 2.5 MB
- Dependencies
- 0 dependencies · 2 peers
Pi manifest JSON
{
"extensions": [
"./dist/pi-actors/index.js"
],
"sourceExtensions": [
"./index.ts"
],
"skills": [
"./dist/skills"
],
"sourceSkills": [
"./skills"
],
"image": "https://github.com/llblab/pi-actors/raw/main/banner.jpg"
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-actors

Local actor kernel for Pi.
pi-actors turns trusted local programs, scripts, services, pipelines, recipes, and sub-agents into addressable actors that Pi can spawn, steer, inspect, and reuse. It is the bridge between one-shot shell commands and durable local capability memory.
A command is a moment. An actor is a local thing with time: address, lifecycle, logs, mailbox, messages, artifacts, state, and an interaction contract.
trusted local capability
→ command template
→ recipe
→ spawn
→ run:<id>
→ message / inspect / artifacts
→ reusable tool memory
Why it exists
Agents are good at reasoning, but they should not reconstruct the same fragile background command every time a task becomes long-lived. pi-actors gives Pi a local-first actor layer: work can outlive the current turn, expose bounded state, receive typed instructions, produce artifacts, and graduate into persistent recipe-backed tools under ~/.pi/agent/recipes.
Use it when the correct shape is not "run a command and forget" but "start a local capability, keep its handle, and come back with intent."
The promise
- Spawn long-lived work without shell gymnastics. Start services, workers, subagents, fanouts, and pipelines as named actor runs.
- Steer instead of restarting. Send typed
messageenvelopes to runs, tools, branches, rooms, sessions, or coordinators. - Inspect intentionally. Read status, logs, messages, mailboxes, artifacts, registry health, and room rosters at decision points.
- Promote what works. Persist trusted command templates and recipes as durable local tools in
~/.pi/agent/recipes. - Keep orchestration local. State is file-backed, inspectable, operator-owned, and designed for Pi sessions rather than a cloud broker.
Core verbs
pi-actors compresses local orchestration into three public verbs:
| Verb | Use it when | Result |
|---|---|---|
spawn |
Work may outlive this turn, fan out, produce artifacts, or need later steering | A run:<id> actor with lifecycle and state |
message |
An existing actor should be continued, stopped, approved, killed, or given scoped input | One typed envelope delivered to one address |
inspect |
You need evidence before deciding the next step | Bounded views of status, logs, messages, registry, artifacts, or rooms |
Everything else is an adapter until proven otherwise.
Install
pi install npm:@llblab/pi-actors
Or from git:
pi install git:github.com/llblab/pi-actors
The npm package is dist-first for JavaScript-only runtimes: Pi metadata points at the named compiled entrypoint dist/pi-actors/index.js plus mirrored runtime assets, so extension discovery identifies pi-actors rather than an anonymous dist directory. Source TypeScript and source skills remain packaged for TypeScript-native or checkout-based runtimes.
First run: actor mode in one minute
Use actors instead of ad hoc shell backgrounding when work is long-running, stateful, resumable, artifact-producing, service-like, parallel, agentic, or worth saving.
Start an actor:
spawn template="sleep 30" as=run:demo
Inspect it when you need evidence:
inspect target=run:demo view=status
inspect target=run:demo view=tail lines=40
Steer it with a typed message:
message to=run:demo type=control.kill body=stop
For non-trivial actor workflows, load the bundled actors skill before improvising. For multi-model review or delegated audit, load the bundled swarm skill.
Address surface
Core addresses stay small:
run:<id> one detached actor run
tool:<name> executable registered tool actor
Advanced addresses exist for coordination and diagnostics:
branch:<run>/<branch> branch-local worker endpoint
room:<run> run-local group timeline plus roster
coordinator current session coordination path
session: current session actor surface
session:all cross-session diagnostics inventory
Messages use one envelope shape:
{
"to": "run:review",
"from": "coordinator",
"type": "control.continue",
"summary": "Continue after checkpoint",
"body": "continue",
"reply_to": "msg_123",
"correlation_id": "task_456",
"metadata": {}
}
Routing comes from to, actor ownership, and runtime policy. type describes intent. Recipes should expose semantic message types instead of transport knobs.
Feature showcase
| Surface | What it gives you | Typical move |
|---|---|---|
| Command templates | Portable command graphs with placeholders, defaults, guards, retries, parallel nodes, recovery, and timeouts | Wrap a trusted local executable without writing a bespoke tool |
| Recipes | JSON/Markdown capability specs with metadata, args, defaults, imports, mailbox contracts, artifacts, and async mode | Save a known-good local workflow as reusable muscle memory |
| Async runs | File-backed detached lifecycle, logs, progress, output, cancellation, artifacts, and durable terminal follow-up notifications | Let model work, media jobs, services, or pipelines continue after the turn |
| Message protocol | Typed envelopes across run, tool, branch, room, coordinator, and session targets | Continue, approve, kill, or route work without restarting actors |
| Rooms and rosters | Run-local group timeline with actor join/leave, contacts, previews, and branch-aware delivery | Coordinate multiple subagents under one visible run |
| Registry and recipe doctor | Discovered tools, overrides, drafts, invalid recipes, and advisory risk labels | Audit local capability memory before using or promoting it |
| Draft promotion | Captured ad hoc spawn patterns can become explicit recipes through one operator-selected promotion or bounded automatic unchanged-source review | Turn successful improvisation into durable local tools without granting a reviewer executable-authoring authority |
| Review/swarm recipes | Maintained packaged pipelines with preflight, marked semantic evidence, quorum knobs, model/thinking inheritance, one-turn prompt-file transport, and diagnostics | Delegate reviews without rebuilding fanout commands |
| Actor inspector | One manual Recipe → Messages or Turns → timeline → one detail level overlay for owned actor evidence, plus confirmed K → control.kill for the selected running run |
Understand the selected recipe and launch, follow actor traffic and persisted subagent turns, or explicitly terminate one owned actor without exposing another session or signaling directly |
| Packaged recipe QA | Installed-package-safe checks for helper paths, mailbox contracts, platform scope, artifacts, and recipe structure | Keep shipped actor components executable and diagnosable |
Detached actors survive ordinary agent turns. When their owning Pi session quits, reloads, or is replaced, pi-actors scans run state without the ordinary index depth cap and attempts canonical control.kill for each readable still-running exact-owner run. Destructive control is fenced by immutable run generation and serialized against state-directory restart; terminal, ambiguous, changed-generation, and other-session runs remain untouched. Unreadable/corrupt state becomes an explicit failure and every shutdown writes a bounded summary under the run root; actors owned by descendant Pi sessions remain outside the exact-owner contract and require their own shutdown hook or manual OS recovery.
Golden path: from local workflow to actor memory
Create a reusable async actor recipe in the user recipe root:
mkdir -p ~/.pi/agent/recipes
cat > ~/.pi/agent/recipes/docs_review.json <<'JSON'
{
"description": "Start an async docs review actor",
"async": true,
"args": ["scope:path", "model:string", "thinking:string"],
"defaults": { "model": "{current_model}", "thinking": "{current_thinking}" },
"mailbox": {
"accepts": ["control.kill", "control.continue"],
"emits": ["review.completed", "run.failed"]
},
"template": "pi -p --model {model} --thinking {thinking} --no-tools \"Review {scope} for unclear actor-runtime onboarding. Return concise findings.\""
}
JSON
Because it lives under ~/.pi/agent/recipes/, the filename becomes the tool id. {current_model} and {current_thinking} inherit the active Pi session policy; pass explicit values only when a run should intentionally diverge.
Run it:
docs_review scope="README.md" run_id=docs_review
Inspect it:
inspect target=tool:pi-actors view=triage
inspect target=run:docs_review view=status
inspect target=run:docs_review view=tail lines=80
inspect target=run:docs_review view=messages
inspect target=run:docs_review view=mailbox
Steer it:
message to=run:docs_review type=control.continue body=continue
message to=run:docs_review type=control.kill body=stop
Recipe memory model
The persistent tool surface is location-derived:
~/.pi/agent/recipes/*.json
~/.pi/agent/recipes/*.md
Rules:
- User recipes in
~/.pi/agent/recipes/are tools by location. - Recipe filenames define tool ids.
- User recipes override same-name lower-priority recipes.
- Same-id JSON recipes shadow Markdown recipes in the same priority layer.
- Packaged recipes are standard-library components, not automatically installed operator policy.
- Draft recipes in
~/.pi/agent/recipes/drafts/are replayable memory, not active tools. register_toolcreates, updates, lists, deletes, or explicitly promotes one draft recipe file through the normal agent interface.- Batch draft consolidation is automatic and silent. Prefer fenced
register_tool draft=...for one early promotion; deliberate move/copy into the recipe root remains valid but may defer an already captured batch.
Register a foreground tool:
register_tool name=transcribe_audio \
description="Transcribe a local audio file" \
template="~/bin/transcribe {file:path} {lang=ru} {model:string}"
Register a recipe-backed tool:
register_tool name=docs_review \
description="Start an async docs review actor" \
template="docs_review" \
args="scope:path,model:string"
Promote a captured draft only after explicit operator approval:
register_tool name=docs_review draft=~/.pi/agent/recipes/drafts/spawned-run.json
Successful inline spawns accumulate draft memory automatically. When twelve drafts exist, pi-actors waits for the foreground turn and active actors to finish, captures an exact immutable batch, and attaches a value-free structural projection to a silent reviewer with no tools. The projection replaces canonical names, draft basenames, and raw hashes with batch-local opaque occurrence IDs and equality-only content groups, and omits recipe bodies, template text, defaults, authored prose, and filesystem paths; the reviewer selects one quota-free promote or discard decision per source but cannot return recipe content. The executor derives every promotion from the exact captured source, applies the batch through its journaled transaction, garbage-collects discarded drafts, and leaves newer drafts for the next cycle.
Automatic review and mutation remain separate trust boundaries: reviewers receive only value-free structural/usage evidence and have neither filesystem tools, raw recipe access, mutation tools, nor executable-authoring authority. Active-tool portfolio review excludes recipes detected as sensitive and can only select keep, unchanged-source rename (evolve), unchanged-source demote, or deduplication of canonically identical recipes (merge). replace, split, and any executable contract change require an explicit operator-authored recipe mutation through the existing recipe/register surface. Deterministic executors revalidate the exact batch, source and target hashes, complete captured recipes, quarantine state, and journals before committing or recovering internally. The runtime exposes no separate manual batch command.
Inspect the registry:
inspect target=recipes view=status
inspect target=recipes view=reviews
inspect target=recipes view=summary verbose=true
inspect target=tool:pi-actors view=triage
Failed automatic cycles retain a bounded failed stage, error, retry count, and exact next action. Retry the same immutable scope through the reserved runtime actor; reset only disposable failed/completed admission state:
message to=tool:pi-actors type=review.retry body={"scope":"draft"}
message to=tool:pi-actors type=review.retry body={"scope":"tool"}
message to=tool:pi-actors type=review.reset body={"scope":"draft"}
Draft retry with an existing transaction journal resumes the original reviewer run and uses the journal’s authenticated decisions for lineage/evidence; it never launches a second reviewer over already-committed filesystem state. Tool review recovery that already has approved/transaction evidence cannot be reset; retry preserves that evidence and may require /reload for the safe session_start activation boundary.
Command templates
A command template is the launch substrate. It can be a string, a sequence, or a composed graph.
Templates support:
- Named placeholders such as
{file},{model},{prompt}; - Compact types such as
string,path,int,number,bool,enum(a,b); - Defaults such as
{lang=ru}and{dry_run:bool=true}; - Fallback and small ternary forms;
- Sequences with stdin flow;
- Parallel nodes;
- Retries, recovery, failure policy, delays, guards, and timeouts;
- Async run values such as
{run_id},{state_dir},{actor_address},{default_room}, and{communication_file}.
The template owns execution shape. The recipe owns saved metadata, defaults, imports, mailbox, artifacts, and async launch policy. The run actor owns detached lifecycle, state, messages, cancellation, and inspection.
Packaged recipe library
Packaged recipes live under recipes/ and helper scripts live under scripts/.
The library includes:
- Subagent launchers;
- Review, critic, planner, verifier, merger, judge, normalizer, and artifact atoms;
- Quorum and lens-style pipelines;
- Repo-health, release-summary, research-synthesis, development-tasking, docs-maintenance, and room-swarm pipelines;
- Coordinator-locker and actor-message utilities;
- Local music-player actor recipe.
Packaged recipes are building blocks. Use spawn file=<recipe> for maintained packaged pipelines before rebuilding equivalent shell commands. Copy or wrap them into ~/.pi/agent/recipes/ only when they should become durable operator-facing tools.
Choosing the right surface
| If the work is... | Prefer... |
|---|---|
| Short, bounded, and foreground | Ordinary tools or registered foreground tools |
| Long-running, service-like, parallel, agentic, artifact-producing, or controllable | spawn / async recipe |
| Already running and needs new input | message |
| Unclear, failing, or ready for a decision | inspect |
| A multi-actor collaboration under one run | room:<run> plus branch addresses |
| A useful output that should survive context compression | Artifacts |
| A repeated local workflow | Recipe/tool memory |
When a directly spawned inline/ad hoc actor or a recipe outside the user recipe root completes successfully, pi-actors may include a promotion suggestion in its terminal follow-up notification. The agent should ask first and never auto-save.
Platform support
Core actor state, inspection, foreground tools, and basic async runs are portable Node.js behavior. Run-local messaging and stop/kill use platform adapters under the same message API.
| Surface | Linux/macOS/WSL | Native Windows |
|---|---|---|
| Foreground tools, recipe discovery, inspect | Supported | Supported |
| Async runs and file-backed state | Supported | Supported |
| Mailbox-only actors and worker recipe | Supported | Supported |
| FIFO control endpoints | Supported | Not supported; use mailbox or named pipe |
| Named-pipe control endpoints | Not needed | Supported when recipe exposes one |
| Process cancel/kill | Process group signal with pid fallback | Windows process-tree adapter |
Packaged recipes should prefer mailbox/wake behavior for portable control. Recipes that require FIFO, Unix shell tools, or platform-specific media backends should make that limitation visible in docs or diagnostics before launch.
Safety boundary
pi-actors is local-first, not sandbox-first.
Commands execute directly without shell evaluation where possible, but trusted executables still run with the same system permissions as Pi. Only register commands, scripts, recipes, and paths you trust.
High-risk templates such as shells, interpreter eval modes, network access, external side effects, and broad filesystem mutation may surface warnings, but the runtime is not a security boundary. Automatic reviewers cannot author or change executable contracts: they receive attached immutable evidence with no tools and may only select unchanged-source lifecycle/name operations. Disable all automatic draft/tool review and safe-boundary activation before starting Pi with PI_ACTORS_AUTOMATIC_REVIEW=off; inspect target=tool:pi-actors view=status reports automatic_review=false.
Prefer:
- Narrow commands;
- Explicit paths;
- Typed args;
- Bounded timeouts for bounded work;
- Explicit tool allowlists for subagents;
- Deterministic utility recipes for filesystem writes;
- Human approval for destructive or external side effects.
Non-goals
pi-actors is not:
- A generic workflow DSL;
- A remote agent interoperability protocol;
- A heavyweight broker;
- A sandbox;
- A facade that hides logs, artifacts, ownership, or local side effects;
- A polling-first async runner.
Its job is narrower: make trusted local capabilities addressable, messageable, inspectable, and reusable by agents.
Documentation
Start here:
Core docs:
- Command templates
- Template recipes
- Async runs
- Actor messages
- Actor inspector
- Tool registry
- Recipe library
License
MIT
