@llblab/pi-actors 0.24.6 → 0.24.8
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/BACKLOG.md +5 -7
- package/CHANGELOG.md +10 -0
- package/README.md +1 -1
- package/dist/lib/mailbox-loop.js +1 -3
- package/dist/lib/tools.js +1 -5
- package/dist/skills/actors/SKILL.md +5 -5
- package/dist/skills/swarm/SKILL.md +1 -1
- package/docs/actor-messages.md +1 -1
- package/docs/async-runs.md +6 -6
- package/docs/recipe-library.md +1 -1
- package/docs/template-recipes.md +1 -1
- package/lib/mailbox-loop.ts +1 -5
- package/lib/tools.ts +1 -6
- package/package.json +1 -1
- package/skills/actors/SKILL.md +5 -5
- package/skills/swarm/SKILL.md +1 -1
package/BACKLOG.md
CHANGED
|
@@ -211,15 +211,13 @@ The backlog is intentionally pruned to the 20% of work most likely to deliver 80
|
|
|
211
211
|
### M-11 Actor Termination Semantics
|
|
212
212
|
|
|
213
213
|
- Priority: Medium.
|
|
214
|
-
- Status: Open.
|
|
214
|
+
- Status: Open; core mailbox-loop hotfix landed in 0.24.8.
|
|
215
215
|
- Goal: Make `control.kill` the canonical parent-to-actor termination action while keeping `control.stop` and `control.cancel` as actor-domain messages whose meaning depends on the actor protocol.
|
|
216
216
|
- Why now: Mailbox workers need a clearer lifecycle boundary before v2 patterns harden. Treating `stop`, `cancel`, and `kill` as equivalent stop messages blurs actor termination with domain-specific task or playback control.
|
|
217
|
-
-
|
|
218
|
-
-
|
|
219
|
-
-
|
|
220
|
-
- Reframe `control.
|
|
221
|
-
- Split mailbox-loop helper semantics so lifecycle termination detection is distinct from general control-message detection.
|
|
222
|
-
- While the package is pre-1.0, allow a small intentional minor-version contract break: remove legacy treatment that aliases `control.stop` or `control.cancel` to actor termination.
|
|
217
|
+
- Remaining direction:
|
|
218
|
+
- Audit packaged recipe `mailbox.accepts` declarations so `control.stop` and `control.cancel` appear only when actor-specific behavior is meaningful.
|
|
219
|
+
- Preserve `control.kill` as the universal lifecycle action for a parent/supervisor terminating an actor or run.
|
|
220
|
+
- Reframe any remaining docs that imply `control.stop` or `control.cancel` are generic runtime termination aliases.
|
|
223
221
|
- Do not preserve compatibility shims for the old stop/cancel-as-termination behavior before the first 1.0 major release unless a concrete safety issue appears during implementation.
|
|
224
222
|
- Acceptance:
|
|
225
223
|
- Docs and actors skill advertise `control.kill` as canonical parent-to-actor termination.
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.24.8: Mailbox Loop Kill Contract Hotfix
|
|
6
|
+
|
|
7
|
+
- `[Mailbox Loop]` Aligned generic mailbox-loop termination with the actor-message kill contract: only `control.kill` stops generic loop drains; `control.stop` and `control.cancel` remain actor-domain messages unless a recipe handles them explicitly.
|
|
8
|
+
- `[Docs]` Updated worker and recipe guidance so backlog implementer shutdown examples use `control.kill` for runtime termination and describe `control.stop` as domain-local vocabulary.
|
|
9
|
+
|
|
10
|
+
## 0.24.7: Actor Message Kill Contract Hotfix
|
|
11
|
+
|
|
12
|
+
- `[Actor Messages]` Narrowed runtime termination by actor message to `control.kill` only; `control.stop` and `control.cancel` now remain recipe-local mailbox vocabulary instead of aliases for killing/cancelling a run.
|
|
13
|
+
- `[Docs]` Updated actor-message, async-run, and actor-skill guidance so only `control.kill` is documented as the action that kills an actor run.
|
|
14
|
+
|
|
5
15
|
## 0.24.6: Async Run Restart Status Hotfix
|
|
6
16
|
|
|
7
17
|
- `[Async Runs]` Treat freshly spawned runner PIDs as running during a short Linux `/proc` identity grace window, preventing restart status checks and immediate run messages from misclassifying a new run as `exited` before its command line is observable.
|
package/README.md
CHANGED
|
@@ -118,7 +118,7 @@ Steer it through messages:
|
|
|
118
118
|
|
|
119
119
|
```text
|
|
120
120
|
message to=run:docs_review type=control.continue body=continue
|
|
121
|
-
message to=run:docs_review type=control.
|
|
121
|
+
message to=run:docs_review type=control.kill body=stop
|
|
122
122
|
```
|
|
123
123
|
|
|
124
124
|
## Actor Rooms
|
package/dist/lib/mailbox-loop.js
CHANGED
|
@@ -9,9 +9,7 @@ export function isMailboxLoopStopMessage(message) {
|
|
|
9
9
|
const type = message && typeof message === "object" && "type" in message
|
|
10
10
|
? message.type
|
|
11
11
|
: undefined;
|
|
12
|
-
return
|
|
13
|
-
type === "control.cancel" ||
|
|
14
|
-
type === "control.kill");
|
|
12
|
+
return type === "control.kill";
|
|
15
13
|
}
|
|
16
14
|
function messageId(message) {
|
|
17
15
|
return typeof message?.id === "string" ? message.id : undefined;
|
package/dist/lib/tools.js
CHANGED
|
@@ -946,11 +946,7 @@ export function createActorMessageToolDefinition(deps = {}) {
|
|
|
946
946
|
`Message type ${message.type} is not declared in mailbox.accepts for run:${address.value}.`,
|
|
947
947
|
]
|
|
948
948
|
: [];
|
|
949
|
-
if (message.type === "control.
|
|
950
|
-
message.type === "control.cancel") {
|
|
951
|
-
result = AsyncRuns.cancelRun(address.value);
|
|
952
|
-
}
|
|
953
|
-
else if (message.type === "control.kill") {
|
|
949
|
+
if (message.type === "control.kill") {
|
|
954
950
|
result = AsyncRuns.killRun(address.value);
|
|
955
951
|
}
|
|
956
952
|
else if (message.type === "control.archive") {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: actors
|
|
3
3
|
description: Highest-density practical guide for pi-actors. Read this skill whenever prompt and tools are not enough for spawn, message, inspect, actor runs, tools, recipes, command templates, async lifecycle, mailboxes, artifacts, and local orchestration mechanics.
|
|
4
4
|
metadata:
|
|
5
|
-
version: 0.24.
|
|
5
|
+
version: 0.24.8
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Actors (pi-actors)
|
|
@@ -86,7 +86,7 @@ Envelope fields:
|
|
|
86
86
|
- Useful: `summary`, `body`, `from`, `reply_to`, `correlation_id`, `metadata`.
|
|
87
87
|
- Addresses: `run:<id>`, `branch:<run>/<branch>`, `room:<run>`, `tool:<name>`, `coordinator`, `session:<id>`.
|
|
88
88
|
- Room posts require `from` from the same run (`run:<run>` or `branch:<run>/<branch>`).
|
|
89
|
-
-
|
|
89
|
+
- Runtime termination message: `control.kill` is the only documented actor message that kills a run. `control.stop` and `control.cancel` are actor-local mailbox vocabulary only when a recipe declares and handles them. Terminal retention messages: `control.archive`, `control.prune`.
|
|
90
90
|
|
|
91
91
|
Check `inspect view=mailbox` before domain-specific messages.
|
|
92
92
|
|
|
@@ -150,9 +150,9 @@ When using actors as backlog implementers, avoid one-shot subagents that exit af
|
|
|
150
150
|
2. Actor posts `task.claim` to `room:<run>` before editing.
|
|
151
151
|
3. Actor executes and validates the slice.
|
|
152
152
|
4. Actor posts `task.result` and `awaiting_assignment`.
|
|
153
|
-
5. Actor stays alive until the coordinator sends another `task.assign` or an explicit `control.
|
|
153
|
+
5. Actor stays alive until the coordinator sends another `task.assign` or an explicit `control.kill`.
|
|
154
154
|
|
|
155
|
-
Use `front`/`back` actors for opposite backlog ends when reducing overlap. Implementer workflows should be packaged as reusable recipe composition, not bespoke scripts: use `coordinator-locker` for queue/assignment/locking, subagent launcher recipes for execution cells, actor-message utility recipes for structured handoffs, and `lib/mailbox-loop.ts` helpers when writing mailbox-consuming workers. Mailbox loops should claim one run or branch inbox message at a time, mark success as `handled`, mark exceptions as `failed`, and treat `control.
|
|
155
|
+
Use `front`/`back` actors for opposite backlog ends when reducing overlap. Implementer workflows should be packaged as reusable recipe composition, not bespoke scripts: use `coordinator-locker` for queue/assignment/locking, subagent launcher recipes for execution cells, actor-message utility recipes for structured handoffs, and `lib/mailbox-loop.ts` helpers when writing mailbox-consuming workers. Mailbox loops should claim one run or branch inbox message at a time, mark success as `handled`, mark exceptions as `failed`, and treat only `control.kill` as the generic loop termination message; `control.stop` and `control.cancel` are actor-domain messages only when the recipe declares and handles them. Bounded drains may process available work until `control.kill` or a max-message guard. If the existing recipe library cannot express the scenario, add missing reusable component recipes first, then compose the higher-level workflow from them. Supervisors should route coordinator assignments by `body.actor`, preserve the assignment as an object rather than a JSON string, and keep stopped-worker summaries tied to the original actor list.
|
|
156
156
|
|
|
157
157
|
Current packaged building blocks:
|
|
158
158
|
|
|
@@ -204,7 +204,7 @@ Minimal actor recipe:
|
|
|
204
204
|
"args": ["path:path", "model:string"],
|
|
205
205
|
"defaults": {},
|
|
206
206
|
"mailbox": {
|
|
207
|
-
"accepts": ["control.
|
|
207
|
+
"accepts": ["control.kill"],
|
|
208
208
|
"emits": ["command.done", "run.done", "run.failed"]
|
|
209
209
|
},
|
|
210
210
|
"artifacts": { "report": "{path}/report.md" },
|
package/docs/actor-messages.md
CHANGED
|
@@ -208,7 +208,7 @@ Runtime operations use the actor/message vocabulary:
|
|
|
208
208
|
```text
|
|
209
209
|
create detached work -> spawn
|
|
210
210
|
run-local control -> message to run:<id>
|
|
211
|
-
run
|
|
211
|
+
run force-kill -> message type control.kill
|
|
212
212
|
platform control -> internal adapter selected from run state
|
|
213
213
|
coordinator signal -> message to coordinator/session
|
|
214
214
|
tool execution -> message to tool:<name>
|
package/docs/async-runs.md
CHANGED
|
@@ -146,7 +146,7 @@ The stable loop is:
|
|
|
146
146
|
2. Actor posts `task.claim` to `room:<run>` before editing.
|
|
147
147
|
3. Actor completes the slice, validates, and posts `task.result` plus `awaiting_assignment`.
|
|
148
148
|
4. Actor remains alive and waits for the next coordinator message.
|
|
149
|
-
5. Coordinator either sends another `task.assign` or sends `control.
|
|
149
|
+
5. Coordinator either sends another `task.assign` or sends `control.kill` after confirming no actionable work remains.
|
|
150
150
|
|
|
151
151
|
Implementer recipes should declare this contract in `mailbox.accepts` and `mailbox.emits`. They should not self-terminate after a successful slice, and they should not silently self-select a new task unless the coordinator deliberately configured that policy for the run. This keeps task choice centralized while preserving actor-local execution autonomy.
|
|
152
152
|
|
|
@@ -165,7 +165,7 @@ Low-level async actions map into the actor surface instead of forming a second p
|
|
|
165
165
|
- Start → `spawn`
|
|
166
166
|
- Send/control → `message`
|
|
167
167
|
- Status/tail/messages/list → `inspect`
|
|
168
|
-
-
|
|
168
|
+
- Force kill → `message` with `control.kill`, with synchronous results
|
|
169
169
|
- Archive/prune terminal state → `message` with `control.archive` or `control.prune`, with active runs rejected fail-closed
|
|
170
170
|
|
|
171
171
|
Compact text is returned by default so async management does not flood agent context; use verbose inspection when the full state object is needed. List output intentionally shares one state root across music, subagents, timers, and other async work; source fields such as `tool` and `recipe` distinguish run purpose when the launcher recorded them. The run root may contain a rebuildable `index.json` with run id, state directory, owner, status, update time, and recipe/tool hints; corrupt indexes fall back to recursive scan. Registered tools are the preferred user-facing surface for reusable recipes. `control.prune` accepts `body.preserve_artifacts=true` to copy existing named artifacts beside the run root before deleting terminal state.
|
|
@@ -196,14 +196,14 @@ Portable control matrix:
|
|
|
196
196
|
| Mailbox-only endpoint | Supported | Supported | Use for cross-platform workers. |
|
|
197
197
|
| FIFO endpoint | Supported | Rejected before delivery | Keep only for Unix-compatible recipes. |
|
|
198
198
|
| Named-pipe endpoint | Optional | Supported | Use for native Windows live delivery. |
|
|
199
|
-
|
|
|
199
|
+
| Kill | Process group signal with pid fallback | Process-tree adapter | Same public `message type=control.kill` API. |
|
|
200
200
|
|
|
201
201
|
|
|
202
202
|
Runtime wake notifications are now modeled separately from durable queues. Message handling records canonical state in file-backed mailbox/event files before attempting optional live endpoint delivery. Runs may expose a mailbox-only control endpoint when durable inbox plus wake notification is the intended delivery path; FIFO and named-pipe endpoints remain compatibility/fast-wake paths rather than the durable queue itself. Successful FIFO or named-pipe delivery marks the run inbox entry `sent`; mailbox-only delivery leaves the entry queued for the runtime to claim. `wake.jsonl` is an advisory doorbell that lets a live runtime subscribe through file-system notifications plus explicit initial, wake-triggered, and polling reconciliation callbacks. A missed wake must not lose work because actors can re-read the canonical mailbox state. Runtime loops that consume the file-backed mailbox should claim queued run inbox entries, then mark them `handled` or `failed`; the helper path uses a small lock so concurrent reconciliation callbacks do not process the same entry twice.
|
|
203
203
|
|
|
204
204
|
## Coordinator Notifications
|
|
205
205
|
|
|
206
|
-
The launching coordinator should not busy-poll long-running async runs. The extension watches run state directories and delivers terminal `done`/`failed`/unhandled `killed`/`exited` transitions plus script-authored `notify`/`followup` actor messages back to the owning session. This gives the top-level async task a completion signal on the happy path while still letting recipe-local messages bubble up when scripts need finer-grained notifications. Terminal follow-ups include recipe-level named `artifacts` when declared. The generic runner also emits compact `command.done` actor messages for completed leaf commands; recipe authors declare that capability in `mailbox.emits` rather than configuring a separate delivery policy. Failures and in-flight parallel branch completions can bubble as follow-ups, while successful final leaf completions stay diagnostic to avoid flooding long sequential pipelines. Branch-level `command.done` follow-ups omit artifact manifests because the top-level terminal follow-up carries them once. Intentional `control.
|
|
206
|
+
The launching coordinator should not busy-poll long-running async runs. The extension watches run state directories and delivers terminal `done`/`failed`/unhandled `killed`/`exited` transitions plus script-authored `notify`/`followup` actor messages back to the owning session. This gives the top-level async task a completion signal on the happy path while still letting recipe-local messages bubble up when scripts need finer-grained notifications. Terminal follow-ups include recipe-level named `artifacts` when declared. The generic runner also emits compact `command.done` actor messages for completed leaf commands; recipe authors declare that capability in `mailbox.emits` rather than configuring a separate delivery policy. Failures and in-flight parallel branch completions can bubble as follow-ups, while successful final leaf completions stay diagnostic to avoid flooding long sequential pipelines. Branch-level `command.done` follow-ups omit artifact manifests because the top-level terminal follow-up carries them once. Intentional `control.kill` and recipe-local stop commands stay out of follow-up context because the initiating message already returns synchronously or is handled by actor-local policy. If a follow-up asks for direction, answer with `message` rather than starting a polling loop. Use explicit `inspect` only when a delivered follow-up requests inspection, a real decision depends on state, or a suspected stuck run needs diagnosis — never merely because a timeout elapsed.
|
|
207
207
|
|
|
208
208
|
Ambient status indicators may refresh while work is active, but coordinator attention is driven from run-state changes rather than a coordinator agent loop. This lets the coordinator continue other work after `spawn`; the run signals back through lifecycle state, results, and actor messages. The ambient triangle count represents active async work units: each running async run contributes at least one triangle, and a run with multiple active parallel command/subagent branches contributes the reported active branch count. If a coordinator starts one parent run with four active parallel branches, four triangles are shown; if the same coordinator starts five independent single-branch runs, five triangles are shown.
|
|
209
209
|
|
|
@@ -233,7 +233,7 @@ Use coordinator/session-bound messages for completion and decision points, not f
|
|
|
233
233
|
|
|
234
234
|
An async run belongs to the current user, cwd, and launching agent session at start time. Send, cancellation, and force-kill target only the recorded runner pid when command line and cwd still match the recorded owner data. Stale pid reuse must fail closed.
|
|
235
235
|
|
|
236
|
-
On Unix-like systems,
|
|
236
|
+
On Unix-like systems, `control.kill` signals the runner process group when available, then falls back to the runner pid. On native Windows, `control.kill` uses Windows process-tree termination through the platform adapter. The runner starts command-template children in the owned process tree, so long-running descendants such as audio players should stop with the run instead of becoming orphaned background processes. After the process exits, status reflects the operator action as `killed` instead of a generic `exited`. Programmatic `cancelRun()` remains an internal lifecycle helper for retirement and tests, but it is not a documented actor-message action.
|
|
237
237
|
|
|
238
238
|
State is append-only where practical. Final result writes should be atomic. Recipe-local control endpoints and actor-message logs may live in the state dir. pi-actors core owns the generic run-local message adapter and runtime attention policy; command and message vocabularies belong to the recipe/script.
|
|
239
239
|
|
|
@@ -267,7 +267,7 @@ Interactive sessions expose compact activity with minimal screen cost:
|
|
|
267
267
|
- With one active command, the triangle blinks between `▶` and `▷`.
|
|
268
268
|
- Triangles disappear as concrete commands exit.
|
|
269
269
|
- No prompt-area widget is shown by default.
|
|
270
|
-
- Terminal `done`/`failed`/unhandled `killed`/`exited` transitions trigger compact follow-up context only in the launching coordinator session; intentional `
|
|
270
|
+
- Terminal `done`/`failed`/unhandled `killed`/`exited` transitions trigger compact follow-up context only in the launching coordinator session; intentional `kill` and actor-local stop actions stay out of agent context because the action already reports synchronously or belongs to recipe-local policy.
|
|
271
271
|
- Full logs remain in state files and are accessed through `inspect target=run:<id> view=tail` or the low-level tail adapter.
|
|
272
272
|
|
|
273
273
|
This keeps background work visible without blocking the agent, occupying the prompt area, or leaking async context into unrelated sessions.
|
package/docs/recipe-library.md
CHANGED
|
@@ -199,4 +199,4 @@ Cross-platform smoke checklist:
|
|
|
199
199
|
- Only play trusted local files or URLs.
|
|
200
200
|
- Volume is clamped to `0..100` by the wrapper.
|
|
201
201
|
- Prefer a stable `run_id` such as `music` when the operator expects to control the run by name.
|
|
202
|
-
- Use `message type=control.kill`
|
|
202
|
+
- Use `message type=control.kill` for runtime termination; `control.stop` is a player-domain pause/stop command, not a generic run-kill alias.
|
package/docs/template-recipes.md
CHANGED
|
@@ -187,7 +187,7 @@ Recipes do not declare a second event-delivery policy. A running actor emits add
|
|
|
187
187
|
```json
|
|
188
188
|
{
|
|
189
189
|
"mailbox": {
|
|
190
|
-
"accepts": ["control.
|
|
190
|
+
"accepts": ["control.kill"],
|
|
191
191
|
"emits": ["command.done", "run.done", "run.failed"]
|
|
192
192
|
},
|
|
193
193
|
"template": "run-subtask {prompt}"
|
package/lib/mailbox-loop.ts
CHANGED
|
@@ -57,11 +57,7 @@ export function isMailboxLoopStopMessage(message: unknown): boolean {
|
|
|
57
57
|
message && typeof message === "object" && "type" in message
|
|
58
58
|
? (message as { type?: unknown }).type
|
|
59
59
|
: undefined;
|
|
60
|
-
return
|
|
61
|
-
type === "control.stop" ||
|
|
62
|
-
type === "control.cancel" ||
|
|
63
|
-
type === "control.kill"
|
|
64
|
-
);
|
|
60
|
+
return type === "control.kill";
|
|
65
61
|
}
|
|
66
62
|
|
|
67
63
|
function messageId(
|
package/lib/tools.ts
CHANGED
|
@@ -1328,12 +1328,7 @@ export function createActorMessageToolDefinition<TContext = unknown>(
|
|
|
1328
1328
|
`Message type ${message.type} is not declared in mailbox.accepts for run:${address.value}.`,
|
|
1329
1329
|
]
|
|
1330
1330
|
: [];
|
|
1331
|
-
if (
|
|
1332
|
-
message.type === "control.stop" ||
|
|
1333
|
-
message.type === "control.cancel"
|
|
1334
|
-
) {
|
|
1335
|
-
result = AsyncRuns.cancelRun(address.value);
|
|
1336
|
-
} else if (message.type === "control.kill") {
|
|
1331
|
+
if (message.type === "control.kill") {
|
|
1337
1332
|
result = AsyncRuns.killRun(address.value);
|
|
1338
1333
|
} else if (message.type === "control.archive") {
|
|
1339
1334
|
result = AsyncRuns.archiveRun(address.value);
|
package/package.json
CHANGED
package/skills/actors/SKILL.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: actors
|
|
3
3
|
description: Highest-density practical guide for pi-actors. Read this skill whenever prompt and tools are not enough for spawn, message, inspect, actor runs, tools, recipes, command templates, async lifecycle, mailboxes, artifacts, and local orchestration mechanics.
|
|
4
4
|
metadata:
|
|
5
|
-
version: 0.24.
|
|
5
|
+
version: 0.24.8
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Actors (pi-actors)
|
|
@@ -86,7 +86,7 @@ Envelope fields:
|
|
|
86
86
|
- Useful: `summary`, `body`, `from`, `reply_to`, `correlation_id`, `metadata`.
|
|
87
87
|
- Addresses: `run:<id>`, `branch:<run>/<branch>`, `room:<run>`, `tool:<name>`, `coordinator`, `session:<id>`.
|
|
88
88
|
- Room posts require `from` from the same run (`run:<run>` or `branch:<run>/<branch>`).
|
|
89
|
-
-
|
|
89
|
+
- Runtime termination message: `control.kill` is the only documented actor message that kills a run. `control.stop` and `control.cancel` are actor-local mailbox vocabulary only when a recipe declares and handles them. Terminal retention messages: `control.archive`, `control.prune`.
|
|
90
90
|
|
|
91
91
|
Check `inspect view=mailbox` before domain-specific messages.
|
|
92
92
|
|
|
@@ -150,9 +150,9 @@ When using actors as backlog implementers, avoid one-shot subagents that exit af
|
|
|
150
150
|
2. Actor posts `task.claim` to `room:<run>` before editing.
|
|
151
151
|
3. Actor executes and validates the slice.
|
|
152
152
|
4. Actor posts `task.result` and `awaiting_assignment`.
|
|
153
|
-
5. Actor stays alive until the coordinator sends another `task.assign` or an explicit `control.
|
|
153
|
+
5. Actor stays alive until the coordinator sends another `task.assign` or an explicit `control.kill`.
|
|
154
154
|
|
|
155
|
-
Use `front`/`back` actors for opposite backlog ends when reducing overlap. Implementer workflows should be packaged as reusable recipe composition, not bespoke scripts: use `coordinator-locker` for queue/assignment/locking, subagent launcher recipes for execution cells, actor-message utility recipes for structured handoffs, and `lib/mailbox-loop.ts` helpers when writing mailbox-consuming workers. Mailbox loops should claim one run or branch inbox message at a time, mark success as `handled`, mark exceptions as `failed`, and treat `control.
|
|
155
|
+
Use `front`/`back` actors for opposite backlog ends when reducing overlap. Implementer workflows should be packaged as reusable recipe composition, not bespoke scripts: use `coordinator-locker` for queue/assignment/locking, subagent launcher recipes for execution cells, actor-message utility recipes for structured handoffs, and `lib/mailbox-loop.ts` helpers when writing mailbox-consuming workers. Mailbox loops should claim one run or branch inbox message at a time, mark success as `handled`, mark exceptions as `failed`, and treat only `control.kill` as the generic loop termination message; `control.stop` and `control.cancel` are actor-domain messages only when the recipe declares and handles them. Bounded drains may process available work until `control.kill` or a max-message guard. If the existing recipe library cannot express the scenario, add missing reusable component recipes first, then compose the higher-level workflow from them. Supervisors should route coordinator assignments by `body.actor`, preserve the assignment as an object rather than a JSON string, and keep stopped-worker summaries tied to the original actor list.
|
|
156
156
|
|
|
157
157
|
Current packaged building blocks:
|
|
158
158
|
|
|
@@ -204,7 +204,7 @@ Minimal actor recipe:
|
|
|
204
204
|
"args": ["path:path", "model:string"],
|
|
205
205
|
"defaults": {},
|
|
206
206
|
"mailbox": {
|
|
207
|
-
"accepts": ["control.
|
|
207
|
+
"accepts": ["control.kill"],
|
|
208
208
|
"emits": ["command.done", "run.done", "run.failed"]
|
|
209
209
|
},
|
|
210
210
|
"artifacts": { "report": "{path}/report.md" },
|
package/skills/swarm/SKILL.md
CHANGED