@llblab/pi-actors 0.38.1 → 0.40.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 +11 -4
- package/BACKLOG.md +2 -11
- package/CHANGELOG.md +51 -0
- package/README.md +120 -131
- package/dist/index.js +6 -4
- package/dist/lib/async-runs.d.ts +4 -0
- package/dist/lib/async-runs.js +112 -17
- package/dist/lib/command-templates.d.ts +9 -0
- package/dist/lib/command-templates.js +92 -11
- package/dist/lib/config.js +0 -5
- package/dist/lib/execution.d.ts +31 -0
- package/dist/lib/execution.js +145 -12
- package/dist/lib/file-state.d.ts +1 -0
- package/dist/lib/file-state.js +91 -3
- package/dist/lib/observability.d.ts +1 -1
- package/dist/lib/observability.js +7 -4
- package/dist/lib/pi.d.ts +1 -1
- package/dist/lib/pi.js +2 -2
- package/dist/lib/prompts.d.ts +1 -2
- package/dist/lib/prompts.js +2 -3
- package/dist/lib/recipes-context.js +17 -9
- package/dist/lib/recipes-discovery.js +11 -5
- package/dist/lib/recipes-references.d.ts +1 -1
- package/dist/lib/recipes-references.js +4 -5
- package/dist/lib/recipes-usage.d.ts +2 -0
- package/dist/lib/recipes-usage.js +35 -21
- package/dist/lib/registry.d.ts +0 -2
- package/dist/lib/registry.js +33 -10
- package/dist/lib/runs-ownership.d.ts +7 -0
- package/dist/lib/runs-ownership.js +82 -0
- package/dist/lib/runs-process.d.ts +17 -2
- package/dist/lib/runs-process.js +99 -11
- package/dist/lib/runs-retention.d.ts +3 -0
- package/dist/lib/runs-retention.js +18 -3
- package/dist/lib/runs-start.d.ts +2 -2
- package/dist/lib/runs-start.js +51 -17
- package/dist/lib/runs-status.d.ts +1 -1
- package/dist/lib/runs-status.js +8 -6
- package/dist/lib/runtime.js +69 -13
- package/dist/lib/tools-inspect.d.ts +2 -0
- package/dist/lib/tools-inspect.js +39 -2
- package/dist/lib/tools-register.js +0 -1
- package/dist/lib/tools-spawn.js +3 -2
- package/dist/lib/tools.d.ts +1 -0
- package/dist/lib/tools.js +3 -0
- package/dist/pi-actors/index.js +1 -0
- package/dist/recipes/subagent-judge.json +2 -1
- package/dist/recipes/subagent-merge.json +2 -1
- package/dist/recipes/subagent-normalize.json +2 -1
- package/dist/recipes/subagent-review-coordinator.json +1 -1
- package/dist/recipes/subagent-review.json +2 -1
- package/dist/recipes/subagent-verify.json +2 -1
- package/dist/scripts/async-runner.mjs +274 -6
- package/dist/scripts/build-dist.mjs +14 -1
- package/dist/skills/actors/SKILL.md +11 -7
- package/dist/skills/swarm/SKILL.md +1 -1
- package/docs/actor-messages.md +1 -1
- package/docs/async-runs.md +14 -5
- package/docs/command-templates.md +4 -2
- package/docs/recipe-library.md +1 -0
- package/docs/template-recipes.md +5 -7
- package/docs/tool-registry.md +4 -2
- package/index.ts +18 -7
- package/lib/async-runs.ts +138 -19
- package/lib/command-templates.ts +132 -13
- package/lib/config.ts +0 -4
- package/lib/execution.ts +198 -13
- package/lib/file-state.ts +106 -3
- package/lib/observability.ts +11 -5
- package/lib/pi.ts +3 -3
- package/lib/prompts.ts +2 -4
- package/lib/recipes-context.ts +17 -9
- package/lib/recipes-discovery.ts +10 -5
- package/lib/recipes-references.ts +5 -6
- package/lib/recipes-usage.ts +36 -20
- package/lib/registry.ts +43 -13
- package/lib/runs-ownership.ts +117 -0
- package/lib/runs-process.ts +138 -16
- package/lib/runs-retention.ts +22 -2
- package/lib/runs-start.ts +89 -31
- package/lib/runs-status.ts +15 -6
- package/lib/runtime.ts +64 -12
- package/lib/tools-inspect.ts +46 -4
- package/lib/tools-register.ts +0 -3
- package/lib/tools-spawn.ts +5 -5
- package/lib/tools.ts +8 -0
- package/package.json +2 -2
- package/recipes/subagent-judge.json +2 -1
- package/recipes/subagent-merge.json +2 -1
- package/recipes/subagent-normalize.json +2 -1
- package/recipes/subagent-review-coordinator.json +1 -1
- package/recipes/subagent-review.json +2 -1
- package/recipes/subagent-verify.json +2 -1
- package/scripts/async-runner.mjs +274 -6
- package/scripts/build-dist.mjs +14 -1
- package/skills/actors/SKILL.md +11 -7
- package/skills/swarm/SKILL.md +1 -1
package/AGENTS.md
CHANGED
|
@@ -61,7 +61,7 @@ Pi host
|
|
|
61
61
|
- `/skills/actors/SKILL.md`: Dense practical reference for operating pi-actors itself.
|
|
62
62
|
- `/skills/swarm/SKILL.md`: Bundled methodology skill for multi-agent standards, strategies, and portable examples.
|
|
63
63
|
- `/tests/*.test.ts`: Focused regression tests for pure domains.
|
|
64
|
-
- `/README.md`: Human-facing install, usage, and runtime semantics.
|
|
64
|
+
- `/README.md`: Human-facing install, usage, and runtime semantics. Keep it as a product/onboarding entrypoint rather than an implementation dump: identity → why it exists → core verbs → install → first run → address/message model → feature showcase → golden path → recipe memory → platform/safety/docs. Preserve both layers: strong local-actor-kernel positioning plus compact practical capability catalog.
|
|
65
65
|
- `/BACKLOG.md`: Canonical open work; only completable future work.
|
|
66
66
|
- `/CHANGELOG.md`: Completed delivery history.
|
|
67
67
|
- `/docs/README.md`: Documentation index.
|
|
@@ -102,20 +102,25 @@ Pi host
|
|
|
102
102
|
## Runtime Contract
|
|
103
103
|
|
|
104
104
|
- Register trusted command templates with placeholder-derived args, progressive typed arg declarations, inline/default/`??`/ternary fallback, and split-first command argv construction.
|
|
105
|
+
- Serialize extension-authored recipe mutations with the canonical-path file lock across the complete check/read/write/runtime-update window; keep usage telemetry in locked `.usage/<recipe-filename>.json` sidecars so metadata cannot overwrite authored recipes, and do not replace keyed locking with a broad registry lock.
|
|
105
106
|
- Keep command templates synchronous and portable; `async: true` is the detached run switch.
|
|
106
107
|
- Preserve node controls: `when`, positive `timeout`, `delay`, bounded `retry`, `failure`, and `recover` cleanup.
|
|
108
|
+
- Persist every async command's complete byte-exact stdout/stderr under command- and retry-specific run-state paths while keeping returned tails bounded and pipeline stdin complete.
|
|
107
109
|
- Keep async run state under `~/.pi/agent/tmp/pi-actors/runs` with injected `{run_id}` and `{state_dir}` values.
|
|
108
|
-
- Preserve event-driven observability: terminal
|
|
109
|
-
-
|
|
110
|
+
- Preserve event-driven observability: durable retrying terminal steering notifications, coordinator-bound outbox messages, branch-aware triangles, process-tree expansion, and bounded body previews. Terminal delivery is at-least-once across the unavoidable send/handled-marker crash window.
|
|
111
|
+
- When a deferred actor result gates the next step, wait for its terminal steering notification. Do not schedule continuation loops, repeatedly inspect, or mutate its reviewed scope while it runs; inspect early only on operator request, meaningful actor event, or diagnosis of an overdue/stuck run.
|
|
112
|
+
- Do not restore busy-polling examples, duplicate terminal notifications, or duplicate notifications for handled `cancel`, `kill`, or control-stop actions.
|
|
110
113
|
|
|
111
114
|
## Recipes And Registry
|
|
112
115
|
|
|
113
116
|
- `~/.pi/agent/recipes/*.json` is executable muscle memory: recipes there become persistent tools by location.
|
|
114
117
|
- Preserve filename identity, atomic writes, explicit operator-gated changes, and local transportability.
|
|
118
|
+
- Recipe live reload must watch the parent when the user recipe root is absent, switch to the root watcher when it appears, and rearm after deletion/rename without polling or duplicate watcher ownership.
|
|
115
119
|
- Packaged/ad hoc recipes outside the agent root are components, not user tools.
|
|
116
120
|
- Register existing recipes by importing them from the user-root wrapper and using a `{ "name": "alias" }` template node; do not duplicate a ready recipe's script command, defaults, mailbox, or artifact contract in the wrapper.
|
|
117
121
|
- Skill-owned scripts must be exposed through skill-owned recipes first. If a local tool needs that capability, import the skill recipe via `{agent}/skills/<skill>/recipes/<recipe>.json` instead of calling `{agent}/skills/<skill>/scripts/*` directly.
|
|
118
122
|
- Tool definitions use `template`, not `script`, and built-in/core tool names must not be shadowed.
|
|
123
|
+
- Host registrations may remain visible because Pi cannot unregister dynamic definitions, but extension-local `message` and `inspect` lookup must consult the current runtime recipe registry before returning or executing a cached definition.
|
|
119
124
|
- Packaged recipe growth is demand-driven: prefer reusable components over speculative scenario catalogs.
|
|
120
125
|
- Recipe templates may point directly at executable helper scripts when the recipe owns that script boundary; keep script executable bits and avoid unnecessary `node` prefixes.
|
|
121
126
|
|
|
@@ -131,12 +136,14 @@ Pi host
|
|
|
131
136
|
|
|
132
137
|
## State, IO, And Safety
|
|
133
138
|
|
|
134
|
-
- Tool stdout and temp state must stay bounded and local.
|
|
139
|
+
- Tool stdout and temp state must stay bounded and local; preserve complete high-volume streams in spill files with byte/truncation metadata, and never feed a truncated capture tail into pipeline stdin.
|
|
135
140
|
- Feedback hints must be evidence-backed, bounded, and action-shaped; prefer `next_actions` pointing to existing verbs over prose, and avoid hints when no concrete next step is justified.
|
|
136
141
|
- Keep tail truncation, full-output temp files, failure formatting, and centralized limits intact.
|
|
137
142
|
- Published docs must not include machine-local absolute paths.
|
|
138
143
|
- Any view scanning run directories must apply coordinator/session ownership filters before exposing summaries or previews.
|
|
139
144
|
- Direct branch messages are active inbox queues; guard branch-local append/status rewrites with the branch inbox lock and keep claim/handled/failed transitions tested.
|
|
145
|
+
- Run-state launch and destructive retention require the runtime ownership marker bound to the canonical directory and run id; reject non-run directories, missing/mismatched markers, and symlink aliases rather than trusting `run.json`.
|
|
146
|
+
- Runner lifecycle and destructive process controls require the persisted cross-platform process identity proof (start time, command, and cwd where available); dead, mismatched, or unsupported proofs stay distinct and fail closed rather than degrading to pid liveness.
|
|
140
147
|
- Room/branch provenance checks should validate that accepted `from` addresses belong to the addressed run.
|
|
141
148
|
|
|
142
149
|
## Coordination And Lifecycle
|
package/BACKLOG.md
CHANGED
|
@@ -37,9 +37,9 @@ Non-goals:
|
|
|
37
37
|
- Arbitrary subrooms.
|
|
38
38
|
- Heavy broker abstraction.
|
|
39
39
|
|
|
40
|
-
##
|
|
40
|
+
## Open Work
|
|
41
41
|
|
|
42
|
-
No
|
|
42
|
+
No active implementation or release-preparation work remains. The `0.40.0` release candidate is validated locally; commit, tag, merge, publish, and release actions remain operator-gated rather than backlog work.
|
|
43
43
|
|
|
44
44
|
## Backlog Curation Rules
|
|
45
45
|
|
|
@@ -49,10 +49,6 @@ No open hotfix items.
|
|
|
49
49
|
- Prefer semantic compression before file splitting: fewer public nouns, consistent outcomes, compact diagnostics, and domain-owned constants/helpers.
|
|
50
50
|
- Preserve signal/noise balance: feedback should be state-backed, compact, and action-shaped; do not add advisory prose just because a surface exists.
|
|
51
51
|
|
|
52
|
-
## Minor Backlog
|
|
53
|
-
|
|
54
|
-
No open minor items.
|
|
55
|
-
|
|
56
52
|
The backlog is intentionally pruned to the 20% of work most likely to deliver 80% of value for `pi-actors` as a local actor kernel. Bias toward consolidation, smaller public surface area, and reliability over new feature breadth.
|
|
57
53
|
|
|
58
54
|
## Explicitly Deferred
|
|
@@ -64,11 +60,6 @@ These are valid ideas but not current focus. Reintroduce only with concrete evid
|
|
|
64
60
|
- Cross-session force kill or attach/adopt/reparent: useful later, but ownership policy should not change until observability makes current boundaries clear.
|
|
65
61
|
- Actor address helper CLI: keep diagnostics improving opportunistically inside existing parser/tests.
|
|
66
62
|
- Golden flow docs and flow conformance runner: useful after the diagnostic and promotion surfaces are stable.
|
|
67
|
-
- Documentation refactor: defer until the canonical mailbox loop and worker recipe exist; avoid rewriting docs twice.
|
|
68
63
|
- Host-level tool unregistration: blocked on host API support.
|
|
69
64
|
- Branch-local checkpoint semantics: wait for real collaborative branch-runner experiments.
|
|
70
65
|
- Actor recipe feedback loop: keep advisory and operator-gated after real runs produce evidence.
|
|
71
|
-
|
|
72
|
-
## Suggested Milestone Order
|
|
73
|
-
|
|
74
|
-
1. Re-curate after the next real packaged review-swarm dogfood run.
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,57 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.40.0: Durable Review and Runtime Hardening
|
|
6
|
+
|
|
7
|
+
- `[Runtime]` Collapsed every natural-language positional fragment in child `pi -p` launches into one inspectable prompt file while preserving Pi options and intentional `@file` attachments, so review stages receive one authoritative user turn and preflight diagnostics resolve the concrete stage.
|
|
8
|
+
- `[Tests]` Made the packaged review-readiness dogfood fake Pi reject fragmented prompt argv, covering preflight, reviewer, verifier, merger, judge, and normalizer transport through the real detached runner.
|
|
9
|
+
- `[Reviews]` Added opt-in `accept_output: review_evidence` semantics and marked packaged reviewer, verifier, merger, judge, and normalizer outputs with `ACTOR_REVIEW_RESULT`, so code-zero format acknowledgements or input requests fail closed instead of satisfying quorum or reaching later stages.
|
|
10
|
+
- `[Diagnostics]` Preserved rejected parallel stdout alongside its semantic rejection reason, allowing degraded review runs to retain accepted and rejected branch evidence without counting placeholders as usable.
|
|
11
|
+
- `[Breaking]` Removed public `spawn.state_dir` overrides and reject direct attempts with a retention-safety diagnostic, keeping every public `run:<id>` actor under the runtime-owned addressable run root.
|
|
12
|
+
- `[Safety]` Added canonical run-state ownership markers and require them before launch reuse, archive, or prune; existing non-run directories, forged metadata, mismatched run ids, and symlink aliases now fail closed before destructive retention.
|
|
13
|
+
- `[Safety]` Added and persisted Linux, macOS, and Windows process-identity proofs with start-time, command, and available cwd evidence; status, state reuse, message delivery, cancellation, kill, and retirement now distinguish dead pids, owner mismatches, unsupported proofs, and valid ownership instead of degrading to liveness alone.
|
|
14
|
+
- `[Execution]` Bounded stdout and stderr tails while child commands are running, spilling complete high-volume streams independently with total byte counts, truncation flags, and diagnostic file paths instead of accumulating unbounded strings in memory.
|
|
15
|
+
- `[Execution]` Propagated capture metadata through foreground results, retries, parallel branch diagnostics, and async run events; sequence and parallel pipelines now fail closed with `incomplete pipeline stdin` instead of feeding truncated tails downstream.
|
|
16
|
+
- `[Registry]` Added cross-process file mutation locks keyed by canonical recipe path and wrapped register, update, delete, and draft-promotion windows; concurrent same-name registrations now have one explicit winner.
|
|
17
|
+
- `[Registry]` Moved user-recipe usage telemetry into locked `.usage/<recipe-filename>.json` sidecars and merge it during discovery, so sibling-process counters remain monotonic while external recipe edits and file-watcher refreshes cannot be overwritten by metadata writes.
|
|
18
|
+
- `[Routing]` Made `message to=tool:<name>` and `inspect tool:<name>` resolve definitions only when the current runtime recipe registry still marks the tool active; deleted/external-removed recipes are revoked immediately and updates route only to the newest extension-local definition despite host-level unregister limitations.
|
|
19
|
+
- `[Retention]` Made pruned artifact preservation collision-safe with readable artifact-name/hash/basename targets and timestamp preservation; duplicate basenames remain distinct, missing optional artifacts stay skipped, and any copy failure aborts before source run state is deleted.
|
|
20
|
+
- `[Registry]` Rearmed recipe live reload through an advisory parent watcher when `~/.pi/agent/recipes` is absent or renamed, switching back to the root watcher on creation and reloading on deletion; first-run creation, recreation, and idempotent shutdown now work without polling or session restart.
|
|
21
|
+
- `[Backlog]` Rewrote the remaining packaged hardening review milestone as ordered open-checkbox tasks with decision-grade evidence, finding classification, reconciliation, and validation exit criteria.
|
|
22
|
+
- `[Review]` Completed the six-lens packaged hardening pipeline above quorum. The normalized verdict was blocked by a reproduced UTF-8 capture defect; other reported concerns remained hypotheses because raw stage outputs were not retained for independent audit. Re-curated the backlog around durable per-stage review evidence before the next release-readiness run.
|
|
23
|
+
- `[Execution]` Preserved raw command bytes across stream chunk boundaries and aligned bounded tails to UTF-8 code-point boundaries, preventing split multibyte output from becoming replacement characters while keeping complete spill files byte-exact.
|
|
24
|
+
- `[Actors]` Added an async-patience invariant to the runtime prompt, project context, and bundled actors skill: when deferred actor output gates the next step, wait for the terminal follow-up instead of scheduling continuation loops, repeatedly inspecting, or mutating the reviewed scope.
|
|
25
|
+
- `[Backlog]` Decomposed durable review provenance into nine ordered open tasks covering byte-exact stage output, evidence manifests, bounded inspection, report references, regression proof, re-review, finding classification, and final context validation.
|
|
26
|
+
- `[Evidence]` Persisted complete stdout and stderr for every async command, including small streams, under collision-safe `captures/command-NNN/attempt-NNN/{stdout,stderr}.log` identities; retries remain distinct while bounded result tails and complete pipeline stdin behavior stay unchanged.
|
|
27
|
+
- `[Evidence]` Added terminal `review-evidence.json` manifests mapping stable command/stage occurrences and repeated branches to prompts, byte-exact attempt files, byte counts, truncation, exit state, semantic marker acceptance, recipe context, and inherited/explicit model policy; manifests update during execution and finish with aligned `done`/`failed` status.
|
|
28
|
+
- `[Inspector]` Exposed owned review-evidence manifests and referenced capture paths through existing `inspect run:<id> view=files|artifacts` responses, bounding command entries by `lines` and reporting total/truncated counts without adding a public verb or bypassing session ownership checks.
|
|
29
|
+
- `[Review Evidence]` Injected stable prior-stage `ACTOR_EVIDENCE_REF` entries into verifier, merger, judge, and normalizer prompts; normalized reports now retain auditable reviewer/downstream references, terminal manifests record cited and missing sources, and a report claiming `complete` fails closed when any required reviewer, verifier, merger, or judge reference is absent.
|
|
30
|
+
- `[Review Dogfood]` Expanded deterministic provenance coverage across small, spilled, UTF-8, retry, parallel, semantic-marker rejection, partial-quorum, and terminal paths; the packaged review fixture now reconstructs reviewer branch identity, accepted/rejected counts, rejected raw output, downstream source references, final degraded status, and exactly-once capture files solely from retained run state.
|
|
31
|
+
- `[Review]` Completed the auditable six-lens `hardening-review-040` run with all 14 stages accepted and every required evidence reference retained. Re-curated confirmed release blockers covering canonical alias locks, live owner-mismatch reuse, symlink-cwd identity, public custom state directories, complete large-pipeline stdin, exact evidence markers, semantic notification alignment, interrupted evidence finalization, and missed terminal replay; kept the cancellation timing race and native platform gaps explicitly unconfirmed.
|
|
32
|
+
- `[Locking]` Keyed mutation locks by filesystem identity: existing targets or nearest existing ancestors are resolved through native `realpath`, nonexistent suffixes are preserved, Windows identities are case-normalized, and stale lock directories are reclaimed only after their persisted owner PID is proven dead. Added a cross-process real-parent/symlink-parent serialization regression.
|
|
33
|
+
- `[Run Safety]` Made live `owner_mismatch` state reuse fail closed in both preflight and state-directory preparation, including terminal-result timing windows; tampered process identity can no longer clear/reuse an occupied run directory while its original runner remains alive.
|
|
34
|
+
- `[Process Identity]` Canonicalized existing launch cwd paths through native `realpath` before matching the runner's process proof, with Windows case normalization; Linux integration now proves a symlinked launch cwd retains a valid, controllable process identity while injected Darwin/Windows contracts remain intact.
|
|
35
|
+
- `[Public Boundary]` Removed lifecycle `state_dir` from `register_tool`, persisted/co-located recipe normalization, generated schemas, result details, serialization, recipe-reference resolution, and prompt copy. Legacy stored values are ignored, and registered async tools now always launch under the runtime-owned run root where `run:<id>` inspection, messaging, indexing, and retention agree.
|
|
36
|
+
- `[Pipeline Dataflow]` Downstream sequence commands now receive complete spilled stdout from sequential and parallel producers while model-facing output, branch reports, and diagnostics remain bounded. Missing or unreadable spill files still fail closed; exact >1 MiB consumer-count regressions cover both composition shapes.
|
|
37
|
+
- `[Review Evidence]` Tightened semantic acceptance to require `ACTOR_REVIEW_RESULT` as the exact first non-whitespace line in both execution policy and persisted evidence manifests; prefixed markers such as `ACTOR_REVIEW_RESULT_BOGUS` now fail with code 65 and remain rejected evidence.
|
|
38
|
+
- `[Review Notifications]` Applied semantic output acceptance before async command accounting, so rejected code-zero review output is consistently recorded as code 65 in `command.done`, terminal progress failures, evidence, and outbox summaries, with follow-up delivery and error severity instead of a false success notification.
|
|
39
|
+
- `[Interrupted Evidence]` Review evidence records now exist before command launch and are finalized as `cancelled` or `killed` by lifecycle control even when the command never returns. Async captures create byte-exact stdout/stderr files at attempt start, preserving small partial streams as well as spills; manifests retain interruption status, signal-derived effective exit code, capture bytes, and semantic interruption state.
|
|
40
|
+
- `[Terminal Delivery]` Terminal actor notifications now use Pi steering with `triggerTurn: true`: busy agents receive completion at the next safe tool boundary and idle agents start a normal turn without a racy manual idle check. Unhandled owned terminal runs retry during same-runtime and replacement reconciliation until `terminal-handled.json` is written after a successful send, without replaying historical outbox traffic. Delivery is honestly at-least-once: a process crash between send and marker persistence may duplicate a notification.
|
|
41
|
+
- `[Cancel Race]` Authoritative terminal result/control state now short-circuits cancel/kill before process-identity probing because no signal will be sent. This removes transient `unsupported proof` classifications while preserving fail-closed identity checks for running processes and derived `exited` states; a 30-run completion/cancel stress regression consistently returns `not running`.
|
|
42
|
+
- `[Release Review]` Completed the final six-lens hardening review with all branches and downstream stages successful and durable evidence under `hardening-review-040-final`. The review blocked release on five bounded correctness findings: large marked-output acceptance, cross-process registry collision state, live aged start locks, same-runtime terminal-delivery retry, and disappearing-run inspection tolerance. Per operator direction, no further reviewer runs are required before release; fixes use local regressions and validation.
|
|
43
|
+
- `[Large Review Output]` Semantic marker acceptance now reads byte-complete captured stdout when the bounded tail is truncated, while returned model-facing output remains bounded. Foreground and async regressions prove valid `ACTOR_REVIEW_RESULT` output above 1 MiB succeeds and persists accepted evidence metadata.
|
|
44
|
+
- `[Registry Collision]` Same-name registration now rereads authoritative recipe state while holding the canonical cross-process mutation lock instead of trusting a process-local tool map. A sibling-process regression proves exactly one create wins and the loser receives the explicit `update=true` collision error without overwriting the recipe.
|
|
45
|
+
- `[Start Lock Ownership]` Run-start locks now persist the starter's process identity and aged locks are reclaimed only when the recorded PID is proven dead. Live, mismatched, unavailable, and malformed ownership proofs remain protected regardless of age; regressions cover both live-owner retention and dead-owner recovery.
|
|
46
|
+
- `[Inspection TOCTOU]` Runtime triage now treats a run that disappears between inventory and status read as a skipped stale entry instead of failing the entire inspection. Injectable inventory/status ports provide a deterministic disappearance regression without weakening ownership filtering for surviving runs.
|
|
47
|
+
- `[Package Entrypoint]` Added a named compiled wrapper at `dist/pi-actors/index.js` and pointed package metadata to it, preserving the compiled runtime while making Pi's extension list identify `pi-actors` instead of the anonymous parent label `dist`.
|
|
48
|
+
- `[Release]` Updated package, lockfile, bundled skill metadata, compiled assets, and changelog identity for the release candidate; validation, conformance, package dry-run, diff checks, and context reconciliation are green.
|
|
49
|
+
|
|
50
|
+
## 0.39.0: Actor Kernel Welcome Refresh
|
|
51
|
+
|
|
52
|
+
- `[Docs]` Reworked the root README as a product/onboarding entrypoint for the local actor kernel, with clearer positioning, first-run path, feature showcase, recipe-memory model, address/message examples, and practical surface-selection guidance. Impact: new operators can understand when to use `spawn`, `message`, `inspect`, recipes, rooms, and artifacts without reading deep implementation docs first.
|
|
53
|
+
- `[Context]` Added a durable README standard to `AGENTS.md` so future edits preserve the RhythmE/product entrypoint shape while keeping the practical capability catalogue visible.
|
|
54
|
+
- `[Release]` Bumped package metadata to `0.39.0` for the onboarding refresh minor release.
|
|
55
|
+
|
|
5
56
|
## 0.38.1: Windows Recipe ACL Hotfix
|
|
6
57
|
|
|
7
58
|
- `[Registry]` Replaced POSIX mode-bit recipe-root writability checks on Windows with ACL-aware diagnostics, avoiding false `world-writable` and `group-writable` startup warnings from Node's NTFS mode emulation while still flagging broad Windows write grants.
|
package/README.md
CHANGED
|
@@ -1,54 +1,48 @@
|
|
|
1
1
|
# pi-actors
|
|
2
2
|
|
|
3
|
-
> Local Actor Kernel for Pi
|
|
4
|
-
|
|
5
3
|

|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
**Local actor kernel for Pi.**
|
|
6
|
+
|
|
7
|
+
`pi-actors` turns trusted local programs, scripts, services, pipelines, recipes, and sub-agents into addressable actors that Pi can spawn, steer, inspect, and reuse. It is the bridge between one-shot shell commands and durable local capability memory.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
A command is a moment. An actor is a local thing with time: address, lifecycle, logs, mailbox, messages, artifacts, state, and an interaction contract.
|
|
10
10
|
|
|
11
11
|
```text
|
|
12
|
-
|
|
12
|
+
trusted local capability
|
|
13
13
|
→ command template
|
|
14
|
-
→
|
|
14
|
+
→ recipe
|
|
15
15
|
→ spawn
|
|
16
16
|
→ run:<id>
|
|
17
17
|
→ message / inspect / artifacts
|
|
18
|
+
→ reusable tool memory
|
|
18
19
|
```
|
|
19
20
|
|
|
20
|
-
##
|
|
21
|
+
## Why it exists
|
|
21
22
|
|
|
22
|
-
`pi-actors`
|
|
23
|
+
Agents are good at reasoning, but they should not reconstruct the same fragile background command every time a task becomes long-lived. `pi-actors` gives Pi a local-first actor layer: work can outlive the current turn, expose bounded state, receive typed instructions, produce artifacts, and graduate into persistent recipe-backed tools under `~/.pi/agent/recipes`.
|
|
23
24
|
|
|
24
|
-
|
|
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
|
-
```
|
|
25
|
+
Use it when the correct shape is not "run a command and forget" but "start a local capability, keep its handle, and come back with intent."
|
|
29
26
|
|
|
30
|
-
|
|
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. For non-trivial actor use, load the bundled `actors` skill before improvising. Do not build polling loops as the default coordination pattern.
|
|
27
|
+
## The promise
|
|
33
28
|
|
|
34
|
-
|
|
29
|
+
- **Spawn long-lived work without shell gymnastics.** Start services, workers, subagents, fanouts, and pipelines as named actor runs.
|
|
30
|
+
- **Steer instead of restarting.** Send typed `message` envelopes to runs, tools, branches, rooms, sessions, or coordinators.
|
|
31
|
+
- **Inspect intentionally.** Read status, logs, messages, mailboxes, artifacts, registry health, and room rosters at decision points.
|
|
32
|
+
- **Promote what works.** Persist trusted command templates and recipes as durable local tools in `~/.pi/agent/recipes`.
|
|
33
|
+
- **Keep orchestration local.** State is file-backed, inspectable, operator-owned, and designed for Pi sessions rather than a cloud broker.
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
## Core verbs
|
|
37
36
|
|
|
38
|
-
-
|
|
39
|
-
- Stateful, resumable, or something you will need to inspect later.
|
|
40
|
-
- Expected to produce named artifacts or follow-up messages.
|
|
41
|
-
- A service, worker, media process, fanout, subagent, or pipeline.
|
|
42
|
-
- A repeatable local capability worth promoting into recipe memory.
|
|
37
|
+
`pi-actors` compresses local orchestration into three public verbs:
|
|
43
38
|
|
|
44
|
-
|
|
39
|
+
| Verb | Use it when | Result |
|
|
40
|
+
| --- | --- | --- |
|
|
41
|
+
| `spawn` | Work may outlive this turn, fan out, produce artifacts, or need later steering | A `run:<id>` actor with lifecycle and state |
|
|
42
|
+
| `message` | An existing actor should be continued, stopped, approved, killed, or given scoped input | One typed envelope delivered to one address |
|
|
43
|
+
| `inspect` | You need evidence before deciding the next step | Bounded views of status, logs, messages, registry, artifacts, or rooms |
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
create actor -> spawn
|
|
48
|
-
steer actor -> message
|
|
49
|
-
read state/results -> inspect
|
|
50
|
-
repeatable pattern -> promote to recipe/tool memory
|
|
51
|
-
```
|
|
45
|
+
Everything else is an adapter until proven otherwise.
|
|
52
46
|
|
|
53
47
|
## Install
|
|
54
48
|
|
|
@@ -62,28 +56,53 @@ Or from git:
|
|
|
62
56
|
pi install git:github.com/llblab/pi-actors
|
|
63
57
|
```
|
|
64
58
|
|
|
65
|
-
The npm package is dist-first for JavaScript-only runtimes:
|
|
59
|
+
The npm package is dist-first for JavaScript-only runtimes: Pi metadata points at the named compiled entrypoint `dist/pi-actors/index.js` plus mirrored runtime assets, so extension discovery identifies `pi-actors` rather than an anonymous `dist` directory. Source TypeScript and source skills remain packaged for TypeScript-native or checkout-based runtimes.
|
|
60
|
+
|
|
61
|
+
## First run: actor mode in one minute
|
|
62
|
+
|
|
63
|
+
Use actors instead of ad hoc shell backgrounding when work is long-running, stateful, resumable, artifact-producing, service-like, parallel, agentic, or worth saving.
|
|
64
|
+
|
|
65
|
+
Start an actor:
|
|
66
|
+
|
|
67
|
+
```text
|
|
68
|
+
spawn template="sleep 30 && echo done" as=run:demo
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Inspect it when you need evidence:
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
inspect target=run:demo view=status
|
|
75
|
+
inspect target=run:demo view=tail lines=40
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Steer it with a typed message:
|
|
79
|
+
|
|
80
|
+
```text
|
|
81
|
+
message to=run:demo type=control.kill body=stop
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
For non-trivial actor workflows, load the bundled `actors` skill before improvising. For multi-model review or delegated audit, load the bundled `swarm` skill.
|
|
66
85
|
|
|
67
|
-
## Address
|
|
86
|
+
## Address surface
|
|
68
87
|
|
|
69
|
-
Core
|
|
88
|
+
Core addresses stay small:
|
|
70
89
|
|
|
71
90
|
```text
|
|
72
91
|
run:<id> one detached actor run
|
|
73
92
|
tool:<name> executable registered tool actor
|
|
74
93
|
```
|
|
75
94
|
|
|
76
|
-
Advanced
|
|
95
|
+
Advanced addresses exist for coordination and diagnostics:
|
|
77
96
|
|
|
78
97
|
```text
|
|
79
98
|
branch:<run>/<branch> branch-local worker endpoint
|
|
80
|
-
room:<run>
|
|
81
|
-
coordinator
|
|
99
|
+
room:<run> run-local group timeline plus roster
|
|
100
|
+
coordinator current session coordination path
|
|
82
101
|
session: current session actor surface
|
|
83
|
-
session:all cross-session inventory
|
|
102
|
+
session:all cross-session diagnostics inventory
|
|
84
103
|
```
|
|
85
104
|
|
|
86
|
-
|
|
105
|
+
Messages use one envelope shape:
|
|
87
106
|
|
|
88
107
|
```json
|
|
89
108
|
{
|
|
@@ -98,9 +117,24 @@ Actor messages use one envelope shape:
|
|
|
98
117
|
}
|
|
99
118
|
```
|
|
100
119
|
|
|
101
|
-
Routing
|
|
120
|
+
Routing comes from `to`, actor ownership, and runtime policy. `type` describes intent. Recipes should expose semantic message types instead of transport knobs.
|
|
102
121
|
|
|
103
|
-
##
|
|
122
|
+
## Feature showcase
|
|
123
|
+
|
|
124
|
+
| Surface | What it gives you | Typical move |
|
|
125
|
+
| --- | --- | --- |
|
|
126
|
+
| Command templates | Portable command graphs with placeholders, defaults, guards, retries, parallel nodes, recovery, and timeouts | Wrap a trusted local executable without writing a bespoke tool |
|
|
127
|
+
| Recipes | JSON/Markdown capability specs with metadata, args, defaults, imports, mailbox contracts, artifacts, and async mode | Save a known-good local workflow as reusable muscle memory |
|
|
128
|
+
| Async runs | File-backed detached lifecycle, logs, progress, output, cancellation, artifacts, and durable terminal steering notifications | Let model work, media jobs, services, or pipelines continue after the turn |
|
|
129
|
+
| Message protocol | Typed envelopes across run, tool, branch, room, coordinator, and session targets | Continue, approve, kill, or route work without restarting actors |
|
|
130
|
+
| Rooms and rosters | Run-local group timeline with actor join/leave, contacts, previews, and branch-aware delivery | Coordinate multiple subagents under one visible run |
|
|
131
|
+
| Registry and recipe doctor | Discovered tools, overrides, drafts, invalid recipes, and advisory risk labels | Audit local capability memory before using or promoting it |
|
|
132
|
+
| Draft promotion | Captured ad hoc spawn patterns can become explicit recipes after operator approval | Turn successful improvisation into durable local tools |
|
|
133
|
+
| Review/swarm recipes | Maintained packaged pipelines with preflight, marked semantic evidence, quorum knobs, model/thinking inheritance, one-turn prompt-file transport, and diagnostics | Delegate reviews without rebuilding fanout commands |
|
|
134
|
+
| Actor inspector | Compact TUI/debug views for active actor coordination, unread branch inboxes, room messages, and attention markers | Watch only the actor traffic that matters right now |
|
|
135
|
+
| Packaged recipe QA | Installed-package-safe checks for helper paths, mailbox contracts, platform scope, artifacts, and recipe structure | Keep shipped actor components executable and diagnosable |
|
|
136
|
+
|
|
137
|
+
## Golden path: from local workflow to actor memory
|
|
104
138
|
|
|
105
139
|
Create a reusable async actor recipe in the user recipe root:
|
|
106
140
|
|
|
@@ -122,15 +156,15 @@ cat > ~/.pi/agent/recipes/docs_review.json <<'JSON'
|
|
|
122
156
|
JSON
|
|
123
157
|
```
|
|
124
158
|
|
|
125
|
-
Because it lives under `~/.pi/agent/recipes/`, the
|
|
159
|
+
Because it lives under `~/.pi/agent/recipes/`, the filename becomes the tool id. `{current_model}` and `{current_thinking}` inherit the active Pi session policy; pass explicit values only when a run should intentionally diverge.
|
|
126
160
|
|
|
127
|
-
|
|
161
|
+
Run it:
|
|
128
162
|
|
|
129
163
|
```text
|
|
130
164
|
docs_review scope="README.md" run_id=docs_review
|
|
131
165
|
```
|
|
132
166
|
|
|
133
|
-
Inspect
|
|
167
|
+
Inspect it:
|
|
134
168
|
|
|
135
169
|
```text
|
|
136
170
|
inspect target=tool:pi-actors view=triage
|
|
@@ -140,79 +174,33 @@ inspect target=run:docs_review view=messages
|
|
|
140
174
|
inspect target=run:docs_review view=mailbox
|
|
141
175
|
```
|
|
142
176
|
|
|
143
|
-
Steer it
|
|
177
|
+
Steer it:
|
|
144
178
|
|
|
145
179
|
```text
|
|
146
180
|
message to=run:docs_review type=control.continue body=continue
|
|
147
181
|
message to=run:docs_review type=control.kill body=stop
|
|
148
182
|
```
|
|
149
183
|
|
|
150
|
-
##
|
|
151
|
-
|
|
152
|
-
Every spawned run can have advanced group messaging at `room:<run>`. Treat this as a run-local timeline plus roster for coordinated actors, not as a core chat/broker concept.
|
|
153
|
-
|
|
154
|
-
Actors can join, post, leave, and discover peers:
|
|
155
|
-
|
|
156
|
-
```text
|
|
157
|
-
message \
|
|
158
|
-
to=room:review \
|
|
159
|
-
from=branch:review/security \
|
|
160
|
-
type=actor.join \
|
|
161
|
-
summary="Security reviewer joined" \
|
|
162
|
-
body='{"role":"reviewer","caps":["security-review"],"claim":"Review auth boundary risks"}'
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
Inspect group messages and roster intentionally:
|
|
166
|
-
|
|
167
|
-
```text
|
|
168
|
-
inspect target=room:review view=status
|
|
169
|
-
inspect target=room:review view=previews
|
|
170
|
-
inspect target=room:review view=roster
|
|
171
|
-
inspect target=room:review view=contacts
|
|
172
|
-
inspect target=room:review view=messages
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
Group posts require a same-run sender, so unrelated runs do not pollute the roster. Direct messages and group 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 visible transcript entry while forwarding branch-targeted copies.
|
|
176
|
-
|
|
177
|
-
## Actor Inspector
|
|
184
|
+
## Recipe memory model
|
|
178
185
|
|
|
179
|
-
The
|
|
180
|
-
|
|
181
|
-
```text
|
|
182
|
-
/actors-inspector-toggle
|
|
183
|
-
/actors-inspector-toggle 20
|
|
184
|
-
/actors-inspector-filter room
|
|
185
|
-
/actors-inspector-filter direct
|
|
186
|
-
/actors-inspector-filter unread
|
|
187
|
-
/actors-inspector-filter branch front
|
|
188
|
-
/actors-inspector-filter mention checkpoint
|
|
189
|
-
/actors-inspect 3
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
The table is compact and optimistic by default: bounded route/type/summary/body previews, capped noisy room rows, branch-local inbox previews, stable event ids in selected-message details, and an inline roster summary in the form `name/role` 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. Use `unread` to focus queued branch inbox work and `branch <name>` / `current-branch <name>` to focus one branch's room/direct/inbox traffic. Rows with `metadata.requires_response=true` show a `!` attention marker. `/actors-inspect <number>` opens the selected row as a full-message view and marks it read for the current session filter; 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.
|
|
193
|
-
|
|
194
|
-
## Registry Model
|
|
195
|
-
|
|
196
|
-
The persistent tool surface is file-discovered:
|
|
186
|
+
The persistent tool surface is location-derived:
|
|
197
187
|
|
|
198
188
|
```text
|
|
199
189
|
~/.pi/agent/recipes/*.json
|
|
200
190
|
~/.pi/agent/recipes/*.md
|
|
201
191
|
```
|
|
202
192
|
|
|
203
|
-
That directory is operator-managed executable memory.
|
|
204
|
-
|
|
205
193
|
Rules:
|
|
206
194
|
|
|
207
|
-
- User recipes in `~/.pi/agent/recipes/` are tools by location
|
|
208
|
-
- Recipe filenames define tool ids
|
|
209
|
-
- User recipes override same-name lower-priority recipes
|
|
210
|
-
- Same-id JSON recipes shadow Markdown recipes in the same priority layer
|
|
211
|
-
- Packaged recipes are standard-library components, not automatically installed operator policy
|
|
212
|
-
- Draft recipes in `~/.pi/agent/recipes/drafts/` are replayable memory, not active tools
|
|
195
|
+
- User recipes in `~/.pi/agent/recipes/` are tools by location.
|
|
196
|
+
- Recipe filenames define tool ids.
|
|
197
|
+
- User recipes override same-name lower-priority recipes.
|
|
198
|
+
- Same-id JSON recipes shadow Markdown recipes in the same priority layer.
|
|
199
|
+
- Packaged recipes are standard-library components, not automatically installed operator policy.
|
|
200
|
+
- Draft recipes in `~/.pi/agent/recipes/drafts/` are replayable memory, not active tools.
|
|
213
201
|
- `register_tool` creates, updates, lists, deletes, or explicitly promotes draft recipe files through the normal agent interface.
|
|
214
202
|
|
|
215
|
-
|
|
203
|
+
Register a foreground tool:
|
|
216
204
|
|
|
217
205
|
```text
|
|
218
206
|
register_tool name=transcribe_audio \
|
|
@@ -220,7 +208,7 @@ register_tool name=transcribe_audio \
|
|
|
220
208
|
template="~/bin/transcribe {file:path} {lang=ru} {model:string}"
|
|
221
209
|
```
|
|
222
210
|
|
|
223
|
-
|
|
211
|
+
Register a recipe-backed tool:
|
|
224
212
|
|
|
225
213
|
```text
|
|
226
214
|
register_tool name=docs_review \
|
|
@@ -229,68 +217,69 @@ register_tool name=docs_review \
|
|
|
229
217
|
args="scope:path,model:string"
|
|
230
218
|
```
|
|
231
219
|
|
|
232
|
-
Promote a
|
|
220
|
+
Promote a captured draft only after explicit operator approval:
|
|
233
221
|
|
|
234
222
|
```text
|
|
235
223
|
register_tool name=docs_review draft=~/.pi/agent/recipes/drafts/spawned-run.json
|
|
236
224
|
```
|
|
237
225
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
Inspect the discovered registry:
|
|
226
|
+
Inspect the registry:
|
|
241
227
|
|
|
242
228
|
```text
|
|
243
229
|
inspect target=recipes view=status
|
|
244
230
|
inspect target=recipes view=summary verbose=true
|
|
231
|
+
inspect target=tool:pi-actors view=triage
|
|
245
232
|
```
|
|
246
233
|
|
|
247
|
-
## Command
|
|
234
|
+
## Command templates
|
|
248
235
|
|
|
249
|
-
A command template is the
|
|
236
|
+
A command template is the launch substrate. It can be a string, a sequence, or a composed graph.
|
|
250
237
|
|
|
251
238
|
Templates support:
|
|
252
239
|
|
|
253
|
-
- Named placeholders
|
|
254
|
-
- Compact types
|
|
255
|
-
- Defaults
|
|
240
|
+
- Named placeholders such as `{file}`, `{model}`, `{prompt}`;
|
|
241
|
+
- Compact types such as `string`, `path`, `int`, `number`, `bool`, `enum(a,b)`;
|
|
242
|
+
- Defaults such as `{lang=ru}` and `{dry_run:bool=true}`;
|
|
256
243
|
- Fallback and small ternary forms;
|
|
257
244
|
- Sequences with stdin flow;
|
|
258
245
|
- Parallel nodes;
|
|
259
|
-
- Retries, recovery, failure policy, delays, and
|
|
246
|
+
- Retries, recovery, failure policy, delays, guards, and timeouts;
|
|
260
247
|
- Async run values such as `{run_id}`, `{state_dir}`, `{actor_address}`, `{default_room}`, and `{communication_file}`.
|
|
261
248
|
|
|
262
|
-
The template owns execution shape. The recipe owns saved metadata, defaults, imports, mailbox,
|
|
249
|
+
The template owns execution shape. The recipe owns saved metadata, defaults, imports, mailbox, artifacts, and async launch policy. The run actor owns detached lifecycle, state, messages, cancellation, and inspection.
|
|
263
250
|
|
|
264
|
-
##
|
|
251
|
+
## Packaged recipe library
|
|
265
252
|
|
|
266
253
|
Packaged recipes live under `recipes/` and helper scripts live under `scripts/`.
|
|
267
254
|
|
|
268
255
|
The library includes:
|
|
269
256
|
|
|
270
|
-
-
|
|
257
|
+
- Subagent launchers;
|
|
271
258
|
- Review, critic, planner, verifier, merger, judge, normalizer, and artifact atoms;
|
|
272
259
|
- Quorum and lens-style pipelines;
|
|
273
260
|
- Repo-health, release-summary, research-synthesis, development-tasking, docs-maintenance, and room-swarm pipelines;
|
|
274
261
|
- Coordinator-locker and actor-message utilities;
|
|
275
262
|
- Local music-player actor recipe.
|
|
276
263
|
|
|
277
|
-
Packaged recipes are building blocks. Copy them into `~/.pi/agent/recipes/`
|
|
278
|
-
|
|
279
|
-
## When To Use What
|
|
280
|
-
|
|
281
|
-
Use a foreground registered tool when the work is short, bounded, and does not need lifecycle.
|
|
282
|
-
|
|
283
|
-
Use an async recipe or `spawn` when the work is long-running, service-like, parallel, agentic, artifact-producing, or needs later control. When a directly spawned inline/ad hoc actor or a recipe outside the user recipe root completes successfully, pi-actors sends the launching agent a follow-up note to offer saving that pattern as a durable recipe/tool under `~/.pi/agent/recipes`; the agent should ask first and never auto-save.
|
|
264
|
+
Packaged recipes are building blocks. Use `spawn file=<recipe>` for maintained packaged pipelines before rebuilding equivalent shell commands. Copy or wrap them into `~/.pi/agent/recipes/` only when they should become durable operator-facing tools.
|
|
284
265
|
|
|
285
|
-
|
|
266
|
+
## Choosing the right surface
|
|
286
267
|
|
|
287
|
-
|
|
268
|
+
| If the work is... | Prefer... |
|
|
269
|
+
| --- | --- |
|
|
270
|
+
| Short, bounded, and foreground | Ordinary tools or registered foreground tools |
|
|
271
|
+
| Long-running, service-like, parallel, agentic, artifact-producing, or controllable | `spawn` / async recipe |
|
|
272
|
+
| Already running and needs new input | `message` |
|
|
273
|
+
| Unclear, failing, or ready for a decision | `inspect` |
|
|
274
|
+
| A multi-actor collaboration under one run | `room:<run>` plus branch addresses |
|
|
275
|
+
| A useful output that should survive context compression | Artifacts |
|
|
276
|
+
| A repeated local workflow | Recipe/tool memory |
|
|
288
277
|
|
|
289
|
-
|
|
278
|
+
When a directly spawned inline/ad hoc actor or a recipe outside the user recipe root completes successfully, `pi-actors` may include a promotion suggestion in its terminal steering notification. The agent should ask first and never auto-save.
|
|
290
279
|
|
|
291
|
-
## Platform
|
|
280
|
+
## Platform support
|
|
292
281
|
|
|
293
|
-
Core actor state, inspection, foreground tools, and basic async runs are portable Node.js behavior. Run-local messaging and stop/kill use
|
|
282
|
+
Core actor state, inspection, foreground tools, and basic async runs are portable Node.js behavior. Run-local messaging and stop/kill use platform adapters under the same `message` API.
|
|
294
283
|
|
|
295
284
|
| Surface | Linux/macOS/WSL | Native Windows |
|
|
296
285
|
| --- | --- | --- |
|
|
@@ -303,13 +292,13 @@ Core actor state, inspection, foreground tools, and basic async runs are portabl
|
|
|
303
292
|
|
|
304
293
|
Packaged recipes should prefer mailbox/wake behavior for portable control. Recipes that require FIFO, Unix shell tools, or platform-specific media backends should make that limitation visible in docs or diagnostics before launch.
|
|
305
294
|
|
|
306
|
-
## Safety
|
|
295
|
+
## Safety boundary
|
|
307
296
|
|
|
308
297
|
`pi-actors` is local-first, not sandbox-first.
|
|
309
298
|
|
|
310
299
|
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.
|
|
311
300
|
|
|
312
|
-
High-risk templates such as shells, interpreter eval modes, and broad filesystem mutation may surface warnings, but the runtime is not a security boundary.
|
|
301
|
+
High-risk templates such as shells, interpreter eval modes, network access, external side effects, and broad filesystem mutation may surface warnings, but the runtime is not a security boundary.
|
|
313
302
|
|
|
314
303
|
Prefer:
|
|
315
304
|
|
|
@@ -317,17 +306,17 @@ Prefer:
|
|
|
317
306
|
- Explicit paths;
|
|
318
307
|
- Typed args;
|
|
319
308
|
- Bounded timeouts for bounded work;
|
|
320
|
-
- Explicit tool allowlists for
|
|
309
|
+
- Explicit tool allowlists for subagents;
|
|
321
310
|
- Deterministic utility recipes for filesystem writes;
|
|
322
311
|
- Human approval for destructive or external side effects.
|
|
323
312
|
|
|
324
|
-
## Non-
|
|
313
|
+
## Non-goals
|
|
325
314
|
|
|
326
|
-
`pi-actors` is
|
|
315
|
+
`pi-actors` is not:
|
|
327
316
|
|
|
328
317
|
- A generic workflow DSL;
|
|
329
318
|
- A remote agent interoperability protocol;
|
|
330
|
-
- A heavyweight broker
|
|
319
|
+
- A heavyweight broker;
|
|
331
320
|
- A sandbox;
|
|
332
321
|
- A facade that hides logs, artifacts, ownership, or local side effects;
|
|
333
322
|
- A polling-first async runner.
|
package/dist/index.js
CHANGED
|
@@ -30,7 +30,7 @@ export default function toolRegistryExtension(pi) {
|
|
|
30
30
|
sendStop: (candidate) => AsyncRuns.sendRunMessage(candidate.stateDir, "stop"),
|
|
31
31
|
});
|
|
32
32
|
};
|
|
33
|
-
const updateRunUi = (ctx, notify = false) => {
|
|
33
|
+
const updateRunUi = (ctx, notify = false, terminalOnly = false) => {
|
|
34
34
|
const ownerId = getRunOwnerId(ctx);
|
|
35
35
|
const snapshot = Observability.readRunUiSnapshot(runUi, ownerId);
|
|
36
36
|
ctx.ui.setStatus("zz-pi-actors-runs", snapshot.status ? ctx.ui.theme.fg("dim", snapshot.status) : undefined);
|
|
@@ -62,7 +62,9 @@ export default function toolRegistryExtension(pi) {
|
|
|
62
62
|
retireCandidateRuns(ctx, snapshot.summary);
|
|
63
63
|
Observability.deliverRunTransitionNotifications(snapshot.transitions, notificationSink);
|
|
64
64
|
Observability.pruneRunUiObservationState(runUi, snapshot);
|
|
65
|
-
|
|
65
|
+
if (!terminalOnly) {
|
|
66
|
+
Observability.deliverRunOutboxNotifications(snapshot.outboxEvents, notificationSink);
|
|
67
|
+
}
|
|
66
68
|
};
|
|
67
69
|
const closeRunWatchers = () => {
|
|
68
70
|
runWatcher.close();
|
|
@@ -126,7 +128,7 @@ export default function toolRegistryExtension(pi) {
|
|
|
126
128
|
activeRunContext = ctx;
|
|
127
129
|
await Temp.prepareExtensionTempDir(Paths.EXTENSION_RUNTIME_PATHS.tempDir);
|
|
128
130
|
runtime.loadTools(ctx);
|
|
129
|
-
updateRunUi(ctx);
|
|
131
|
+
updateRunUi(ctx, true, true);
|
|
130
132
|
closeRunWatchers();
|
|
131
133
|
recipeReload.close();
|
|
132
134
|
runWatcher.refresh();
|
|
@@ -178,7 +180,7 @@ export default function toolRegistryExtension(pi) {
|
|
|
178
180
|
Pi.registerToolDefinitions(pi, Tools.createCoreActorToolDefinitions({
|
|
179
181
|
configPath: Paths.EXTENSION_RUNTIME_PATHS.configPath,
|
|
180
182
|
getActiveTools: () => pi.getActiveTools(),
|
|
181
|
-
getRuntimeTool: (name) => actorToolDefinitions.get(
|
|
183
|
+
getRuntimeTool: (name) => Tools.resolveActiveRuntimeTool(name, runtime.getTools(), (activeName) => actorToolDefinitions.get(activeName)),
|
|
182
184
|
registryRuntime: runtime,
|
|
183
185
|
setActiveTools: (toolNames) => pi.setActiveTools(toolNames),
|
|
184
186
|
}).map(withCurrentThinkingContext));
|