@llblab/pi-actors 0.58.1 → 0.58.2
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 +2 -2
- package/CHANGELOG.md +6 -0
- package/README.md +37 -35
- package/dist/lib/draft-sleep.js +3 -3
- package/dist/lib/extension-runtime.js +7 -2
- package/dist/lib/prompts.d.ts +3 -3
- package/dist/lib/prompts.js +10 -9
- package/dist/lib/recipes-references.js +7 -7
- package/dist/lib/registry.js +27 -24
- package/dist/lib/review-control.js +1 -1
- package/dist/lib/run-evidence-policy.js +2 -2
- package/dist/lib/runtime.d.ts +3 -0
- package/dist/lib/runtime.js +24 -10
- package/dist/lib/tool-review-scheduler.js +7 -7
- package/dist/lib/tools-access.js +1 -1
- package/dist/lib/tools-inspect.js +10 -10
- package/dist/lib/tools-message.d.ts +1 -1
- package/dist/lib/tools-message.js +10 -10
- package/dist/lib/tools-register.d.ts +3 -3
- package/dist/lib/tools-register.js +4 -4
- package/dist/lib/tools-response.d.ts +1 -1
- package/dist/lib/tools-response.js +18 -18
- package/dist/lib/tools-spawn.js +1 -1
- package/dist/lib/tools.d.ts +7 -0
- package/dist/lib/tools.js +25 -0
- package/dist/skills/actors/SKILL.md +28 -20
- package/dist/skills/actors/references/diagnostics.md +11 -11
- package/dist/skills/actors/references/persistent-tools.md +19 -15
- package/dist/skills/actors/references/recipes.md +1 -1
- package/dist/skills/actors/references/runs.md +7 -7
- package/dist/skills/music-player/SKILL.md +4 -4
- package/dist/skills/music-player/scripts/playback.mjs +1 -1
- package/dist/skills/recipe-memory/SKILL.md +7 -7
- package/docs/README.md +2 -2
- package/docs/actor-inspector.md +1 -1
- package/docs/async-runs.md +13 -13
- package/docs/capability-memory.md +6 -6
- package/docs/inspection.md +21 -21
- package/docs/run-supervision.md +21 -21
- package/docs/tool-registry.md +27 -19
- package/docs/windows-process-observation.md +1 -1
- package/lib/draft-sleep.ts +3 -3
- package/lib/extension-runtime.ts +7 -5
- package/lib/prompts.ts +10 -9
- package/lib/recipes-references.ts +7 -7
- package/lib/registry.ts +26 -24
- package/lib/review-control.ts +1 -1
- package/lib/run-evidence-policy.ts +2 -2
- package/lib/runtime.ts +26 -11
- package/lib/tool-review-scheduler.ts +7 -7
- package/lib/tools-access.ts +1 -1
- package/lib/tools-inspect.ts +10 -10
- package/lib/tools-message.ts +10 -10
- package/lib/tools-register.ts +4 -4
- package/lib/tools-response.ts +18 -18
- package/lib/tools-spawn.ts +1 -1
- package/lib/tools.ts +28 -0
- package/package.json +1 -1
- package/skills/actors/SKILL.md +28 -20
- package/skills/actors/references/diagnostics.md +11 -11
- package/skills/actors/references/persistent-tools.md +19 -15
- package/skills/actors/references/recipes.md +1 -1
- package/skills/actors/references/runs.md +7 -7
- package/skills/music-player/SKILL.md +4 -4
- package/skills/music-player/scripts/playback.mjs +1 -1
- package/skills/recipe-memory/SKILL.md +7 -7
|
@@ -404,7 +404,7 @@ export function applyApprovedToolReviewAtSessionBoundary(
|
|
|
404
404
|
...state,
|
|
405
405
|
failedStage: "approval_state",
|
|
406
406
|
lastError: "approved review path is unavailable",
|
|
407
|
-
nextAction: "
|
|
407
|
+
nextAction: "actors_control_apply target=runtime action=review.retry input={\"scope\":\"tool\"}",
|
|
408
408
|
phase: "processing_failed" as const,
|
|
409
409
|
updatedAt: (options.now ?? (() => new Date()))().toISOString(),
|
|
410
410
|
};
|
|
@@ -427,7 +427,7 @@ export function applyApprovedToolReviewAtSessionBoundary(
|
|
|
427
427
|
...state,
|
|
428
428
|
failedStage: "transaction",
|
|
429
429
|
lastError: `tool review transaction remained ${transaction.phase}`,
|
|
430
|
-
nextAction: "
|
|
430
|
+
nextAction: "actors_control_apply target=runtime action=review.retry input={\"scope\":\"tool\"}",
|
|
431
431
|
phase: "processing_failed" as const,
|
|
432
432
|
updatedAt: (options.now ?? (() => new Date()))().toISOString(),
|
|
433
433
|
};
|
|
@@ -458,7 +458,7 @@ export function applyApprovedToolReviewAtSessionBoundary(
|
|
|
458
458
|
...pending,
|
|
459
459
|
failedStage: "lineage",
|
|
460
460
|
lastError: error instanceof Error ? error.message : String(error),
|
|
461
|
-
nextAction: "
|
|
461
|
+
nextAction: "actors_control_apply target=runtime action=review.retry input={\"scope\":\"tool\"}",
|
|
462
462
|
};
|
|
463
463
|
writeJsonAtomic(statePath, failedPending);
|
|
464
464
|
return { outcome: "lineage_pending", state: failedPending };
|
|
@@ -478,7 +478,7 @@ export function applyApprovedToolReviewAtSessionBoundary(
|
|
|
478
478
|
...state,
|
|
479
479
|
failedStage: "transaction",
|
|
480
480
|
lastError: error instanceof Error ? error.message : String(error),
|
|
481
|
-
nextAction: "
|
|
481
|
+
nextAction: "actors_control_apply target=runtime action=review.retry input={\"scope\":\"tool\"}",
|
|
482
482
|
phase: "processing_failed" as const,
|
|
483
483
|
updatedAt: (options.now ?? (() => new Date()))().toISOString(),
|
|
484
484
|
};
|
|
@@ -541,7 +541,7 @@ export function createToolReviewScheduler(
|
|
|
541
541
|
...existing,
|
|
542
542
|
failedStage: processed.stage ?? "review_result",
|
|
543
543
|
lastError: processed.error ?? "automatic tool reviewer failed",
|
|
544
|
-
nextAction: "
|
|
544
|
+
nextAction: "actors_control_apply target=runtime action=review.retry input={\"scope\":\"tool\"}",
|
|
545
545
|
phase: processed.outcome === "processing_failed"
|
|
546
546
|
? "processing_failed"
|
|
547
547
|
: "failed",
|
|
@@ -577,7 +577,7 @@ export function createToolReviewScheduler(
|
|
|
577
577
|
attempts: existing.attempts + 1,
|
|
578
578
|
failedStage: "review_launch",
|
|
579
579
|
lastError: error instanceof Error ? error.message : String(error),
|
|
580
|
-
nextAction: "
|
|
580
|
+
nextAction: "actors_control_apply target=runtime action=review.retry input={\"scope\":\"tool\"}",
|
|
581
581
|
phase: "failed",
|
|
582
582
|
updatedAt: now().toISOString(),
|
|
583
583
|
} satisfies ToolReviewAdmissionState);
|
|
@@ -612,7 +612,7 @@ export function createToolReviewScheduler(
|
|
|
612
612
|
failedStage: "review_launch",
|
|
613
613
|
inputPath: batch.inputPath,
|
|
614
614
|
lastError: error instanceof Error ? error.message : String(error),
|
|
615
|
-
nextAction: "
|
|
615
|
+
nextAction: "actors_control_apply target=runtime action=review.retry input={\"scope\":\"tool\"}",
|
|
616
616
|
phase: "failed",
|
|
617
617
|
reviewerInputPath: batch.reviewerInputPath,
|
|
618
618
|
reviewId: batch.reviewId,
|
package/lib/tools-access.ts
CHANGED
|
@@ -55,7 +55,7 @@ export function sessionMismatchError(input: {
|
|
|
55
55
|
),
|
|
56
56
|
{
|
|
57
57
|
current_session: input.currentSession,
|
|
58
|
-
hint: "
|
|
58
|
+
hint: "actors_inspect target=runtime view=runs",
|
|
59
59
|
owner_session: input.expectedSession,
|
|
60
60
|
reason: "session_mismatch",
|
|
61
61
|
run: input.run,
|
package/lib/tools-inspect.ts
CHANGED
|
@@ -171,13 +171,13 @@ function runtimeTriage(
|
|
|
171
171
|
trace_diagnostic_count: traceDiagnostics.length, trace_diagnostics: traceDiagnostics.slice(0, 40),
|
|
172
172
|
attention_events: attentionEvents.slice(-40).reverse(),
|
|
173
173
|
next_actions: [
|
|
174
|
-
...(failed.length ? ["
|
|
174
|
+
...(failed.length ? ["actors_inspect target=runtime view=runs status=failed"] : []),
|
|
175
175
|
...new Set([...staleControls, ...backpressuredRuns].slice(0, 3).map((entry) =>
|
|
176
|
-
`
|
|
176
|
+
`actors_inspect target=run:${entry.run} view=control`,
|
|
177
177
|
)),
|
|
178
178
|
...(attentionEvents.length
|
|
179
179
|
? attentionEvents.slice(-3).map((entry) =>
|
|
180
|
-
`
|
|
180
|
+
`actors_inspect target=run:${String(entry.run)} view=trace source=runtime`,
|
|
181
181
|
)
|
|
182
182
|
: []),
|
|
183
183
|
],
|
|
@@ -247,7 +247,7 @@ function formatInspectFailure(
|
|
|
247
247
|
return { omittable, full, selected };
|
|
248
248
|
});
|
|
249
249
|
// Only producer-known read-only inspect literals become a typed next, never a parsed action.
|
|
250
|
-
const typedNext = next ? { next: { tool: "
|
|
250
|
+
const typedNext = next ? { next: { tool: "actors_inspect", target: next[0], view: next[1] } } : undefined;
|
|
251
251
|
const nextFallback = { next_action: omitted };
|
|
252
252
|
const document = () => ({ ...Object.assign({}, ...parts.map((part) => part.selected)),
|
|
253
253
|
...(typedNext ?? nextFallback) });
|
|
@@ -412,15 +412,15 @@ function inspectRecipeIdentity(
|
|
|
412
412
|
...(rejectedReason ? { rejected_reason: rejectedReason } : {}),
|
|
413
413
|
next_actions: resolvable
|
|
414
414
|
? [
|
|
415
|
-
`
|
|
416
|
-
`
|
|
415
|
+
`actors_run_spawn recipe=${identity}`,
|
|
416
|
+
`actors_tool_register name=<tool-name> from=${identity}`,
|
|
417
417
|
]
|
|
418
418
|
: roots.length === 0 && skill
|
|
419
419
|
? [
|
|
420
420
|
`activate Skill ${skill}`,
|
|
421
|
-
`
|
|
421
|
+
`actors_inspect target=recipes view=doctor identity=${identity}`,
|
|
422
422
|
]
|
|
423
|
-
: ["
|
|
423
|
+
: ["actors_inspect target=recipes view=imports verbose=true"],
|
|
424
424
|
};
|
|
425
425
|
}
|
|
426
426
|
|
|
@@ -707,7 +707,7 @@ function compactResult(target: string, view: string, details: Record<string, unk
|
|
|
707
707
|
? String(details.next_actions[0])
|
|
708
708
|
: details.callable_now === true
|
|
709
709
|
? `call tool ${name}`
|
|
710
|
-
: `
|
|
710
|
+
: `actors_tool_register name=${name} update=true`;
|
|
711
711
|
const hint = ToolsResponse.nextActionMetadata(next, Limits.RUN_DELIVERY_MODEL_MAX_BYTES);
|
|
712
712
|
const required = compactArguments("required_args", details.required_args);
|
|
713
713
|
const optional = compactArguments("optional_args", details.optional_args);
|
|
@@ -727,7 +727,7 @@ export function createInspectToolDefinition<TContext = unknown>(
|
|
|
727
727
|
deps: InspectToolDeps<TContext> = {},
|
|
728
728
|
): any {
|
|
729
729
|
return {
|
|
730
|
-
name: "
|
|
730
|
+
name: "actors_inspect",
|
|
731
731
|
label: "Inspect",
|
|
732
732
|
description:
|
|
733
733
|
"Inspect a Run's Recipe, Trace, or Control evidence, or runtime/recipe/tool diagnostics.",
|
package/lib/tools-message.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Public Control facade under the stable `
|
|
2
|
+
* Public Control facade under the stable `actors_control_apply` tool name.
|
|
3
3
|
* Zones: Control request validation, Run/runtime dispatch, recipient-scoped receipts
|
|
4
4
|
* Owns public Control execution; journaling, delivery, and lifecycle mutation stay in Run domains.
|
|
5
5
|
*/
|
|
@@ -52,9 +52,9 @@ function controlDocument(render: () => ControlDocument, order: readonly ControlP
|
|
|
52
52
|
|
|
53
53
|
/** Only producer-known read-only inspect literals become typed next; other advice stays opaque content. */
|
|
54
54
|
function controlNextPart(action: string): ControlPart {
|
|
55
|
-
const inspect = /^
|
|
55
|
+
const inspect = /^actors_inspect target=([^\s]+) view=([^\s]+)$/u.exec(action);
|
|
56
56
|
if (inspect) {
|
|
57
|
-
return ToolsResponse.selectYamlNode("next", { tool: "
|
|
57
|
+
return ToolsResponse.selectYamlNode("next", { tool: "actors_inspect", target: inspect[1], view: inspect[2] }, CONTROL_BUDGET);
|
|
58
58
|
}
|
|
59
59
|
const wellFormed = action.isWellFormed();
|
|
60
60
|
const omitted: ControlDocument = { next: { instruction: wellFormed ? "[omitted]" : "[unavailable]",
|
|
@@ -123,15 +123,15 @@ export function compactControlResult(
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
function runNextActions(run: string, result: Record<string, unknown>): string[] {
|
|
126
|
-
if (result.stopped === true) return [`
|
|
126
|
+
if (result.stopped === true) return [`actors_inspect target=run:${run} view=trace`];
|
|
127
127
|
if (result.stopped === false || result.archived === false || result.pruned === false) {
|
|
128
128
|
if (result.reason === "ownership changed" || result.reason === "run generation changed") {
|
|
129
|
-
return ["
|
|
129
|
+
return ["actors_inspect target=runtime view=runs"];
|
|
130
130
|
}
|
|
131
|
-
if (result.stopped === false && result.reason !== "not running") return [`
|
|
131
|
+
if (result.stopped === false && result.reason !== "not running") return [`actors_inspect target=run:${run} view=trace`];
|
|
132
132
|
}
|
|
133
133
|
if (result.delivery === "queued" || result.delivery === "delivered") {
|
|
134
|
-
return [`
|
|
134
|
+
return [`actors_inspect target=run:${run} view=control`];
|
|
135
135
|
}
|
|
136
136
|
return [];
|
|
137
137
|
}
|
|
@@ -148,10 +148,10 @@ export function createControlToolDefinition<TContext = unknown>(
|
|
|
148
148
|
deps: ControlToolDeps = {},
|
|
149
149
|
): any {
|
|
150
150
|
return {
|
|
151
|
-
name: "
|
|
151
|
+
name: "actors_control_apply",
|
|
152
152
|
label: "Control",
|
|
153
153
|
description:
|
|
154
|
-
"Apply one Control action
|
|
154
|
+
"Apply one Run/runtime Control action. This is not chat or peer messaging.",
|
|
155
155
|
parameters: Schema.objectSchema(
|
|
156
156
|
{
|
|
157
157
|
target: Schema.stringSchema("Run target run:<id>, or literal runtime."),
|
|
@@ -260,7 +260,7 @@ export function createControlToolDefinition<TContext = unknown>(
|
|
|
260
260
|
// Admission-era correlation is not current reply-scope proof after an awaited dispatch.
|
|
261
261
|
// Display one whole caller-owned id or an explicit whole-id omission; the warning stays literal.
|
|
262
262
|
const identity = controlSelected("run", run);
|
|
263
|
-
const next = controlNextPart("
|
|
263
|
+
const next = controlNextPart("actors_inspect target=runtime view=runs");
|
|
264
264
|
const render = (): ControlDocument => ({ ...identity.selected, action: request.action,
|
|
265
265
|
result: "request failed", delivery: "unconfirmed", handling: "unconfirmed",
|
|
266
266
|
warning: "Effects may already exist.\nDo not repeat automatically.", ...next.selected });
|
package/lib/tools-register.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Public
|
|
3
|
-
* Zones: runtime tool registration, tool registry mutation,
|
|
4
|
-
* Owns the public
|
|
2
|
+
* Public actors_tool_register behavior
|
|
3
|
+
* Zones: runtime tool registration, tool registry mutation, actors_tool_register schema
|
|
4
|
+
* Owns the public actors_tool_register definition that persists local agent capabilities
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import * as Prompts from "./prompts.ts";
|
|
@@ -24,7 +24,7 @@ export function createRegisterToolDefinition<TContext>(
|
|
|
24
24
|
deps: RegisterToolRuntimeDeps<TContext>,
|
|
25
25
|
) {
|
|
26
26
|
return {
|
|
27
|
-
name: "
|
|
27
|
+
name: "actors_tool_register",
|
|
28
28
|
label: "Register Tool",
|
|
29
29
|
description: Prompts.REGISTER_TOOL_DESCRIPTION,
|
|
30
30
|
promptSnippet: Prompts.REGISTER_TOOL_PROMPT_SNIPPET,
|
package/lib/tools-response.ts
CHANGED
|
@@ -154,8 +154,8 @@ export function formatMarkdownField(key: string, value: string, depth = 0): stri
|
|
|
154
154
|
: `${indent}- ${key}: ${value}`;
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
export function formatInspectNextAction(target: string, view: string, verbose?: boolean): string {
|
|
158
|
-
return ["- next:", formatMarkdownField("tool",
|
|
157
|
+
export function formatInspectNextAction(target: string, view: string, verbose?: boolean, tool = "inspect"): string {
|
|
158
|
+
return ["- next:", formatMarkdownField("tool", tool, 1), formatMarkdownField("target", target, 1),
|
|
159
159
|
formatMarkdownField("view", view, 1), ...(verbose === undefined ? [] : [formatMarkdownField("verbose", String(verbose), 1)])].join("\n");
|
|
160
160
|
}
|
|
161
161
|
|
|
@@ -289,20 +289,20 @@ function launchModelPolicy(value: unknown): Record<string, unknown> {
|
|
|
289
289
|
return fields;
|
|
290
290
|
}
|
|
291
291
|
|
|
292
|
-
const RUN_FILE_INVESTIGATION_COMMAND = "
|
|
292
|
+
const RUN_FILE_INVESTIGATION_COMMAND = "actors_inspect target=runtime view=runs verbose=true";
|
|
293
293
|
|
|
294
294
|
/** Frozen older completion-format text: new launch layout must not change this shared packet helper. */
|
|
295
295
|
export function formatRunFileNavigationHandoff(): string {
|
|
296
|
-
return
|
|
296
|
+
return "Files (optional; current session):\n`inspect target=runtime view=runs verbose=true`";
|
|
297
297
|
}
|
|
298
298
|
|
|
299
299
|
export function runNextActions(run: unknown): string[] {
|
|
300
300
|
const id = String(run ?? "").trim();
|
|
301
301
|
if (!id) return [];
|
|
302
302
|
return [
|
|
303
|
-
`
|
|
304
|
-
`
|
|
305
|
-
`
|
|
303
|
+
`actors_inspect target=run:${id} view=recipe`,
|
|
304
|
+
`actors_inspect target=run:${id} view=trace`,
|
|
305
|
+
`actors_inspect target=run:${id} view=control`,
|
|
306
306
|
RUN_FILE_INVESTIGATION_COMMAND,
|
|
307
307
|
];
|
|
308
308
|
}
|
|
@@ -329,7 +329,7 @@ export function compactAsyncRunStatus(value: unknown): string {
|
|
|
329
329
|
}
|
|
330
330
|
if (result.killed === true) fields.killed = true;
|
|
331
331
|
if (status.draft_recipe) fields.draft_recipe = String(status.draft_recipe);
|
|
332
|
-
const hint = { file_investigation: "optional; current session", next: { tool: "
|
|
332
|
+
const hint = { file_investigation: "optional; current session", next: { tool: "actors_inspect", target: "runtime", view: "runs", verbose: true } };
|
|
333
333
|
const hasNavigation = Object.hasOwn(status, "file_navigation");
|
|
334
334
|
let navigation: unknown;
|
|
335
335
|
if (hasNavigation) {
|
|
@@ -509,25 +509,25 @@ export function recipeRegistryNextActions(
|
|
|
509
509
|
: 0;
|
|
510
510
|
const topAction = asRecord(summary.top_action);
|
|
511
511
|
if (view !== "doctor" && (invalid > 0 || diagnostics > 0)) {
|
|
512
|
-
actions.push("
|
|
512
|
+
actions.push("actors_inspect target=recipes view=doctor");
|
|
513
513
|
}
|
|
514
514
|
if (view === "doctor" && typeof topAction.action === "string") {
|
|
515
515
|
actions.push(String(topAction.action));
|
|
516
516
|
}
|
|
517
517
|
if (summary.skill_recipe_catalog_partial === true) {
|
|
518
|
-
actions.push("
|
|
518
|
+
actions.push("actors_inspect target=recipes view=imports verbose=true");
|
|
519
519
|
}
|
|
520
520
|
if (
|
|
521
521
|
(Array.isArray(summary.retained) && summary.retained.length > 0) ||
|
|
522
522
|
(Array.isArray(summary.retained_diagnostics) && summary.retained_diagnostics.length > 0)
|
|
523
523
|
) {
|
|
524
|
-
actions.push("
|
|
524
|
+
actions.push("actors_inspect target=recipes view=summary verbose=true");
|
|
525
525
|
}
|
|
526
526
|
if (drafts.length > 0) {
|
|
527
|
-
actions.push("
|
|
527
|
+
actions.push("actors_inspect target=recipes view=summary verbose=true");
|
|
528
528
|
const firstPath =
|
|
529
529
|
typeof drafts[0]?.path === "string" ? drafts[0].path : undefined;
|
|
530
|
-
if (firstPath) actions.push(`
|
|
530
|
+
if (firstPath) actions.push(`actors_run_spawn file=${firstPath}`);
|
|
531
531
|
}
|
|
532
532
|
return [...new Set(actions)].slice(0, 4);
|
|
533
533
|
}
|
|
@@ -539,9 +539,9 @@ export function compactYamlDocument(value: Record<string, unknown>): string {
|
|
|
539
539
|
}
|
|
540
540
|
|
|
541
541
|
function recipeInspectionHint(action: string): { view: "doctor" | "imports" | "summary"; verbose?: true } | undefined {
|
|
542
|
-
if (action === "
|
|
543
|
-
if (action === "
|
|
544
|
-
if (action === "
|
|
542
|
+
if (action === "actors_inspect target=recipes view=doctor") return { view: "doctor" };
|
|
543
|
+
if (action === "actors_inspect target=recipes view=imports verbose=true") return { view: "imports", verbose: true };
|
|
544
|
+
if (action === "actors_inspect target=recipes view=summary verbose=true") return { view: "summary", verbose: true };
|
|
545
545
|
return undefined;
|
|
546
546
|
}
|
|
547
547
|
|
|
@@ -549,7 +549,7 @@ function recipeInspectionHint(action: string): { view: "doctor" | "imports" | "s
|
|
|
549
549
|
export function nextActionMetadata(action: string, byteBudget: number): YamlPart {
|
|
550
550
|
const hint = recipeInspectionHint(action);
|
|
551
551
|
if (hint) {
|
|
552
|
-
const typed = { next: { tool: "
|
|
552
|
+
const typed = { next: { tool: "actors_inspect", target: "recipes", ...hint } };
|
|
553
553
|
return { full: typed, selected: typed };
|
|
554
554
|
}
|
|
555
555
|
const instruction = selectYamlField("instruction", action, byteBudget);
|
|
@@ -559,7 +559,7 @@ export function nextActionMetadata(action: string, byteBudget: number): YamlPart
|
|
|
559
559
|
/** Only these existing read-only inspection hints become action nodes; other advice stays content. */
|
|
560
560
|
export function formatInspectionHint(action: string): string {
|
|
561
561
|
const hint = recipeInspectionHint(action);
|
|
562
|
-
return hint ? formatInspectNextAction("recipes", hint.view, hint.verbose) : formatMarkdownField("instruction", action);
|
|
562
|
+
return hint ? formatInspectNextAction("recipes", hint.view, hint.verbose, "actors_inspect") : formatMarkdownField("instruction", action);
|
|
563
563
|
}
|
|
564
564
|
|
|
565
565
|
export function compactRecipeRegistry(
|
package/lib/tools-spawn.ts
CHANGED
|
@@ -124,7 +124,7 @@ export function createSpawnToolDefinition<
|
|
|
124
124
|
TContext extends SpawnToolContext,
|
|
125
125
|
>(): any {
|
|
126
126
|
return {
|
|
127
|
-
name: "
|
|
127
|
+
name: "actors_run_spawn",
|
|
128
128
|
label: "Spawn",
|
|
129
129
|
description:
|
|
130
130
|
"Create one controllable Run from a Recipe file or inline command template.",
|
package/lib/tools.ts
CHANGED
|
@@ -54,12 +54,40 @@ export const RESERVED_TOOL_NAMES = new Set([
|
|
|
54
54
|
"find",
|
|
55
55
|
"grep",
|
|
56
56
|
"ls",
|
|
57
|
+
"actors_tool_register",
|
|
58
|
+
"actors_run_spawn",
|
|
59
|
+
"actors_control_apply",
|
|
60
|
+
"actors_inspect",
|
|
57
61
|
"register_tool",
|
|
58
62
|
"message",
|
|
59
63
|
"spawn",
|
|
60
64
|
"inspect",
|
|
61
65
|
]);
|
|
62
66
|
|
|
67
|
+
// Compatibility dispatch is registered but omitted from model declarations and normal
|
|
68
|
+
// callable listings. Active legacy names still execute saved native tool calls.
|
|
69
|
+
export const LEGACY_TOOL_NAMES = {
|
|
70
|
+
register_tool: "actors_tool_register",
|
|
71
|
+
spawn: "actors_run_spawn",
|
|
72
|
+
message: "actors_control_apply",
|
|
73
|
+
inspect: "actors_inspect",
|
|
74
|
+
} as const;
|
|
75
|
+
|
|
76
|
+
export function createLegacyActorToolDefinitions(
|
|
77
|
+
definitions: ActorToolDefinition[],
|
|
78
|
+
): ActorToolDefinition[] {
|
|
79
|
+
return Object.entries(LEGACY_TOOL_NAMES).map(([name, canonical]) => {
|
|
80
|
+
const definition = definitions.find((tool) => tool.name === canonical);
|
|
81
|
+
if (!definition) throw new Error(`Missing canonical actor tool: ${canonical}`);
|
|
82
|
+
return {
|
|
83
|
+
...definition, name, exposure: "deferred",
|
|
84
|
+
description: `Compatibility dispatch for ${canonical}; use the canonical tool for new calls.`,
|
|
85
|
+
promptSnippet: undefined, promptGuidelines: undefined,
|
|
86
|
+
prepareLoadout: () => ({ hiddenDeclarations: Object.keys(LEGACY_TOOL_NAMES) }),
|
|
87
|
+
};
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
63
91
|
export function createCoreActorToolDefinitions<
|
|
64
92
|
TContext extends RuntimeToolContext,
|
|
65
93
|
>(deps: CoreActorToolDefinitionDeps<TContext>): ActorToolDefinition[] {
|
package/package.json
CHANGED
package/skills/actors/SKILL.md
CHANGED
|
@@ -5,31 +5,39 @@ description: Use for any non-trivial pi-actors operation, diagnosis, or developm
|
|
|
5
5
|
|
|
6
6
|
# Actors
|
|
7
7
|
|
|
8
|
+
## Public tool names and migration
|
|
9
|
+
|
|
10
|
+
Use only `actors_tool_register`, `actors_run_spawn`, `actors_control_apply`, and `actors_inspect` for new calls. The old `register_tool`, `spawn`, `message`, and `inspect` names are explicit compatibility dispatch to the same schemas and executors, not a second advertised API. Saved calls and logical Recipe identities stay unchanged; do not migrate the live registry or reload the host implicitly. Compatibility entries are deferred, active dispatch names with model declarations hidden by the host loadout hook; explicit inspection/search or the host's active/registered inventory can still reveal them. They remain subject to the same host permissions and session fences.
|
|
11
|
+
|
|
12
|
+
Name new configurable Recipe tools under their functional owner's namespace, such as `audio_transcribe`, `music_player`, or `repo_check`, not generic host verbs. This is a caller naming contract, not a new Recipe identity field or an automatic prefix. Preserve existing persisted names and calls. Registration and discovery reject normalized collisions with foreign host tools, even inactive ones; `update=true` cannot authorize replacing another owner's tool. A rejected exposure does not make a foreign tool callable as a Recipe. Within the same runtime, observed name/source-path provenance survives Recipe deactivation so an owned retained host declaration does not block recreation or restoration. A different-source or normalized foreign declaration still blocks exposure; identical host name/source metadata cannot distinguish a replacement. This is not complete host unregister or activation proof: require fresh `callable_now` evidence.
|
|
13
|
+
|
|
14
|
+
`actors_control_apply` applies Run/runtime actions, never chat or peer messages. The rename changes no Control envelope, ownership, generation, delivery/handling distinction or Run semantics.
|
|
15
|
+
|
|
8
16
|
## Choose the operation
|
|
9
17
|
|
|
10
18
|
Start from the intended outcome:
|
|
11
19
|
|
|
12
20
|
```text
|
|
13
21
|
Run a maintained capability once
|
|
14
|
-
→ use
|
|
22
|
+
→ use actors_run_spawn recipe=<skill>/<recipe>
|
|
15
23
|
|
|
16
24
|
Make a maintained capability a persistent agent-callable tool
|
|
17
|
-
→ use
|
|
25
|
+
→ use actors_tool_register from=<skill>/<recipe>
|
|
18
26
|
|
|
19
27
|
Keep the same capability but narrow caller defaults
|
|
20
|
-
→ use
|
|
28
|
+
→ use actors_tool_register from=<skill>/<recipe> defaults={...}
|
|
21
29
|
|
|
22
30
|
Retain a new named capability without exposing a tool
|
|
23
|
-
→ use
|
|
31
|
+
→ use actors_tool_register expose=false with from or template
|
|
24
32
|
|
|
25
33
|
Register a trusted command directly
|
|
26
|
-
→ use
|
|
34
|
+
→ use actors_tool_register template="..."
|
|
27
35
|
|
|
28
36
|
Build a reusable multi-node execution graph
|
|
29
37
|
→ author a Recipe with named imports
|
|
30
38
|
|
|
31
39
|
Run a long-lived controlled process
|
|
32
|
-
→
|
|
40
|
+
→ use actors_run_spawn for its async Recipe, then actors_control_apply and actors_inspect
|
|
33
41
|
|
|
34
42
|
Coordinate several independent actors or subagents
|
|
35
43
|
→ also read the swarm Skill
|
|
@@ -55,13 +63,13 @@ direct delegation ≠ named import composition
|
|
|
55
63
|
Run Control ≠ actor chat
|
|
56
64
|
```
|
|
57
65
|
|
|
58
|
-
A Skill Recipe is a maintained component addressed by `<skill>/<recipe>`. `
|
|
66
|
+
A Skill Recipe is a maintained component addressed by `<skill>/<recipe>`. `actors_run_spawn` creates a Run from a Recipe. `actors_tool_register from=<skill>/<recipe>` persists compact logical delegation and activates from the resolved effective contract without copying, symlinking, or ambient re-resolution. A tool is callable in the current session only when activation evidence says `callable_now: true`.
|
|
59
67
|
|
|
60
|
-
Sync/async is an execution contract, not a usefulness or tool-exposure rule. A sync tool awaits its result; an async tool returns a Run launch receipt, with the eventual result delivered separately. A subagent-backed tool is a capability launcher, not a persisted live subagent. Register a stable, meaningfully parameterized capability when its name and contract save repeated planning; prefer one-off `
|
|
68
|
+
Sync/async is an execution contract, not a usefulness or tool-exposure rule. A sync tool awaits its result; an async tool returns a Run launch receipt, with the eventual result delivered separately. A subagent-backed tool is a capability launcher, not a persisted live subagent. Register a stable, meaningfully parameterized capability when its name and contract save repeated planning; prefer one-off `actors_run_spawn` over a redundant generic launcher or a new tool for every mission.
|
|
61
69
|
|
|
62
|
-
Use `
|
|
70
|
+
Use `actors_tool_register expose=false` with a new name and one `template` or `from` source to retain a capability without requesting tool activation. Its `kind: retained_recipe`, `activation: not_requested` receipt is deliberate retention, not failed registration; it omits global callability flags because a same-named tool may already exist. Reuse the exact returned Recipe path through `actors_run_spawn`, or deliberately expose it later with ordinary `actors_tool_register from=<exact path>`. Retained update, delete and draft promotion are unsupported; do not hand-edit the live registry to bypass those guards.
|
|
63
71
|
|
|
64
|
-
Automatic retained lifecycle is not implemented. Current user-root tool discovery and automatic review actions are unchanged. `
|
|
72
|
+
Automatic retained lifecycle is not implemented. Current user-root tool discovery and automatic review actions are unchanged. `actors_inspect target=recipes view=summary` distinguishes retained definitions under `recipes/library` from root tool candidates; verbose detail gives exact paths, resolved mode and invalid/disabled diagnostics. Storage is not proof of review, callability or a running Actor. `expose` is registration input, not a Recipe field or automatic-review action; do not invent retain/defer review commands. See [persistent tools](./references/persistent-tools.md) for current selection and activation proof.
|
|
65
73
|
|
|
66
74
|
`actors` owns generic Recipe/tool/Run mechanics. The owning capability Skill owns capability-specific selection and constraints. `swarm` owns multi-actor decomposition and integration methodology.
|
|
67
75
|
|
|
@@ -87,15 +95,15 @@ Four locally authored Control guard errors use caller target/action/result recor
|
|
|
87
95
|
|
|
88
96
|
Local spawn guards identify unsupported state_dir or invalid as with field/result and the selected caller value, not an admitted Run. Whole values fit16KiB or show field omission; malformed text is unavailable, not repaired. The host may reject unsupported state_dir by its own schema before the facade, so not every SDK validation error has AX text. This adds no launch, no-effects receipt, retry permission, generated identity or change to Recipe/session/post-launch failures.
|
|
89
97
|
|
|
90
|
-
Fresh source normal
|
|
98
|
+
Fresh source normal actors_tool_register receipts use bare block-YAML tool/result/source/callable_now fields and native argument/warning sequences, including empty argument lists. Normal callability remains Boolean and a non-template source stays one exact safely quoted scalar; complete warnings take priority under16KiB, and whole-field/list omissions count only selected metadata, not hidden chars. Call advice remains opaque instruction, not automatic invocation; an unverified registration keeps its existing read-only tool-status next. Persistence is not callability: rely on the existing activation evidence, never substitute spawn or infer fresh host readiness from this layout. Transaction/errors/list/delete/draft and saved messages are not restyled by this slice.
|
|
91
99
|
|
|
92
100
|
Fresh source registry listings and deletion receipts use bare block YAML. Listings preserve the same selected sorted names as a native sequence with coverage; empty selection is `[]`, an overlarge whole group is explicitly omitted rather than mislabeled empty, and malformed text is unavailable without repair. Counts describe selected names, not active/callable or the complete loaded-host registry. Deletion returns tool/result and preserves the manual reload note as opaque instruction: neither a current-map miss nor returned deletion proves full host removal or authorizes automatic reload/retry. Existing partial-effect exceptions and machine details remain unchanged. Combined compiled/package acceptance and loaded-host observation remain separate; an older runtime can still return the prior flat-list text.
|
|
93
101
|
|
|
94
102
|
Fresh source draft-promotion success uses bare block YAML only for its original selected name/new-update/source=draft/callable display and one prior hint. The selected callable display remains a string, including quoted "false", "true" or "0", not reconstructed Boolean readiness. It adds no default/body/argument/path or activation facts and does not become an ordinary registration transaction. A zero, opaque legacy display or unavailable field is not permission to infer readiness or repair callability. Whole scalar/action omissions stay explicit; invocation advice is content and only the existing read-only status hint may be typed. Promotion callbacks/display can still fail after writes with original errors; no automatic rollback/retry/reload follows.
|
|
95
103
|
|
|
96
|
-
Local
|
|
104
|
+
Local actors_tool_register source-mode refusals now identify field/result and actual replacement/reference/source-mode/inherited-field choices. Existing correction advice is instruction content, not automatic retry/update or a no-effects receipt. Supplied values are not echoed. The host owns clone/coercion/schema behavior before the facade, so use the actual outcome rather than assuming every wrong-typed request reaches a local AX guard. Other registry errors and all existing activation/transaction contracts remain unchanged.
|
|
97
105
|
|
|
98
|
-
Ordinary invalid/reserved-name and new-registration missing-source errors now use AX fields. Reserved-name display is only the old selected value, not ownership or tool-invocation permission; an unfit/malformed value is wholly omitted/unavailable, not repaired. Missing-source choices and prior correction advice do not impose a new source rule on listing or existing-tool updates. Dependency/normalizer/blocker errors keep their own behavior; no retry, overwrite or no-effects authority follows from these records. Ordinary/draft already-registered refusals likewise identify only the original selected name and preserve Use update=true to overwrite as opaque instruction. This layout neither merges their admission policies nor authorizes overwriting, automatic retry or invocation; unfit/malformed name display stays explicitly omitted/unavailable under16KiB. Local template-shape errors now identify nested Recipe-shaped template, empty sequence or unsupported type, with actual string/object/sequence choices and old repair advice as opaque instruction. Supplied values are not echoed; this adds no source mode, global null/undefined rule, retry permission or change to host validation/coercion and dependency errors. Four later authored-Recipe validation errors now likewise identify defaults, description or template with fixed field/result. Their original stages remain: front null can delete, existing source can be inherited, and host schema/earlier source checks may reject or route a request before these local errors. No new value echo, automatic correction, activation or no-effects authority follows. A delegated-source runtime-owned-default refusal now names only its existing first selected key under defaults/key/result with prior advice as opaque instruction. It neither displays supplied values/all reserved keys nor authorizes retry or changes command-template/default admission behavior; original copy faults can still precede the refusal. Draft-path refusals now identify the allowed-root or resolved-path reference as a whole literal, or explicit omission/unavailability when unfit/malformed. Old summary-inspection advice remains opaque instruction, not automatic action or a new guarantee that a summary lists every draft. Existing root/exists checks and unowned faults keep their semantics; this is not filesystem absence, no-effects or native proof. Public from-normalization failures now show the prior displayed source, reason, legacy active-skill summary and doctor advice as AX. Source stays a whole literal or explicit field omission/unavailability; reason/summary/body labels are opaque, and advice remains instruction rather than an automatic call. The legacy summary is not a complete Skill inventory, display is not freshly normalized ownership, and a failure does not grant retry, broader source/cause access or host readiness. Normal candidate-admission refusals now likewise report selected joined diagnostics and, only on the existing source branch, prior displayed source/legacy summary/doctor advice. Diagnostics/summary are opaque values, not complete lists or raw causes; upstream diagnostic clipping remains legacy/unproven. Full fields fit16KiB or have explicit omission/unavailability without repair. This does not alter admission, make failures effect-free/transactional, or authorize automatic correction, retry or invocation. Draft invalid-Recipe refusals now similarly show only the previously selected optional reason or joined diagnostics with draft/result. They add no path/body, source permission, raw cause or rollback guarantee; read/diagnose/admission behavior and legacy upstream limits remain. Whole values fit16KiB or show omission/unavailability without repair, and absent reason is not synthesized. Outer registration transaction failure now also separates old stage, resolution_generation, legacy summary and surfaced error as AX after the original cleanup path. That generation identifies resolution context, not fresh Run identity/epoch. Inner rollback/advice wording remains opaque error content, not proof of complete host rollback/removal or permission to repeat. Original cleanup/formatting faults and partial effects remain; no new cause/source access or transaction guarantee. Registry activation/promotion/deletion UI notices now use report/tool fields with only old selected display. A report is not callable or complete-host-removal proof; original hasUI/callback/post-effect failures remain. Whole well-formed notifier values are not subject to the model16KiB cap, malformed selected name is unavailable without repair, and RPC forwarding is not client handling/visibility proof. Recipe registry watcher warning/refresh reports use AX fields too; their old default-root wording is not a freshly verified actual path, and restart/
|
|
106
|
+
Ordinary invalid/reserved-name and new-registration missing-source errors now use AX fields. Reserved-name display is only the old selected value, not ownership or tool-invocation permission; an unfit/malformed value is wholly omitted/unavailable, not repaired. Missing-source choices and prior correction advice do not impose a new source rule on listing or existing-tool updates. Dependency/normalizer/blocker errors keep their own behavior; no retry, overwrite or no-effects authority follows from these records. Ordinary/draft already-registered refusals likewise identify only the original selected name and preserve Use update=true to overwrite as opaque instruction. This layout neither merges their admission policies nor authorizes overwriting, automatic retry or invocation; unfit/malformed name display stays explicitly omitted/unavailable under16KiB. Local template-shape errors now identify nested Recipe-shaped template, empty sequence or unsupported type, with actual string/object/sequence choices and old repair advice as opaque instruction. Supplied values are not echoed; this adds no source mode, global null/undefined rule, retry permission or change to host validation/coercion and dependency errors. Four later authored-Recipe validation errors now likewise identify defaults, description or template with fixed field/result. Their original stages remain: front null can delete, existing source can be inherited, and host schema/earlier source checks may reject or route a request before these local errors. No new value echo, automatic correction, activation or no-effects authority follows. A delegated-source runtime-owned-default refusal now names only its existing first selected key under defaults/key/result with prior advice as opaque instruction. It neither displays supplied values/all reserved keys nor authorizes retry or changes command-template/default admission behavior; original copy faults can still precede the refusal. Draft-path refusals now identify the allowed-root or resolved-path reference as a whole literal, or explicit omission/unavailability when unfit/malformed. Old summary-inspection advice remains opaque instruction, not automatic action or a new guarantee that a summary lists every draft. Existing root/exists checks and unowned faults keep their semantics; this is not filesystem absence, no-effects or native proof. Public from-normalization failures now show the prior displayed source, reason, legacy active-skill summary and doctor advice as AX. Source stays a whole literal or explicit field omission/unavailability; reason/summary/body labels are opaque, and advice remains instruction rather than an automatic call. The legacy summary is not a complete Skill inventory, display is not freshly normalized ownership, and a failure does not grant retry, broader source/cause access or host readiness. Normal candidate-admission refusals now likewise report selected joined diagnostics and, only on the existing source branch, prior displayed source/legacy summary/doctor advice. Diagnostics/summary are opaque values, not complete lists or raw causes; upstream diagnostic clipping remains legacy/unproven. Full fields fit16KiB or have explicit omission/unavailability without repair. This does not alter admission, make failures effect-free/transactional, or authorize automatic correction, retry or invocation. Draft invalid-Recipe refusals now similarly show only the previously selected optional reason or joined diagnostics with draft/result. They add no path/body, source permission, raw cause or rollback guarantee; read/diagnose/admission behavior and legacy upstream limits remain. Whole values fit16KiB or show omission/unavailability without repair, and absent reason is not synthesized. Outer registration transaction failure now also separates old stage, resolution_generation, legacy summary and surfaced error as AX after the original cleanup path. That generation identifies resolution context, not fresh Run identity/epoch. Inner rollback/advice wording remains opaque error content, not proof of complete host rollback/removal or permission to repeat. Original cleanup/formatting faults and partial effects remain; no new cause/source access or transaction guarantee. Registry activation/promotion/deletion UI notices now use report/tool fields with only old selected display. A report is not callable or complete-host-removal proof; original hasUI/callback/post-effect failures remain. Whole well-formed notifier values are not subject to the model16KiB cap, malformed selected name is unavailable without repair, and RPC forwarding is not client handling/visibility proof. Recipe registry watcher warning/refresh reports use AX fields too; their old default-root wording is not a freshly verified actual path, and restart/actors_tool_register advice is only opaque instruction, never automatic action. Startup registry warnings use category sequences with whole opaque selected diagnostics; authored next/tool labels are content, malformed selected text unavailable and old doctor advice only opaque instruction. The reports do not establish callability, full upstream diagnostics or new source permission.
|
|
99
107
|
|
|
100
108
|
Compact Control receipts now use flat Markdown-list key/value records: run names have no duplicated namespace, action/result/delivery/handling remain distinct, and an optional next node names the inspect tool and its target/view. Multiline values retain their internal Markdown under an outer indentation; they are not extra status fields. This is a presentation of existing facts, not a raw dump or proof of completion. Delivery is not handling; a legacy kill attempt is not full termination. Changed-owner/generation refusals withhold replacement status even in verbose/detail output. Kernel delivery exceptions retain original/later causes and genuinely admitted correlation, but raw cause chains are not a new public message schema or proof that handling failed. Actor-local dispatch exceptions stay errors and report delivery/handling/effects uncertainty with a fresh-owned-inventory hint; they intentionally withhold saved correlation, including verbose, because an admission-era context does not prove current reply scope. Do not interpret this as a handling receipt or no-effect refusal. Do not repeat destructive actions to obtain verbose detail or follow a changed owner/generation blindly. See the Runs reference for this boundary.
|
|
101
109
|
|
|
@@ -108,7 +116,7 @@ Manual archive/prune exceptions can follow moved/copied/removed data. A single s
|
|
|
108
116
|
To make `music-player/playback` callable as `music_player` with a default source:
|
|
109
117
|
|
|
110
118
|
```text
|
|
111
|
-
|
|
119
|
+
actors_tool_register
|
|
112
120
|
name=music_player
|
|
113
121
|
from=music-player/playback
|
|
114
122
|
defaults={"source":"~/Music/1MIX"}
|
|
@@ -117,8 +125,8 @@ register_tool
|
|
|
117
125
|
Then:
|
|
118
126
|
|
|
119
127
|
1. Require registration to report successful resolution, validation, persistence, registry admission, host registration, activation, and `callable_now: true`.
|
|
120
|
-
2. Call the actual `music_player` tool. Do not call `
|
|
121
|
-
3. Verify agent-facing evidence reports `launch_kind: "tool"`; use `
|
|
128
|
+
2. Call the actual `music_player` tool. Do not call `actors_run_spawn` and describe that as tool invocation.
|
|
129
|
+
3. Verify agent-facing evidence reports `launch_kind: "tool"`; use `actors_inspect target=tool:music_player view=status` when usage or activation needs confirmation.
|
|
122
130
|
4. If callability is false, stop at the reported activation boundary. Preserve the logical source and diagnose it; do not substitute a Recipe spawn as proof.
|
|
123
131
|
|
|
124
132
|
Use direct delegation for the same maintained capability under a persistent name or narrower defaults. Use named imports only when one Recipe graph contains reusable child nodes. See [persistent tools](./references/persistent-tools.md) and [Recipes](./references/recipes.md).
|
|
@@ -136,7 +144,7 @@ Recipes remain with the Skill that owns their behavior. Load that Skill for sele
|
|
|
136
144
|
| `music-player` | The controlled `playback` singleton |
|
|
137
145
|
| `recipe-memory` | Internal automatic reviewers; use its Skill only for diagnosis/recovery |
|
|
138
146
|
|
|
139
|
-
Use the `actors/*` helpers only for their narrow requested result or intentional composition. Prefer public `
|
|
147
|
+
Use the `actors/*` helpers only for their narrow requested result or intentional composition. Prefer public `actors_inspect` for ordinary runtime diagnosis and the capability's primary workflow for a complete outcome.
|
|
140
148
|
|
|
141
149
|
## Delegation boundary
|
|
142
150
|
|
|
@@ -157,12 +165,12 @@ Run = Recipe + Trace + Control
|
|
|
157
165
|
2. Retain the returned `run:<id>` and normally wait for the root coordinator's completion batch instead of polling. While Pi is active, ready results arrive together at the next safe model-step boundary after the full tool batch; already-idle Pi wakes through a debounced follow-up. Nested actor completions wait for their complete containing top-level tree and arrive in that one compressed batch; descendant sessions do not need notification options.
|
|
158
166
|
3. Inspect `view=trace` when retained observations or attention matter.
|
|
159
167
|
4. Inspect `view=control` before diagnosing service readiness, stale work, or saturation.
|
|
160
|
-
5. Send `
|
|
168
|
+
5. Send `actors_control_apply` only for an action declared and consumed by that controlled Recipe.
|
|
161
169
|
6. Use terminal state, result, declared artifacts, and execution evidence to prove completion. When an outcome includes a retained primary-source, declaration-inventory or diagnostic-metadata reference, use that exact reference for further reading, not guessed captures or sibling files. Literal previews may be clipped; their field/range/counts describe what was shown. Diagnostic sources contain recorded command/error/failure-reason metadata only, not complete primary output; other recorded fields may be referenced without being shown. Artifact inventories list declarations only: they do not assert that target files exist or were produced, or grant body-read permission. Explicit unavailability has no guessed legacy body/path fallback.
|
|
162
170
|
|
|
163
171
|
Compact launch receipts include `run_files` as nested block YAML containing the exact selected observed location values, labeled observed locations/mutable for the exact launched Run generation when the current session and physical identity agree; otherwise they report unavailability or whole-row omission. Machine `file_navigation` details stay JSON-compatible; saved terminal messages retain their own original encodings. Selectively ordinary-read those starting locations when needed; layout/size hints are not body, privacy, terminal or native proof. No evidence bodies or session-wide catalog map are read to build this row. New terminal packets also freeze bounded location rows for captured completion members at fresh current-session admission. Fresh rooted completion headers group paths under literal roots with relative entries, English purposes and a read_first group/entry pointer; no cwd guess, source refresh or automatic read follows. Unknown bases stay explicit. Runtime navigation/omission/inventory facts remain above the Actor Markdown, not in a footer; retained packets keep their original projection. Each shown result keeps its whole Run-file row or explicit per-record omission; wholly omitted results stay covered by result omission/inventory. This describes Run-row coverage, not a complete file/tree inventory. Older captured formats retain their original shown/omitted/total counters; unavailability remains explicit. Ordinary-read selected paths only when needed. Packet reload/render never refreshes sources, and old absent/request-only formats keep their text. Source/npm SDK verifies an explicitly requested ordinary read from a delivered terminal result path; this is research, never routine completion polling or new primary/privacy/clock/native authority. Use the request only for file investigation, not routine completion/status polling. Copied locations/hints remain data, never transferred scope; older batches keep their original text.
|
|
164
172
|
|
|
165
|
-
For selective investigation of already cataloged files, use `
|
|
173
|
+
For selective investigation of already cataloged files, use `actors_inspect target=runtime view=runs verbose=true`, then ordinary file tools on its current-session root-first navigation. Ordinary maps keep latest-registration order between roots and prioritize known failed subtrees within each root. For a failed investigation add status=failed: inventory is filtered, while the full owned map prioritizes observed failed subtrees across roots, always ancestors first. Priority uses only exact-generation matched inventory observations, not complete terminal truth. Launches and compatible singleton attachments populate the catalog; reads do not backfill missing locations. A `catalog: unavailable` launch warning is not workload failure: do not spawn again merely to repair navigation. The starting map's format hints do not certify syntax, encoding or complete output. See [Runs](./references/runs.md) for selective recorded-capture research and resume boundaries.
|
|
166
174
|
|
|
167
175
|
Trusted parent-session shutdown keeps the existing Kill attempts for quit/reload/new/resume/fork; a Run is not promised to survive session replacement. This is logical-session ownership, not independent PID-bound ownership for parallel hosts with the same ID. A teardown report is not scope closure or crash/hung-host cleanup, and bare AgentSession.dispose alone emits no shutdown. See the Runs reference for the boundary.
|
|
168
176
|
|
|
@@ -179,7 +187,7 @@ When a pi-actors operation fails:
|
|
|
179
187
|
|
|
180
188
|
Stop if spawn and registry resolve the same Recipe differently. When tool exposure was requested, stop if registration persists but is not callable. A `retained_recipe` receipt with `activation: not_requested` instead permits ordinary Recipe reuse, not a claim of tool invocation. Stop if an operation cannot be proven through pi-actors surfaces.
|
|
181
189
|
|
|
182
|
-
Never recover by copying maintained Recipe args, defaults, Control, artifacts, or helper commands. Never hard-code a `{skill_dir}` replacement path. Never introduce `bash -lc`, `eval`, direct bundled-helper execution, or shell backgrounding to bypass resolution. Never call `
|
|
190
|
+
Never recover by copying maintained Recipe args, defaults, Control, artifacts, or helper commands. Never hard-code a `{skill_dir}` replacement path. Never introduce `bash -lc`, `eval`, direct bundled-helper execution, or shell backgrounding to bypass resolution. Never call `actors_run_spawn` and claim a tool call. Use [diagnostics](./references/diagnostics.md) for the safe next action.
|
|
183
191
|
|
|
184
192
|
## When to read another Skill
|
|
185
193
|
|