@llblab/pi-actors 0.43.1 → 0.45.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 -6
- package/BACKLOG.md +1 -189
- package/CHANGELOG.md +419 -402
- package/README.md +8 -6
- package/dist/index.js +7 -3
- package/dist/lib/async-runs.d.ts +2 -0
- package/dist/lib/async-runs.js +41 -34
- package/dist/lib/config.js +1 -0
- package/dist/lib/file-state.d.ts +3 -1
- package/dist/lib/file-state.js +25 -7
- package/dist/lib/inspector-overlay.js +46 -30
- package/dist/lib/inspector.js +8 -2
- package/dist/lib/limits.d.ts +10 -0
- package/dist/lib/limits.js +10 -0
- package/dist/lib/observability.d.ts +4 -2
- package/dist/lib/observability.js +43 -36
- package/dist/lib/recipes-discovery.js +20 -3
- package/dist/lib/recipes-references.d.ts +10 -0
- package/dist/lib/recipes-references.js +168 -5
- package/dist/lib/run-evidence-policy.d.ts +95 -0
- package/dist/lib/run-evidence-policy.js +177 -0
- package/dist/lib/run-ui-runtime.js +2 -0
- package/dist/lib/runs-controls.d.ts +7 -5
- package/dist/lib/runs-controls.js +186 -49
- package/dist/lib/runs-retention.js +27 -14
- package/dist/lib/runs-trace.d.ts +25 -1
- package/dist/lib/runs-trace.js +410 -21
- package/dist/lib/runtime-triage.js +6 -22
- package/dist/lib/schema.d.ts +3 -0
- package/dist/lib/schema.js +34 -1
- package/dist/lib/tools-inspect.js +58 -14
- package/dist/lib/tools-local.js +27 -10
- package/dist/lib/tools-spawn.js +2 -2
- package/dist/lib/trace-projection.js +90 -44
- package/dist/scripts/conformance.mjs +5 -0
- package/dist/scripts/locker.mjs +31 -74
- package/dist/scripts/music-player.mjs +41 -129
- package/dist/scripts/release-gates.mjs +26 -4
- package/dist/skills/actors/SKILL.md +9 -8
- package/dist/skills/swarm/SKILL.md +2 -2
- package/docs/README.md +0 -1
- package/docs/actor-inspector.md +3 -2
- package/docs/async-runs.md +10 -8
- package/docs/command-templates.md +2 -2
- package/docs/recipe-library.md +4 -2
- package/docs/template-recipes.md +10 -4
- package/docs/tool-registry.md +1 -1
- package/index.ts +9 -3
- package/lib/async-runs.ts +51 -54
- package/lib/config.ts +4 -0
- package/lib/file-state.ts +28 -7
- package/lib/inspector-overlay.ts +29 -17
- package/lib/inspector.ts +16 -2
- package/lib/limits.ts +10 -0
- package/lib/observability.ts +55 -57
- package/lib/recipes-discovery.ts +23 -3
- package/lib/recipes-references.ts +227 -7
- package/lib/run-evidence-policy.ts +242 -0
- package/lib/run-ui-runtime.ts +2 -0
- package/lib/runs-controls.ts +177 -108
- package/lib/runs-retention.ts +28 -20
- package/lib/runs-trace.ts +496 -21
- package/lib/runtime-triage.ts +11 -25
- package/lib/schema.ts +53 -1
- package/lib/tools-inspect.ts +56 -15
- package/lib/tools-local.ts +49 -19
- package/lib/tools-spawn.ts +2 -2
- package/lib/trace-projection.ts +137 -75
- package/package.json +1 -1
- package/scripts/conformance.mjs +5 -0
- package/scripts/locker.mjs +31 -74
- package/scripts/music-player.mjs +41 -129
- package/scripts/release-gates.mjs +26 -4
- package/skills/actors/SKILL.md +9 -8
- package/skills/swarm/SKILL.md +2 -2
- package/dist/lib/runtime-notifier.d.ts +0 -48
- package/dist/lib/runtime-notifier.js +0 -138
- package/docs/0.43-baseline.md +0 -39
- package/lib/runtime-notifier.ts +0 -211
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import { spawn, spawnSync } from "node:child_process";
|
|
16
|
-
import { randomUUID } from "node:crypto";
|
|
17
16
|
import {
|
|
18
17
|
accessSync,
|
|
19
18
|
constants,
|
|
@@ -50,8 +49,8 @@ async function importRuntimeModule(name) {
|
|
|
50
49
|
return await import(pathToFileURL(existsSync(compiled) ? compiled : source).href);
|
|
51
50
|
}
|
|
52
51
|
|
|
53
|
-
const {
|
|
54
|
-
await importRuntimeModule("
|
|
52
|
+
const { appendRunControlInStateDir, claimRunControlByIdInStateDir,
|
|
53
|
+
updateRunControlStatusInStateDir } = await importRuntimeModule("runs-controls");
|
|
55
54
|
const { appendRunTraceEvent } = await importRuntimeModule("runs-trace");
|
|
56
55
|
|
|
57
56
|
const AUDIO_EXTENSIONS = new Set([
|
|
@@ -408,8 +407,8 @@ function playerCommand(ctx, player, volume, track) {
|
|
|
408
407
|
}
|
|
409
408
|
}
|
|
410
409
|
|
|
411
|
-
function writeText(path, value
|
|
412
|
-
writeFileSync(path, value,
|
|
410
|
+
function writeText(path, value) {
|
|
411
|
+
writeFileSync(path, value, "utf8");
|
|
413
412
|
}
|
|
414
413
|
|
|
415
414
|
function readText(path) {
|
|
@@ -584,7 +583,24 @@ async function startControlServer(ctx, wakeControlLoop) {
|
|
|
584
583
|
: join(ctx.stateDir, "control.sock");
|
|
585
584
|
if (process.platform !== "win32") rmSync(path, { force: true });
|
|
586
585
|
const server = createServer((socket) => {
|
|
587
|
-
|
|
586
|
+
let content = "";
|
|
587
|
+
socket.setEncoding("utf8");
|
|
588
|
+
socket.on("data", (chunk) => { content += chunk; });
|
|
589
|
+
socket.on("end", () => {
|
|
590
|
+
for (const line of content.split("\n")) {
|
|
591
|
+
if (!line.trim()) continue;
|
|
592
|
+
try {
|
|
593
|
+
const claimed = claimControl(ctx, JSON.parse(line));
|
|
594
|
+
if (!claimed) continue;
|
|
595
|
+
handleControl(ctx, claimed.command);
|
|
596
|
+
finalizeControl(ctx, claimed.id, "handled");
|
|
597
|
+
} catch (error) {
|
|
598
|
+
const id = (() => { try { return JSON.parse(line).id; } catch { return undefined; } })();
|
|
599
|
+
finalizeControl(ctx, id, "failed", error instanceof Error ? error.message : String(error));
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
wakeControlLoop();
|
|
603
|
+
});
|
|
588
604
|
socket.resume();
|
|
589
605
|
});
|
|
590
606
|
await new Promise((resolveReady, rejectReady) => {
|
|
@@ -606,133 +622,38 @@ async function startControlServer(ctx, wakeControlLoop) {
|
|
|
606
622
|
};
|
|
607
623
|
}
|
|
608
624
|
|
|
609
|
-
function acquireControlsLock(ctx) {
|
|
610
|
-
return acquireFileMutationLock(ctx.controlsFile);
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
function readControls(ctx) {
|
|
614
|
-
if (!exists(ctx.controlsFile)) return [];
|
|
615
|
-
return readFileSync(ctx.controlsFile, "utf8")
|
|
616
|
-
.split("\n")
|
|
617
|
-
.filter((line) => line.trim())
|
|
618
|
-
.map((line) => {
|
|
619
|
-
try {
|
|
620
|
-
return JSON.parse(line);
|
|
621
|
-
} catch {
|
|
622
|
-
return undefined;
|
|
623
|
-
}
|
|
624
|
-
})
|
|
625
|
-
.filter(Boolean);
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
function writeControls(ctx, controls) {
|
|
629
|
-
writeTextAtomic(
|
|
630
|
-
ctx.controlsFile,
|
|
631
|
-
controls.length
|
|
632
|
-
? `${controls.map((control) => JSON.stringify(control)).join("\n")}\n`
|
|
633
|
-
: "",
|
|
634
|
-
);
|
|
635
|
-
}
|
|
636
|
-
|
|
637
625
|
function commandFromControl(control) {
|
|
638
626
|
if (typeof control.action !== "string") return undefined;
|
|
639
627
|
const action = control.action.trim();
|
|
640
628
|
return CONTROL_COMMANDS.has(action) ? action : undefined;
|
|
641
629
|
}
|
|
642
630
|
|
|
643
|
-
function runtimeWakeFile(ctx) {
|
|
644
|
-
return join(ctx.stateDir, "wake.jsonl");
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
function notifyControlWake(ctx, reason = "control.queued") {
|
|
648
|
-
try {
|
|
649
|
-
writeText(
|
|
650
|
-
runtimeWakeFile(ctx),
|
|
651
|
-
`${JSON.stringify({
|
|
652
|
-
actor: `run:${basename(ctx.stateDir)}`,
|
|
653
|
-
id: randomUUID(),
|
|
654
|
-
metadata: { command: "music-player" },
|
|
655
|
-
reason,
|
|
656
|
-
state_dir: ctx.stateDir,
|
|
657
|
-
ts: new Date().toISOString(),
|
|
658
|
-
})}\n`,
|
|
659
|
-
"a",
|
|
660
|
-
);
|
|
661
|
-
} catch {
|
|
662
|
-
// Wake records are advisory; the Control journal remains authoritative.
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
|
|
666
631
|
function appendControl(ctx, action) {
|
|
667
|
-
const
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
action,
|
|
673
|
-
id: randomUUID(),
|
|
674
|
-
queued_at: new Date().toISOString(),
|
|
675
|
-
run_instance_id: run.run_instance_id,
|
|
676
|
-
status: "queued",
|
|
677
|
-
});
|
|
678
|
-
writeControls(ctx, controls);
|
|
679
|
-
} finally {
|
|
680
|
-
release();
|
|
681
|
-
}
|
|
682
|
-
notifyControlWake(ctx);
|
|
632
|
+
const run = readJsonFile(runJsonFile(ctx), {});
|
|
633
|
+
appendRunControlInStateDir(ctx.stateDir, {
|
|
634
|
+
action,
|
|
635
|
+
run_instance_id: run.run_instance_id,
|
|
636
|
+
});
|
|
683
637
|
}
|
|
684
638
|
|
|
685
|
-
function
|
|
686
|
-
const
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
const command =
|
|
695
|
-
control.run_instance_id === ctx.runInstanceId
|
|
696
|
-
? commandFromControl(control)
|
|
697
|
-
: undefined;
|
|
698
|
-
if (!command) {
|
|
699
|
-
control.failed_at = claimedAt;
|
|
700
|
-
control.status = "failed";
|
|
701
|
-
control.error = "Unsupported or stale music-player Control";
|
|
702
|
-
changed = true;
|
|
703
|
-
continue;
|
|
704
|
-
}
|
|
705
|
-
control.claimed_at = claimedAt;
|
|
706
|
-
control.status = "claimed";
|
|
707
|
-
commands.push({ command, id: control.id });
|
|
708
|
-
changed = true;
|
|
709
|
-
}
|
|
710
|
-
if (changed) writeControls(ctx, controls);
|
|
711
|
-
return commands;
|
|
712
|
-
} finally {
|
|
713
|
-
release();
|
|
639
|
+
function claimControl(ctx, wire) {
|
|
640
|
+
const control = claimRunControlByIdInStateDir(
|
|
641
|
+
ctx.stateDir, ctx.runInstanceId, wire.id,
|
|
642
|
+
);
|
|
643
|
+
const command = control ? commandFromControl(control) : undefined;
|
|
644
|
+
if (!command && control) {
|
|
645
|
+
updateRunControlStatusInStateDir(ctx.stateDir, control.id, "failed", {
|
|
646
|
+
error: "Unsupported music-player Control",
|
|
647
|
+
}, ["claimed"]);
|
|
714
648
|
}
|
|
649
|
+
return command && control ? { command, id: control.id } : undefined;
|
|
715
650
|
}
|
|
716
651
|
|
|
717
652
|
function finalizeControl(ctx, id, status, error) {
|
|
718
653
|
if (!id) return;
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
const timestamp = new Date().toISOString();
|
|
723
|
-
let changed = false;
|
|
724
|
-
for (const control of controls) {
|
|
725
|
-
if (control.id !== id || control.status !== "claimed") continue;
|
|
726
|
-
control.status = status;
|
|
727
|
-
if (status === "handled") control.handled_at = timestamp;
|
|
728
|
-
else control.failed_at = timestamp;
|
|
729
|
-
if (error) control.error = error;
|
|
730
|
-
changed = true;
|
|
731
|
-
}
|
|
732
|
-
if (changed) writeControls(ctx, controls);
|
|
733
|
-
} finally {
|
|
734
|
-
release();
|
|
735
|
-
}
|
|
654
|
+
updateRunControlStatusInStateDir(
|
|
655
|
+
ctx.stateDir, id, status, error ? { error } : {}, ["claimed"],
|
|
656
|
+
);
|
|
736
657
|
}
|
|
737
658
|
|
|
738
659
|
function controlsSignature(ctx) {
|
|
@@ -754,8 +675,7 @@ function startControlLoop(ctx) {
|
|
|
754
675
|
const name = file ? String(file) : "";
|
|
755
676
|
if (
|
|
756
677
|
!name ||
|
|
757
|
-
name === basename(ctx.controlsFile)
|
|
758
|
-
name === basename(runtimeWakeFile(ctx))
|
|
678
|
+
name === basename(ctx.controlsFile)
|
|
759
679
|
) {
|
|
760
680
|
dirty = true;
|
|
761
681
|
}
|
|
@@ -774,14 +694,6 @@ function startControlLoop(ctx) {
|
|
|
774
694
|
const signature = controlsSignature(ctx);
|
|
775
695
|
if (dirty || signature !== lastSignature) {
|
|
776
696
|
dirty = false;
|
|
777
|
-
for (const { command, id } of claimControls(ctx)) {
|
|
778
|
-
try {
|
|
779
|
-
handleControl(ctx, command);
|
|
780
|
-
finalizeControl(ctx, id, "handled");
|
|
781
|
-
} catch (error) {
|
|
782
|
-
finalizeControl(ctx, id, "failed", error.message);
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
697
|
lastSignature = controlsSignature(ctx);
|
|
786
698
|
continue;
|
|
787
699
|
}
|
|
@@ -165,8 +165,30 @@ try {
|
|
|
165
165
|
text.includes('importRuntimeModule("runs-trace")') && text.includes("appendRunTraceEvent"),
|
|
166
166
|
`first-party Trace writer bypasses canonical runtime module: ${path}`,
|
|
167
167
|
);
|
|
168
|
+
if (path !== "scripts/async-runner.mjs") check(
|
|
169
|
+
text.includes('importRuntimeModule("runs-controls")') &&
|
|
170
|
+
!/function (?:read|write|claimControls|finalizeControls)\b/u.test(text),
|
|
171
|
+
`first-party Control writer bypasses canonical runtime module: ${path}`,
|
|
172
|
+
);
|
|
168
173
|
}
|
|
169
|
-
console.log("[release] canonical Trace writer residue checked");
|
|
174
|
+
console.log("[release] canonical Trace and Control writer residue checked");
|
|
175
|
+
|
|
176
|
+
// owner | class | lock | record bound | byte bound | recovery
|
|
177
|
+
const appendOnlyOwners = new Set([
|
|
178
|
+
"lib/runs-trace.ts", // canonical Run evidence | token lock | 2048 | 4 MiB | compact valid suffix
|
|
179
|
+
"lib/runs-retention.ts", // shared kernel evidence | token lock | 256 | 1 MiB | skip malformed
|
|
180
|
+
"scripts/locker.mjs", // first-party actor state | token lock | 512 | 1 MiB | skip malformed
|
|
181
|
+
"lib/command-templates.ts", // complete execution capture | command owner | n/a | artifact policy | preserve
|
|
182
|
+
"scripts/async-runner.mjs", // captures/prompts | Run owner | n/a | artifact policy | preserve
|
|
183
|
+
"scripts/recipe-utils.mjs", // user-declared artifact | caller owner | n/a | caller policy | preserve
|
|
184
|
+
"scripts/release-gates.mjs", // build/test-only source inventory | n/a | n/a | n/a | self-match
|
|
185
|
+
]);
|
|
186
|
+
const appendOnlyPattern = /\bappendFileSync\b|\b(?:writeFileSync|writeTextAtomic)\s*\([^)]*\{\s*flag:\s*["']a["']/su;
|
|
187
|
+
for (const path of files.filter((candidate) => /^(?:lib\/.*\.ts|scripts\/.*\.mjs)$/u.test(candidate)))
|
|
188
|
+
if (appendOnlyPattern.test(stagedText(path) ?? ""))
|
|
189
|
+
check(appendOnlyOwners.has(path), `unregistered shipped append-only writer: ${path}`);
|
|
190
|
+
for (const path of appendOnlyOwners) check(fileSet.has(path), `stale append-only owner inventory: ${path}`);
|
|
191
|
+
console.log(`[release] append-only owner inventory checked: ${appendOnlyOwners.size} source owners`);
|
|
170
192
|
|
|
171
193
|
check(
|
|
172
194
|
(stagedText("scripts/validate-recipe.mjs") ?? "").includes(
|
|
@@ -176,13 +198,13 @@ try {
|
|
|
176
198
|
);
|
|
177
199
|
console.log("[release] zero-warning Recipe QA gate checked");
|
|
178
200
|
|
|
179
|
-
const
|
|
201
|
+
const maximumShippedLines = 29_767;
|
|
180
202
|
const shippedPath = /^(?:lib\/|scripts\/|recipes\/|docs\/|skills\/)/u;
|
|
181
203
|
const shippedLines = files
|
|
182
204
|
.filter((path) => shippedPath.test(path))
|
|
183
205
|
.reduce((total, path) => total + (((stagedText(path) ?? "").match(/\n/gu) ?? []).length + 1), 0);
|
|
184
|
-
check(shippedLines
|
|
185
|
-
console.log(`[release] shipped lines ${shippedLines}
|
|
206
|
+
check(shippedLines <= maximumShippedLines, `shipped lines ${shippedLines} exceed release maximum ${maximumShippedLines}`);
|
|
207
|
+
console.log(`[release] shipped lines ${shippedLines} <= release maximum ${maximumShippedLines}`);
|
|
186
208
|
|
|
187
209
|
const sources = files.filter((path) => path === "index.ts" || (path.startsWith("lib/") && path.endsWith(".ts")));
|
|
188
210
|
const sourceSet = new Set(sources);
|
|
@@ -25,11 +25,11 @@ A Run target exposes exactly three inspect views: `recipe`, `trace`, and `contro
|
|
|
25
25
|
|
|
26
26
|
## Recipe
|
|
27
27
|
|
|
28
|
-
A Recipe defines execution. It may declare args,
|
|
28
|
+
A Recipe defines execution. It may declare named typed args, inline fallbacks, configuration `defaults`, composition `values`, imports, artifacts, command-template flags, and `control: ["action"]` when a long-lived service actually consumes actor-local inputs.
|
|
29
29
|
|
|
30
30
|
Do not declare Control for ordinary one-shot work. Runtime lifecycle actions such as `kill` stay runtime-owned and must not appear in Recipe Control declarations. Imported Recipes act as local definitions inside one Run; they do not create nested Runs unless execution explicitly spawns them.
|
|
31
31
|
|
|
32
|
-
Prefer maintained packaged Recipes over ad hoc wrappers. Keep model, thinking, mission, concurrency, quorum, and timeout choices caller-owned unless a Recipe documents a stable policy.
|
|
32
|
+
Prefer maintained packaged Recipes over ad hoc wrappers. Use `std:<recipe>` for exact packaged lookup and `skill:<skill>/<recipe-path>` for a component bundled with a Pi-active Skill. File-backed Recipes own `{recipe_dir}` and Skill Recipes own `{skill_dir}`; callers never pass or override these origins. Skill Recipes are components, not automatic tools. Keep model, thinking, mission, concurrency, quorum, and timeout choices caller-owned unless a Recipe documents a stable policy.
|
|
33
33
|
|
|
34
34
|
## Trace
|
|
35
35
|
|
|
@@ -47,7 +47,7 @@ Trace records bounded structured observations in `trace.jsonl`:
|
|
|
47
47
|
}
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
Trace never carries sender, recipient, route, reply, or message-envelope fields.
|
|
50
|
+
Trace never carries sender, recipient, route, reply, or message-envelope fields. It is a bounded retained suffix: the canonical lock appends within 2,048 events and 4 MiB or atomically keeps the newest suffix plus one warning-only `runtime.trace_compacted` marker. That marker means older history was discarded; terminal/result/execution/artifact evidence stays independently authoritative. `inspect view=trace` reports completeness. Equal timestamps use same-source physical order, fixed source rank, then stable id without exposing an ordinal or claiming cross-source causality. Attention is a wake hint, not a queue: persist durable state or an artifact first, use `notify` for visible status, and reserve `followup` for needed coordinator context. Compaction may discard old hints.
|
|
51
51
|
|
|
52
52
|
## Control
|
|
53
53
|
|
|
@@ -57,9 +57,9 @@ The public Control request is exact:
|
|
|
57
57
|
{ "target": "run:<id>", "action": "pause", "input": {}, "verbose": false }
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
Valid Controls persist in `controls.jsonl` before delivery; invalid envelopes remain outside
|
|
60
|
+
Valid Controls persist in `controls.jsonl` before delivery; invalid envelopes remain outside it. One token-owned lock rejects a 65th pending Control or 1 MiB rewrite before admission, fails closed on malformed or stale-generation evidence, and atomically admits one queued record. Exact-id claims/finalization preserve a 128-terminal tail, expected-state fencing, and 4 KiB errors. Admitted nonterminal Controls never expire automatically. `inspect view=control` reports capacity, saturation, stale work, bytes, and diagnostics. Endpoints carry immutable startup `run_instance_id`; FIFO and named pipe share limits of 64 action characters, 380 serialized input bytes, and 512 newline-terminated wire bytes. Partial writes fail. Put larger data in an artifact and send only its reference. Delivery revalidates owner, generation, state, and process identity.
|
|
61
61
|
|
|
62
|
-
`kill` remains
|
|
62
|
+
`kill` remains the runtime recovery path for a stuck saturated Run: it bypasses actor-local Control capacity and adds no synthetic Control. Use actor-local `stop` only when declared and implemented. Restart clears generation-local evidence; archive preserves the bounded terminal tree, while prune preserves only requested artifacts.
|
|
63
63
|
|
|
64
64
|
## Run State and Safety
|
|
65
65
|
|
|
@@ -72,6 +72,8 @@ Run state lives under `~/.pi/agent/tmp/pi-actors/runs/<run>/`. Important evidenc
|
|
|
72
72
|
- `execution.json`: command/session provenance and bounded complete-capture references.
|
|
73
73
|
- `result.json`, logs, and declared artifacts.
|
|
74
74
|
|
|
75
|
+
Trace/Control quotas do not constrain user-declared artifacts, repositories, media sources, complete captures, or actor-owned workload state. No public noun, tool, target, or view is added by bounded retention.
|
|
76
|
+
|
|
75
77
|
Never bypass owner filtering, immutable generation fencing, process-identity verification, path containment, redaction, terminal reconciliation, or shutdown kill behavior. Do not edit active Run state to force a result.
|
|
76
78
|
|
|
77
79
|
## Operating Pattern
|
|
@@ -79,8 +81,8 @@ Never bypass owner filtering, immutable generation fencing, process-identity ver
|
|
|
79
81
|
1. Inspect the Recipe before launch when its contract or policy matters.
|
|
80
82
|
2. Spawn with explicit values and retain the returned `run:<id>`.
|
|
81
83
|
3. Let short Runs finish; avoid polling.
|
|
82
|
-
4. Inspect Trace when evidence or attention requires it.
|
|
83
|
-
5.
|
|
84
|
+
4. Inspect Trace when evidence or attention requires it; its summary states whether retained history is complete.
|
|
85
|
+
5. Inspect Control capacity before diagnosing stale work or saturation, then send only declared actor-local Controls.
|
|
84
86
|
6. Use runtime kill/cancel behavior for lifecycle termination.
|
|
85
87
|
7. Inspect artifacts and execution evidence for final validation.
|
|
86
88
|
|
|
@@ -98,6 +100,5 @@ If work may outlive the current turn, needs steering, produces artifacts, fans o
|
|
|
98
100
|
|
|
99
101
|
- [Recipe library](../../docs/recipe-library.md)
|
|
100
102
|
- [Async Runs](../../docs/async-runs.md)
|
|
101
|
-
- [Baseline and preservation gates](../../docs/0.43-baseline.md)
|
|
102
103
|
|
|
103
104
|
Read repository source and tests for exact contracts when changing pi-actors itself. Update this skill whenever durable Run mechanics change.
|
|
@@ -265,9 +265,9 @@ Report white spots, contradictions, evidence, and risks.
|
|
|
265
265
|
|
|
266
266
|
Detached execution is an adapter concern, not a portable Swarm-script requirement. When the host offers Runs, launch the composed Recipe, return its id, and rely on terminal follow-up rather than blocking or polling.
|
|
267
267
|
|
|
268
|
-
`Progress contract`: expose bounded structured Trace, logs, artifacts, status, timestamps, and final result evidence. Read
|
|
268
|
+
`Progress contract`: expose bounded structured Trace, logs, artifacts, status, timestamps, and final result evidence. Treat Trace as a retained suffix and attention as a wake hint; write durable task cards, checkpoints, and large evidence to artifacts before signaling attention. Read completeness and Control capacity through existing Run inspection rather than scraping output. Artifact size/lifecycle remains separate from Trace/Control quotas.
|
|
269
269
|
|
|
270
|
-
`Resumable checkpoint goal`: a controlled agent-backed Run may preserve context and accept a declared Control. When the host cannot preserve context, write a handoff artifact and launch a clean-context Run while marking the context loss explicitly.
|
|
270
|
+
`Resumable checkpoint goal`: a controlled agent-backed Run may preserve context and accept a declared Control. Control saturation rejects before admission and admitted work does not expire; lifecycle recovery remains host-owned. When the host cannot preserve context, write a handoff artifact and launch a clean-context Run while marking the context loss explicitly.
|
|
271
271
|
|
|
272
272
|
`Cancellation boundary`: terminate only an owned active generation whose process identity the runtime can prove. Stale pid reuse must fail closed.
|
|
273
273
|
|
package/docs/README.md
CHANGED
|
@@ -4,7 +4,6 @@ Living index of all documentation in the `/docs` directory.
|
|
|
4
4
|
|
|
5
5
|
## Documents
|
|
6
6
|
|
|
7
|
-
- [0.43-baseline.md](./0.43-baseline.md) — Released tree, strict shipped-line ratchet, and retained-invariant preservation evidence
|
|
8
7
|
- [command-templates.md](./command-templates.md) — Portable synchronous command execution standard
|
|
9
8
|
- [template-recipes.md](./template-recipes.md) — Saved JSON/Markdown recipe standard, imports, and reusable command-template graph composition
|
|
10
9
|
- [async-runs.md](./async-runs.md) — Run lifecycle, state, Control, Trace, cancellation, and terminal reconciliation
|
package/docs/actor-inspector.md
CHANGED
|
@@ -24,7 +24,7 @@ Captured Recipe evidence belongs to the Run generation and does not change when
|
|
|
24
24
|
|
|
25
25
|
Shows the unified bounded Trace projection. Sources include lifecycle/runtime observations, Controls, owned Pi turns, command-log tails, results, artifacts, and diagnostics. Filter by source and open a row for structured detail.
|
|
26
26
|
|
|
27
|
-
Trace ordering stays deterministic and newest-first. Row numbers still read chronologically from bottom to top: the oldest visible event is `#1` and the newest carries the highest number. The projection applies path containment and redaction before rendering.
|
|
27
|
+
Trace ordering stays deterministic and newest-first: timestamp descending, same-source physical ordinal descending, fixed internal source rank, then stable id. Internal ordinals are never displayed or interpreted as cross-source causality. Row numbers still read chronologically from bottom to top: the oldest visible event is `#1` and the newest carries the highest number. The summary states whether retained history is complete; `runtime.trace_compacted` means older history was discarded and shows bounded cumulative drop evidence. Terminal/result/execution/artifact evidence keeps its own authority. The projection applies path containment and redaction before rendering.
|
|
28
28
|
|
|
29
29
|
## Control
|
|
30
30
|
|
|
@@ -33,9 +33,10 @@ Shows:
|
|
|
33
33
|
- Recipe-declared actor-local actions;
|
|
34
34
|
- runtime-owned lifecycle actions;
|
|
35
35
|
- generation-fenced endpoint readiness;
|
|
36
|
+
- pending capacity, saturation, journal bytes, stale count, and diagnostics;
|
|
36
37
|
- recent durable Control records and outcomes.
|
|
37
38
|
|
|
38
|
-
A service endpoint counts as ready only when `control-endpoint.json` matches the Run's immutable `run_instance_id`. Recent Control input and errors use the same bounded structured redaction as tool inspection. The durable `controls.jsonl` journal remains raw and local; rendering never mutates it or attaches an unredacted copy.
|
|
39
|
+
A service endpoint counts as ready only when `control-endpoint.json` matches the Run's immutable `run_instance_id`. Capacity reaches zero at 64 pending Controls; further requests are rejected before admission, while admitted nonterminal Controls never expire automatically. Runtime-owned kill remains available for a stuck saturated Run. Recent Control input and errors use the same bounded structured redaction as tool inspection. The durable `controls.jsonl` journal remains raw and local; rendering never mutates it or attaches an unredacted copy.
|
|
39
40
|
|
|
40
41
|
## Keys
|
|
41
42
|
|
package/docs/async-runs.md
CHANGED
|
@@ -55,9 +55,9 @@ Trace records strict bounded events:
|
|
|
55
55
|
{"id":"…","ts":"…","kind":"command.done","summary":"Command completed","data":{"code":0},"level":"info","attention":"followup"}
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
Required fields: `id`, `ts`, `kind`. Optional fields: `summary`, `data`, `level`, `attention`. Trace rejects addressed-envelope fields and malformed or oversized data.
|
|
58
|
+
Required fields: `id`, `ts`, `kind`. Optional fields: `summary`, `data`, `level`, `attention`. Trace rejects addressed-envelope fields and malformed or oversized data. It retains a recent suffix within 2,048 events and 4 MiB. When either bound would be exceeded, the canonical lock atomically keeps a newest suffix near the lower targets, the new event, and one cumulative warning-only `runtime.trace_compacted` marker. The marker means older history was discarded; it reports cumulative drop evidence and never requests attention.
|
|
59
59
|
|
|
60
|
-
Runtime lifecycle, runner progress, command completion, cancellation, kill, parent teardown, and controlled-service observations use Trace. `inspect view=trace` projects
|
|
60
|
+
Runtime lifecycle, runner progress, command completion, cancellation, kill, parent teardown, and controlled-service observations use Trace. Bounded reads preserve complete UTF-8 lines and disclose omitted legacy prefixes. `inspect view=trace` reports retained-history completeness and projects events with Controls, owned Pi turns, logs, results, artifacts, and diagnostics newest-first. Equal timestamps use same-source physical order, then fixed source rank and stable id without claiming cross-source causality. Terminal state, `result.json`, `execution.json`, and artifacts remain authoritative even when old Trace has compacted.
|
|
61
61
|
|
|
62
62
|
## Control
|
|
63
63
|
|
|
@@ -84,13 +84,13 @@ The runtime:
|
|
|
84
84
|
|
|
85
85
|
Unix services may publish a FIFO; native Windows services publish a Windows named pipe. Native Windows FIFO delivery fails before transport rather than degrading to another protocol. Both transports admit the same portable envelope: action is at most 64 lowercase ASCII characters, serialized JSON input is at most 380 bytes, and the newline-terminated wire record is at most 512 bytes. Invalid envelopes fail before journal admission or transport. Put larger data in a declared artifact/path and send only a bounded reference or instruction through Control.
|
|
86
86
|
|
|
87
|
-
A service claims queued or transport-delivered Controls and records handled/failed outcomes
|
|
87
|
+
A service exact-id claims queued or transport-delivered Controls and records handled/failed outcomes through the canonical Control journal authority. Admission performs one locked read, integrity/generation check, terminal-tail compaction, capacity decision, and atomic write. The 65th pending Control and a rewrite exceeding 1 MiB fail as bounded `control_backpressure` before admission; malformed, unreadable, oversized, or stale-generation journals fail with an integrity reason and no rejected record. `inspect view=control` reports pending capacity, saturation, stale work, journal bytes, and diagnostics. Every transition uses the same lock, expected-state fence, 128-terminal compaction, and atomic bounded rewrite; persisted errors truncate inside the string at 4 KiB. Admitted nonterminal Controls never expire automatically. Delivery failure evidence cannot regress a Control already claimed or completed by a fast consumer. Services capture their startup generation, so stale-generation Controls never execute.
|
|
88
88
|
|
|
89
|
-
Runtime lifecycle `kill`, retention actions, and review retry/reset remain runtime-owned rather than Recipe-declared.
|
|
89
|
+
Runtime lifecycle `kill`, retention actions, and review retry/reset remain runtime-owned rather than Recipe-declared. Kill is the recovery path for a stuck saturated Run: it bypasses actor-local Control capacity and creates no synthetic Control. Same-directory restart clears all generation-local evidence before the new `run_instance_id`; archive moves the exact bounded terminal tree, while prune removes kernel state and preserves only explicitly requested artifacts.
|
|
90
90
|
|
|
91
91
|
## Execution Evidence
|
|
92
92
|
|
|
93
|
-
`execution.json` stores general command/session provenance. The async runner keeps bounded stdout/stderr logs plus
|
|
93
|
+
`execution.json` stores general command/session provenance. The async runner keeps bounded stdout/stderr logs plus complete capture artifacts when semantic validation requires untruncated evidence. Pi command execution also records owned session provenance for later Trace projection and review checks. Trace and Control quotas do not constrain declared user artifacts, repositories or media sources, complete execution captures, or actor-owned queue/workload state; each remains governed by its own lifecycle and policy.
|
|
94
94
|
|
|
95
95
|
Review acceptance remains a command-stage concern. General execution evidence does not imply review approval.
|
|
96
96
|
|
|
@@ -98,7 +98,7 @@ Review acceptance remains a command-stage concern. General execution evidence do
|
|
|
98
98
|
|
|
99
99
|
Statuses include `running`, `done`, `failed`, `exited`, `cancelled`, and `killed`. Status resolution combines persisted metadata, result/terminal evidence, and verified process state.
|
|
100
100
|
|
|
101
|
-
Ambient observation detects terminal transitions and Trace attention. Terminal follow-up delivery persists handled/failure evidence so reloads retry unhandled transitions without duplicating completed notifications.
|
|
101
|
+
Ambient observation detects terminal transitions and retained Trace attention. Canonical attention is an in-memory wake hint, not a durable queue: observers prime retained ids at startup, deliver each later retained unseen id once, and bound memory to the current retained set across compaction. Persist durable recovery state or an artifact before emitting attention; compaction may discard older hints and its marker makes that history loss explicit. Terminal follow-up delivery persists handled/failure evidence so reloads retry unhandled transitions without duplicating completed notifications.
|
|
102
102
|
|
|
103
103
|
Large semantic results stay outside compact visible follow-up text and remain available in structured details, execution captures, or artifacts.
|
|
104
104
|
|
|
@@ -124,7 +124,9 @@ Archive and prune apply only to terminal Runs and enforce path containment. Rete
|
|
|
124
124
|
Packaged controlled services demonstrate the endpoint protocol:
|
|
125
125
|
|
|
126
126
|
- `music-player` consumes playback Controls and emits playback Trace;
|
|
127
|
-
- `resource-locker` consumes queue/lease actions
|
|
127
|
+
- `resource-locker` consumes queue/lease actions, emits lock Trace, and atomically retains at most 512 valid journal records within 1 MiB.
|
|
128
|
+
|
|
129
|
+
Shared archive/prune evidence similarly retains at most 256 valid records within 1 MiB under its canonical lock. The obsolete advisory `wake.jsonl` notifier was removed; filesystem watchers and bounded reconciliation observe authoritative state directly.
|
|
128
130
|
|
|
129
131
|
One-shot pipelines omit Control and terminate through their command graph.
|
|
130
132
|
|
|
@@ -136,4 +138,4 @@ inspect target=run:<id> view=trace source=lifecycle lines=40
|
|
|
136
138
|
inspect target=run:<id> view=control
|
|
137
139
|
```
|
|
138
140
|
|
|
139
|
-
Use `/actor-inspector` to inspect Runs as concrete actor instances in the live TUI. Runtime, Recipe registry, and tool definitions remain separate management targets.
|
|
141
|
+
Use `/actor-inspector` to inspect Runs as concrete actor instances in the live TUI. Runtime, Recipe registry, and tool definitions remain separate management targets. No public noun, tool, target, or view is added by bounded retention.
|
|
@@ -53,7 +53,7 @@ Common object fields:
|
|
|
53
53
|
- `concurrency`: Optional positive integer cap for a `parallel: true` node. Omit it to launch all children at once.
|
|
54
54
|
- `min_successful`: Optional non-negative integer evidence threshold for a `parallel: true` node. Usable branches are successful branches with non-empty stdout; joins include a `parallel_status` header when this is set.
|
|
55
55
|
- `when`: Optional node guard. A false guard skips the node; strings may be `flag`, `!flag`, or `{flag?yes:no}` style expressions.
|
|
56
|
-
- `args`: Optional placeholder declarations. Untyped names remain valid; compact typed forms such as `file:path`, `request_timeout:int`, `speed:number`, `dry_run:bool`, `prompts:array`, and `mode:enum(check,fix)` are valid when the host supports typed tool schemas.
|
|
56
|
+
- `args`: Optional placeholder declarations. Untyped names remain valid; compact typed forms such as `file:path`, `request_timeout:int`, `speed:number`, `dry_run:bool`, `prompts:array`, and `mode:enum(check,fix)` are valid when the host supports typed tool schemas. `name:type=value` is an optional argument with an inline fallback. Hosts reject duplicate names and conflicting declared/placeholder types rather than selecting one silently.
|
|
57
57
|
- `defaults`: Placeholder default values by name.
|
|
58
58
|
- `timeout`: Optional execution timeout in milliseconds. Omit it, or set `0`, to leave the command unbounded. Set an explicit positive timeout when a tool must fail closed instead of waiting indefinitely. Numeric control fields may be literal numbers or placeholders such as `"{timeout_ms}"`.
|
|
59
59
|
- `delay`: Optional wait in milliseconds before starting this node. Default is no delay. It may be a literal number or placeholder.
|
|
@@ -104,7 +104,7 @@ With runtime values `{ "text": "hello" }`, argv is:
|
|
|
104
104
|
["--text", "hello", "--lang", "ru", "--rate", "+30%"]
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
-
Use `defaults` for visible configuration
|
|
107
|
+
Use `defaults` for visible fallback configuration, `values` for composition binding, and inline defaults for compact local literals. Named resolution uses caller values before composition values, explicit defaults, and inline defaults; the final selected value is type/enum validated. Prefer flag-style examples such as `/path/to/tool --file {file} --lang {lang=ru}` for readability, but positional forms such as `/path/to/tool {file} {lang=ru}` are valid when the invoked script defines that CLI contract.
|
|
108
108
|
|
|
109
109
|
Use `{env??dev}` for fallback values and `{all?--all:}` to map boolean args to optional text.
|
|
110
110
|
|
package/docs/recipe-library.md
CHANGED
|
@@ -35,7 +35,7 @@ Artifact pipelines terminate in files/manifests and result evidence; they do not
|
|
|
35
35
|
### Controlled services
|
|
36
36
|
|
|
37
37
|
- `music-player.json` — 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
|
-
- `resource-locker.json` — optional queue/lease-lock service with explicit owner/resource input and
|
|
38
|
+
- `resource-locker.json` — optional queue/lease-lock service with explicit owner/resource input, lock Trace, and a 512-record/1 MiB atomically retained journal.
|
|
39
39
|
|
|
40
40
|
These are the packaged Recipes that declare actor-local Control. Ordinary one-shot Recipes omit it. Helper-backed packaged Recipes self-locate their installed package root when `repo` is omitted; an explicit caller value still wins for development or custom layouts.
|
|
41
41
|
|
|
@@ -45,6 +45,8 @@ Subagent components provide reusable command-template cells for normalization, p
|
|
|
45
45
|
|
|
46
46
|
Imports compose these definitions inside one parent Run. They are not independently addressable peers. Parent template flags control sequencing, parallelism, retries, failure scope, recovery, and repeated execution.
|
|
47
47
|
|
|
48
|
+
Packaged components can be selected exactly as `std:<recipe-name>`. Recipes bundled under a Pi-active Skill are selected as `skill:<skill-name>/<recipe-path>` and receive runtime-owned `{skill_dir}` plus `{recipe_dir}`. Active Skill components are namespaced library entries, never automatic tools; expose one intentionally through a user Recipe wrapper when a direct tool is desired.
|
|
49
|
+
|
|
48
50
|
## Utility Recipes
|
|
49
51
|
|
|
50
52
|
Utilities wrap deterministic local capabilities such as:
|
|
@@ -64,7 +66,7 @@ Use utilities as imported cells or registered tools where their contract fits.
|
|
|
64
66
|
3. Use inline templates for genuinely one-off trusted work.
|
|
65
67
|
4. Declare artifacts for outputs that callers must retain.
|
|
66
68
|
5. Declare Control only when a service process actually consumes it.
|
|
67
|
-
6. Keep large semantic evidence in artifacts or execution captures, not Trace summaries.
|
|
69
|
+
6. Keep large semantic evidence in artifacts or execution captures, not Trace summaries; Trace/Control quotas do not bound user artifacts or actor-owned workload state.
|
|
68
70
|
|
|
69
71
|
## Installation Safety
|
|
70
72
|
|
package/docs/template-recipes.md
CHANGED
|
@@ -44,7 +44,7 @@ Fences marked `template`, `command-template`, `json`, or `recipe` can define exe
|
|
|
44
44
|
Common Recipe fields:
|
|
45
45
|
|
|
46
46
|
- `name`, `description`, `disabled`;
|
|
47
|
-
- `args`, typed arg declarations, and `
|
|
47
|
+
- `args`, typed arg declarations, inline defaults, `defaults`, and composition `values`;
|
|
48
48
|
- `imports` with optional binding defaults/values;
|
|
49
49
|
- `template`;
|
|
50
50
|
- `async`;
|
|
@@ -71,7 +71,9 @@ Common Recipe fields:
|
|
|
71
71
|
}
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
Imports are local definitions. Named nodes call imported templates inside the same execution graph and Run.
|
|
74
|
+
Imports are local definitions. Named nodes call imported templates inside the same execution graph and Run. Effective values follow `caller > node/import/Recipe values > defaults > inline arg default > missing-value error`, then the selected value is checked against its declared type or enum.
|
|
75
|
+
|
|
76
|
+
Bare references preserve user → adjacent → packaged resolution. `std:<name>` selects a packaged Recipe exactly. `skill:<skill-name>/<recipe-path>` selects a component under the `recipes/` tree of a Skill currently active through Pi resource discovery. Skill Recipes never become tools merely by existing, and duplicate active Skill names fail as ambiguous rather than shadowing silently.
|
|
75
77
|
|
|
76
78
|
Direct delegation can use another Recipe as the entire template. The delegated Recipe remains the source of truth while the wrapper may narrow args/defaults or override selected lifecycle metadata.
|
|
77
79
|
|
|
@@ -102,9 +104,13 @@ Actions must be lowercase ASCII, unique, non-reserved, and at most 64 characters
|
|
|
102
104
|
|
|
103
105
|
Artifact paths resolve under containment policy and appear in Run inspection. Recipes should write declared artifacts deterministically and fail when the requested write policy cannot be honored.
|
|
104
106
|
|
|
107
|
+
## File Origins
|
|
108
|
+
|
|
109
|
+
Every file-backed Recipe receives immutable `{recipe_dir}`. A Recipe under an active Skill also receives `{skill_dir}`, resolved to the directory containing that Skill's `SKILL.md`; using `{skill_dir}` elsewhere fails clearly. These runtime values cannot be declared in `args`, `defaults`, or `values`, and caller input cannot override them. They expand in templates, recursive defaults/values, imports, and artifacts while existing `./` executable behavior remains relative to invocation `cwd`.
|
|
110
|
+
|
|
105
111
|
## Context and Provenance
|
|
106
112
|
|
|
107
|
-
File-backed Runs capture Recipe context records for the entry and imports. The captured bundle explains composition identity and remains generation-local evidence. It does not override the authored task prompt.
|
|
113
|
+
File-backed Runs capture Recipe context records for the entry and imports, including qualified `std:` or `skill:` identity when applicable. The captured bundle explains composition identity and remains generation-local evidence. Runtime origin paths remain in local Run provenance but are omitted from model-facing launch values. It does not override the authored task prompt.
|
|
108
114
|
|
|
109
115
|
Recipes that need a minimal child prompt may opt out of injected Recipe context through the documented `actor_context` launch option.
|
|
110
116
|
|
|
@@ -125,7 +131,7 @@ Resolution fails before launch when required current policy is unavailable. The
|
|
|
125
131
|
|
|
126
132
|
## Resolution and Shadowing
|
|
127
133
|
|
|
128
|
-
User Recipes under `~/.pi/agent/recipes` take priority over packaged Recipes. An invalid active file blocks fallback and reports both paths. Disabled Recipes cannot launch. Registry watchers converge after atomic changes without executing partial definitions.
|
|
134
|
+
User Recipes under `~/.pi/agent/recipes` take priority over adjacent and packaged Recipes for compatible bare lookup. Exact `std:` and `skill:` references bypass that ambiguous space. The active Skill namespace converges from Pi's loaded Skill metadata on startup/reload; pi-actors does not scan ambient Skill roots independently. An invalid active file blocks fallback and reports both paths. Disabled Recipes cannot launch. Registry watchers converge after atomic changes without executing partial definitions.
|
|
129
135
|
|
|
130
136
|
## Validation
|
|
131
137
|
|
package/docs/tool-registry.md
CHANGED
|
@@ -61,7 +61,7 @@ Usage and lineage live in locked metadata ledgers rather than authored Recipe fi
|
|
|
61
61
|
|
|
62
62
|
## Wrapping Existing Recipes
|
|
63
63
|
|
|
64
|
-
Prefer a small user-root wrapper that imports a maintained
|
|
64
|
+
Prefer a small user-root wrapper that imports a maintained Recipe by exact `std:<recipe>` or `skill:<skill>/<recipe-path>` identity and delegates by alias. Skill Recipes remain components and are never exposed merely because their Skill is active. Do not duplicate executable templates, defaults, Control declarations, artifacts, or runtime-owned `{recipe_dir}`/`{skill_dir}`. Install only specific capabilities; internal automatic-review Recipes must not become user-callable tools.
|
|
65
65
|
|
|
66
66
|
## Safety
|
|
67
67
|
|
package/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ import * as InspectorCommand from "./lib/inspector-command.ts";
|
|
|
11
11
|
import * as Paths from "./lib/paths.ts";
|
|
12
12
|
import * as Pi from "./lib/pi.ts";
|
|
13
13
|
import * as Prompts from "./lib/prompts.ts";
|
|
14
|
+
import * as RecipesReferences from "./lib/recipes-references.ts";
|
|
14
15
|
import * as RunUiRuntime from "./lib/run-ui-runtime.ts";
|
|
15
16
|
import * as Runtime from "./lib/runtime.ts";
|
|
16
17
|
import * as Temp from "./lib/temp.ts";
|
|
@@ -98,9 +99,14 @@ export default function toolRegistryExtension(pi: Pi.ExtensionAPI) {
|
|
|
98
99
|
runUiRuntime.shutdown(event.reason, ctx);
|
|
99
100
|
});
|
|
100
101
|
InspectorCommand.registerActorInspectorCommand(pi, getRunOwnerId);
|
|
101
|
-
pi.on("before_agent_start", async (event) =>
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
pi.on("before_agent_start", async (event) => {
|
|
103
|
+
RecipesReferences.setActiveSkillRecipeSources(
|
|
104
|
+
event.systemPromptOptions.skills ?? [],
|
|
105
|
+
);
|
|
106
|
+
return {
|
|
107
|
+
systemPrompt: `${event.systemPrompt}\n\n${Prompts.ONBOARDING_SYSTEM_PROMPT}`,
|
|
108
|
+
};
|
|
109
|
+
});
|
|
104
110
|
Pi.registerToolDefinitions(
|
|
105
111
|
pi,
|
|
106
112
|
Tools.createCoreActorToolDefinitions<Pi.ExtensionContext>({
|