@llblab/pi-actors 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +5 -3
- package/BACKLOG.md +54 -29
- package/CHANGELOG.md +18 -2
- package/README.md +184 -300
- package/docs/actor-messages.md +6 -2
- package/docs/async-runs.md +3 -5
- package/docs/command-templates.md +2 -0
- package/docs/recipe-library.md +3 -0
- package/docs/task-first-recipes.md +29 -0
- package/docs/template-recipes.md +9 -14
- package/index.ts +158 -34
- package/lib/actor-inspector-tui.ts +374 -118
- package/lib/actor-rooms.ts +222 -24
- package/lib/async-runs.ts +59 -1
- package/lib/execution.ts +17 -0
- package/lib/file-state.ts +2 -1
- package/lib/observability.ts +82 -2
- package/lib/prompts.ts +2 -2
- package/lib/recipe-discovery.ts +86 -6
- package/lib/recipe-migration.ts +0 -2
- package/lib/recipe-references.ts +43 -10
- package/lib/temp.ts +55 -2
- package/lib/tools.ts +99 -11
- package/package.json +1 -1
- package/recipes/coordinator-locker.json +0 -1
- package/recipes/lens-swarm.json +0 -1
- package/recipes/music-player.json +0 -1
- package/recipes/pipeline-architect-coordinator.json +0 -1
- package/recipes/pipeline-artifact-bundle.json +0 -1
- package/recipes/pipeline-artifact-report.json +0 -1
- package/recipes/pipeline-artifact-write.json +0 -1
- package/recipes/pipeline-async-run-ops.json +0 -1
- package/recipes/pipeline-checkpoint-continuation.json +0 -1
- package/recipes/pipeline-development-tasking.json +0 -1
- package/recipes/pipeline-docs-maintenance.json +0 -1
- package/recipes/pipeline-media-library.json +0 -1
- package/recipes/pipeline-quorum-review.json +0 -1
- package/recipes/pipeline-release-readiness.json +0 -1
- package/recipes/pipeline-release-summary.json +0 -1
- package/recipes/pipeline-repo-health.json +0 -1
- package/recipes/pipeline-research-synthesis.json +0 -1
- package/recipes/pipeline-review-readiness.json +0 -1
- package/recipes/pipeline-room-swarm.json +48 -0
- package/recipes/subagent-artifact.json +0 -1
- package/recipes/subagent-checkpoint.json +0 -1
- package/recipes/subagent-conflict-report.json +0 -1
- package/recipes/subagent-contradiction-map.json +0 -1
- package/recipes/subagent-critic.json +0 -1
- package/recipes/subagent-evidence-map.json +0 -1
- package/recipes/subagent-followup.json +0 -1
- package/recipes/subagent-judge.json +0 -1
- package/recipes/subagent-merge.json +0 -1
- package/recipes/subagent-message.json +0 -1
- package/recipes/subagent-normalize.json +0 -1
- package/recipes/subagent-plan.json +0 -1
- package/recipes/subagent-prompt.json +0 -1
- package/recipes/subagent-quorum.json +0 -1
- package/recipes/subagent-review-coordinator.json +0 -1
- package/recipes/subagent-review.json +0 -1
- package/recipes/subagent-task-card.json +0 -1
- package/recipes/subagent-tools.json +0 -1
- package/recipes/subagent-verify.json +0 -1
- package/recipes/subagents-prompts.json +0 -1
- package/recipes/utility-actor-message.json +0 -1
- package/recipes/utility-artifact-manifest.json +0 -1
- package/recipes/utility-artifact-write.json +0 -1
- package/recipes/utility-changelog-head.json +0 -1
- package/recipes/utility-changelog-section.json +0 -1
- package/recipes/utility-coordinator-lock-snapshot.json +0 -1
- package/recipes/utility-git-log.json +0 -1
- package/recipes/utility-git-status.json +0 -1
- package/recipes/utility-jsonl-tail.json +0 -1
- package/recipes/utility-markdown-index.json +0 -1
- package/recipes/utility-package-summary.json +0 -1
- package/recipes/utility-playlist-build.json +0 -1
- package/recipes/utility-playlist-scan.json +0 -1
- package/recipes/utility-run-ops-snapshot.json +0 -1
- package/recipes/utility-run-state-files.json +0 -1
- package/recipes/utility-run-summary.json +0 -1
- package/recipes/utility-skill-summary.json +0 -1
- package/recipes/utility-validate-recipe.json +0 -1
- package/recipes/utility-validation-wrapper.json +0 -1
- package/scripts/room-swarm.mjs +243 -0
- package/skills/actors/SKILL.md +25 -12
- package/skills/swarm/SKILL.md +15 -1
package/README.md
CHANGED
|
@@ -1,236 +1,193 @@
|
|
|
1
1
|
# pi-actors
|
|
2
2
|
|
|
3
|
-
> Actor
|
|
3
|
+
> Local Actor Kernel for Pi
|
|
4
4
|
|
|
5
|
-
[
|
|
5
|
+

|
|
6
6
|
|
|
7
|
-
`pi-actors` turns local programs, scripts, services,
|
|
7
|
+
`pi-actors` turns trusted local programs, scripts, recipes, services, pipelines, and sub-agents into addressable actors that agents can spawn, message, inspect, and compose.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
## Start Here
|
|
12
|
-
|
|
13
|
-
- [Project Context](./AGENTS.md)
|
|
14
|
-
- [Open Backlog](./BACKLOG.md)
|
|
15
|
-
- [Changelog](./CHANGELOG.md)
|
|
16
|
-
- [Documentation](./docs/README.md)
|
|
17
|
-
- [Actors skill](./skills/actors/SKILL.md) — dense agent-facing reference for operating the extension
|
|
18
|
-
- [Swarm skill](./skills/swarm/SKILL.md) — multi-agent methodology, strategies, standards, and portable examples for actor-backed swarms
|
|
19
|
-
- [Swarm MAWP notes](./skills/swarm/references/development-swarm.md) — optional small-team development swarm reference
|
|
20
|
-
|
|
21
|
-
## What It Is
|
|
22
|
-
|
|
23
|
-
`pi-actors` is the runtime layer that lets a pi agent turn a local capability into a controllable actor:
|
|
9
|
+
It is not just a command registry. A tool is a verb. An actor is a noun with time: address, lifecycle, state, logs, mailbox, artifacts, and an interaction contract.
|
|
24
10
|
|
|
25
11
|
```text
|
|
26
|
-
program/process/service
|
|
12
|
+
program / process / service
|
|
27
13
|
→ command template
|
|
28
14
|
→ actor recipe
|
|
29
15
|
→ spawn
|
|
30
|
-
→
|
|
16
|
+
→ run:<id>
|
|
31
17
|
→ message / inspect / artifacts
|
|
32
18
|
```
|
|
33
19
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
- A sub-agent running `pi -p` in a clean context.
|
|
37
|
-
- A background music player controlled by `player.next` or `player.pause` messages.
|
|
38
|
-
- A validation or repo-health pipeline that reports completion and artifacts.
|
|
39
|
-
- A parallel quorum review with branch-level progress.
|
|
40
|
-
- Any trusted local process with a launch template and a useful control surface.
|
|
41
|
-
|
|
42
|
-
The key move is not just “register a command.” It is to wrap a process in an agent-readable contract:
|
|
43
|
-
|
|
44
|
-
- **Launch**: `spawn` starts the actor from a template or recipe.
|
|
45
|
-
- **Interface**: `mailbox` declares accepted and emitted message types.
|
|
46
|
-
- **Control**: `message` sends typed envelopes to runs, branches, tools, or the coordinator.
|
|
47
|
-
- **Observation**: `inspect` reads status, logs, messages, mailbox metadata, files, and artifacts intentionally.
|
|
48
|
-
- **Persistence**: `artifacts` and state files make outcomes durable.
|
|
49
|
-
- **Memory**: `~/.pi/agent/recipes/*.json` stores reusable actor-control wrappers across sessions.
|
|
50
|
-
|
|
51
|
-
## Key Features
|
|
52
|
-
|
|
53
|
-
- **Actor Runtime**: Starts local templates and recipes as addressable `run:<id>` actors with state, logs, message mailboxes, cancellation, and artifacts.
|
|
54
|
-
- **Agent-Managed Processes**: Wraps sub-agents, media players, pipelines, diagnostics, and other local programs as controllable entities instead of one-off commands.
|
|
55
|
-
- **Message-Oriented Control**: Uses `spawn`, `message`, and `inspect` as the public coordination vocabulary for start, control, and observation.
|
|
56
|
-
- **Actor Rooms**: Lets actors post shared messages to `room:<run>`, update join/leave rosters, inspect room timelines or members, read compact run communication snapshots, and see recent actor communication previews in the terminal without adding a heavyweight broker.
|
|
57
|
-
- **Mailbox Contracts**: Lets recipes declare what messages they accept and emit, so agents can discover how to interact with an actor.
|
|
58
|
-
- **Actor Tool Registry**: Stores persistent actor-control tools as recipe files in `~/.pi/agent/recipes/*.json` and registers them automatically on session start.
|
|
59
|
-
- **Command Template Substrate**: Keeps process launch portable with named placeholders, typed args, defaults, sequences, guarded nodes, retries, failure policy, and `parallel: true` fanout.
|
|
60
|
-
- **Composable Actor Recipes**: Stores reusable recipe JSON under `~/.pi/agent/recipes/*.json`; recipes can import other recipes, reuse defaults, declare artifacts, and opt into detached actor lifecycle with `async: true`.
|
|
61
|
-
- **Coordinator-Scoped Observability**: Shows ambient triangles for active actor runs and sends compact completion or request-for-attention follow-ups only to the launching coordinator.
|
|
62
|
-
- **Bounded Context Impact**: Returns compact output by default, truncates oversized stdout, and keeps full logs/artifacts in files for intentional inspection.
|
|
63
|
-
- **Local-First Tool Memory**: Still lets agents create durable semantic tools from trusted commands so they do not repeatedly reconstruct shell invocations.
|
|
20
|
+
## Core Contract
|
|
64
21
|
|
|
65
|
-
|
|
22
|
+
`pi-actors` compresses local agent orchestration to three durable verbs:
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
spawn create an addressable actor
|
|
26
|
+
message send one typed envelope to one address
|
|
27
|
+
inspect intentionally read state, logs, messages, contracts, or artifacts
|
|
28
|
+
```
|
|
66
29
|
|
|
67
|
-
|
|
30
|
+
Everything else is an adapter until proven otherwise.
|
|
31
|
+
|
|
32
|
+
Use `spawn` when work may outlive the current turn. Use `message` when the actor should be steered rather than restarted. Use `inspect` at decision points, after actor follow-ups, or during diagnosis. Do not build polling loops as the default coordination pattern.
|
|
33
|
+
|
|
34
|
+
## Install
|
|
68
35
|
|
|
69
36
|
```bash
|
|
70
37
|
pi install npm:@llblab/pi-actors
|
|
71
38
|
```
|
|
72
39
|
|
|
73
|
-
|
|
40
|
+
Or from git:
|
|
74
41
|
|
|
75
42
|
```bash
|
|
76
43
|
pi install git:github.com/llblab/pi-actors
|
|
77
44
|
```
|
|
78
45
|
|
|
79
|
-
##
|
|
46
|
+
## Address Surface
|
|
80
47
|
|
|
81
|
-
|
|
48
|
+
Actors and coordination endpoints are addressed with compact route strings:
|
|
82
49
|
|
|
83
50
|
```text
|
|
84
|
-
|
|
51
|
+
run:<id> one detached actor run
|
|
52
|
+
branch:<run>/<branch> branch-local actor endpoint
|
|
53
|
+
room:<run> shared run-local task room
|
|
54
|
+
coordinator launching coordinator attention path
|
|
55
|
+
session: current session actor surface
|
|
56
|
+
session:all cross-session inventory surface
|
|
57
|
+
tool:<name> executable registered tool
|
|
85
58
|
```
|
|
86
59
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
## Mental Model
|
|
60
|
+
Actor messages use one envelope shape:
|
|
90
61
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"to": "run:review",
|
|
65
|
+
"from": "coordinator",
|
|
66
|
+
"type": "control.continue",
|
|
67
|
+
"summary": "Continue after checkpoint",
|
|
68
|
+
"body": "continue",
|
|
69
|
+
"reply_to": "msg_123",
|
|
70
|
+
"correlation_id": "task_456",
|
|
71
|
+
"metadata": {}
|
|
72
|
+
}
|
|
102
73
|
```
|
|
103
74
|
|
|
104
|
-
|
|
105
|
-
- A **command template** is the reusable launch shape for that process, with named placeholders.
|
|
106
|
-
- An **actor recipe** is saved JSON containing a template, defaults, imports, mailbox metadata, artifacts, and optional detached lifecycle.
|
|
107
|
-
- A **registered tool** gives a template or actor recipe a stable agent-facing name.
|
|
108
|
-
- A **run actor** is one execution instance with state, logs, actor messages, mailbox metadata, status, cancellation, and kill control.
|
|
75
|
+
Routing is inferred from `to`, actor ownership, and runtime policy. Recipes should expose semantic message types, not transport knobs.
|
|
109
76
|
|
|
110
|
-
|
|
77
|
+
## Golden Path
|
|
111
78
|
|
|
112
|
-
|
|
79
|
+
Create a reusable async actor recipe in the user recipe root:
|
|
113
80
|
|
|
114
|
-
|
|
81
|
+
```bash
|
|
82
|
+
mkdir -p ~/.pi/agent/recipes
|
|
115
83
|
|
|
116
|
-
|
|
84
|
+
cat > ~/.pi/agent/recipes/docs_review.json <<'JSON'
|
|
117
85
|
{
|
|
118
|
-
"
|
|
119
|
-
"
|
|
120
|
-
"
|
|
121
|
-
"
|
|
122
|
-
"
|
|
123
|
-
"
|
|
124
|
-
|
|
125
|
-
}
|
|
86
|
+
"description": "Start an async docs review actor",
|
|
87
|
+
"async": true,
|
|
88
|
+
"args": ["scope:path", "model:string"],
|
|
89
|
+
"mailbox": {
|
|
90
|
+
"accepts": ["control.stop", "control.continue"],
|
|
91
|
+
"emits": ["review.completed", "run.failed"]
|
|
92
|
+
},
|
|
93
|
+
"template": "pi -p --model {model} --no-tools \"Review {scope} for unclear actor-runtime onboarding. Return concise findings.\""
|
|
126
94
|
}
|
|
95
|
+
JSON
|
|
127
96
|
```
|
|
128
97
|
|
|
129
|
-
|
|
98
|
+
Because it lives under `~/.pi/agent/recipes/`, the file becomes a persistent agent tool by location. The filename is the tool id.
|
|
99
|
+
|
|
100
|
+
Start it:
|
|
130
101
|
|
|
131
102
|
```text
|
|
132
|
-
|
|
133
|
-
inspect target=room:review view=status
|
|
134
|
-
inspect target=room:review view=roster
|
|
135
|
-
inspect target=room:review view=contacts
|
|
136
|
-
inspect target=room:review view=previews
|
|
137
|
-
inspect target=room:review view=messages
|
|
103
|
+
docs_review scope="README.md" model="current-review-model" run_id=docs_review
|
|
138
104
|
```
|
|
139
105
|
|
|
140
|
-
|
|
106
|
+
Inspect only when there is a reason:
|
|
141
107
|
|
|
142
|
-
|
|
108
|
+
```text
|
|
109
|
+
inspect target=run:docs_review view=status
|
|
110
|
+
inspect target=run:docs_review view=tail lines=80
|
|
111
|
+
inspect target=run:docs_review view=messages
|
|
112
|
+
inspect target=run:docs_review view=mailbox
|
|
113
|
+
```
|
|
143
114
|
|
|
144
|
-
|
|
115
|
+
Steer it through messages:
|
|
145
116
|
|
|
146
117
|
```text
|
|
147
|
-
|
|
118
|
+
message to=run:docs_review type=control.continue body=continue
|
|
119
|
+
message to=run:docs_review type=control.stop body=stop
|
|
148
120
|
```
|
|
149
121
|
|
|
150
|
-
|
|
122
|
+
## Actor Rooms
|
|
151
123
|
|
|
152
|
-
|
|
153
|
-
{
|
|
154
|
-
"name": "docs_review",
|
|
155
|
-
"async": true,
|
|
156
|
-
"args": ["scope:path", "model:string"],
|
|
157
|
-
"defaults": {},
|
|
158
|
-
"mailbox": {
|
|
159
|
-
"accepts": ["control.stop"],
|
|
160
|
-
"emits": ["review.completed", "run.failed"]
|
|
161
|
-
},
|
|
162
|
-
"template": "pi -p --model {model} --no-tools \"Review {scope} for unclear actor-runtime onboarding. Return concise findings.\""
|
|
163
|
-
}
|
|
164
|
-
```
|
|
124
|
+
Every spawned run can have a shared room at `room:<run>`. A room is not a broker and not a chat app. It is a run-local coordination surface: append-only timeline, compact roster, member discovery, and previews.
|
|
165
125
|
|
|
166
|
-
|
|
126
|
+
Actors can join, post, leave, and discover peers:
|
|
167
127
|
|
|
168
128
|
```text
|
|
169
|
-
|
|
129
|
+
message \
|
|
130
|
+
to=room:review \
|
|
131
|
+
from=branch:review/security \
|
|
132
|
+
type=actor.join \
|
|
133
|
+
summary="Security reviewer joined" \
|
|
134
|
+
body='{"role":"reviewer","caps":["security-review"],"claim":"Review auth boundary risks"}'
|
|
170
135
|
```
|
|
171
136
|
|
|
172
|
-
|
|
137
|
+
Inspect the room intentionally:
|
|
173
138
|
|
|
174
|
-
|
|
139
|
+
```text
|
|
140
|
+
inspect target=room:review view=status
|
|
141
|
+
inspect target=room:review view=previews
|
|
142
|
+
inspect target=room:review view=roster
|
|
143
|
+
inspect target=room:review view=contacts
|
|
144
|
+
inspect target=room:review view=messages
|
|
145
|
+
```
|
|
175
146
|
|
|
176
|
-
|
|
147
|
+
Room posts require a same-run sender, so unrelated runs do not pollute the roster. Direct messages and room messages use the same envelope; only the address changes. Direct `branch:<run>/<branch>` messages are private: they are forwarded through the parent run mailbox and recorded in the recipient branch inbox for worker protocols that consume queued branch work. For selected-recipient multicast, send to `room:<run>` with `metadata.recipients` set to same-run `branch:<run>/<branch>` addresses; this keeps one room transcript entry while forwarding branch-targeted copies.
|
|
177
148
|
|
|
178
|
-
|
|
149
|
+
## Actor Inspector
|
|
179
150
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
151
|
+
The terminal actor inspector is hidden by default. When opened without an explicit size, it shows 12 log rows by default. Use it when async actors are actively coordinating:
|
|
152
|
+
|
|
153
|
+
```text
|
|
154
|
+
/actors-inspector-toggle
|
|
155
|
+
/actors-inspector-toggle 20
|
|
156
|
+
/actors-inspector-filter room
|
|
157
|
+
/actors-inspector-filter direct
|
|
158
|
+
/actors-inspector-filter mention checkpoint
|
|
159
|
+
/actors-inspect 3
|
|
187
160
|
```
|
|
188
161
|
|
|
189
|
-
`
|
|
162
|
+
The table is compact and optimistic by default: bounded route/type/summary/body previews, capped noisy room rows, and an inline roster summary in the form `role/name` that wraps only when needed. Active roster members use the target color; members that sent `actor.leave` remain visible as inactive/muted participants from the current run. `/actors-inspect <number>` opens the selected row as a full-message view; toggle again to return to the table or close it. Actor display names come from room `actor.join` roster metadata or branch addresses, keeping debugger output plain and name-driven.
|
|
190
163
|
|
|
191
|
-
|
|
192
|
-
{
|
|
193
|
-
"name": "review-pair",
|
|
194
|
-
"async": true,
|
|
195
|
-
"imports": {
|
|
196
|
-
"review": "review-one.json"
|
|
197
|
-
},
|
|
198
|
-
"parallel": true,
|
|
199
|
-
"failure": "branch",
|
|
200
|
-
"template": [
|
|
201
|
-
{ "name": "review", "values": { "scope": "README.md" } },
|
|
202
|
-
{ "name": "review", "values": { "scope": "docs/template-recipes.md" } }
|
|
203
|
-
]
|
|
204
|
-
}
|
|
205
|
-
```
|
|
164
|
+
## Registry Model
|
|
206
165
|
|
|
207
|
-
|
|
166
|
+
The persistent tool surface is file-discovered:
|
|
208
167
|
|
|
209
168
|
```text
|
|
210
|
-
|
|
211
|
-
description="Start a parallel async docs review" \
|
|
212
|
-
template="review-pair.json"
|
|
169
|
+
~/.pi/agent/recipes/*.json
|
|
213
170
|
```
|
|
214
171
|
|
|
215
|
-
|
|
172
|
+
That directory is operator-managed executable memory.
|
|
216
173
|
|
|
217
|
-
|
|
174
|
+
Rules:
|
|
218
175
|
|
|
219
|
-
|
|
176
|
+
- User recipes in `~/.pi/agent/recipes/` are tools by location;
|
|
177
|
+
- Recipe filenames define tool ids;
|
|
178
|
+
- User recipes override same-name lower-priority recipes;
|
|
179
|
+
- Packaged recipes are standard-library components, not automatically installed operator policy;
|
|
180
|
+
- `register_tool` creates, updates, lists, or deletes user recipe files through the normal agent interface.
|
|
220
181
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
`pi-actors` is also useful for exposing stable local commands as normal tools. For example, register an STT command:
|
|
182
|
+
Example foreground tool:
|
|
224
183
|
|
|
225
184
|
```text
|
|
226
|
-
register_tool name=
|
|
185
|
+
register_tool name=transcribe_audio \
|
|
227
186
|
description="Transcribe a local audio file" \
|
|
228
|
-
template="/
|
|
187
|
+
template="~/bin/transcribe {file:path} {lang=ru} {model:string}"
|
|
229
188
|
```
|
|
230
189
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
For reusable actor workflows, keep the large template and mailbox contract in a recipe file and register a small tool:
|
|
190
|
+
Example recipe-backed tool:
|
|
234
191
|
|
|
235
192
|
```text
|
|
236
193
|
register_tool name=docs_review \
|
|
@@ -239,180 +196,107 @@ register_tool name=docs_review \
|
|
|
239
196
|
args="scope:path,model:string"
|
|
240
197
|
```
|
|
241
198
|
|
|
242
|
-
|
|
199
|
+
Inspect the discovered registry:
|
|
243
200
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
{
|
|
248
|
-
"description": "Start an async docs review",
|
|
249
|
-
"async": true,
|
|
250
|
-
"args": ["scope:path", "model:string"],
|
|
251
|
-
"template": "pi -p --model {model} --tools read,bash \"Review {scope}\""
|
|
252
|
-
}
|
|
201
|
+
```text
|
|
202
|
+
inspect target=recipes view=status
|
|
203
|
+
inspect target=recipes view=summary verbose=true
|
|
253
204
|
```
|
|
254
205
|
|
|
255
|
-
|
|
206
|
+
## Command Templates
|
|
256
207
|
|
|
257
|
-
|
|
208
|
+
A command template is the portable launch substrate. It can be a string, a sequence, or a composed graph.
|
|
258
209
|
|
|
259
|
-
|
|
260
|
-
register_tool name=call_subagent \
|
|
261
|
-
description="Run pi as a non-interactive sub-agent" \
|
|
262
|
-
template="pi -p --model {model} --no-tools {prompt}" args="prompt:string,model:string"
|
|
263
|
-
```
|
|
210
|
+
Templates support:
|
|
264
211
|
|
|
265
|
-
|
|
212
|
+
- Named placeholders: `{file}`, `{model}`, `{prompt}`;
|
|
213
|
+
- Compact types: `string`, `path`, `int`, `number`, `bool`, `enum(a,b)`;
|
|
214
|
+
- Defaults: `{lang=ru}`, `{dry_run:bool=true}`;
|
|
215
|
+
- Fallback and small ternary forms;
|
|
216
|
+
- Sequences with stdin flow;
|
|
217
|
+
- Parallel nodes;
|
|
218
|
+
- Retries, recovery, failure policy, delays, and guarded execution;
|
|
219
|
+
- Async run values such as `{run_id}`, `{state_dir}`, `{actor_address}`, `{default_room}`, and `{communication_file}`.
|
|
266
220
|
|
|
267
|
-
|
|
268
|
-
register_tool name=call_subagent \
|
|
269
|
-
description="Run a focused pi sub-agent without tools" \
|
|
270
|
-
update=true
|
|
271
|
-
```
|
|
221
|
+
The template owns execution shape. The recipe owns saved metadata, defaults, imports, mailbox, and artifacts. The run actor owns detached lifecycle, state, messages, cancellation, and inspection.
|
|
272
222
|
|
|
273
|
-
|
|
223
|
+
## Recipe Library
|
|
274
224
|
|
|
275
|
-
|
|
276
|
-
register_tool name=call_subagent template=null
|
|
277
|
-
```
|
|
225
|
+
Packaged recipes live under `recipes/` and helper scripts live under `scripts/`.
|
|
278
226
|
|
|
279
|
-
|
|
227
|
+
The library includes:
|
|
280
228
|
|
|
281
|
-
|
|
229
|
+
- Sub-agent launchers;
|
|
230
|
+
- Review, critic, planner, verifier, merger, judge, normalizer, and artifact atoms;
|
|
231
|
+
- Quorum and lens-style pipelines;
|
|
232
|
+
- Repo-health, release-summary, research-synthesis, development-tasking, docs-maintenance, and room-swarm pipelines;
|
|
233
|
+
- Coordinator-locker and actor-message utilities;
|
|
234
|
+
- Local music-player actor recipe.
|
|
282
235
|
|
|
283
|
-
|
|
284
|
-
{
|
|
285
|
-
"description": "Transcribe a local audio file",
|
|
286
|
-
"template": "/path/to/stt --file {file} --lang {lang=ru}"
|
|
287
|
-
}
|
|
288
|
-
```
|
|
236
|
+
Packaged recipes are building blocks. Copy them into `~/.pi/agent/recipes/` or register tools that point at them when they should become durable operator-facing capabilities.
|
|
289
237
|
|
|
290
|
-
|
|
291
|
-
{
|
|
292
|
-
"description": "Run pi as a non-interactive sub-agent",
|
|
293
|
-
"args": ["prompt:string", "model:string"],
|
|
294
|
-
"template": "pi -p --model {model} --no-tools {prompt}"
|
|
295
|
-
}
|
|
296
|
-
```
|
|
238
|
+
## When To Use What
|
|
297
239
|
|
|
298
|
-
|
|
240
|
+
Use a foreground registered tool when the work is short, bounded, and does not need lifecycle.
|
|
299
241
|
|
|
300
|
-
|
|
242
|
+
Use an async recipe or `spawn` when the work is long-running, service-like, parallel, agentic, artifact-producing, or needs later control.
|
|
301
243
|
|
|
302
|
-
Use `
|
|
244
|
+
Use `room:<run>` when multiple actors in the same run need shared context, roster discovery, or group-visible progress.
|
|
303
245
|
|
|
304
|
-
|
|
246
|
+
Use artifacts when outputs should survive context compression.
|
|
305
247
|
|
|
306
|
-
|
|
307
|
-
{
|
|
308
|
-
"as": "run:docs_review",
|
|
309
|
-
"template": "pi -p --model {model} --no-tools {prompt}",
|
|
310
|
-
"values": {
|
|
311
|
-
"prompt": "Review docs/spec.md for contradictions.",
|
|
312
|
-
"model": "current-review-model"
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
```
|
|
248
|
+
Use mailbox declarations when an actor has a stable conversational surface.
|
|
316
249
|
|
|
317
|
-
|
|
250
|
+
## Safety Boundary
|
|
318
251
|
|
|
319
|
-
|
|
320
|
-
{ "to": "run:docs_review", "type": "control.continue", "body": "continue" }
|
|
321
|
-
```
|
|
252
|
+
`pi-actors` is local-first, not sandbox-first.
|
|
322
253
|
|
|
323
|
-
|
|
254
|
+
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.
|
|
324
255
|
|
|
325
|
-
|
|
326
|
-
{ "target": "run:docs_review", "view": "tail", "lines": "80" }
|
|
327
|
-
```
|
|
256
|
+
High-risk templates such as shells, interpreter eval modes, and broad filesystem mutation may surface warnings, but the runtime is not a security boundary.
|
|
328
257
|
|
|
329
|
-
|
|
258
|
+
Prefer:
|
|
330
259
|
|
|
331
|
-
|
|
260
|
+
- Narrow commands;
|
|
261
|
+
- Explicit paths;
|
|
262
|
+
- Typed args;
|
|
263
|
+
- Bounded timeouts for bounded work;
|
|
264
|
+
- Explicit tool allowlists for sub-agents;
|
|
265
|
+
- Deterministic utility recipes for filesystem writes;
|
|
266
|
+
- Human approval for destructive or external side effects.
|
|
332
267
|
|
|
333
|
-
|
|
268
|
+
## Non-Goals
|
|
334
269
|
|
|
335
|
-
|
|
270
|
+
`pi-actors` is NOT:
|
|
336
271
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
description="Start an async pi subagent with an explicit tool allowlist" \
|
|
344
|
-
template="subagent-tools.json"
|
|
345
|
-
|
|
346
|
-
register_tool name=subagents_prompts \
|
|
347
|
-
description="Start parallel no-tools subagents from a prompt array as one run actor" \
|
|
348
|
-
template="subagents-prompts.json"
|
|
349
|
-
|
|
350
|
-
subagent_prompt prompt="Review docs/async-runs.md for unclear wording." run_id=docs_review
|
|
351
|
-
subagent_tools prompt="Inspect package metadata and report risks." tools="read,bash" run_id=package-review
|
|
352
|
-
subagents_prompts \
|
|
353
|
-
prompts='["Review README.md for unclear release-onboarding wording. Return concise findings.","Review docs/template-recipes.md for unclear recipe-import wording. Return concise findings."]' \
|
|
354
|
-
run_id=review-prompts
|
|
355
|
-
inspect target=run:review-prompts view=tail
|
|
356
|
-
```
|
|
272
|
+
- A generic workflow DSL;
|
|
273
|
+
- A remote agent interoperability protocol;
|
|
274
|
+
- A heavyweight broker or chat subsystem;
|
|
275
|
+
- A sandbox;
|
|
276
|
+
- A facade that hides logs, artifacts, ownership, or local side effects;
|
|
277
|
+
- A polling-first async runner.
|
|
357
278
|
|
|
358
|
-
|
|
279
|
+
Its job is narrower: make trusted local capabilities addressable, messageable, inspectable, and reusable by agents.
|
|
359
280
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
template="music-player.json" \
|
|
364
|
-
args="source:string,loop:bool=true,volume:int=70,player:enum(auto,mpv,ffplay,cvlc,play)=auto"
|
|
365
|
-
|
|
366
|
-
music_player source="~/Music" volume=55 run_id=music
|
|
367
|
-
message to=run:music type=player.next body=next
|
|
368
|
-
message to=run:music type=player.pause body=pause
|
|
369
|
-
message to=run:music type=player.play body=play
|
|
370
|
-
message to=run:music type=player.stop body=stop
|
|
371
|
-
```
|
|
281
|
+
## Documentation
|
|
282
|
+
|
|
283
|
+
Start here:
|
|
372
284
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
-
|
|
378
|
-
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
-
|
|
383
|
-
-
|
|
384
|
-
-
|
|
385
|
-
-
|
|
386
|
-
-
|
|
387
|
-
-
|
|
388
|
-
- Timeout is disabled by default; set a positive `timeout` on bounded commands that should fail closed. Numeric node fields may read placeholders such as `timeout: "{timeout_ms}"`.
|
|
389
|
-
- Nodes may set `when` to skip conditional work and `delay` in milliseconds to wait before launch; delay is not inherited.
|
|
390
|
-
- Failed steps default to `failure: "continue"`, which records the failure and continues with empty stdin.
|
|
391
|
-
- `failure: "branch"` stops the current sequence/subtree without cancelling sibling parallel branches; `failure: "root"` aborts the composition.
|
|
392
|
-
- `retry` retries a leaf or whole node on non-zero exit; default attempts is `1`.
|
|
393
|
-
- `recover` runs a cleanup command template between failed retry attempts and stops retries if cleanup fails.
|
|
394
|
-
- Commands execute directly without shell evaluation, but trusted executables still run with the same permissions as pi.
|
|
395
|
-
- Obvious high-risk templates such as shells, interpreter eval modes, and broad filesystem mutation surface lightweight warnings without blocking existing tools.
|
|
396
|
-
- `async: true` on a recipe selects detached run-actor lifecycle; omitted or false runs the recipe foreground through registered tools.
|
|
397
|
-
- Layer boundaries stay explicit: command templates define synchronous execution graphs; template recipes add saved JSON metadata/import resolution and named `artifacts`; run actors add detached lifecycle, state, IPC, and observability.
|
|
398
|
-
- `spawn`, `message`, and `inspect` are high-level actor adapters. `spawn` creates `run:<id>` actors from recipes or inline templates with optional state/artifact metadata, `message` sends one typed envelope to `run:<id>` mailboxes, `branch:<run>/<branch>` mailboxes, `room:<run>` task rooms, `tool:<name>` calls, or coordinator/session attention paths, and `inspect` intentionally reads `run:<id>` status/tail/messages/mailbox metadata, `room:<run>` status/messages/previews/roster/contacts, coordinator/session run status, or registered `tool:<name>` contracts while the broader actor/message protocol is refined.
|
|
399
|
-
- `spawn`, `message`, and `inspect` are the public async coordination vocabulary. Low-level async actions map to this actor API: start belongs to `spawn`; send/control/stop/kill belongs to `message`; status/tail/messages/list belongs to `inspect`. Use `inspect view=messages` for actor-envelope streams. Use `control.stop`, `control.cancel`, and `control.kill` for run termination; runtime-prefixed control aliases are no longer part of the public surface.
|
|
400
|
-
- Actor management returns compact text by default; pass `verbose: true` to `inspect` when full JSON state is needed.
|
|
401
|
-
- Detached runs inject `{run_id}` and `{state_dir}` into template values for run-local artifacts or recipe-specific control endpoints.
|
|
402
|
-
- Runtime actor messages are persisted in the run state dir; coordinator attention is inferred by the runtime, not exposed as recipe or message-envelope input. Follow-ups preserve bounded body previews and metadata for decision messages.
|
|
403
|
-
- Native Windows should use WSL or a recipe-specific transport for run-local message-controlled recipes; Linux uses stricter `/proc` runner ownership checks for stale PID protection.
|
|
404
|
-
- Registered tools may set `template` to a recipe JSON path/name; calling them follows that recipe's `async` mode.
|
|
405
|
-
- File-backed recipes may declare `imports` and embed imported recipes with `{ "name": "alias" }` nodes, or read `{alias.defaults.key}`, `{alias.defaults.key=fallback}`, and `{alias.values.key?yes:no}` references before command-template execution.
|
|
406
|
-
- Interactive sessions show ambient actor activity as stable `▷` triangles aggregated across runs started by the current agent session. Each running run actor contributes at least one triangle; parallel active branches can contribute more. One `▶` wave moves over the active set; terminal `done`/`failed`/unhandled `killed`/`exited` messages are delivered as compact follow-up context only to the launching coordinator agent, while intentional `cancel`, `kill`, and `stop` actions stay silent because the action already reports synchronously. Failed commands and in-flight parallel branch completions can bubble through `command.done`; successful final leaf completions remain diagnostic to avoid sequential pipeline noise.
|
|
407
|
-
- Use `{file}` as the canonical local file path arg.
|
|
408
|
-
- Stored `script` entries are rejected with migration guidance.
|
|
409
|
-
|
|
410
|
-
See [`docs/command-templates.md`](./docs/command-templates.md) for the portable synchronous command-template contract; [`docs/template-recipes.md`](./docs/template-recipes.md) for saved recipe JSON; [`docs/async-runs.md`](./docs/async-runs.md) for detached lifecycle, state files, cancellation, and observability; [`docs/tool-registry.md`](./docs/tool-registry.md) for registry storage; and [`docs/recipe-library.md`](./docs/recipe-library.md) for the packaged standard recipe library.
|
|
411
|
-
|
|
412
|
-
## Notes
|
|
413
|
-
|
|
414
|
-
- Only register trusted local commands. Registered tools run with the same system permissions as pi.
|
|
415
|
-
- `index.ts` is a small composition root; reusable behavior lives in flat `/lib` domains covered by focused tests.
|
|
285
|
+
- [Project context](./AGENTS.md)
|
|
286
|
+
- [Changelog](./CHANGELOG.md)
|
|
287
|
+
- [Open backlog](./BACKLOG.md)
|
|
288
|
+
- [Documentation index](./docs/README.md)
|
|
289
|
+
- [Actors skill](./skills/actors/SKILL.md)
|
|
290
|
+
- [Swarm skill](./skills/swarm/SKILL.md)
|
|
291
|
+
|
|
292
|
+
Core docs:
|
|
293
|
+
|
|
294
|
+
- [Command templates](./docs/command-templates.md)
|
|
295
|
+
- [Template recipes](./docs/template-recipes.md)
|
|
296
|
+
- [Async runs](./docs/async-runs.md)
|
|
297
|
+
- [Actor messages](./docs/actor-messages.md)
|
|
298
|
+
- [Tool registry](./docs/tool-registry.md)
|
|
299
|
+
- [Recipe library](./docs/recipe-library.md)
|
|
416
300
|
|
|
417
301
|
## License
|
|
418
302
|
|
package/docs/actor-messages.md
CHANGED
|
@@ -94,8 +94,8 @@ Transports differ, but the public contract does not:
|
|
|
94
94
|
|
|
95
95
|
- `to: run:<id>` routes through the run-local control channel selected by that recipe or runtime adapter.
|
|
96
96
|
- `to: coordinator` routes to the runtime attention path when `from` names a run actor. `to: session:<id>` uses the same actor-message path only when the sender run is owned by that session, making explicit session-directed checkpoints possible without exposing runtime delivery knobs. Generic async-runner `command.done` messages and explicit coordinator/session-bound messages include the actor envelope fields alongside runtime metadata.
|
|
97
|
-
- `to: branch:<run>/<branch>` routes through the parent run mailbox with the full envelope preserved so the run can dispatch branch-local control.
|
|
98
|
-
- `to: room:<run>` appends the full envelope to the room timeline
|
|
97
|
+
- `to: branch:<run>/<branch>` currently routes through the parent run mailbox with the full envelope preserved so the run or recipe-specific worker protocol can dispatch branch-local control. It also persists a queued branch-local copy under `branches/<branch>/inbox.jsonl`, inspectable with `inspect branch:<run>/<branch> view=mailbox`; compact inspection includes the inbox message `id`, status, route, type, and timestamps so worker protocols can correlate claims/retries. It is not a broadcast room and it does not make an arbitrary prompt process consume the message automatically. Target direction: direct branch messages should become initiating inbox work for long-lived branch runners, delivered into the recipient's next prompt/context as soon as the runner can accept work.
|
|
98
|
+
- `to: room:<run>` appends the full envelope to the room timeline, updates room state for room-control types such as `actor.join` and `actor.leave`, and can route selected-recipient multicast when `metadata.recipients` contains same-run `branch:<run>/<branch>` addresses.
|
|
99
99
|
- `to: tool:<name>` invokes an executable pi tool by name. Object bodies become tool parameters; primitive bodies are passed as `{ "input": body }`.
|
|
100
100
|
|
|
101
101
|
Transport is not public API unless a recipe explicitly documents a custom endpoint.
|
|
@@ -104,6 +104,10 @@ Transport is not public API unless a recipe explicitly documents a custom endpoi
|
|
|
104
104
|
|
|
105
105
|
The task room is the discovery and shared-context layer for actors whose spawn-tree positions do not give them each other's addresses. The spawn tree remains the lifecycle/provenance structure; the task room describes the group communication graph. Direct messages and room messages can share the same semantic `type` such as `chat.message`; the route (`to: branch:*` versus `to: room:*`) determines whether delivery is private or group-wide.
|
|
106
106
|
|
|
107
|
+
Use direct branch messages only when the receiving branch is backed by a worker or recipe that reads the parent run mailbox or branch inbox and dispatches branch-targeted envelopes. Room roster contacts are discovery hints, not a guarantee that an independent prompt process is subscribed to its branch address. The current branch inbox records queued FIFO work; the intended next step is runner-side claiming/handling so direct messages become prompt work for the recipient branch, while room messages remain shared transcript entries. A direct message may ask the recipient to inspect room history when broader shared context is needed. For ad hoc or transcript-driven swarms without such a runner, prefer room-visible replies and mentions so every participant can inspect the shared timeline.
|
|
108
|
+
|
|
109
|
+
Selected-recipient multicast stays route-based: send one `to: room:<run>` envelope with `metadata.recipients` set to same-run branch addresses. The room timeline keeps the original room-visible envelope, and the runtime also forwards branch-targeted copies to each listed recipient. This is not a subroom; it is a shared transcript plus explicit direct delivery for actors whose worker protocol consumes branch envelopes.
|
|
110
|
+
|
|
107
111
|
A minimal join message:
|
|
108
112
|
|
|
109
113
|
```json
|