@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
package/dist/lib/runtime.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { existsSync, watch } from "node:fs";
|
|
7
7
|
import { basename, dirname } from "node:path";
|
|
8
|
+
import * as Identity from "./identity.js";
|
|
8
9
|
import * as Paths from "./paths.js";
|
|
9
10
|
import * as RecipesDiscovery from "./recipes-discovery.js";
|
|
10
11
|
import * as RecipesReferences from "./recipes-references.js";
|
|
@@ -15,6 +16,8 @@ export function createAutoToolsRuntime(deps) {
|
|
|
15
16
|
const tools = new Map();
|
|
16
17
|
const runtimeToolFingerprints = new Map();
|
|
17
18
|
const runtimeTools = new Set();
|
|
19
|
+
// Host declarations survive deactivation; retain their observed provenance separately.
|
|
20
|
+
const runtimeToolSources = new Map();
|
|
18
21
|
const recipeRoot = deps.recipeRoot ?? Paths.getRecipeRoot();
|
|
19
22
|
const status = {
|
|
20
23
|
active_tool_count: 0,
|
|
@@ -28,9 +31,13 @@ export function createAutoToolsRuntime(deps) {
|
|
|
28
31
|
ctx.ui.notify(message, type);
|
|
29
32
|
}
|
|
30
33
|
function getToolNameBlocker(name) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
:
|
|
34
|
+
const normalized = Identity.normalizeToolName(name);
|
|
35
|
+
if ([...deps.reservedToolNames].some((reserved) => Identity.normalizeToolName(reserved) === normalized))
|
|
36
|
+
return `Reserved tool name: ${name}`;
|
|
37
|
+
const foreign = deps.getAllTools?.().find((tool) => Identity.normalizeToolName(tool.name) === normalized &&
|
|
38
|
+
!(tool.name === name && runtimeToolSources.has(name) &&
|
|
39
|
+
tool.sourceInfo?.path === runtimeToolSources.get(name)));
|
|
40
|
+
return foreign ? `Host tool name collision: ${name} conflicts with ${foreign.name}` : undefined;
|
|
34
41
|
}
|
|
35
42
|
function getToolFingerprint(cfg) {
|
|
36
43
|
return JSON.stringify({
|
|
@@ -61,13 +68,15 @@ export function createAutoToolsRuntime(deps) {
|
|
|
61
68
|
const stale = [...runtimeTools].filter((name) => !activeNames.has(name));
|
|
62
69
|
if (stale.length === 0)
|
|
63
70
|
return;
|
|
71
|
+
const hostTools = deps.getAllTools?.();
|
|
72
|
+
const staleOwned = stale.filter((name) => !hostTools || hostTools.some((tool) => tool.name === name && tool.sourceInfo?.path === runtimeToolSources.get(name)));
|
|
64
73
|
for (const name of stale) {
|
|
65
74
|
runtimeTools.delete(name);
|
|
66
75
|
runtimeToolFingerprints.delete(name);
|
|
67
76
|
}
|
|
68
77
|
if (!deps.getActiveTools || !deps.setActiveTools)
|
|
69
78
|
return;
|
|
70
|
-
const staleSet = new Set(
|
|
79
|
+
const staleSet = new Set(staleOwned);
|
|
71
80
|
deps.setActiveTools(deps.getActiveTools().filter((name) => !staleSet.has(name)));
|
|
72
81
|
}
|
|
73
82
|
function activationFor(name) {
|
|
@@ -81,10 +90,14 @@ export function createAutoToolsRuntime(deps) {
|
|
|
81
90
|
};
|
|
82
91
|
}
|
|
83
92
|
function registerRuntimeTool(cfg) {
|
|
93
|
+
const blocker = getToolNameBlocker(cfg.name);
|
|
94
|
+
if (blocker)
|
|
95
|
+
throw new Error(blocker);
|
|
84
96
|
const fingerprint = getToolFingerprint(cfg);
|
|
85
97
|
if (runtimeToolFingerprints.get(cfg.name) !== fingerprint) {
|
|
86
98
|
deps.registerTool(ToolsLocal.createRuntimeToolDefinition(cfg, deps.exec));
|
|
87
99
|
runtimeTools.add(cfg.name);
|
|
100
|
+
runtimeToolSources.set(cfg.name, deps.getAllTools?.().find((tool) => tool.name === cfg.name)?.sourceInfo?.path);
|
|
88
101
|
runtimeToolFingerprints.set(cfg.name, fingerprint);
|
|
89
102
|
}
|
|
90
103
|
if (deps.getActiveTools && deps.setActiveTools) {
|
|
@@ -129,7 +142,7 @@ export function createAutoToolsRuntime(deps) {
|
|
|
129
142
|
lines.push(...other.map((warning) => `• ${warning}`));
|
|
130
143
|
groups[groups.length] = ["other_diagnostics", start, lines.length];
|
|
131
144
|
}
|
|
132
|
-
lines.push("Next:
|
|
145
|
+
lines.push("Next: actors_inspect target=recipes view=doctor");
|
|
133
146
|
// Preserve the original layout join/coercion and its faults before projecting owned warning slots.
|
|
134
147
|
void `${lines.join("\n")}\n`;
|
|
135
148
|
let text = ToolsResponse.formatMarkdownField("report", "pi-actors recipe registry warning");
|
|
@@ -141,7 +154,7 @@ export function createAutoToolsRuntime(deps) {
|
|
|
141
154
|
: " - warning:\n - result: unavailable\n - reason: malformed_selected_text");
|
|
142
155
|
}
|
|
143
156
|
}
|
|
144
|
-
return text + "\n" + ToolsResponse.formatMarkdownField("instruction", "Next:
|
|
157
|
+
return text + "\n" + ToolsResponse.formatMarkdownField("instruction", "Next: actors_inspect target=recipes view=doctor") + "\n";
|
|
145
158
|
}
|
|
146
159
|
function loadTools(ctx, resolutionContext) {
|
|
147
160
|
const warnings = [];
|
|
@@ -170,6 +183,7 @@ export function createAutoToolsRuntime(deps) {
|
|
|
170
183
|
const blocker = getToolNameBlocker(cfg.name);
|
|
171
184
|
if (blocker) {
|
|
172
185
|
warnings.push(blocker);
|
|
186
|
+
tools.delete(cfg.name);
|
|
173
187
|
continue;
|
|
174
188
|
}
|
|
175
189
|
registerRuntimeTool(cfg);
|
|
@@ -195,7 +209,7 @@ export function createAutoToolsRuntime(deps) {
|
|
|
195
209
|
}),
|
|
196
210
|
getToolStatus: (name) => {
|
|
197
211
|
const cfg = tools.get(name);
|
|
198
|
-
if (!cfg)
|
|
212
|
+
if (!cfg || getToolNameBlocker(name))
|
|
199
213
|
return undefined;
|
|
200
214
|
const usage = cfg.sourcePath
|
|
201
215
|
? RecipesUsage.readRecipeUsage(cfg.sourcePath)
|
|
@@ -217,8 +231,8 @@ export function createAutoToolsRuntime(deps) {
|
|
|
217
231
|
next_actions: activation.callable_now
|
|
218
232
|
? [`call tool ${name}`]
|
|
219
233
|
: [
|
|
220
|
-
`
|
|
221
|
-
`
|
|
234
|
+
`actors_tool_register name=${name} update=true`,
|
|
235
|
+
`actors_inspect target=tool:${name} view=status`,
|
|
222
236
|
],
|
|
223
237
|
...(usage?.launch_kind ? { launch_kind: usage.launch_kind } : {}),
|
|
224
238
|
spawn_calls: Number(usage?.spawn_calls ?? 0),
|
|
@@ -271,7 +285,7 @@ export function createRecipeToolReloadWatcher(runtime, deps = {}) {
|
|
|
271
285
|
failureNotified = true;
|
|
272
286
|
setWatchStatus("failed");
|
|
273
287
|
try {
|
|
274
|
-
ctx.ui.notify("- report: Recipe live reload watcher failed\n- instruction: restart the session or use
|
|
288
|
+
ctx.ui.notify("- report: Recipe live reload watcher failed\n- instruction: restart the session or use actors_tool_register again to refresh recipe tools.", "warning");
|
|
275
289
|
}
|
|
276
290
|
catch (error) {
|
|
277
291
|
reportCallbackError(error);
|
|
@@ -264,7 +264,7 @@ export function applyApprovedToolReviewAtSessionBoundary(options = {}) {
|
|
|
264
264
|
...state,
|
|
265
265
|
failedStage: "approval_state",
|
|
266
266
|
lastError: "approved review path is unavailable",
|
|
267
|
-
nextAction: "
|
|
267
|
+
nextAction: "actors_control_apply target=runtime action=review.retry input={\"scope\":\"tool\"}",
|
|
268
268
|
phase: "processing_failed",
|
|
269
269
|
updatedAt: (options.now ?? (() => new Date()))().toISOString(),
|
|
270
270
|
};
|
|
@@ -287,7 +287,7 @@ export function applyApprovedToolReviewAtSessionBoundary(options = {}) {
|
|
|
287
287
|
...state,
|
|
288
288
|
failedStage: "transaction",
|
|
289
289
|
lastError: `tool review transaction remained ${transaction.phase}`,
|
|
290
|
-
nextAction: "
|
|
290
|
+
nextAction: "actors_control_apply target=runtime action=review.retry input={\"scope\":\"tool\"}",
|
|
291
291
|
phase: "processing_failed",
|
|
292
292
|
updatedAt: (options.now ?? (() => new Date()))().toISOString(),
|
|
293
293
|
};
|
|
@@ -316,7 +316,7 @@ export function applyApprovedToolReviewAtSessionBoundary(options = {}) {
|
|
|
316
316
|
...pending,
|
|
317
317
|
failedStage: "lineage",
|
|
318
318
|
lastError: error instanceof Error ? error.message : String(error),
|
|
319
|
-
nextAction: "
|
|
319
|
+
nextAction: "actors_control_apply target=runtime action=review.retry input={\"scope\":\"tool\"}",
|
|
320
320
|
};
|
|
321
321
|
writeJsonAtomic(statePath, failedPending);
|
|
322
322
|
return { outcome: "lineage_pending", state: failedPending };
|
|
@@ -337,7 +337,7 @@ export function applyApprovedToolReviewAtSessionBoundary(options = {}) {
|
|
|
337
337
|
...state,
|
|
338
338
|
failedStage: "transaction",
|
|
339
339
|
lastError: error instanceof Error ? error.message : String(error),
|
|
340
|
-
nextAction: "
|
|
340
|
+
nextAction: "actors_control_apply target=runtime action=review.retry input={\"scope\":\"tool\"}",
|
|
341
341
|
phase: "processing_failed",
|
|
342
342
|
updatedAt: (options.now ?? (() => new Date()))().toISOString(),
|
|
343
343
|
};
|
|
@@ -401,7 +401,7 @@ export function createToolReviewScheduler(deps) {
|
|
|
401
401
|
...existing,
|
|
402
402
|
failedStage: processed.stage ?? "review_result",
|
|
403
403
|
lastError: processed.error ?? "automatic tool reviewer failed",
|
|
404
|
-
nextAction: "
|
|
404
|
+
nextAction: "actors_control_apply target=runtime action=review.retry input={\"scope\":\"tool\"}",
|
|
405
405
|
phase: processed.outcome === "processing_failed"
|
|
406
406
|
? "processing_failed"
|
|
407
407
|
: "failed",
|
|
@@ -437,7 +437,7 @@ export function createToolReviewScheduler(deps) {
|
|
|
437
437
|
attempts: existing.attempts + 1,
|
|
438
438
|
failedStage: "review_launch",
|
|
439
439
|
lastError: error instanceof Error ? error.message : String(error),
|
|
440
|
-
nextAction: "
|
|
440
|
+
nextAction: "actors_control_apply target=runtime action=review.retry input={\"scope\":\"tool\"}",
|
|
441
441
|
phase: "failed",
|
|
442
442
|
updatedAt: now().toISOString(),
|
|
443
443
|
});
|
|
@@ -471,7 +471,7 @@ export function createToolReviewScheduler(deps) {
|
|
|
471
471
|
failedStage: "review_launch",
|
|
472
472
|
inputPath: batch.inputPath,
|
|
473
473
|
lastError: error instanceof Error ? error.message : String(error),
|
|
474
|
-
nextAction: "
|
|
474
|
+
nextAction: "actors_control_apply target=runtime action=review.retry input={\"scope\":\"tool\"}",
|
|
475
475
|
phase: "failed",
|
|
476
476
|
reviewerInputPath: batch.reviewerInputPath,
|
|
477
477
|
reviewId: batch.reviewId,
|
package/dist/lib/tools-access.js
CHANGED
|
@@ -33,7 +33,7 @@ export function sessionMismatchError(input) {
|
|
|
33
33
|
const actor = input.run ? `run:${input.run}` : (input.target ?? "session");
|
|
34
34
|
return Object.assign(new Error(`${actor} reason=session_mismatch owner_session=${ownerSession} current_session=${currentSession} hint=inspect_runtime_runs`), {
|
|
35
35
|
current_session: input.currentSession,
|
|
36
|
-
hint: "
|
|
36
|
+
hint: "actors_inspect target=runtime view=runs",
|
|
37
37
|
owner_session: input.expectedSession,
|
|
38
38
|
reason: "session_mismatch",
|
|
39
39
|
run: input.run,
|
|
@@ -145,10 +145,10 @@ function runtimeTriage(ctx, deps) {
|
|
|
145
145
|
trace_diagnostic_count: traceDiagnostics.length, trace_diagnostics: traceDiagnostics.slice(0, 40),
|
|
146
146
|
attention_events: attentionEvents.slice(-40).reverse(),
|
|
147
147
|
next_actions: [
|
|
148
|
-
...(failed.length ? ["
|
|
149
|
-
...new Set([...staleControls, ...backpressuredRuns].slice(0, 3).map((entry) => `
|
|
148
|
+
...(failed.length ? ["actors_inspect target=runtime view=runs status=failed"] : []),
|
|
149
|
+
...new Set([...staleControls, ...backpressuredRuns].slice(0, 3).map((entry) => `actors_inspect target=run:${entry.run} view=control`)),
|
|
150
150
|
...(attentionEvents.length
|
|
151
|
-
? attentionEvents.slice(-3).map((entry) => `
|
|
151
|
+
? attentionEvents.slice(-3).map((entry) => `actors_inspect target=run:${String(entry.run)} view=trace source=runtime`)
|
|
152
152
|
: []),
|
|
153
153
|
],
|
|
154
154
|
};
|
|
@@ -209,7 +209,7 @@ function formatInspectFailure(fields, next) {
|
|
|
209
209
|
return { omittable, full, selected };
|
|
210
210
|
});
|
|
211
211
|
// Only producer-known read-only inspect literals become a typed next, never a parsed action.
|
|
212
|
-
const typedNext = next ? { next: { tool: "
|
|
212
|
+
const typedNext = next ? { next: { tool: "actors_inspect", target: next[0], view: next[1] } } : undefined;
|
|
213
213
|
const nextFallback = { next_action: omitted };
|
|
214
214
|
const document = () => ({ ...Object.assign({}, ...parts.map((part) => part.selected)),
|
|
215
215
|
...(typedNext ?? nextFallback) });
|
|
@@ -336,15 +336,15 @@ function inspectRecipeIdentity(identity, resolutionContext, namespaces, inventor
|
|
|
336
336
|
...(rejectedReason ? { rejected_reason: rejectedReason } : {}),
|
|
337
337
|
next_actions: resolvable
|
|
338
338
|
? [
|
|
339
|
-
`
|
|
340
|
-
`
|
|
339
|
+
`actors_run_spawn recipe=${identity}`,
|
|
340
|
+
`actors_tool_register name=<tool-name> from=${identity}`,
|
|
341
341
|
]
|
|
342
342
|
: roots.length === 0 && skill
|
|
343
343
|
? [
|
|
344
344
|
`activate Skill ${skill}`,
|
|
345
|
-
`
|
|
345
|
+
`actors_inspect target=recipes view=doctor identity=${identity}`,
|
|
346
346
|
]
|
|
347
|
-
: ["
|
|
347
|
+
: ["actors_inspect target=recipes view=imports verbose=true"],
|
|
348
348
|
};
|
|
349
349
|
}
|
|
350
350
|
function inspectRecipes(requestedView, input, deps, context) {
|
|
@@ -583,7 +583,7 @@ function compactResult(target, view, details) {
|
|
|
583
583
|
? String(details.next_actions[0])
|
|
584
584
|
: details.callable_now === true
|
|
585
585
|
? `call tool ${name}`
|
|
586
|
-
: `
|
|
586
|
+
: `actors_tool_register name=${name} update=true`;
|
|
587
587
|
const hint = ToolsResponse.nextActionMetadata(next, Limits.RUN_DELIVERY_MODEL_MAX_BYTES);
|
|
588
588
|
const required = compactArguments("required_args", details.required_args);
|
|
589
589
|
const optional = compactArguments("optional_args", details.optional_args);
|
|
@@ -601,7 +601,7 @@ function compactResult(target, view, details) {
|
|
|
601
601
|
}
|
|
602
602
|
export function createInspectToolDefinition(deps = {}) {
|
|
603
603
|
return {
|
|
604
|
-
name: "
|
|
604
|
+
name: "actors_inspect",
|
|
605
605
|
label: "Inspect",
|
|
606
606
|
description: "Inspect a Run's Recipe, Trace, or Control evidence, or runtime/recipe/tool diagnostics.",
|
|
607
607
|
parameters: Schema.objectSchema({
|
|
@@ -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
|
*/
|
|
@@ -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
|
*/
|
|
@@ -40,9 +40,9 @@ function controlDocument(render, order) {
|
|
|
40
40
|
}
|
|
41
41
|
/** Only producer-known read-only inspect literals become typed next; other advice stays opaque content. */
|
|
42
42
|
function controlNextPart(action) {
|
|
43
|
-
const inspect = /^
|
|
43
|
+
const inspect = /^actors_inspect target=([^\s]+) view=([^\s]+)$/u.exec(action);
|
|
44
44
|
if (inspect) {
|
|
45
|
-
return ToolsResponse.selectYamlNode("next", { tool: "
|
|
45
|
+
return ToolsResponse.selectYamlNode("next", { tool: "actors_inspect", target: inspect[1], view: inspect[2] }, CONTROL_BUDGET);
|
|
46
46
|
}
|
|
47
47
|
const wellFormed = action.isWellFormed();
|
|
48
48
|
const omitted = { next: { instruction: wellFormed ? "[omitted]" : "[unavailable]",
|
|
@@ -107,24 +107,24 @@ export function compactControlResult(request, result) {
|
|
|
107
107
|
}
|
|
108
108
|
function runNextActions(run, result) {
|
|
109
109
|
if (result.stopped === true)
|
|
110
|
-
return [`
|
|
110
|
+
return [`actors_inspect target=run:${run} view=trace`];
|
|
111
111
|
if (result.stopped === false || result.archived === false || result.pruned === false) {
|
|
112
112
|
if (result.reason === "ownership changed" || result.reason === "run generation changed") {
|
|
113
|
-
return ["
|
|
113
|
+
return ["actors_inspect target=runtime view=runs"];
|
|
114
114
|
}
|
|
115
115
|
if (result.stopped === false && result.reason !== "not running")
|
|
116
|
-
return [`
|
|
116
|
+
return [`actors_inspect target=run:${run} view=trace`];
|
|
117
117
|
}
|
|
118
118
|
if (result.delivery === "queued" || result.delivery === "delivered") {
|
|
119
|
-
return [`
|
|
119
|
+
return [`actors_inspect target=run:${run} view=control`];
|
|
120
120
|
}
|
|
121
121
|
return [];
|
|
122
122
|
}
|
|
123
123
|
export function createControlToolDefinition(deps = {}) {
|
|
124
124
|
return {
|
|
125
|
-
name: "
|
|
125
|
+
name: "actors_control_apply",
|
|
126
126
|
label: "Control",
|
|
127
|
-
description: "Apply one Control action
|
|
127
|
+
description: "Apply one Run/runtime Control action. This is not chat or peer messaging.",
|
|
128
128
|
parameters: Schema.objectSchema({
|
|
129
129
|
target: Schema.stringSchema("Run target run:<id>, or literal runtime."),
|
|
130
130
|
action: Schema.stringSchema("Lowercase ASCII Control action, at most 64 characters."),
|
|
@@ -214,7 +214,7 @@ export function createControlToolDefinition(deps = {}) {
|
|
|
214
214
|
// Admission-era correlation is not current reply-scope proof after an awaited dispatch.
|
|
215
215
|
// Display one whole caller-owned id or an explicit whole-id omission; the warning stays literal.
|
|
216
216
|
const identity = controlSelected("run", run);
|
|
217
|
-
const next = controlNextPart("
|
|
217
|
+
const next = controlNextPart("actors_inspect target=runtime view=runs");
|
|
218
218
|
const render = () => ({ ...identity.selected, action: request.action,
|
|
219
219
|
result: "request failed", delivery: "unconfirmed", handling: "unconfirmed",
|
|
220
220
|
warning: "Effects may already exist.\nDo not repeat automatically.", ...next.selected });
|
|
@@ -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
|
import * as Registry from "./registry.ts";
|
|
7
7
|
import * as Schema from "./schema.ts";
|
|
@@ -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
|
import * as Prompts from "./prompts.js";
|
|
7
7
|
import * as Registry from "./registry.js";
|
|
@@ -15,7 +15,7 @@ const objectSchema = Schema.objectSchema;
|
|
|
15
15
|
const looseObjectSchema = Schema.looseObjectSchema;
|
|
16
16
|
export function createRegisterToolDefinition(deps) {
|
|
17
17
|
return {
|
|
18
|
-
name: "
|
|
18
|
+
name: "actors_tool_register",
|
|
19
19
|
label: "Register Tool",
|
|
20
20
|
description: Prompts.REGISTER_TOOL_DESCRIPTION,
|
|
21
21
|
promptSnippet: Prompts.REGISTER_TOOL_PROMPT_SNIPPET,
|
|
@@ -28,7 +28,7 @@ export declare function formatYamlNotice(value: Record<string, string | number |
|
|
|
28
28
|
/** Close one rendered YAML header; a separate opaque body gets exactly one delimiter pair. */
|
|
29
29
|
export declare function frameMetadataDocument(header: string, body?: string): string;
|
|
30
30
|
export declare function formatMarkdownField(key: string, value: string, depth?: number): string;
|
|
31
|
-
export declare function formatInspectNextAction(target: string, view: string, verbose?: boolean): string;
|
|
31
|
+
export declare function formatInspectNextAction(target: string, view: string, verbose?: boolean, tool?: string): string;
|
|
32
32
|
export declare function formatLiteralBlock(value: string): string;
|
|
33
33
|
export type RunSnapshotRendering = {
|
|
34
34
|
readonly state: "available";
|
|
@@ -163,8 +163,8 @@ export function formatMarkdownField(key, value, depth = 0) {
|
|
|
163
163
|
? `${indent}- ${key}:\n${indent} ${value.replaceAll(/\r\n|\r|\n/gu, newline => `${newline}${indent} `)}`
|
|
164
164
|
: `${indent}- ${key}: ${value}`;
|
|
165
165
|
}
|
|
166
|
-
export function formatInspectNextAction(target, view, verbose) {
|
|
167
|
-
return ["- next:", formatMarkdownField("tool",
|
|
166
|
+
export function formatInspectNextAction(target, view, verbose, tool = "inspect") {
|
|
167
|
+
return ["- next:", formatMarkdownField("tool", tool, 1), formatMarkdownField("target", target, 1),
|
|
168
168
|
formatMarkdownField("view", view, 1), ...(verbose === undefined ? [] : [formatMarkdownField("verbose", String(verbose), 1)])].join("\n");
|
|
169
169
|
}
|
|
170
170
|
export function formatLiteralBlock(value) {
|
|
@@ -292,19 +292,19 @@ function launchModelPolicy(value) {
|
|
|
292
292
|
}
|
|
293
293
|
return fields;
|
|
294
294
|
}
|
|
295
|
-
const RUN_FILE_INVESTIGATION_COMMAND = "
|
|
295
|
+
const RUN_FILE_INVESTIGATION_COMMAND = "actors_inspect target=runtime view=runs verbose=true";
|
|
296
296
|
/** Frozen older completion-format text: new launch layout must not change this shared packet helper. */
|
|
297
297
|
export function formatRunFileNavigationHandoff() {
|
|
298
|
-
return
|
|
298
|
+
return "Files (optional; current session):\n`inspect target=runtime view=runs verbose=true`";
|
|
299
299
|
}
|
|
300
300
|
export function runNextActions(run) {
|
|
301
301
|
const id = String(run ?? "").trim();
|
|
302
302
|
if (!id)
|
|
303
303
|
return [];
|
|
304
304
|
return [
|
|
305
|
-
`
|
|
306
|
-
`
|
|
307
|
-
`
|
|
305
|
+
`actors_inspect target=run:${id} view=recipe`,
|
|
306
|
+
`actors_inspect target=run:${id} view=trace`,
|
|
307
|
+
`actors_inspect target=run:${id} view=control`,
|
|
308
308
|
RUN_FILE_INVESTIGATION_COMMAND,
|
|
309
309
|
];
|
|
310
310
|
}
|
|
@@ -342,7 +342,7 @@ export function compactAsyncRunStatus(value) {
|
|
|
342
342
|
fields.killed = true;
|
|
343
343
|
if (status.draft_recipe)
|
|
344
344
|
fields.draft_recipe = String(status.draft_recipe);
|
|
345
|
-
const hint = { file_investigation: "optional; current session", next: { tool: "
|
|
345
|
+
const hint = { file_investigation: "optional; current session", next: { tool: "actors_inspect", target: "runtime", view: "runs", verbose: true } };
|
|
346
346
|
const hasNavigation = Object.hasOwn(status, "file_navigation");
|
|
347
347
|
let navigation;
|
|
348
348
|
if (hasNavigation) {
|
|
@@ -504,23 +504,23 @@ export function recipeRegistryNextActions(summary, view) {
|
|
|
504
504
|
: 0;
|
|
505
505
|
const topAction = asRecord(summary.top_action);
|
|
506
506
|
if (view !== "doctor" && (invalid > 0 || diagnostics > 0)) {
|
|
507
|
-
actions.push("
|
|
507
|
+
actions.push("actors_inspect target=recipes view=doctor");
|
|
508
508
|
}
|
|
509
509
|
if (view === "doctor" && typeof topAction.action === "string") {
|
|
510
510
|
actions.push(String(topAction.action));
|
|
511
511
|
}
|
|
512
512
|
if (summary.skill_recipe_catalog_partial === true) {
|
|
513
|
-
actions.push("
|
|
513
|
+
actions.push("actors_inspect target=recipes view=imports verbose=true");
|
|
514
514
|
}
|
|
515
515
|
if ((Array.isArray(summary.retained) && summary.retained.length > 0) ||
|
|
516
516
|
(Array.isArray(summary.retained_diagnostics) && summary.retained_diagnostics.length > 0)) {
|
|
517
|
-
actions.push("
|
|
517
|
+
actions.push("actors_inspect target=recipes view=summary verbose=true");
|
|
518
518
|
}
|
|
519
519
|
if (drafts.length > 0) {
|
|
520
|
-
actions.push("
|
|
520
|
+
actions.push("actors_inspect target=recipes view=summary verbose=true");
|
|
521
521
|
const firstPath = typeof drafts[0]?.path === "string" ? drafts[0].path : undefined;
|
|
522
522
|
if (firstPath)
|
|
523
|
-
actions.push(`
|
|
523
|
+
actions.push(`actors_run_spawn file=${firstPath}`);
|
|
524
524
|
}
|
|
525
525
|
return [...new Set(actions)].slice(0, 4);
|
|
526
526
|
}
|
|
@@ -530,11 +530,11 @@ export function compactYamlDocument(value) {
|
|
|
530
530
|
return `\n${text.replace(/\n$/u, "")}`;
|
|
531
531
|
}
|
|
532
532
|
function recipeInspectionHint(action) {
|
|
533
|
-
if (action === "
|
|
533
|
+
if (action === "actors_inspect target=recipes view=doctor")
|
|
534
534
|
return { view: "doctor" };
|
|
535
|
-
if (action === "
|
|
535
|
+
if (action === "actors_inspect target=recipes view=imports verbose=true")
|
|
536
536
|
return { view: "imports", verbose: true };
|
|
537
|
-
if (action === "
|
|
537
|
+
if (action === "actors_inspect target=recipes view=summary verbose=true")
|
|
538
538
|
return { view: "summary", verbose: true };
|
|
539
539
|
return undefined;
|
|
540
540
|
}
|
|
@@ -542,7 +542,7 @@ function recipeInspectionHint(action) {
|
|
|
542
542
|
export function nextActionMetadata(action, byteBudget) {
|
|
543
543
|
const hint = recipeInspectionHint(action);
|
|
544
544
|
if (hint) {
|
|
545
|
-
const typed = { next: { tool: "
|
|
545
|
+
const typed = { next: { tool: "actors_inspect", target: "recipes", ...hint } };
|
|
546
546
|
return { full: typed, selected: typed };
|
|
547
547
|
}
|
|
548
548
|
const instruction = selectYamlField("instruction", action, byteBudget);
|
|
@@ -551,7 +551,7 @@ export function nextActionMetadata(action, byteBudget) {
|
|
|
551
551
|
/** Only these existing read-only inspection hints become action nodes; other advice stays content. */
|
|
552
552
|
export function formatInspectionHint(action) {
|
|
553
553
|
const hint = recipeInspectionHint(action);
|
|
554
|
-
return hint ? formatInspectNextAction("recipes", hint.view, hint.verbose) : formatMarkdownField("instruction", action);
|
|
554
|
+
return hint ? formatInspectNextAction("recipes", hint.view, hint.verbose, "actors_inspect") : formatMarkdownField("instruction", action);
|
|
555
555
|
}
|
|
556
556
|
export function compactRecipeRegistry(summary) {
|
|
557
557
|
const count = (key, source) => Array.isArray(source) ? source.length : 0;
|
package/dist/lib/tools-spawn.js
CHANGED
|
@@ -90,7 +90,7 @@ function runIdFromTarget(target) {
|
|
|
90
90
|
}
|
|
91
91
|
export function createSpawnToolDefinition() {
|
|
92
92
|
return {
|
|
93
|
-
name: "
|
|
93
|
+
name: "actors_run_spawn",
|
|
94
94
|
label: "Spawn",
|
|
95
95
|
description: "Create one controllable Run from a Recipe file or inline command template.",
|
|
96
96
|
parameters: Schema.objectSchema({
|
package/dist/lib/tools.d.ts
CHANGED
|
@@ -25,4 +25,11 @@ export interface CoreActorToolDefinitionDeps<TContext extends RuntimeToolContext
|
|
|
25
25
|
}
|
|
26
26
|
export declare function resolveActiveRuntimeTool(name: string, activeTools: Pick<Map<string, unknown>, "has">, getDefinition: (name: string) => unknown): unknown;
|
|
27
27
|
export declare const RESERVED_TOOL_NAMES: Set<string>;
|
|
28
|
+
export declare const LEGACY_TOOL_NAMES: {
|
|
29
|
+
readonly register_tool: "actors_tool_register";
|
|
30
|
+
readonly spawn: "actors_run_spawn";
|
|
31
|
+
readonly message: "actors_control_apply";
|
|
32
|
+
readonly inspect: "actors_inspect";
|
|
33
|
+
};
|
|
34
|
+
export declare function createLegacyActorToolDefinitions(definitions: ActorToolDefinition[]): ActorToolDefinition[];
|
|
28
35
|
export declare function createCoreActorToolDefinitions<TContext extends RuntimeToolContext>(deps: CoreActorToolDefinitionDeps<TContext>): ActorToolDefinition[];
|
package/dist/lib/tools.js
CHANGED
|
@@ -18,11 +18,36 @@ export const RESERVED_TOOL_NAMES = new Set([
|
|
|
18
18
|
"find",
|
|
19
19
|
"grep",
|
|
20
20
|
"ls",
|
|
21
|
+
"actors_tool_register",
|
|
22
|
+
"actors_run_spawn",
|
|
23
|
+
"actors_control_apply",
|
|
24
|
+
"actors_inspect",
|
|
21
25
|
"register_tool",
|
|
22
26
|
"message",
|
|
23
27
|
"spawn",
|
|
24
28
|
"inspect",
|
|
25
29
|
]);
|
|
30
|
+
// Compatibility dispatch is registered but omitted from model declarations and normal
|
|
31
|
+
// callable listings. Active legacy names still execute saved native tool calls.
|
|
32
|
+
export const LEGACY_TOOL_NAMES = {
|
|
33
|
+
register_tool: "actors_tool_register",
|
|
34
|
+
spawn: "actors_run_spawn",
|
|
35
|
+
message: "actors_control_apply",
|
|
36
|
+
inspect: "actors_inspect",
|
|
37
|
+
};
|
|
38
|
+
export function createLegacyActorToolDefinitions(definitions) {
|
|
39
|
+
return Object.entries(LEGACY_TOOL_NAMES).map(([name, canonical]) => {
|
|
40
|
+
const definition = definitions.find((tool) => tool.name === canonical);
|
|
41
|
+
if (!definition)
|
|
42
|
+
throw new Error(`Missing canonical actor tool: ${canonical}`);
|
|
43
|
+
return {
|
|
44
|
+
...definition, name, exposure: "deferred",
|
|
45
|
+
description: `Compatibility dispatch for ${canonical}; use the canonical tool for new calls.`,
|
|
46
|
+
promptSnippet: undefined, promptGuidelines: undefined,
|
|
47
|
+
prepareLoadout: () => ({ hiddenDeclarations: Object.keys(LEGACY_TOOL_NAMES) }),
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
}
|
|
26
51
|
export function createCoreActorToolDefinitions(deps) {
|
|
27
52
|
return [
|
|
28
53
|
ToolsRegister.createRegisterToolDefinition({
|