@llblab/pi-actors 0.17.1 → 0.19.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 +6 -2
- package/BACKLOG.md +32 -26
- package/CHANGELOG.md +19 -3
- package/README.md +23 -8
- package/docs/actor-messages.md +5 -3
- package/docs/async-runs.md +3 -5
- package/docs/command-templates.md +2 -0
- package/docs/recipe-library.md +3 -1
- package/docs/task-first-recipes.md +29 -0
- package/docs/template-recipes.md +9 -14
- package/index.ts +111 -32
- package/lib/actor-inspector-tui.ts +192 -42
- package/lib/actor-rooms.ts +220 -26
- 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 +1 -2
- package/recipes/lens-swarm.json +0 -1
- package/recipes/locker.json +45 -0
- 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 +3 -2
- 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/coordinator.mjs +434 -0
- package/scripts/{coordinator-locker.mjs → locker.mjs} +23 -22
- package/skills/actors/SKILL.md +26 -12
- package/skills/swarm/SKILL.md +15 -1
- package/scripts/room-swarm.mjs +0 -244
package/AGENTS.md
CHANGED
|
@@ -45,12 +45,16 @@
|
|
|
45
45
|
- `Layer boundary discipline`: Command-template evolution must be separated from template-recipe configuration and async-run lifecycle configuration | Trigger: Adding syntax, placeholders, imports, async controls, or docs | Action: Put portable execution graph semantics in `docs/command-templates.md`, recipe storage/import/default/reference behavior in `docs/template-recipes.md`, and detached lifecycle/state/IPC behavior in `docs/async-runs.md`; type imported recipes as command-template-shaped recipe definitions, not async-run instances
|
|
46
46
|
- `Executable script recipes`: Recipe templates may point directly at executable helper scripts, including JavaScript `.mjs` files with shebangs; do not prefix such recipes with `node` unless the script is intentionally not executable | Trigger: Adding or editing script-backed recipes and docs | Action: Keep the script executable bit, call `{repo}/scripts/name.mjs ...` directly, and keep the standard library on one maintained wrapper per capability unless a second wrapper has a concrete platform reason
|
|
47
47
|
- `Registry safety boundaries`: Tool definitions use `template`, not `script`, and built-in/core tool names must not be shadowed | Trigger: Loading/editing persisted config or registration logic | Action: Reject legacy `script` entries explicitly, avoid silent user-config rewrites outside the repo, and keep conflict checks before persistence/runtime registration
|
|
48
|
-
- `Async run observability`: Ambient triangles count active async work units: each running async run contributes at least one triangle,
|
|
48
|
+
- `Async run observability`: Ambient triangles count active async work units across the visible run tree: each running async run contributes at least one triangle, reported active parallel command/subagent branches contribute the visible branch count when greater than one, and descendant `pi -p` subagent processes are folded in so coordinator-plus-workers scenarios expand beyond a single coordinator marker. Event-driven terminal/outbox watchers should initiate follow-up for unhandled terminal completion/failure states, failed or in-flight `command.done` branch completions, and coordinator-bound script-authored messages with bounded body previews; actor `message` is the explicit coordinator-to-run command channel paired with these upward events. Do not restore busy-polling loops, sleep-then-status smoke examples, duplicate follow-ups for final successful leaf commands, or duplicate follow-ups for `cancel`, `kill`, or control-stop actions already handled by synchronous tool results. | Trigger: Changing async run UI, notifications, actor-message routing, or smoke-test interpretation | Action: Preserve branch-aware triangles from `progress.activeSubagents`, runtime-inferred branch bubbling for packaged fanout completion, process-tree expansion for coordinator-launched workers, terminal notifications as event-driven behavior, and docs/examples that teach reactive run→coordinator→message loops before sleep-polling patterns.
|
|
49
49
|
- `Communication direction`: The design target is an organic universal message layer across sync tasks, async runs, branches, tools, and coordinators. Breaking changes are allowed to compress concepts, remove accidental duplication, and make duplex communication symmetric where the domain is symmetric. | Trigger: Designing APIs or recipes that communicate | Action: Prefer a concentrated actor/message protocol (`spawn`, `message`, `inspect`, addressed endpoints, typed message envelopes, mailbox accepts/emits) over exposing FIFO/outbox/status mechanics directly; use one envelope for upward, downward, lateral, parent/branch, and branch/parent messages; absorb runtime async primitives into actor API instead of preserving parallel public concepts.
|
|
50
50
|
- `Runtime IO discipline`: Tool stdout and temp state must stay bounded and local | Trigger: Changing execution, formatting, temp files, run state, logs, or artifacts | Action: Keep tail truncation/full-output temp files/failure formatting intact; keep extension-owned temp state under `~/.pi/agent/tmp/pi-actors` unless explicitly overridden
|
|
51
|
-
- `Backlog is planning, not history`: `BACKLOG.md` should contain only future
|
|
51
|
+
- `Backlog is planning, not history`: `BACKLOG.md` should contain only completable future work with current task/scope/exit criteria; completed delivery history belongs in `CHANGELOG.md`, and durable or evergreen behavior belongs in `AGENTS.md`, README, docs, or skills | Trigger: Editing backlog or reconciling completed slices | Action: Remove historical progress narratives, version-scoped headings, watch-mode/monitoring principles, open-ended “continue evolving” items, and conditional “if usage proves” notes unless they are framed as a concrete gated task; keep priority order and prefer an 80/20 focus list when many remaining tasks compete for attention
|
|
52
52
|
- `Release artifact hygiene`: PR/release summaries become stale during active branch work and do not belong in the repository documentation tree | Trigger: Preparing release notes or PR bodies | Action: Create temporary/operator-facing artifacts outside the repo only during explicit release finalization; keep durable release evidence in `CHANGELOG.md` and open gates in `BACKLOG.md`
|
|
53
|
+
- `Graceful actor retirement`: Coordinator/helper actors that exist only to supervise a bounded worker tree should have explicit retirement semantics instead of relying on the operator or LLM to remember cleanup | Trigger: Designing coordinator recipes, helper actors, worker fanout, locker-backed swarms, or auto-stop behavior | Action: Make retirement opt-in through recipe/run metadata, retire only after observed child actors or descendant workers are terminal and outputs are flushed, prefer graceful control messages before process termination, record retirement events, and never infer retirement for persistent services or backlog implementers
|
|
53
54
|
- `Persistent implementer workflows are recipe composition`: Backlog implementer scenarios should be launched through reusable component recipes, not one-off scripts or ad hoc shell orchestration | Trigger: Designing implementer swarms, backlog workers, coordinator-assigned task loops, or related recipes | Action: Compose cells such as `coordinator-locker`, subagent launchers, and actor-message utilities; preserve JSON envelope object shape across handoffs; add missing reusable component recipes only when needed; update the actors skill launcher map with supported scenarios
|
|
55
|
+
- `Modular coordination and separate lock state`: The coordination of multi-agent workflows is split into two cleanly decoupled layers: the active coordinator and the stateful locker. The locker manages task queueing and resource lock leases over Unix FIFO/pipes without project policy. The coordinator script (`scripts/coordinator.mjs`) manages process pools, rooms, and lifecycles, and supports different pluggable mode strategies (`pipeline`, `fanout`, `pool`, `consensus`). | Trigger: Modifying coordination scripts, queues, locking, or parallel worker flows | Action: Keep the locker generic and thin, and implement all orchestration strategy rules inside the multi-mode coordinator.
|
|
56
|
+
- `Active branch inbox queues`: Direct branch messages are active, work-triggering inbox queues rather than passive files. During subagent execution, the coordinator automatically claims (`claimed`), injects, and handles (`handled`/`failed`) queued branch-local direct messages to allow interactive/resumable worker workflows. | Trigger: Delivering branch messages, executing subagents, or updating branch queues | Action: Ensure direct messages can continue or wake long-lived branch runners, and keep the FIFO queue status transitions clean and fully tested.
|
|
57
|
+
- `Recipe library growth is demand-driven`: Packaged recipes should grow from concrete repeated task patterns, not speculative scenario catalogs | Trigger: Adding packaged utilities, pipelines, or component recipes | Action: Prefer existing component composition, keep recipes policy-light with caller-owned prompts/models/paths/knobs, avoid scenario-specific scripts when existing components suffice, and document new reusable launch scenarios in the actors skill only after the recipe exists
|
|
54
58
|
- `Context sync`: Meaningful implementation or docs changes must reconcile `BACKLOG.md`, `CHANGELOG.md`, README, and docs navigation | Trigger: Closing, narrowing, or discovering work | Action: Run the context validator before final status when practical
|
|
55
59
|
- `Public path hygiene`: Published docs must not include machine-local absolute paths | Trigger: Adding validation commands, examples, or local instructions to README/AGENTS/docs/changelog | Action: Use `~/.pi/...`, `<repo>/...`, `${SKILL_DIR}/...`, or relative paths
|
|
56
60
|
|
package/BACKLOG.md
CHANGED
|
@@ -9,23 +9,47 @@
|
|
|
9
9
|
- Direction:
|
|
10
10
|
- Evaluate whether room storage/routing should remain built into the tool adapter or move behind a dedicated non-LLM communication actor recipe/script, possibly singleton-scoped. Preserve the same public `room:<run>` address and envelope either way.
|
|
11
11
|
- Consider reducing direct file-backed state where it improves coherence: model room/roster state as actor-owned data structures served by helper scripts/actors, with files retained only for durable snapshots, recovery, artifacts, or audit logs.
|
|
12
|
-
-
|
|
13
|
-
- Clarify which worker protocols consume direct `branch:<run>/<branch>` envelopes and which swarm scenarios should stay room-visible.
|
|
12
|
+
- Avoid full roster rewrite amplification during bursty room activity; branch communication snapshot writes are already debounced while root snapshots stay current.
|
|
14
13
|
- Exit:
|
|
15
14
|
- Any backend/storage change preserves existing `spawn` / `message` / `inspect` semantics and room address compatibility.
|
|
16
|
-
- Selected-recipient multicast remains route-based and does not introduce named subrooms.
|
|
17
15
|
|
|
18
16
|
### Actor Communication TUI Preview
|
|
19
17
|
|
|
20
18
|
- Priority: High.
|
|
21
19
|
- Goal: Make actor-to-actor communication more navigable in the terminal UI without exposing large payloads by default.
|
|
22
20
|
- Direction:
|
|
23
|
-
- Add
|
|
24
|
-
- Add a roster panel for current run/room participants with address, role, caps, status, and last seen.
|
|
25
|
-
- Collapse long bodies by default and respect sensitive/redacted metadata.
|
|
26
|
-
- Rate-limit noisy rooms and keep full body inspection intentional.
|
|
21
|
+
- Add current-branch and unread filters after branch read-state semantics are real.
|
|
27
22
|
- Exit:
|
|
28
|
-
- Operators can
|
|
23
|
+
- Operators can distinguish unread/current-branch messages while retaining intentional full-body inspection.
|
|
24
|
+
|
|
25
|
+
### Graceful Actor Retirement
|
|
26
|
+
|
|
27
|
+
- Priority: Medium.
|
|
28
|
+
- Goal: Automatically retire coordinator/helper actors that were launched only to supervise a bounded worker tree once their dependent workers have finished.
|
|
29
|
+
- Direction:
|
|
30
|
+
- Build on the existing `retire_when: "children_terminal"` recipe/run metadata contract and observability retirement-candidate detection for ephemeral supervisors.
|
|
31
|
+
- Treat auto-retirement as opt-in only; never infer it for arbitrary long-lived services, user tools, or persistent backlog implementers.
|
|
32
|
+
- Extend candidate detection from current `progress.activeSubagents === 0` gating to full observed child/descendant actor state rather than log text: the supervisor may retire only when all launched child async runs or descendant `pi -p` workers are terminal and required artifacts/outbox events have been flushed.
|
|
33
|
+
- Prefer graceful stop (`control.stop` / actor message) before process termination; escalate only after a bounded timeout and record the retirement event in run state.
|
|
34
|
+
- Preserve manual `cancel` / `kill` semantics and make retirement visible through `inspect` / ambient observability.
|
|
35
|
+
- Exit:
|
|
36
|
+
- A packaged coordinator recipe can launch worker actors, complete its coordination duties, and shut itself down automatically after the worker tree reaches terminal state.
|
|
37
|
+
- Persistent services and implementer actors remain alive unless their recipe explicitly opts into retirement.
|
|
38
|
+
|
|
39
|
+
### Consensus-First Build Recipe
|
|
40
|
+
|
|
41
|
+
- Priority: Medium.
|
|
42
|
+
- Goal: Promote the proven proposer → implementer → QA → finalizer pattern into a generic packaged workflow instead of demo-specific scripts; pi-actors should grow its standard recipe/script library for recurring actor OS scenarios.
|
|
43
|
+
- Direction:
|
|
44
|
+
- Public inputs: mission, artifact paths/assertions, proposer role JSON, implementer prompt, QA prompt, model/thinking/tool knobs, and optional room/locker settings.
|
|
45
|
+
- Proposers should coordinate through room messages with no write tools.
|
|
46
|
+
- The implementer owns the first artifact write after inspecting room consensus.
|
|
47
|
+
- QA inspects artifacts and room evidence without mutating files.
|
|
48
|
+
- The finalizer applies QA-grounded fixes and emits `run.done` only after artifact assertions pass.
|
|
49
|
+
- Reuse packaged subagent/message/artifact components where practical; if a script is needed, make it a generic packaged helper in the extension, not a task-local demo script.
|
|
50
|
+
- Exit:
|
|
51
|
+
- A packaged recipe can reproduce the interactive-music-instrument workflow shape for another single-artifact task without copying the demo script.
|
|
52
|
+
- Docs and skills point agents to the packaged recipe and explain when to choose it over a free-form room swarm.
|
|
29
53
|
|
|
30
54
|
### Persistent Backlog Implementer Workflow
|
|
31
55
|
|
|
@@ -41,16 +65,6 @@
|
|
|
41
65
|
- A packaged workflow, if added, is described by recipes and existing helper cells; no one-off backlog-implementer scripts are required.
|
|
42
66
|
- The actors skill documents the supported launch scenarios and the concrete packaged recipes for each.
|
|
43
67
|
|
|
44
|
-
### Recipe Schema Simplification
|
|
45
|
-
|
|
46
|
-
- Priority: Medium.
|
|
47
|
-
- Goal: Remove recipe metadata that duplicates storage context.
|
|
48
|
-
- Direction:
|
|
49
|
-
- Remove `name` from the recipe standard. Recipe identity should come from the recipe filename/id rather than a redundant JSON property. Keep migration/backward compatibility explicit for existing packaged and user recipes.
|
|
50
|
-
- Finish hardening validators/discovery against recipe-owned tool exposure: tool status should be determined by location under `~/.pi/agent/recipes/*.json`, while packaged/ad hoc/component recipes are not tools by default. Repository recipes and docs no longer author `tool`.
|
|
51
|
-
- Exit:
|
|
52
|
-
- Docs, validators, packaged recipes, discovery, and migration behavior all agree on filename-derived identity and location-derived tool exposure.
|
|
53
|
-
|
|
54
68
|
### Branch-Local Checkpoint Semantics
|
|
55
69
|
|
|
56
70
|
- Priority: Low.
|
|
@@ -86,11 +100,3 @@
|
|
|
86
100
|
- Direction:
|
|
87
101
|
- Consider sidecar stats sync/backup policy after inline user-owned `usage.calls` / `usage.last_called` proves useful.
|
|
88
102
|
- Do not add failure counters as primary usefulness evidence unless there is a strong operator-facing need.
|
|
89
|
-
|
|
90
|
-
### Opportunistic Recipe Library Growth
|
|
91
|
-
|
|
92
|
-
- Priority: Low.
|
|
93
|
-
- Goal: Expand packaged recipes only when concrete repeated task patterns justify them.
|
|
94
|
-
- Direction:
|
|
95
|
-
- Add new utilities or pipelines when they can be expressed as reusable recipe composition.
|
|
96
|
-
- Avoid scenario-specific scripts when existing component recipes can be composed.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,16 +1,32 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.19.0: Modular Coordination And Active Mailboxes
|
|
4
|
+
|
|
5
|
+
- `[Coordination]` Decoupled the overloaded `coordinator-locker.mjs` script into two completely independent, single-purpose components: a dedicated stateful `locker.mjs` (recipes `locker.json` and `coordinator-locker.json`) that manages resource locking, task queueing, and lease expirations; and a powerful, modular `coordinator.mjs` orchestrator. The coordinator manages execution lifecycles and process pools, supporting four distinct pluggable strategies via `--mode`: `consensus` (chat-swarm), `pipeline` (sequential), `fanout` (parallel review), and `pool` (worker pool pulling from locker).
|
|
6
|
+
- `[Actor Messages]` Implemented active direct actor inbox queue semantics. The modular coordinator now automatically inspects, claims (`claimed`), injects into prompt context, and finalizes (`handled` or `failed`) any queued direct branch messages (`branches/<branch>/inbox.jsonl`) during subagent executions, making direct messages active initiating work items. Backed by complete regression test coverage.
|
|
7
|
+
|
|
8
|
+
## 0.18.0: Actor Runtime Hardening And Recipe Guardrails
|
|
9
|
+
|
|
10
|
+
- `[Async Runs]` Made actor starts safer under concurrency and stale state. Duplicate active `run_id` / `state_dir` launches now fail before state is cleared, concurrent starts are serialized by a start lock, stale terminal run directories are cleaned automatically, and atomic JSON writes use collision-resistant temp names. Impact: restarts and concurrent launches no longer orphan active processes or overwrite logs, messages, progress, and control metadata.
|
|
11
|
+
- `[Command Templates]` Added a default parallel fanout cap of 64 branches, configurable with `PI_ACTORS_MAX_PARALLEL_BRANCHES`. Impact: accidental huge repeat/parallel expansions fail early instead of spawning unbounded child processes.
|
|
12
|
+
- `[Rooms & Messages]` Hardened room communication while preserving the single public actor-message model. Room timeline/roster/snapshot writes are serialized, branch direct messages are also persisted as queued per-branch inbox entries with IDs and internal claimed/handled/failed state transitions, bursty branch communication snapshot rewrites are debounced while root snapshots stay current, room reads use bounded tails, room timelines compact to a bounded retained tail, and `room:<run>` supports selected-recipient multicast via `metadata.recipients` while keeping one room-visible transcript entry. Impact: long-lived swarms can address subsets of same-run branches without subrooms, lost concurrent writes, unbounded room logs, repeated burst branch-snapshot rewrites, or expensive full-log reads.
|
|
13
|
+
- `[Actor Inspector]` Turned the inspector into a compact operator view for active actor coordination. It now has channel/mention filters, bounded body previews, default noisy-room row caps, an inline wrapping `role/name` roster summary with inactive departed participants muted, stable narrow-row rendering, plain name-driven actor identity, and bounded wide-character layout. Impact: operators can follow busy rooms, distinguish current and completed participants, and inspect selected messages without flooding the terminal, expanding roster dashboards, or adding extra preview-mode commands.
|
|
14
|
+
- `[Observability]` Reduced long-session overhead by pruning stale run observation state, caching active-subagent process scans, and expanding ambient run triangles with descendant `pi -p` workers launched by coordinators. Impact: terminal status remains useful during long actor sessions without retaining completed-run bookkeeping, repeatedly scanning `/proc` on every refresh, or showing one coordinator triangle when a visible worker tree is still running.
|
|
15
|
+
- `[Recipes]` Strengthened the recipe registry as a local capability surface. Recipe loading now rejects oversized files and excessive import depth, reports risky executable shapes and unsafe recipe-root permissions, exposes an integrity manifest, warns when the recipe-root watcher fails, derives recipe identity from filenames, resolves bare import names by recipe-root priority, and makes tool exposure location-derived: user recipe-root files are tools, packaged/ad hoc recipes are components. Impact: recipes are easier to audit, easier to compose from the standard library, harder to misuse accidentally, and no longer depend on redundant `name` / `tool` JSON fields for identity or exposure.
|
|
16
|
+
- `[Docs/Skills/Context]` Updated the README, actor-message/template-recipe/command-template docs, recipe-library/task-first docs, actors/swarm skills, onboarding prompt, and project context to reflect the hardened runtime, room/inspector controls, filename-derived recipes, location-derived tools, consensus-first build orchestration, shell-placeholder boundaries, and the rule that recurring multi-agent scenarios should grow packaged recipes/pipelines instead of task-local orchestration scripts. `BACKLOG.md` now stays focused on completable future work while durable operating principles live in project context.
|
|
17
|
+
- `[Package]` Bumped package and packaged skill metadata to `0.18.0`; promoted the release from a hotfix to a minor release because the scope now includes actor runtime hardening, room/TUI behavior, recipe guardrails, observability cleanup, and agent-facing guidance updates.
|
|
18
|
+
|
|
3
19
|
## 0.17.1: Inspector Hotfix And Room Swarm Hardening
|
|
4
20
|
|
|
5
|
-
- `[TUI]` Fixed actor inspector line bounding to use `visibleWidth()` for direction/type/summary/body width math, replaced the verbose two-line preview with a hidden-by-default numbered table, made bare `/actors-inspector-toggle` open 12 rows from closed state, removed the verbosity toggle, made `/actors-inspector-toggle <rows>` update the live row count, upgraded `/actors-inspect <number>` to show a separated two-column header plus all preview-object properties as aligned two-space key/value columns, and added a styled
|
|
6
|
-
- `[Recipe Library]` Added `pipeline-room-swarm` backed by `scripts/room-swarm.mjs`: repeated room-aware participants join `room:<run>`, coordinate over multiple room-visible rounds, leave cleanly, and synthesize the room transcript into a Markdown artifact. Roles can be supplied via `roles_path` to avoid raw JSON placeholders, default roles
|
|
21
|
+
- `[TUI]` Fixed actor inspector line bounding to use `visibleWidth()` for direction/type/summary/body width math, replaced the verbose two-line preview with a hidden-by-default numbered table, made bare `/actors-inspector-toggle` open 12 rows from closed state, removed the verbosity toggle, made `/actors-inspector-toggle <rows>` update the live row count, upgraded `/actors-inspect <number>` to show a separated two-column header plus all preview-object properties as aligned two-space key/value columns, and added a styled wide-character regression. Impact: room previews with wide text no longer crash Pi, actor logs stay dense while preserving message type visibility, operators can tune visible row count without persistent inspector settings, and they can drill into one visible row then toggle back to the table.
|
|
22
|
+
- `[Recipe Library]` Added `pipeline-room-swarm` backed by `scripts/room-swarm.mjs`: repeated room-aware participants join `room:<run>`, coordinate over multiple room-visible rounds, leave cleanly, and synthesize the room transcript into a Markdown artifact. Roles can be supplied via `roles_path` to avoid raw JSON placeholders, default roles use plain actor names, room rosters preserve display metadata, and `locker=true` composes a local coordinator-locker cell for artifact locks and decision journaling with regression coverage. Direct branch delivery remains available for worker protocols that consume parent-run branch envelopes, but the packaged swarm no longer relies on it for peer coordination. Impact: the DeepSeek room-swarm experiment is now represented as a policy-light packaged scenario while concrete model choice remains caller/operator policy.
|
|
7
23
|
- `[Docs]` Reconciled `BACKLOG.md` back to future-only open work, removing completed hotfix implementation notes and version-scoped backlog language now captured in this changelog. Refreshed README and project context around the packaged room-swarm/coordinator-locker library surface and actor-inspector TUI ownership.
|
|
8
24
|
- `[Package]` Bumped package and packaged skill metadata to `0.17.1` for the hotfix release.
|
|
9
25
|
|
|
10
26
|
## 0.17.0: Actor Rooms And Inspector
|
|
11
27
|
|
|
12
28
|
- `[Actor Messages]` Added the 0.17 actor-room communication slice: `room:<run>` task rooms, append-only room timelines, room rosters, join/leave handling, same-run room/direct provenance checks, branch/run communication snapshots, `inspect room:<run> view=status|messages|previews|roster|contacts`, and `inspect run:<id> view=communication`. Impact: run actors and contacted branches can discover peers, post shared task messages, and inspect communication state through the same `spawn` / `message` / `inspect` actor model.
|
|
13
|
-
- `[TUI]` Added the hidden-by-default actor inspector widget with `/actors-inspector-toggle` and `/actors-inspector-verbosity-toggle`, compact and verbose layouts, current-run scoping, chronological sequence numbers, owner filtering, JSONL-tolerant preview reads, mobile-width and wide-
|
|
29
|
+
- `[TUI]` Added the hidden-by-default actor inspector widget with `/actors-inspector-toggle` and `/actors-inspector-verbosity-toggle`, compact and verbose layouts, current-run scoping, chronological sequence numbers, owner filtering, JSONL-tolerant preview reads, mobile-width and wide-character-aware truncation, and transparent/dark row striping. Impact: operators can see the current actor conversation at a glance without flooding the prompt or leaking unrelated session previews.
|
|
14
30
|
- `[Registry]` Added usage metadata and operator-gated cleanup recommendations to recipe registry summaries, removed stale public references to the old tool config filename, removed recipe-owned `tool` properties from repository recipes/docs/fixtures, and fixed the 0.17 registry model around location-derived tool exposure: every recipe in `~/.pi/agent/recipes/*.json` is an agent tool, `register_tool` creates recipe files there under the hood, and packaged/ad hoc recipes outside that root are components. Impact: the sticky agent tool surface is explicit executable muscle memory, maintained like capability state rather than configured through per-recipe tool flags.
|
|
15
31
|
- `[Docs]` Updated README, actor-message docs, async-run docs, recipe-library docs, actors skill, backlog, and project context around the room/roster protocol, inspector behavior, release-artifact hygiene, and the persistent-backlog-implementer protocol. The implementer workflow remains future recipe-composition work around reusable cells such as `coordinator-locker`, not bespoke release scripts.
|
|
16
32
|
- `[Package]` Bumped package and packaged skill metadata to `0.17.0`; validated with `npm run validate` and context validation. PR #42 tracks the squashed `actor-rooms-017` branch as one release commit against `main` with green checks.
|
package/README.md
CHANGED
|
@@ -48,13 +48,13 @@ pi install git:github.com/llblab/pi-actors
|
|
|
48
48
|
Actors and coordination endpoints are addressed with compact route strings:
|
|
49
49
|
|
|
50
50
|
```text
|
|
51
|
-
run:<id>
|
|
52
|
-
branch:<run>/<branch>
|
|
53
|
-
room:<run>
|
|
54
|
-
coordinator
|
|
55
|
-
session:
|
|
56
|
-
session:all
|
|
57
|
-
tool:<name>
|
|
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
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
Actor messages use one envelope shape:
|
|
@@ -144,7 +144,22 @@ inspect target=room:review view=contacts
|
|
|
144
144
|
inspect target=room:review view=messages
|
|
145
145
|
```
|
|
146
146
|
|
|
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.
|
|
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.
|
|
148
|
+
|
|
149
|
+
## Actor Inspector
|
|
150
|
+
|
|
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
|
|
160
|
+
```
|
|
161
|
+
|
|
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.
|
|
148
163
|
|
|
149
164
|
## Registry Model
|
|
150
165
|
|
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 or recipe-specific worker protocol can dispatch branch-local control. It is not a broadcast room and it does not make an arbitrary prompt process consume the message automatically.
|
|
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,7 +104,9 @@ 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 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. For ad hoc or transcript-driven swarms, prefer room-visible replies and mentions so every participant can inspect the shared timeline.
|
|
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.
|
|
108
110
|
|
|
109
111
|
A minimal join message:
|
|
110
112
|
|
package/docs/async-runs.md
CHANGED
|
@@ -22,7 +22,7 @@ Async-run standard owns:
|
|
|
22
22
|
Async-run standard does not own:
|
|
23
23
|
|
|
24
24
|
- Command-template syntax, placeholders, graph semantics, or branch policy.
|
|
25
|
-
- Recipe import resolution, recipe
|
|
25
|
+
- Recipe import resolution, filename-derived recipe identity, or recipe storage format.
|
|
26
26
|
- Domain semantics for subagents, swarms, release readiness, media playback, or project policy.
|
|
27
27
|
- Scheduling, queue daemons, distributed workers, or workflow DSLs.
|
|
28
28
|
|
|
@@ -52,7 +52,6 @@ A recipe with `async: true` starts detached when invoked through its registered
|
|
|
52
52
|
|
|
53
53
|
```json
|
|
54
54
|
{
|
|
55
|
-
"name": "music-player",
|
|
56
55
|
"async": true,
|
|
57
56
|
"template": "play-audio {source}"
|
|
58
57
|
}
|
|
@@ -72,7 +71,7 @@ A caller can also start any recipe or inline template explicitly through `spawn`
|
|
|
72
71
|
|
|
73
72
|
`spawn` always starts a detached run actor. Registered recipe tools follow the recipe's `async` flag.
|
|
74
73
|
|
|
75
|
-
Use `run_id` on async recipe tools or `as: "run:<id>"` on `spawn` when the caller wants a stable id for later inspection or control.
|
|
74
|
+
Use `run_id` on async recipe tools or `as: "run:<id>"` on `spawn` when the caller wants a stable id for later inspection or control. The recipe filename identifies the saved definition; the run id identifies one execution instance of that recipe. Async runs inject lifecycle and communication values into template values so scripts can write run-local status files, control endpoints, or room-aware coordination messages:
|
|
76
75
|
|
|
77
76
|
- `{run_id}`: stable run id.
|
|
78
77
|
- `{state_dir}`: run-local state directory.
|
|
@@ -182,7 +181,7 @@ Some recipes expose a run-local control channel. When present, a caller can send
|
|
|
182
181
|
}
|
|
183
182
|
```
|
|
184
183
|
|
|
185
|
-
For `run:<id>`, `message` adapts the body to the recipe's run-local control channel. For `branch:<run>/<branch>`, it sends the full envelope through the parent run mailbox so the run can dispatch branch-local control. For `tool:<name>`, object bodies become the target tool parameters and primitive bodies are passed as `{ "input": body }`. The generic runtime records control messages but does not interpret arbitrary run mailbox content. For example, a music player may accept `play`, `pause`, `next`, and `stop`, while a collaborative agent recipe may accept `continue`, `revise:<note>`, `approve`, or `abort`. Recipes may treat terminal control messages such as `stop` as synchronously handled so the later process exit does not generate a duplicate async follow-up.
|
|
184
|
+
For `run:<id>`, `message` adapts the body to the recipe's run-local control channel. For `branch:<run>/<branch>`, it sends the full envelope through the parent run mailbox and records a queued branch-local inbox entry at `branches/<branch>/inbox.jsonl` so the run can dispatch branch-local control. Current consumers are recipe-specific worker protocols that read the parent run mailbox or branch inbox; independent one-shot prompt processes do not automatically consume branch inbox entries. For `tool:<name>`, object bodies become the target tool parameters and primitive bodies are passed as `{ "input": body }`. The generic runtime records control messages but does not interpret arbitrary run mailbox content. For example, a music player may accept `play`, `pause`, `next`, and `stop`, while a collaborative agent recipe may accept `continue`, `revise:<note>`, `approve`, or `abort`. Recipes may treat terminal control messages such as `stop` as synchronously handled so the later process exit does not generate a duplicate async follow-up.
|
|
186
185
|
|
|
187
186
|
The standard run-local transport is Unix-oriented. Use WSL/Linux/macOS for packaged message-controlled recipes, or let a Windows-specific recipe expose its own transport such as a Windows named pipe or localhost socket.
|
|
188
187
|
|
|
@@ -294,7 +293,6 @@ Example recipe:
|
|
|
294
293
|
|
|
295
294
|
```json
|
|
296
295
|
{
|
|
297
|
-
"name": "collab-{run}",
|
|
298
296
|
"async": true,
|
|
299
297
|
"parallel": true,
|
|
300
298
|
"timeout": 1800000,
|
|
@@ -159,6 +159,8 @@ template="echo 'literal words' {text}"
|
|
|
159
159
|
|
|
160
160
|
## Composition
|
|
161
161
|
|
|
162
|
+
Shell syntax warning: command-template placeholder parsing still sees braces inside shell snippets. Avoid inline Bash parameter expansion such as `${file%.md}` or `${name}` in recipe/template strings because `{file...}` can be parsed as a pi-actors placeholder. For non-trivial shell loops or parameter expansion, put the shell logic in a small trusted script and call that script from the template; keep the command template as the launch boundary.
|
|
163
|
+
|
|
162
164
|
`template: [...]` means sequential composition by default; each leaf is a command template executed with one shared runtime value map:
|
|
163
165
|
|
|
164
166
|
```json
|
package/docs/recipe-library.md
CHANGED
|
@@ -48,6 +48,8 @@ Core subagent recipes:
|
|
|
48
48
|
|
|
49
49
|
Most atoms expose policy knobs such as `model`, `thinking`, `tools`, `output_format`, `evidence_policy`, `risk_policy`, source policy, continuity policy, handoff format, or model pools. Packaged recipes intentionally do not ship concrete model-version defaults: callers must pass current model policy at launch, which keeps reusable recipe components from aging around old provider aliases. The generic prompt launchers, including `subagent-tools` and `subagents-prompts`, expose the same core model/thinking/tool/output knobs so callers do not need separate recipe families for policy tuning. Interactive async atoms also declare mailbox metadata for their basic control, completion, and domain-result message surface. Higher-level recipes pass these knobs through instead of hard-coding local policy.
|
|
50
50
|
|
|
51
|
+
For build-oriented swarms, prefer a consensus-first shape over parallel writers: proposer roles coordinate in a room with message/inspect tools, a named implementer owns the first artifact write, a QA reviewer inspects the result, and a finalizer applies review-grounded fixes before `run.done`. This pattern keeps creative/lens diversity while preserving one coherent artifact and gives recipes concrete artifact assertions instead of treating room discussion as success.
|
|
52
|
+
|
|
51
53
|
Register one atom:
|
|
52
54
|
|
|
53
55
|
```text
|
|
@@ -82,7 +84,7 @@ Pipeline recipes demonstrate second-order composition:
|
|
|
82
84
|
- `recipes/pipeline-development-tasking.json`: Plan → task card → critique → integrator handoff.
|
|
83
85
|
- `recipes/pipeline-docs-maintenance.json`: Docs index → documentation review → maintenance plan → artifact report.
|
|
84
86
|
- `recipes/pipeline-media-library.json`: Playlist build → media-library artifact report.
|
|
85
|
-
- `recipes/pipeline-room-swarm.json`: Room participants join `room:<run>`, coordinate over repeated room-visible rounds, leave cleanly, and synthesize the room transcript into a caller-provided artifact path. Keep model/thinking/mission policy caller-owned. Custom roles can be supplied with `roles_path` as a JSON array of `{ "name", "persona"
|
|
87
|
+
- `recipes/pipeline-room-swarm.json`: Room participants join `room:<run>`, coordinate over repeated room-visible rounds, leave cleanly, and synthesize the room transcript into a caller-provided artifact path. Keep model/thinking/mission policy caller-owned. Custom roles can be supplied with `roles_path` as a JSON array of `{ "name", "persona" }` objects; `name` stays ASCII-safe for `branch:<run>/<name>` addresses and debugger output remains plain and name-driven. The packaged swarm uses contacts for peer awareness but does not rely on direct branch delivery unless a caller-specific worker protocol consumes branch envelopes. Set `locker=true` to compose a local `coordinator-locker` cell under `{state_dir}/locker` for artifact ownership, resource lease locks, and a decision journal without merging locker policy into the room-participant script.
|
|
86
88
|
- `recipes/pipeline-artifact-report.json`: Normalize → artifact-shaped output → actor-message-shaped record. This pipeline prepares a candidate artifact and emits `artifact.prepared`/`artifact.blocked`; the `artifact_path` is a target path, not a guarantee that the file was written.
|
|
87
89
|
- `recipes/pipeline-artifact-write.json`: Normalize → artifact-shaped output → deterministic artifact write → actor-message-shaped record. Use only when the caller explicitly wants filesystem writes; `write_mode` is `create`, `overwrite`, or `append`.
|
|
88
90
|
- `recipes/pipeline-artifact-bundle.json`: Optional validation → deterministic artifact write → machine-readable manifest generation → deterministic manifest write → actor-message-shaped record. Use when the caller explicitly wants a filesystem handoff bundle with both artifact and manifest paths.
|
|
@@ -137,6 +137,35 @@ Existing seeds:
|
|
|
137
137
|
- `subagent-contradiction-map`
|
|
138
138
|
- `subagent-verify`
|
|
139
139
|
|
|
140
|
+
### Consensus-First Build Cell
|
|
141
|
+
|
|
142
|
+
Purpose: turn several expert proposals into one coherent artifact without parallel writers fragmenting the result.
|
|
143
|
+
|
|
144
|
+
Pipeline:
|
|
145
|
+
|
|
146
|
+
```text
|
|
147
|
+
mission → lens proposers in room → consensus transcript → named implementer writes artifact → QA reviewer checks artifact + transcript → finalizer applies fixes → artifact assertions
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Use this for creative demos, single-file artifacts, specs, docs, prompt packs, and product/UX deliverables where broad input matters but one owner should shape the final file. Proposers should have message/inspect tools only. The implementer should be the first role with write tools. QA should inspect/read but not mutate. The finalizer may write only after reading QA evidence.
|
|
151
|
+
|
|
152
|
+
Required gates:
|
|
153
|
+
|
|
154
|
+
- Artifact path, report path, and minimum acceptance checks are explicit inputs.
|
|
155
|
+
- The workflow fails if the requested artifact is missing, too small, or not self-contained enough for the task.
|
|
156
|
+
- `run.done` is emitted only after QA/finalizer passes, not merely after room discussion.
|
|
157
|
+
|
|
158
|
+
Existing seeds:
|
|
159
|
+
|
|
160
|
+
- `pipeline-room-swarm` for room-visible discussion and rosters.
|
|
161
|
+
- `subagent-message` for explicit room handoffs.
|
|
162
|
+
- `subagent-review` / `subagent-verify` for QA roles.
|
|
163
|
+
- `pipeline-artifact-write` or a small helper script for deterministic artifact assertion.
|
|
164
|
+
|
|
165
|
+
Next recipe direction:
|
|
166
|
+
|
|
167
|
+
- Add a generic packaged consensus-build pipeline once the interface stabilizes around proposer roles, implementer prompt, QA prompt, artifact assertions, and public model/tool knobs.
|
|
168
|
+
|
|
140
169
|
### Implementation Tasking Cell
|
|
141
170
|
|
|
142
171
|
Purpose: prepare bounded work for one or more implementation agents.
|
package/docs/template-recipes.md
CHANGED
|
@@ -19,7 +19,7 @@ async: true = run through detached lifecycle
|
|
|
19
19
|
|
|
20
20
|
A recipe wraps one command-template tree. The wrapped `template` keeps the normal command-template semantics: argv splitting, placeholders, defaults, typed args, sequence, `parallel: true`, `when`, delay, retry, failure propagation, recover cleanup, and output selection.
|
|
21
21
|
|
|
22
|
-
Layer boundary: `imports`, `{ "name": "alias" }` imported-recipe nodes, `{alias.defaults.key}` references, fallback expressions, and recipe-local ternaries are recipe-loading features. They resolve before the command-template graph runs and do not extend the portable Command Template Standard. Typed imports are recipe definitions: they expose the imported recipe's command-template-shaped metadata (`template`, `args`, `defaults`, flags, and `values`), while async-run launch fields such as `async` and `
|
|
22
|
+
Layer boundary: `imports`, `{ "name": "alias" }` imported-recipe nodes, `{alias.defaults.key}` references, fallback expressions, and recipe-local ternaries are recipe-loading features. They resolve before the command-template graph runs and do not extend the portable Command Template Standard. Typed imports are recipe definitions: they expose the imported recipe's command-template-shaped metadata (`template`, `args`, `defaults`, flags, and `values`), while async-run launch fields such as `async`, `state_dir`, and `retire_when` remain lifecycle configuration for starting a run, not part of the imported execution graph.
|
|
23
23
|
|
|
24
24
|
Packaged recipes are the pi-actors recipe standard library: declarative actor config components that can be imported, launched, inspected, overridden, or composed by user recipes. Treat them as stable building blocks rather than user-local policy.
|
|
25
25
|
|
|
@@ -29,7 +29,7 @@ Template-recipe standard owns:
|
|
|
29
29
|
|
|
30
30
|
- Saved JSON definitions around one command-template graph.
|
|
31
31
|
- File-backed and co-located recipe shapes.
|
|
32
|
-
- Recipe identity through
|
|
32
|
+
- Recipe identity through file-backed filename or co-located tool id.
|
|
33
33
|
- Recipe defaults, values, imports, import references, and import-node expansion.
|
|
34
34
|
- Ordered named artifact declarations through `artifacts`.
|
|
35
35
|
- Foreground-vs-detached selection through `async: true` when invoked by a recipe-aware host.
|
|
@@ -52,7 +52,6 @@ Synchronous recipe:
|
|
|
52
52
|
|
|
53
53
|
```json
|
|
54
54
|
{
|
|
55
|
-
"name": "check-docs",
|
|
56
55
|
"template": "npm run check:docs"
|
|
57
56
|
}
|
|
58
57
|
```
|
|
@@ -61,13 +60,12 @@ Async recipe:
|
|
|
61
60
|
|
|
62
61
|
```json
|
|
63
62
|
{
|
|
64
|
-
"name": "review-docs",
|
|
65
63
|
"async": true,
|
|
66
64
|
"template": "review docs/spec.md"
|
|
67
65
|
}
|
|
68
66
|
```
|
|
69
67
|
|
|
70
|
-
|
|
68
|
+
A file-backed recipe's id comes from its filename, not a JSON `name` field. Legacy files may still contain `name`, but loaders ignore it for identity. `template` is the command-template tree. `async: true` selects detached run mode when the recipe is invoked through a registered tool.
|
|
71
69
|
|
|
72
70
|
## Discovery Priority
|
|
73
71
|
|
|
@@ -107,7 +105,6 @@ Use recipe-level `artifacts` to declare stable artifact names and paths for the
|
|
|
107
105
|
|
|
108
106
|
```json
|
|
109
107
|
{
|
|
110
|
-
"name": "report-task",
|
|
111
108
|
"args": ["report_path:path"],
|
|
112
109
|
"defaults": { "report_path": "artifacts/report.md" },
|
|
113
110
|
"artifacts": {
|
|
@@ -156,11 +153,10 @@ Recipes do not declare a second event-delivery policy. A running actor emits add
|
|
|
156
153
|
|
|
157
154
|
## Command-Template Flags At Recipe Top Level
|
|
158
155
|
|
|
159
|
-
Top-level command-template flags may sit beside
|
|
156
|
+
Top-level command-template flags may sit beside recipe metadata such as `async`:
|
|
160
157
|
|
|
161
158
|
```json
|
|
162
159
|
{
|
|
163
|
-
"name": "review-docs",
|
|
164
160
|
"async": true,
|
|
165
161
|
"parallel": true,
|
|
166
162
|
"timeout": 300000,
|
|
@@ -199,7 +195,7 @@ Bare recipe names resolve under that directory, so `file: "review-docs"` loads:
|
|
|
199
195
|
~/.pi/agent/recipes/review-docs.json
|
|
200
196
|
```
|
|
201
197
|
|
|
202
|
-
Call-time params override file params. `values` are merged with file values; call-time values win. If a run id is omitted for an explicit async start, the
|
|
198
|
+
Call-time params override file params. `values` are merged with file values; call-time values win. If a run id is omitted for an explicit async start, the file basename becomes the default run id.
|
|
203
199
|
|
|
204
200
|
## Registered Recipe Tools
|
|
205
201
|
|
|
@@ -226,7 +222,7 @@ Example: a recipe may expose a private `repo` default for an example script, whi
|
|
|
226
222
|
|
|
227
223
|
## Recipe Imports
|
|
228
224
|
|
|
229
|
-
File-backed recipes may import other file-backed recipes at the recipe layer. Imports are resolved before the command-template graph is executed, so command-template core stays registry-free and synchronous.
|
|
225
|
+
File-backed recipes may import other file-backed recipes at the recipe layer. Imports are resolved before the command-template graph is executed, so command-template core stays registry-free and synchronous. Recipe loading is intentionally bounded: a single recipe file larger than 1 MiB is rejected before JSON parsing, and import chains deeper than 32 are rejected before further resolution. Split very large prompts/data into explicit files or artifacts and keep recipe graphs shallow enough for operator review.
|
|
230
226
|
|
|
231
227
|
```json
|
|
232
228
|
{
|
|
@@ -244,17 +240,16 @@ File-backed recipes may import other file-backed recipes at the recipe layer. Im
|
|
|
244
240
|
|
|
245
241
|
An import binding may be either a string recipe path/name or an object with:
|
|
246
242
|
|
|
247
|
-
- `from`: recipe path or bare name. Import paths support static load-time placeholders: `{repo}` expands to the directory above the active recipe root, and `{agent}` expands to the pi agent directory. For a packaged recipe in `<repo>/recipes/name.json`, `{repo}/recipes/other.json` resolves to a sibling packaged recipe. For a user recipe in `~/.pi/agent/recipes/name.json`, `{repo}` and `{agent}` both resolve to `~/.pi/agent`.
|
|
243
|
+
- `from`: recipe path or bare recipe name. Import paths support static load-time placeholders: `{repo}` expands to the directory above the active recipe root, and `{agent}` expands to the pi agent directory. For a packaged recipe in `<repo>/recipes/name.json`, `{repo}/recipes/other.json` resolves to a sibling packaged recipe. For a user recipe in `~/.pi/agent/recipes/name.json`, `{repo}` and `{agent}` both resolve to `~/.pi/agent`. Bare names such as `utility-package-summary` resolve by recipe priority: first `~/.pi/agent/recipes`, then the importing recipe's directory, then the packaged standard library. This makes packaged recipes easy to reuse while preserving user/ad hoc overrides by filename identity.
|
|
248
244
|
- `defaults`: extra default values exposed through the import.
|
|
249
245
|
- `values`: explicit values for embedding that imported recipe.
|
|
250
246
|
|
|
251
247
|
A template node of `{ "name": "alias" }` is replaced with the imported recipe's command-template graph. Imported recipe defaults are merged with import `defaults`, import `values`, node `defaults`, and node `values`; later layers win. This lets a parent recipe embed a reusable recipe in a sequence or `parallel: true` branch without inventing a workflow language.
|
|
252
248
|
|
|
253
|
-
Async composition stays explicit: importing a recipe reuses its command-template-shaped definition. It does not start a nested async run. Put `async: true` on the parent recipe when the combined imported graph should run detached as one run with one state dir. For agent-callable fanout, prefer public inputs such as `prompts:array` plus `repeat: "{prompts.length}"`, then select each branch value with `{prompts[index]}` instead of baking concrete prompts or file names into the reusable recipe.
|
|
249
|
+
Async composition stays explicit: importing a recipe reuses its command-template-shaped definition. It does not start a nested async run. Put `async: true` on the parent recipe when the combined imported graph should run detached as one run with one state dir. Ephemeral coordinator recipes may declare `retire_when: "children_terminal"` as an opt-in lifecycle hint for future graceful retirement handling; persistent services and implementer loops should omit it. For agent-callable fanout, prefer public inputs such as `prompts:array` plus `repeat: "{prompts.length}"`, then select each branch value with `{prompts[index]}` instead of baking concrete prompts or file names into the reusable recipe.
|
|
254
250
|
|
|
255
251
|
```json
|
|
256
252
|
{
|
|
257
|
-
"name": "parallel-review",
|
|
258
253
|
"async": true,
|
|
259
254
|
"imports": {
|
|
260
255
|
"review": "review-one.json"
|
|
@@ -301,6 +296,6 @@ Nested object keys are dot-separated. Import references are resolved before norm
|
|
|
301
296
|
|
|
302
297
|
## Recipe Shape
|
|
303
298
|
|
|
304
|
-
Use
|
|
299
|
+
Use the filename for file-backed recipe ids, and use `async: true` for detached runs. Use `parallel: true` for fanout, `when` for node guards, and semantic public args such as `tools`, `all`, or `timeout_ms` instead of leaking CLI fragments or reusing node-control names. Local files belong under `~/.pi/agent/recipes/*.json` before relying on recipe launchers.
|
|
305
300
|
|
|
306
301
|
If a proposed recipe needs a scheduler, queue daemon, `goto`, or custom workflow syntax, stop. Keep the recipe as saved command-template JSON and put policy in the registered tool, script, or caller.
|