@llblab/pi-actors 0.46.0 → 0.47.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 +7 -5
- package/CHANGELOG.md +20 -0
- package/README.md +2 -1
- package/dist/lib/async-runs.d.ts +1 -0
- package/dist/lib/async-runs.js +4 -1
- package/dist/lib/execution.d.ts +1 -0
- package/dist/lib/execution.js +1 -0
- package/dist/lib/extension-runtime.js +25 -9
- package/dist/lib/inspector.js +1 -0
- package/dist/lib/prompts.d.ts +6 -5
- package/dist/lib/prompts.js +22 -23
- package/dist/lib/recipes-context.d.ts +12 -3
- package/dist/lib/recipes-context.js +28 -4
- package/dist/lib/recipes-discovery.d.ts +22 -0
- package/dist/lib/recipes-discovery.js +108 -23
- package/dist/lib/recipes-references.d.ts +18 -0
- package/dist/lib/recipes-references.js +129 -38
- package/dist/lib/registry.d.ts +23 -6
- package/dist/lib/registry.js +294 -101
- package/dist/lib/runtime.d.ts +30 -3
- package/dist/lib/runtime.js +108 -9
- package/dist/lib/tools-inspect.d.ts +3 -0
- package/dist/lib/tools-inspect.js +190 -26
- package/dist/lib/tools-local.d.ts +2 -2
- package/dist/lib/tools-local.js +5 -2
- package/dist/lib/tools-register.js +2 -1
- package/dist/lib/tools-response.js +7 -1
- package/dist/lib/tools-spawn.d.ts +2 -2
- package/dist/lib/tools-spawn.js +1 -1
- package/dist/lib/tools.d.ts +4 -1
- package/dist/lib/tools.js +2 -0
- package/dist/scripts/conformance.mjs +1 -0
- package/dist/skills/actors/SKILL.md +76 -65
- package/dist/skills/actors/references/diagnostics.md +44 -0
- package/dist/skills/actors/references/persistent-tools.md +74 -0
- package/dist/skills/actors/references/recipes.md +51 -0
- package/dist/skills/actors/references/runs.md +39 -0
- package/dist/skills/artifacts/SKILL.md +24 -7
- package/dist/skills/media/SKILL.md +35 -7
- package/dist/skills/project-work/SKILL.md +28 -7
- package/dist/skills/recipe-memory/SKILL.md +27 -7
- package/dist/skills/swarm/SKILL.md +41 -445
- package/dist/skills/swarm/references/development-swarm.md +87 -539
- package/dist/skills/swarm/references/review-swarms.md +115 -0
- package/docs/README.md +5 -5
- package/docs/recipe-library.md +15 -10
- package/docs/template-recipes.md +3 -1
- package/docs/tool-registry.md +18 -6
- package/lib/async-runs.ts +5 -1
- package/lib/execution.ts +2 -0
- package/lib/extension-runtime.ts +33 -14
- package/lib/inspector.ts +1 -0
- package/lib/prompts.ts +24 -24
- package/lib/recipes-context.ts +49 -4
- package/lib/recipes-discovery.ts +186 -25
- package/lib/recipes-references.ts +176 -44
- package/lib/registry.ts +441 -113
- package/lib/runtime.ts +147 -12
- package/lib/tools-inspect.ts +254 -28
- package/lib/tools-local.ts +9 -3
- package/lib/tools-register.ts +4 -3
- package/lib/tools-response.ts +7 -1
- package/lib/tools-spawn.ts +3 -2
- package/lib/tools.ts +4 -1
- package/package.json +1 -1
- package/scripts/conformance.mjs +1 -0
- package/skills/actors/SKILL.md +76 -65
- package/skills/actors/references/diagnostics.md +44 -0
- package/skills/actors/references/persistent-tools.md +74 -0
- package/skills/actors/references/recipes.md +51 -0
- package/skills/actors/references/runs.md +39 -0
- package/skills/artifacts/SKILL.md +24 -7
- package/skills/media/SKILL.md +35 -7
- package/skills/project-work/SKILL.md +28 -7
- package/skills/recipe-memory/SKILL.md +27 -7
- package/skills/swarm/SKILL.md +41 -445
- package/skills/swarm/references/development-swarm.md +87 -539
- package/skills/swarm/references/review-swarms.md +115 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Review Swarms
|
|
2
|
+
|
|
3
|
+
Use this reference for independent review, delegated audit, research synthesis, quorum judgement, and post-merge review. Generic actor execution remains owned by `actors`.
|
|
4
|
+
|
|
5
|
+
## Select breadth or confidence
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
Different lenses on one target → breadth → lens swarm
|
|
9
|
+
Same exact claim, independent judges → confidence → quorum
|
|
10
|
+
Important lenses each need repeated judges → breadth + confidence → lens swarms of quorums
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Use the smallest shape that covers the decision risk. A lens swarm of quorums is reserved for high-impact security, financial, governance, migration, or release decisions.
|
|
14
|
+
|
|
15
|
+
Primary Recipes:
|
|
16
|
+
|
|
17
|
+
- `swarm/lens-review` for parallel risk lenses plus verification, merge, judge, and normalized result;
|
|
18
|
+
- `swarm/quorum-review` for one prompt judged independently by explicitly selected models;
|
|
19
|
+
- `swarm/research-synthesis` for plan, evidence map, contradictions, verification, and risk-first synthesis;
|
|
20
|
+
- `swarm/architect` for competing directions and one validated smallest next slice;
|
|
21
|
+
- `swarm/review-readiness` for a multi-lens ship/readiness verdict.
|
|
22
|
+
|
|
23
|
+
## Lens selection
|
|
24
|
+
|
|
25
|
+
Choose lenses from plausible failure modes, not from a fixed catalog. Common software lenses include correctness, architecture, security, tests, concurrency, data integrity, performance, operator UX, accessibility, maintainability, documentation, and release risk.
|
|
26
|
+
|
|
27
|
+
A good lens assignment states:
|
|
28
|
+
|
|
29
|
+
```markdown
|
|
30
|
+
Target:
|
|
31
|
+
Question or claim:
|
|
32
|
+
Lens:
|
|
33
|
+
Evidence required:
|
|
34
|
+
Out of scope:
|
|
35
|
+
Severity rule:
|
|
36
|
+
Output shape:
|
|
37
|
+
Stop condition:
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Do not ask every reviewer to cover everything. Keep reviewers independent until synthesis so one early narrative does not contaminate all findings.
|
|
41
|
+
|
|
42
|
+
## Quorum design
|
|
43
|
+
|
|
44
|
+
A quorum keeps the target, claim, evidence standard, and output shape constant while varying independent judges. Before fanout:
|
|
45
|
+
|
|
46
|
+
1. define the exact decision claim;
|
|
47
|
+
2. define what counts as supporting and contradicting evidence;
|
|
48
|
+
3. select the minimum successful threshold;
|
|
49
|
+
4. choose concurrency and timeout bounds;
|
|
50
|
+
5. preflight model and tool availability;
|
|
51
|
+
6. define how partial results affect status.
|
|
52
|
+
|
|
53
|
+
Provider or model failure reduces available evidence; it is not a vote. When evidence falls below threshold, mark the result degraded or insufficient data.
|
|
54
|
+
|
|
55
|
+
## Research evidence
|
|
56
|
+
|
|
57
|
+
Research participants separate source discovery, verification, contradiction mapping, and synthesis when stakes justify it.
|
|
58
|
+
|
|
59
|
+
- Every material claim traces to a source note, inspected artifact, or explicit uncertainty.
|
|
60
|
+
- Source quality and confidence remain visible.
|
|
61
|
+
- Contradictory evidence is first-class output.
|
|
62
|
+
- Missing source classes block overconfident synthesis.
|
|
63
|
+
- Unsafe or unverifiable evidence is excluded with a reason.
|
|
64
|
+
|
|
65
|
+
Do not turn a research swarm into an automatic publication pipeline. Stop at the caller's evidence and decision boundary.
|
|
66
|
+
|
|
67
|
+
## Merge protocol
|
|
68
|
+
|
|
69
|
+
A merger is a synthesis participant, not a formatter. It may deduplicate, rank, connect evidence, and add a grounded `merger finding`, but it may not fabricate support.
|
|
70
|
+
|
|
71
|
+
For serious quorum work, use a clean-context merger. The merger receives all retained participant outputs and must produce:
|
|
72
|
+
|
|
73
|
+
- status: complete, degraded, or insufficient data;
|
|
74
|
+
- consensus findings and vote shape where applicable;
|
|
75
|
+
- minority high-impact findings;
|
|
76
|
+
- contradictions and unresolved evidence gaps;
|
|
77
|
+
- merger findings, clearly labeled;
|
|
78
|
+
- confidence and limitations;
|
|
79
|
+
- ordered next actions.
|
|
80
|
+
|
|
81
|
+
Keep raw participant outputs until the merged result is accepted. Preserve attribution for major findings. Never promote repeated low-value observations merely because they are numerous, and never discard a severe evidence-backed minority finding merely because it is unique.
|
|
82
|
+
|
|
83
|
+
## Conflict and disagreement
|
|
84
|
+
|
|
85
|
+
Disagreement can mean different assumptions, different evidence, ambiguous criteria, or real uncertainty. The merger records:
|
|
86
|
+
|
|
87
|
+
```markdown
|
|
88
|
+
Finding:
|
|
89
|
+
Supporting participants and evidence:
|
|
90
|
+
Contradicting participants and evidence:
|
|
91
|
+
Assumption difference:
|
|
92
|
+
Impact if minority view is correct:
|
|
93
|
+
Resolution status:
|
|
94
|
+
Next evidence needed:
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Resolve only when evidence supports resolution. Otherwise preserve the disagreement and lower confidence.
|
|
98
|
+
|
|
99
|
+
## Post-merge review
|
|
100
|
+
|
|
101
|
+
Use a fresh reviewer when the merged result will drive consequential implementation or decisions. The post-merge reviewer checks the report, not the original target by default:
|
|
102
|
+
|
|
103
|
+
- evidence traceability;
|
|
104
|
+
- honest severity;
|
|
105
|
+
- correct quorum accounting;
|
|
106
|
+
- preserved minority findings;
|
|
107
|
+
- unsupported merger narrative;
|
|
108
|
+
- actionable next steps;
|
|
109
|
+
- retained uncertainty and contradictions.
|
|
110
|
+
|
|
111
|
+
Possible decisions are accept, accept with notes, revise merge, rerun bounded quorum, or escalate. Rerun only when the raw evidence or scope is genuinely insufficient, not because the verdict is inconvenient.
|
|
112
|
+
|
|
113
|
+
## Completion and stop rules
|
|
114
|
+
|
|
115
|
+
A review swarm is complete only when requested evidence is retained, threshold status is explicit, synthesis preserves dissent, and the coordinator can state the safe decision or next evidence slice. Stop when the claim is ambiguous, target changes during review, preflight fails, evidence is not inspectable, threshold cannot be met, or merger independence required by the stakes is unavailable.
|
package/docs/README.md
CHANGED
|
@@ -12,9 +12,9 @@ Living index of all documentation in the `/docs` directory.
|
|
|
12
12
|
- [recipe-library.md](./recipe-library.md) — Packaged standard recipe library such as async subagents, coordinator pipelines, utilities, and music playback
|
|
13
13
|
- [releasing.md](./releasing.md) — Guarded tag validation, npm Trusted Publisher setup, registry verification, and GitHub Release convergence
|
|
14
14
|
|
|
15
|
-
##
|
|
15
|
+
## Project Surfaces
|
|
16
16
|
|
|
17
|
-
- [
|
|
18
|
-
- [
|
|
19
|
-
- [
|
|
20
|
-
- [
|
|
17
|
+
- [Human product entrypoint](../README.md)
|
|
18
|
+
- [Implementation protocol](../AGENTS.md)
|
|
19
|
+
- [Future work](../BACKLOG.md)
|
|
20
|
+
- [Completed delivery history](../CHANGELOG.md)
|
package/docs/recipe-library.md
CHANGED
|
@@ -6,34 +6,39 @@ Active Skills provide maintained execution graphs and service definitions. Skill
|
|
|
6
6
|
|
|
7
7
|
### Repository and delivery
|
|
8
8
|
|
|
9
|
-
- `project-work/repo-health` — repository
|
|
10
|
-
- `project-work/docs-maintenance` — documentation
|
|
11
|
-
- `project-work/release-readiness` —
|
|
12
|
-
- `project-work/release-summary` — release
|
|
13
|
-
- `
|
|
9
|
+
- `project-work/repo-health` — repository status, recent history, docs surface, trusted validation, and bounded report content.
|
|
10
|
+
- `project-work/docs-maintenance` — documentation consistency evidence and a maintenance plan; it does not edit documentation.
|
|
11
|
+
- `project-work/release-readiness` — multi-lens readiness verdict and blockers; it does not publish.
|
|
12
|
+
- `project-work/release-summary` — evidence-only release summary and PR-body draft with no external release side effect.
|
|
13
|
+
- `project-work/run-ops` — read-only report over existing Run state; it does not send Control.
|
|
14
|
+
- `swarm/development-tasking` — bounded task-card and scope-critique pipeline.
|
|
14
15
|
|
|
15
16
|
### Review and synthesis
|
|
16
17
|
|
|
17
18
|
- `swarm/quorum-review` — parallel reviewers with quorum-oriented synthesis.
|
|
18
19
|
- `swarm/review-readiness` — review plus readiness stages.
|
|
19
|
-
- `swarm/research-synthesis` — evidence-
|
|
20
|
-
- `swarm/lens-review` —
|
|
20
|
+
- `swarm/research-synthesis` — evidence map, contradiction analysis, and risk-first research synthesis.
|
|
21
|
+
- `swarm/lens-review` — different independent risk lenses for breadth.
|
|
22
|
+
- `swarm/architect` — competing architecture directions and one validated smallest next slice.
|
|
21
23
|
- `swarm/subagent-review-coordinator` — lower-level review/verify/merge/judge composition.
|
|
22
24
|
|
|
23
25
|
Callers should own model, thinking, concurrency, quorum, and mission policy. Review pipelines preflight provider/model availability before expensive fanout.
|
|
24
26
|
|
|
25
27
|
### Artifacts
|
|
26
28
|
|
|
27
|
-
- `artifacts/report` — prepare
|
|
28
|
-
- `artifacts/write` — prepare and deterministically write
|
|
29
|
+
- `artifacts/report` — prepare normalized report content without committing a filesystem write.
|
|
30
|
+
- `artifacts/write` — prepare and deterministically write one artifact with explicit create/overwrite/append policy.
|
|
29
31
|
- `artifacts/bundle` — optional validation, artifact write, manifest generation, and manifest write.
|
|
30
32
|
- `artifacts/file-write` — deterministic create/overwrite/append helper.
|
|
31
33
|
- `artifacts/manifest` — artifact manifest generation.
|
|
32
34
|
|
|
33
35
|
Artifact pipelines terminate in files/manifests and result evidence; they do not fabricate communication events.
|
|
34
36
|
|
|
35
|
-
###
|
|
37
|
+
### Media and controlled services
|
|
36
38
|
|
|
39
|
+
- `media/playlist-scan` — shallow unfiltered path inventory.
|
|
40
|
+
- `media/playlist-build` — extension-filtered `paths`, `m3u`, or `inline` playlist output; it does not create a playlist file.
|
|
41
|
+
- `media/library` — filtered playlist plus bounded library-report content; `artifact_path` alone is not durable-write proof.
|
|
37
42
|
- `media/player` — playback service with declared playback actions, `controls.jsonl`, generation-fenced endpoint readiness, state artifact, and playback Trace. Player selection is `player:enum(auto,mpv,afplay,ffplay,cvlc,play,wmp)=auto`.
|
|
38
43
|
- `actors/resource-locker` — optional queue/lease-lock service with explicit owner/resource input, lock Trace, and a 512-record/1 MiB atomically retained journal.
|
|
39
44
|
|
package/docs/template-recipes.md
CHANGED
|
@@ -147,7 +147,9 @@ Resolution fails before launch when required current policy is unavailable. The
|
|
|
147
147
|
|
|
148
148
|
## Resolution Context
|
|
149
149
|
|
|
150
|
-
User Recipes under `~/.pi/agent/recipes` remain intentionally registered tools, not an ambient import namespace. Each session receives
|
|
150
|
+
User Recipes under `~/.pi/agent/recipes` remain intentionally registered tools, not an ambient import namespace. Each session receives one immutable resolution context from Pi's loaded Skill metadata; spawn, user-Recipe admission, registration, schema derivation, live inspection, and watcher reconciliation consume that same context rather than scanning ambient Skill roots or keeping a process-global mutable namespace. A launch captures its resolved graph, so later Skill changes affect only future launches. An invalid or missing exact target fails without fallback. Disabled Recipes cannot launch. Registry watchers converge after atomic changes without executing partial definitions.
|
|
151
|
+
|
|
152
|
+
Active-Skill catalog inventory is fail-soft diagnostic state, not exact-resolution authority. Invalid components are reported individually and make the catalog partial while unrelated valid `<skill>/<recipe>` references remain exactly resolvable.
|
|
151
153
|
|
|
152
154
|
## Validation
|
|
153
155
|
|
package/docs/tool-registry.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
~/.pi/agent/recipes/*.json
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
Each
|
|
9
|
+
Each valid Recipe admitted against the current session context can become an agent-callable tool. `register_tool` creates, updates, promotes, or deletes these files through fenced mutation paths and reports the resulting activation state.
|
|
10
10
|
|
|
11
11
|
## Registration
|
|
12
12
|
|
|
@@ -16,13 +16,23 @@ Register a command template:
|
|
|
16
16
|
register_tool name=repo_check template="make check" description="Run repository checks"
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Specialize a maintained Recipe without copying its contract:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
register_tool name=music_player from=media/player defaults={"source":"~/Music/1MIX"}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`from`, `template`, and `draft` are distinct source modes. `from` accepts exact `<skill>/<recipe>` identity or an explicit `.json` / `.md` path and inherits async behavior, args/types, source defaults, artifacts, Control, and runtime-owned origins. `defaults` may set only effective caller-owned args and must satisfy their types. `template` is only for trusted command definitions; public `values` authoring has been removed in favor of caller defaults or an authored Recipe file.
|
|
20
26
|
|
|
21
27
|
Promote an immutable captured draft only with its draft path and explicit target name. Name collisions require `update=true`. Invalid content fails before active mutation.
|
|
22
28
|
|
|
29
|
+
Registration resolves the effective delegated contract before persistence, then reports logical `source`, effective `required_args` / `optional_args`, and distinct `persisted`, `registry_active`, `host_registered`, `active_tool`, and `callable_now` states. A callable result points to the actual generated tool as the next action. An uncallable result names its `activation_boundary` and status/doctor action without suggesting spawn as a substitute. Diagnose one maintained source with `inspect target=recipes view=doctor identity=<skill>/<recipe>`; diagnose final activation, source, schema summary, and separate spawn/tool usage with `inspect target=tool:<name> view=status`. Treat the tool as callable in the current session only when `callable_now` is true; persistence alone is not activation proof. Registration results omit raw persisted paths and executable template/config payloads.
|
|
30
|
+
|
|
23
31
|
## Resolution
|
|
24
32
|
|
|
25
|
-
User Recipes are the only file-discovered tool source. Invalid or disabled user entries fail closed. Active Skill Recipes remain exact components outside tool discovery. Runtime reload watches the user Recipe root and converges after atomic changes; stale watcher generations cannot replace current registration state.
|
|
33
|
+
User Recipes are the only file-discovered tool source. Invalid or disabled user entries fail closed. Active Skill Recipes remain exact components outside tool discovery. Spawn, registration, registry admission, schema derivation, and live inspection resolve against one immutable session context containing the current working directory and active Skills. Runtime reload watches the user Recipe root using that current context and converges after atomic changes; stale watcher generations cannot replace current registration state.
|
|
34
|
+
|
|
35
|
+
Skill component inventory is diagnostic and fail-soft: valid components remain listed and exactly resolvable when an unrelated component is rejected. Recipe inspection reports rejected components and marks the catalog partial instead of treating one bad component as an empty catalog.
|
|
26
36
|
|
|
27
37
|
Inspect registry state with:
|
|
28
38
|
|
|
@@ -31,7 +41,9 @@ inspect target=recipes view=status
|
|
|
31
41
|
inspect target=tool:<name> view=status
|
|
32
42
|
```
|
|
33
43
|
|
|
34
|
-
Recipe inspection reports active, shadowed, invalid, disabled, diagnostic, risk, usage, and review evidence. Tool
|
|
44
|
+
Recipe inspection reports generation, scan/watch state, active, shadowed, invalid, disabled, component rejection, diagnostic, risk, usage, and review evidence. Tool status reports current activation plus separate `tool_calls` and `spawn_calls`; tool schema reports the caller-owned capability contract. A registered tool is not a running actor.
|
|
45
|
+
|
|
46
|
+
`spawn recipe=<name>` executes a Recipe and reports `launch_kind: "spawn"`; it does not prove that a registered tool was exposed or invoked. Registered-tool execution reports `launch_kind: "tool"`.
|
|
35
47
|
|
|
36
48
|
## Automatic Review
|
|
37
49
|
|
|
@@ -59,9 +71,9 @@ Set `PI_ACTORS_AUTOMATIC_REVIEW=off` to disable scheduling and safe-boundary act
|
|
|
59
71
|
|
|
60
72
|
Usage and lineage live in locked metadata ledgers rather than authored Recipe files. Launch accounting briefly shares the portfolio transaction fence so quarantine cannot invalidate an already-authorized launch. Revision snapshots, rollback, demotion, rename, and identical-source deduplication retain CAS/hash evidence.
|
|
61
73
|
|
|
62
|
-
##
|
|
74
|
+
## Specializing Existing Recipes
|
|
63
75
|
|
|
64
|
-
|
|
76
|
+
Use `register_tool from=<skill>/<recipe> defaults={...}` for one maintained capability under a persistent name or narrower defaults. The stored user Recipe remains compact direct delegation; it does not copy async, args/types, Control, artifacts, helpers, or runtime-owned `{recipe_dir}`/`{skill_dir}`. Named imports remain for multi-node Recipe composition, not one-source specialization. Skill Recipes remain components and are never exposed merely because their Skill is active. Install only specific capabilities; internal automatic-review Recipes must not become user-callable tools.
|
|
65
77
|
|
|
66
78
|
## Safety
|
|
67
79
|
|
package/lib/async-runs.ts
CHANGED
|
@@ -161,6 +161,7 @@ export interface AsyncRunMeta {
|
|
|
161
161
|
argv: string[];
|
|
162
162
|
createdAt: string;
|
|
163
163
|
cwd: string;
|
|
164
|
+
launch_kind?: AsyncRunLaunchSource;
|
|
164
165
|
launch_source?: AsyncRunLaunchSource;
|
|
165
166
|
launch_correlation?: {
|
|
166
167
|
correlation_id?: string;
|
|
@@ -600,7 +601,10 @@ export function startRun(
|
|
|
600
601
|
createdAt: new Date().toISOString(),
|
|
601
602
|
cwd,
|
|
602
603
|
...(startParams.launch_source
|
|
603
|
-
? {
|
|
604
|
+
? {
|
|
605
|
+
launch_kind: startParams.launch_source,
|
|
606
|
+
launch_source: startParams.launch_source,
|
|
607
|
+
}
|
|
604
608
|
: {}),
|
|
605
609
|
...(startParams.launch_correlation
|
|
606
610
|
? { launch_correlation: startParams.launch_correlation } : {}),
|
package/lib/execution.ts
CHANGED
|
@@ -83,6 +83,7 @@ export interface RegisteredToolExecutionResult {
|
|
|
83
83
|
command: string;
|
|
84
84
|
fullOutputPath?: string;
|
|
85
85
|
killed: boolean;
|
|
86
|
+
launch_kind: "tool";
|
|
86
87
|
stderrBytes?: number;
|
|
87
88
|
stderrCapturedBytes?: number;
|
|
88
89
|
stderrFile?: string;
|
|
@@ -1136,6 +1137,7 @@ export async function executeRegisteredTool(
|
|
|
1136
1137
|
command,
|
|
1137
1138
|
fullOutputPath: result.stdoutFile ?? formatted.fullOutputPath,
|
|
1138
1139
|
killed: result.killed,
|
|
1140
|
+
launch_kind: "tool",
|
|
1139
1141
|
...getCaptureDetails(result),
|
|
1140
1142
|
...(executed.branches.length > 0 ? { branches: executed.branches } : {}),
|
|
1141
1143
|
...(executed.failures.length > 0
|
package/lib/extension-runtime.ts
CHANGED
|
@@ -9,6 +9,7 @@ import * as CommandTemplates from "./command-templates.ts";
|
|
|
9
9
|
import * as Paths from "./paths.ts";
|
|
10
10
|
import * as Pi from "./pi.ts";
|
|
11
11
|
import * as Prompts from "./prompts.ts";
|
|
12
|
+
import * as RecipeResolution from "./recipes-context.ts";
|
|
12
13
|
import * as RecipesReferences from "./recipes-references.ts";
|
|
13
14
|
import * as RunUiRuntime from "./run-ui-runtime.ts";
|
|
14
15
|
import * as Runtime from "./runtime.ts";
|
|
@@ -34,14 +35,21 @@ export function createActorExtensionRuntime(
|
|
|
34
35
|
pi: Pi.ExtensionAPI,
|
|
35
36
|
): ActorExtensionRuntime {
|
|
36
37
|
let activeRunContext: Pi.ExtensionContext | undefined;
|
|
37
|
-
const
|
|
38
|
+
const recipeResolutionContextsBySession = new Map<
|
|
38
39
|
string,
|
|
39
|
-
|
|
40
|
+
RecipeResolution.RecipeResolutionContext
|
|
40
41
|
>();
|
|
41
42
|
const getRunOwnerId = Pi.getSessionId;
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
const getRecipeResolutionContext = (ctx: Pi.ExtensionContext) => {
|
|
44
|
+
const sessionId = getRunOwnerId(ctx);
|
|
45
|
+
const resolutionContext = recipeResolutionContextsBySession.get(sessionId);
|
|
46
|
+
if (!resolutionContext) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`Recipe resolution context is unavailable for session ${sessionId}.`,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
return resolutionContext;
|
|
52
|
+
};
|
|
45
53
|
const automaticReview = AutomaticReviewRuntime.createAutomaticReviewRuntime({
|
|
46
54
|
getActiveContext: () => activeRunContext,
|
|
47
55
|
getRunOwnerId,
|
|
@@ -67,7 +75,7 @@ export function createActorExtensionRuntime(
|
|
|
67
75
|
if (ctx && typeof ctx === "object") {
|
|
68
76
|
nextArgs[4] = {
|
|
69
77
|
...(ctx as Record<string, unknown>),
|
|
70
|
-
|
|
78
|
+
recipeResolutionContext: getRecipeResolutionContext(
|
|
71
79
|
ctx as Pi.ExtensionContext,
|
|
72
80
|
),
|
|
73
81
|
getThinkingLevel: () => pi.getThinkingLevel(),
|
|
@@ -85,6 +93,7 @@ export function createActorExtensionRuntime(
|
|
|
85
93
|
configPath: Paths.EXTENSION_RUNTIME_PATHS.configPath,
|
|
86
94
|
exec: CommandTemplates.execCommandTemplate,
|
|
87
95
|
getActiveTools: () => pi.getActiveTools(),
|
|
96
|
+
getAllTools: () => pi.getAllTools(),
|
|
88
97
|
registerTool: (definition) => {
|
|
89
98
|
const wrapped = withCurrentThinkingContext(definition);
|
|
90
99
|
actorToolDefinitions.set(wrapped.name, wrapped);
|
|
@@ -93,13 +102,22 @@ export function createActorExtensionRuntime(
|
|
|
93
102
|
reservedToolNames: Tools.RESERVED_TOOL_NAMES,
|
|
94
103
|
setActiveTools: (toolNames) => pi.setActiveTools(toolNames),
|
|
95
104
|
});
|
|
96
|
-
const recipeReload = Runtime.createRecipeToolReloadWatcher(runtime
|
|
105
|
+
const recipeReload = Runtime.createRecipeToolReloadWatcher(runtime, {
|
|
106
|
+
getResolutionContext: () =>
|
|
107
|
+
activeRunContext
|
|
108
|
+
? getRecipeResolutionContext(activeRunContext)
|
|
109
|
+
: undefined,
|
|
110
|
+
});
|
|
97
111
|
return {
|
|
98
112
|
beforeAgentStart(systemPrompt, skills, ctx) {
|
|
99
|
-
|
|
100
|
-
|
|
113
|
+
const sessionId = getRunOwnerId(ctx);
|
|
114
|
+
const resolutionContext = RecipeResolution.createRecipeResolutionContext(
|
|
115
|
+
sessionId,
|
|
116
|
+
ctx.cwd,
|
|
101
117
|
RecipesReferences.createActiveSkillRecipeContext(skills),
|
|
102
118
|
);
|
|
119
|
+
recipeResolutionContextsBySession.set(sessionId, resolutionContext);
|
|
120
|
+
runtime.loadTools(ctx, resolutionContext);
|
|
103
121
|
return {
|
|
104
122
|
systemPrompt: `${systemPrompt}\n\n${Prompts.ONBOARDING_SYSTEM_PROMPT}`,
|
|
105
123
|
};
|
|
@@ -113,16 +131,17 @@ export function createActorExtensionRuntime(
|
|
|
113
131
|
if (activeRunContext === ctx) automaticReview.schedule();
|
|
114
132
|
},
|
|
115
133
|
onSessionShutdown(reason, ctx) {
|
|
116
|
-
|
|
134
|
+
recipeResolutionContextsBySession.delete(getRunOwnerId(ctx));
|
|
117
135
|
activeRunContext = undefined;
|
|
118
136
|
automaticReview.close();
|
|
119
137
|
recipeReload.close();
|
|
120
138
|
runUiRuntime.shutdown(reason, ctx);
|
|
121
139
|
},
|
|
122
140
|
async onSessionStart(ctx) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
141
|
+
const sessionId = getRunOwnerId(ctx);
|
|
142
|
+
recipeResolutionContextsBySession.set(
|
|
143
|
+
sessionId,
|
|
144
|
+
RecipeResolution.createEmptyRecipeResolutionContext(sessionId, ctx.cwd),
|
|
126
145
|
);
|
|
127
146
|
ctx.ui.setWidget("zz-pi-actors-comms", undefined);
|
|
128
147
|
activeRunContext = ctx;
|
|
@@ -132,7 +151,6 @@ export function createActorExtensionRuntime(
|
|
|
132
151
|
await Temp.prepareExtensionTempDir(Paths.EXTENSION_RUNTIME_PATHS.tempDir);
|
|
133
152
|
if (activeRunContext !== ctx) return;
|
|
134
153
|
automaticReview.start(ctx);
|
|
135
|
-
runtime.loadTools(ctx);
|
|
136
154
|
runUiRuntime.start(ctx);
|
|
137
155
|
recipeReload.watch(ctx);
|
|
138
156
|
},
|
|
@@ -148,6 +166,7 @@ export function createActorExtensionRuntime(
|
|
|
148
166
|
runtime.getTools(),
|
|
149
167
|
(activeName) => actorToolDefinitions.get(activeName),
|
|
150
168
|
),
|
|
169
|
+
getRuntimeToolStatus: runtime.getToolStatus,
|
|
151
170
|
handleRuntimeControl: automaticReview.handleControl,
|
|
152
171
|
registryRuntime: runtime,
|
|
153
172
|
setActiveTools: (toolNames) => pi.setActiveTools(toolNames),
|
package/lib/inspector.ts
CHANGED
|
@@ -183,6 +183,7 @@ export function readActorInspectorRecipe(
|
|
|
183
183
|
logical_reference: primaryLogicalReference,
|
|
184
184
|
...(typeof primary?.skill === "string" ? { skill: primary.skill } : {}),
|
|
185
185
|
source_kind: primarySourceKind,
|
|
186
|
+
launch_kind: meta.launch_kind ?? meta.launch_source,
|
|
186
187
|
launch_source: meta.launch_source,
|
|
187
188
|
}),
|
|
188
189
|
launch: redactedRecord({
|
package/lib/prompts.ts
CHANGED
|
@@ -5,52 +5,52 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
export const REGISTER_TOOL_DESCRIPTION =
|
|
8
|
-
"Register a persistent custom tool from
|
|
9
|
-
"
|
|
10
|
-
"
|
|
8
|
+
"Register a persistent custom tool from one maintained Recipe, command template, or captured draft. " +
|
|
9
|
+
"Use from for Recipe specialization, template for trusted commands, or draft for promotion. " +
|
|
10
|
+
"Definitions persist under ~/.pi/agent/recipes; activation is reported separately.";
|
|
11
11
|
|
|
12
12
|
export const REGISTER_TOOL_PROMPT_SNIPPET =
|
|
13
|
-
"Register persistent command templates as agent-callable tools";
|
|
13
|
+
"Register persistent Recipes or command templates as agent-callable tools";
|
|
14
14
|
|
|
15
15
|
export const REGISTER_TOOL_GUIDELINES = [
|
|
16
|
-
"Use register_tool
|
|
17
|
-
"
|
|
16
|
+
"Use register_tool from=<skill>/<recipe> with defaults={...} to specialize a maintained Recipe without copying its contract.",
|
|
17
|
+
"Use register_tool template only for trusted command templates, and use register_tool draft only for captured draft promotion.",
|
|
18
|
+
"After register_tool succeeds, trust its callable_now and activation result; persistence alone is not callability.",
|
|
18
19
|
'Set template=null or template="" in register_tool to delete a persisted tool.',
|
|
19
20
|
"Set update=true in register_tool to overwrite an existing tool registration.",
|
|
20
21
|
];
|
|
21
22
|
|
|
22
|
-
export const ONBOARDING_SYSTEM_PROMPT = `pi-actors
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
- Maintain ~/.pi/agent/recipes like MEMORY.md for capabilities: keep useful tools, curate stale ones, and fix/remove/disable invalid recipes flagged by registry warnings; active-Skill and explicit file Recipes remain components outside user tool discovery; offer to save successful recurring patterns only after confirmation.
|
|
34
|
-
- Prefer maintained active-Skill Recipes with spawn recipe=<skill>/<recipe> before ad hoc scripts/wrappers; explicit file Recipes use exact .json/.md paths; review swarms inherit current model/thinking, preflight before fanout, and expose quorum/concurrency/TTL knobs unless explicit args are passed.
|
|
35
|
-
- For any non-trivial actor use or pi-actors change, read the bundled actors skill first. Before launching multiple actors/subagents for parallel implementation, independent artifact generation, delegated audit, or review, also read the bundled swarm skill; the coordinator owns decomposition, disjoint scopes, launch correctness, integration, and final validation. For deeper guidance, inspect installed extension sources/docs/recipes because README/docs are not automatically in context.`;
|
|
23
|
+
export const ONBOARDING_SYSTEM_PROMPT = `pi-actors Skill routing:
|
|
24
|
+
- Treat active bundled Skills as the operating authority.
|
|
25
|
+
- For non-trivial pi-actors operation, diagnosis, or development, load and read the actors Skill before acting.
|
|
26
|
+
- For work requiring multiple actors or subagents, additionally load and read the swarm Skill.
|
|
27
|
+
- For capability-specific selection or constraints, load the owning capability Skill; actors owns generic mechanics and swarm owns multi-actor methodology.
|
|
28
|
+
- Keep a Skill Recipe distinct from a registered tool and a Recipe spawn distinct from registered-tool invocation; actors owns the proof rules.
|
|
29
|
+
- Treat persistence or registration as distinct from current callability; actors owns activation proof.
|
|
30
|
+
- On failure or disagreement, preserve the logical Recipe identity, stop, and follow actors diagnosis; never bypass the owning Skills with copied contracts, helper paths, shell evaluation, or background-process workarounds.
|
|
31
|
+
- If a capability Skill conflicts with actors about generic mechanics, follow actors and report the stale capability guidance.
|
|
32
|
+
- README and docs are human-facing references, not the normal agent operating path.
|
|
33
|
+
- AGENTS, source, and tests are implementation protocol and evidence; use them when changing or debugging the extension, not as substitutes for operating Skills.`;
|
|
36
34
|
|
|
37
35
|
export const REGISTER_TOOL_PARAM_DESCRIPTIONS = {
|
|
38
36
|
name: "Tool name in snake_case (e.g., 'transcribe')",
|
|
39
37
|
description:
|
|
40
38
|
"Describe what the tool does for the LLM. Required unless deleting; omitted updates keep the old description.",
|
|
39
|
+
from:
|
|
40
|
+
"Recipe to specialize by canonical <skill>/<recipe> identity or explicit .json/.md path. Inherits async, args/types, source defaults, artifacts, Control, and runtime origins.",
|
|
41
|
+
defaults:
|
|
42
|
+
"Optional caller-owned defaults. Keys and values must satisfy the effective source or command-template argument contract.",
|
|
41
43
|
draft:
|
|
42
|
-
"Promote a draft
|
|
44
|
+
"Promote a captured draft Recipe path from ~/.pi/agent/recipes/drafts. This is a source mode; do not combine it with from or template.",
|
|
43
45
|
async:
|
|
44
46
|
"Set true for a co-located async template recipe. Omit for ordinary command templates or file-backed recipe references.",
|
|
45
47
|
template:
|
|
46
|
-
"
|
|
48
|
+
"Trusted command template with {arg} or {arg=default} placeholders. To specialize a Recipe, use from instead. Omitted updates keep the old template; empty string deletes the tool.",
|
|
47
49
|
templateArray:
|
|
48
50
|
"Sequential command-template composition array. Leaves may be strings or objects with template/defaults/timeout/retry/failure/recover.",
|
|
49
51
|
templateNull: "Delete the tool when template is null.",
|
|
50
52
|
args: "Optional comma-separated placeholder declarations. Usually omit because args are derived from template placeholders. Interactive shorthand defaults are accepted and normalized. Example: file,lang,mode=fast",
|
|
51
53
|
update: "Set to true to overwrite an existing tool registration.",
|
|
52
|
-
values:
|
|
53
|
-
"Optional default runtime placeholder values for a co-located template recipe.",
|
|
54
54
|
} as const;
|
|
55
55
|
|
|
56
56
|
export function formatRegisteredToolPromptSnippet(template: unknown): string {
|
package/lib/recipes-context.ts
CHANGED
|
@@ -1,15 +1,60 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Recipe context prompt assembly.
|
|
3
|
-
* Zones: async runner prompt context, recipe provenance, LLM child launches
|
|
4
|
-
* Owns compact actor
|
|
2
|
+
* Recipe context contracts and prompt assembly.
|
|
3
|
+
* Zones: live session resolution, async runner prompt context, recipe provenance, LLM child launches
|
|
4
|
+
* Owns the immutable live Recipe environment and compact actor context appended to child-agent prompts.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { createHash } from "node:crypto";
|
|
7
8
|
import { writeFileSync } from "node:fs";
|
|
8
|
-
import { basename } from "node:path";
|
|
9
|
+
import { basename, resolve } from "node:path";
|
|
9
10
|
|
|
10
11
|
import type { CommandTemplateActorRecipeContext } from "./command-templates.ts";
|
|
12
|
+
import * as RecipesReferences from "./recipes-references.ts";
|
|
11
13
|
import type { TemplateRecipeContextRecord } from "./recipes-references.ts";
|
|
12
14
|
|
|
15
|
+
export interface RecipeResolutionContext {
|
|
16
|
+
readonly activeSkills: RecipesReferences.ActiveSkillRecipeContext;
|
|
17
|
+
readonly cwd: string;
|
|
18
|
+
readonly generation: string;
|
|
19
|
+
readonly sessionId: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function createRecipeResolutionContext(
|
|
23
|
+
sessionId: string,
|
|
24
|
+
cwd: string,
|
|
25
|
+
activeSkills: RecipesReferences.ActiveSkillRecipeContext,
|
|
26
|
+
): RecipeResolutionContext {
|
|
27
|
+
const normalizedSessionId = sessionId.trim();
|
|
28
|
+
if (!normalizedSessionId) throw new Error("Recipe resolution session id is required.");
|
|
29
|
+
const normalizedCwd = resolve(cwd);
|
|
30
|
+
const generation = createHash("sha256")
|
|
31
|
+
.update(
|
|
32
|
+
JSON.stringify({
|
|
33
|
+
activeSkills: RecipesReferences.getActiveSkillRecipeNamespaces(activeSkills),
|
|
34
|
+
cwd: normalizedCwd,
|
|
35
|
+
sessionId: normalizedSessionId,
|
|
36
|
+
}),
|
|
37
|
+
)
|
|
38
|
+
.digest("hex");
|
|
39
|
+
return Object.freeze({
|
|
40
|
+
activeSkills,
|
|
41
|
+
cwd: normalizedCwd,
|
|
42
|
+
generation,
|
|
43
|
+
sessionId: normalizedSessionId,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function createEmptyRecipeResolutionContext(
|
|
48
|
+
sessionId: string,
|
|
49
|
+
cwd: string,
|
|
50
|
+
): RecipeResolutionContext {
|
|
51
|
+
return createRecipeResolutionContext(
|
|
52
|
+
sessionId,
|
|
53
|
+
cwd,
|
|
54
|
+
RecipesReferences.EMPTY_ACTIVE_SKILL_RECIPE_CONTEXT,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
13
58
|
export interface MarkedRecipeContextRecord extends TemplateRecipeContextRecord {
|
|
14
59
|
you_are_here?: true;
|
|
15
60
|
you_are_here_path?: string;
|