@llblab/pi-actors 0.58.0 → 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 +5 -5
- package/BACKLOG.md +1 -1
- package/CHANGELOG.md +12 -1
- package/README.md +37 -35
- package/dist/lib/draft-sleep.js +3 -3
- package/dist/lib/extension-runtime.js +7 -2
- package/dist/lib/pi.js +1 -1
- 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-delivery.d.ts +1 -1
- package/dist/lib/run-delivery.js +19 -9
- 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 +27 -28
- 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 +29 -21
- 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 +8 -8
- 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/agent-experience.md +5 -6
- package/docs/async-runs.md +13 -13
- package/docs/capability-memory.md +11 -56
- package/docs/coordinator-delivery.md +2 -2
- package/docs/inspection.md +21 -21
- package/docs/output-projection-map.md +1 -1
- package/docs/releasing.md +1 -1
- package/docs/run-supervision.md +21 -21
- package/docs/tool-registry.md +46 -21
- package/docs/windows-process-observation.md +1 -1
- package/lib/draft-sleep.ts +3 -3
- package/lib/extension-runtime.ts +7 -5
- package/lib/pi.ts +1 -1
- 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-delivery.ts +22 -11
- 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 +25 -25
- package/lib/tools-spawn.ts +1 -1
- package/lib/tools.ts +28 -0
- package/package.json +1 -1
- package/skills/actors/SKILL.md +29 -21
- 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 +8 -8
- 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/lib/run-delivery.ts
CHANGED
|
@@ -69,7 +69,7 @@ export interface RunCompletionBatch {
|
|
|
69
69
|
/** Retained singleton capture; absence preserves older indexed bytes. Never a new-capture selector. */
|
|
70
70
|
readonly single_result?: true;
|
|
71
71
|
/** Captured record-list shape; no public format/version choice or source authority. */
|
|
72
|
-
readonly result_layout?: "records" | "run_headers" | "headings" | "headings_flat_omissions" | "headings_outcomes" | "headings_shared_results" | "headings_shared_kinds" | "frontmatter_v1" | "frontmatter_v2" | "completion_yaml_core_v1" | "completion_yaml_files_v1";
|
|
72
|
+
readonly result_layout?: "records" | "run_headers" | "headings" | "headings_flat_omissions" | "headings_outcomes" | "headings_shared_results" | "headings_shared_kinds" | "frontmatter_v1" | "frontmatter_v2" | "completion_yaml_core_v1" | "completion_yaml_files_v1" | "completion_yaml_files_v2";
|
|
73
73
|
/** Immutable scope/order/range data, not a caller-selected format or allocation authority. */
|
|
74
74
|
readonly numbering?: RunCompletionNumbering;
|
|
75
75
|
/** Formatting version/data only; no recipient ownership, read or publication capability. */
|
|
@@ -467,8 +467,12 @@ function isFrontmatterCompletionLayout(layout: unknown): boolean {
|
|
|
467
467
|
return layout === "frontmatter_v1" || layout === "frontmatter_v2";
|
|
468
468
|
}
|
|
469
469
|
|
|
470
|
+
function isRootedCompletionLayout(layout: unknown): boolean {
|
|
471
|
+
return layout === "completion_yaml_files_v1" || layout === "completion_yaml_files_v2";
|
|
472
|
+
}
|
|
473
|
+
|
|
470
474
|
function isYamlCompletionLayout(layout: unknown): boolean {
|
|
471
|
-
return layout === "completion_yaml_core_v1" || layout
|
|
475
|
+
return layout === "completion_yaml_core_v1" || isRootedCompletionLayout(layout);
|
|
472
476
|
}
|
|
473
477
|
|
|
474
478
|
function isSharedCompletionLayout(layout: unknown): boolean {
|
|
@@ -895,7 +899,7 @@ export function requestRunCompletionStream(input: { tempDir: string; ownerId: st
|
|
|
895
899
|
}
|
|
896
900
|
|
|
897
901
|
export function admitRunCompletionBatch(input: AdmitRunCompletionBatchInput): RunCompletionBatch {
|
|
898
|
-
return captureCompletionBatch(input, false, "
|
|
902
|
+
return captureCompletionBatch(input, false, "completion_yaml_files_v2");
|
|
899
903
|
}
|
|
900
904
|
|
|
901
905
|
/** Kernel-only opt-in; ordinary Pi capture stays fenced until session/lifecycle integration is admitted. */
|
|
@@ -905,10 +909,10 @@ export function captureRunCompletionStreamBatch(input: AdmitRunCompletionBatchIn
|
|
|
905
909
|
|
|
906
910
|
/** Private ordinary candidate composition; stream capture retains its separately gated codec. */
|
|
907
911
|
export function captureRunCompletionYamlCandidateBatch(input: AdmitRunCompletionBatchInput): RunCompletionBatch {
|
|
908
|
-
return captureCompletionBatch(input, false, "
|
|
912
|
+
return captureCompletionBatch(input, false, "completion_yaml_files_v2");
|
|
909
913
|
}
|
|
910
914
|
|
|
911
|
-
function captureCompletionBatch(input: AdmitRunCompletionBatchInput, numbered: boolean, layout: "frontmatter_v2" | "completion_yaml_core_v1" | "completion_yaml_files_v1" = "frontmatter_v2"): RunCompletionBatch {
|
|
915
|
+
function captureCompletionBatch(input: AdmitRunCompletionBatchInput, numbered: boolean, layout: "frontmatter_v2" | "completion_yaml_core_v1" | "completion_yaml_files_v1" | "completion_yaml_files_v2" = "frontmatter_v2"): RunCompletionBatch {
|
|
912
916
|
const now = (input.now ?? new Date()).toISOString();
|
|
913
917
|
if (Object.hasOwn(input, "presentationFormat")) throw new Error("Completion presentation selection is not supported; new batches use AX.");
|
|
914
918
|
if (Object.hasOwn(input, "numbering")) throw new Error("Completion numbering is assigned only by journal capture");
|
|
@@ -1869,12 +1873,13 @@ type PreparedCompletionYamlProjection =
|
|
|
1869
1873
|
function prepareCompletionYamlProjection(safe: RunCompletionBatch, candidates: readonly { row: CompletionRow; location?: CompletionPiece }[],
|
|
1870
1874
|
references: ReadonlySet<number>, ordered: readonly RunCompletionBatchMember[]): PreparedCompletionYamlProjection {
|
|
1871
1875
|
const packet: CompletionYamlPacket = { batchId: safe.batch_id, records: [] };
|
|
1872
|
-
const rooted = safe.result_layout
|
|
1876
|
+
const rooted = isRootedCompletionLayout(safe.result_layout);
|
|
1877
|
+
const localSingleton = safe.result_layout === "completion_yaml_files_v2" && !safe.numbering && candidates.length === 1;
|
|
1873
1878
|
if (!safe.batch_id.isWellFormed()) return { state: "unsupported" };
|
|
1874
1879
|
for (const [index, { row, location }] of candidates.entries()) {
|
|
1875
1880
|
const member = ordered[index]!;
|
|
1876
1881
|
const displayed = safe.numbering ? safe.numbering.kind === "stream" ? safe.numbering.first_index + index : "?" : index;
|
|
1877
|
-
const metadata: Record<string, CompletionYamlData> = { index: displayed };
|
|
1882
|
+
const metadata: Record<string, CompletionYamlData> = localSingleton ? {} : { index: displayed };
|
|
1878
1883
|
for (const piece of row.pieces) {
|
|
1879
1884
|
if (piece.block) continue;
|
|
1880
1885
|
if (!piece.field) return { state: "unsupported" };
|
|
@@ -1917,7 +1922,9 @@ function prepareCompletionYamlProjection(safe: RunCompletionBatch, candidates: r
|
|
|
1917
1922
|
}
|
|
1918
1923
|
packet.records.push({ metadata, parts });
|
|
1919
1924
|
}
|
|
1920
|
-
const service: Record<string, CompletionYamlData> = rooted ? {
|
|
1925
|
+
const service: Record<string, CompletionYamlData> = rooted ? {
|
|
1926
|
+
header_layout: safe.result_layout === "completion_yaml_files_v2" ? "rooted_files_v2" : "rooted_files_v1",
|
|
1927
|
+
} : {};
|
|
1921
1928
|
const omitted = safe.members.length - candidates.length;
|
|
1922
1929
|
if (omitted) {
|
|
1923
1930
|
service.omitted_results = omitted;
|
|
@@ -2349,7 +2356,7 @@ export function readRunCompletionPresentation(content: string, value: unknown):
|
|
|
2349
2356
|
!completionYamlKeys(hint, ["format", "content_sha256"]) || hint.format !== completionYamlCodec ||
|
|
2350
2357
|
hint.content_sha256 !== createHash("sha256").update(content).digest("hex")) return full;
|
|
2351
2358
|
const segments: NonNullable<RunCompletionPresentationView["segments"]>[number][] = [];
|
|
2352
|
-
const rooted = core.packet.service?.header_layout === "rooted_files_v1";
|
|
2359
|
+
const rooted = core.packet.service?.header_layout === "rooted_files_v1" || core.packet.service?.header_layout === "rooted_files_v2";
|
|
2353
2360
|
const facts = Object.fromEntries(Object.entries(core.packet.service ?? {}).filter(([key]) => key !== "header_layout"));
|
|
2354
2361
|
for (const [index, record] of core.packet.records.entries()) {
|
|
2355
2362
|
if (index) segments.push({ kind: "separator", text: "\n" });
|
|
@@ -2581,6 +2588,8 @@ export function encodeCompletionYamlCarrier(input: unknown): { state: "available
|
|
|
2581
2588
|
typeof packet.batchId !== "string" || !packet.batchId.length || !Array.isArray(packet.records) || packet.records.length > 64 ||
|
|
2582
2589
|
(Object.hasOwn(packet, "service") && (!completionYamlMapping(packet.service) || !Object.keys(packet.service).length)) ||
|
|
2583
2590
|
(!packet.records.length && !Object.hasOwn(packet, "service"))) return unavailable;
|
|
2591
|
+
const localSingleton = packet.records.length === 1 && completionYamlMapping(packet.service) &&
|
|
2592
|
+
packet.service.header_layout === "rooted_files_v2" && !Object.hasOwn(packet.service, "numbering");
|
|
2584
2593
|
const rows: string[] = [];
|
|
2585
2594
|
for (let index = 0; index < Math.max(1, packet.records.length); index++) {
|
|
2586
2595
|
const row: CompletionYamlData | undefined = packet.records[index];
|
|
@@ -2596,13 +2605,15 @@ export function encodeCompletionYamlCarrier(input: unknown): { state: "available
|
|
|
2596
2605
|
if (!completionYamlMapping(row) || !completionYamlKeys(row, ["metadata", "parts"]) ||
|
|
2597
2606
|
!completionYamlMapping(row.metadata) || !Array.isArray(row.parts)) return unavailable;
|
|
2598
2607
|
const meta = row.metadata;
|
|
2599
|
-
|
|
2608
|
+
const validIndex = localSingleton ? !Object.hasOwn(meta, "index")
|
|
2609
|
+
: meta.index === "?" || (typeof meta.index === "number" && Number.isSafeInteger(meta.index) && meta.index >= 0);
|
|
2610
|
+
if (!validIndex ||
|
|
2600
2611
|
typeof meta.run !== "string" || !meta.run.length || typeof meta.state !== "string" || !meta.state.length ||
|
|
2601
2612
|
(Object.hasOwn(meta, "kind") && meta.kind !== "primary" && meta.kind !== "diagnostic") ||
|
|
2602
2613
|
Object.hasOwn(meta, completionYamlServiceKey) ||
|
|
2603
2614
|
// JS enumerates array-index keys before semantic core fields; do not silently reorder the header.
|
|
2604
2615
|
Object.keys(meta).some(key => /^(0|[1-9]\d*)$/u.test(key) && Number(key) < 4294967295)) return unavailable;
|
|
2605
|
-
for (const key of ["index", "run", "state", ...(Object.hasOwn(meta, "kind") ? ["kind"] : []),
|
|
2616
|
+
for (const key of [...(localSingleton ? [] : ["index"]), "run", "state", ...(Object.hasOwn(meta, "kind") ? ["kind"] : []),
|
|
2606
2617
|
...Object.keys(meta).filter(key => !["index", "run", "state", "kind"].includes(key))]) {
|
|
2607
2618
|
Object.defineProperty(header, key, { value: meta[key]!, enumerable: true });
|
|
2608
2619
|
}
|
|
@@ -69,8 +69,8 @@ export type RunControlAdmissionInput = {
|
|
|
69
69
|
const PENDING_CONTROL_STATUSES = new Set<RunControlStatus>(["queued", "delivered", "claimed"]);
|
|
70
70
|
const TERMINAL_CONTROL_STATUSES = new Set<RunControlStatus>(["handled", "failed"]);
|
|
71
71
|
const CONTROL_ADMISSION_NEXT_ACTIONS = [
|
|
72
|
-
"
|
|
73
|
-
"
|
|
72
|
+
"actors_inspect target=run:<id> view=control",
|
|
73
|
+
"actors_inspect target=runtime view=triage",
|
|
74
74
|
];
|
|
75
75
|
|
|
76
76
|
function isCount(value: number): boolean {
|
package/lib/runtime.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { existsSync, watch, type FSWatcher } from "node:fs";
|
|
|
8
8
|
import { basename, dirname } from "node:path";
|
|
9
9
|
|
|
10
10
|
import * as Config from "./config.ts";
|
|
11
|
+
import * as Identity from "./identity.ts";
|
|
11
12
|
import type { RegisteredToolExec } from "./execution.ts";
|
|
12
13
|
import * as Paths from "./paths.ts";
|
|
13
14
|
import type { RecipeResolutionContext } from "./recipes-context.ts";
|
|
@@ -36,7 +37,7 @@ export interface ToolRegistryRuntimeDeps {
|
|
|
36
37
|
exec: RegisteredToolExec;
|
|
37
38
|
recipeRoot?: string;
|
|
38
39
|
getActiveTools?: () => string[];
|
|
39
|
-
getAllTools?: () => Array<{ name: string }>;
|
|
40
|
+
getAllTools?: () => Array<{ name: string; sourceInfo?: { path: string } }>;
|
|
40
41
|
registerTool: (
|
|
41
42
|
definition: ReturnType<typeof ToolsLocal.createRuntimeToolDefinition>,
|
|
42
43
|
) => void;
|
|
@@ -83,6 +84,8 @@ export function createAutoToolsRuntime(
|
|
|
83
84
|
const tools = new Map<string, Config.RegisteredTool>();
|
|
84
85
|
const runtimeToolFingerprints = new Map<string, string>();
|
|
85
86
|
const runtimeTools = new Set<string>();
|
|
87
|
+
// Host declarations survive deactivation; retain their observed provenance separately.
|
|
88
|
+
const runtimeToolSources = new Map<string, string | undefined>();
|
|
86
89
|
const recipeRoot = deps.recipeRoot ?? Paths.getRecipeRoot();
|
|
87
90
|
const status: RecipeRegistryStatus = {
|
|
88
91
|
active_tool_count: 0,
|
|
@@ -99,9 +102,14 @@ export function createAutoToolsRuntime(
|
|
|
99
102
|
if (ctx.hasUI) ctx.ui.notify(message, type);
|
|
100
103
|
}
|
|
101
104
|
function getToolNameBlocker(name: string): string | undefined {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
:
|
|
105
|
+
const normalized = Identity.normalizeToolName(name);
|
|
106
|
+
if ([...deps.reservedToolNames].some((reserved) => Identity.normalizeToolName(reserved) === normalized))
|
|
107
|
+
return `Reserved tool name: ${name}`;
|
|
108
|
+
const foreign = deps.getAllTools?.().find((tool) =>
|
|
109
|
+
Identity.normalizeToolName(tool.name) === normalized &&
|
|
110
|
+
!(tool.name === name && runtimeToolSources.has(name) &&
|
|
111
|
+
tool.sourceInfo?.path === runtimeToolSources.get(name)));
|
|
112
|
+
return foreign ? `Host tool name collision: ${name} conflicts with ${foreign.name}` : undefined;
|
|
105
113
|
}
|
|
106
114
|
function getToolFingerprint(cfg: Config.RegisteredTool): string {
|
|
107
115
|
return JSON.stringify({
|
|
@@ -135,12 +143,15 @@ export function createAutoToolsRuntime(
|
|
|
135
143
|
function deactivateMissingRuntimeTools(activeNames: Set<string>): void {
|
|
136
144
|
const stale = [...runtimeTools].filter((name) => !activeNames.has(name));
|
|
137
145
|
if (stale.length === 0) return;
|
|
146
|
+
const hostTools = deps.getAllTools?.();
|
|
147
|
+
const staleOwned = stale.filter((name) => !hostTools || hostTools.some((tool) =>
|
|
148
|
+
tool.name === name && tool.sourceInfo?.path === runtimeToolSources.get(name)));
|
|
138
149
|
for (const name of stale) {
|
|
139
150
|
runtimeTools.delete(name);
|
|
140
151
|
runtimeToolFingerprints.delete(name);
|
|
141
152
|
}
|
|
142
153
|
if (!deps.getActiveTools || !deps.setActiveTools) return;
|
|
143
|
-
const staleSet = new Set(
|
|
154
|
+
const staleSet = new Set(staleOwned);
|
|
144
155
|
deps.setActiveTools(
|
|
145
156
|
deps.getActiveTools().filter((name) => !staleSet.has(name)),
|
|
146
157
|
);
|
|
@@ -157,10 +168,13 @@ export function createAutoToolsRuntime(
|
|
|
157
168
|
};
|
|
158
169
|
}
|
|
159
170
|
function registerRuntimeTool(cfg: Config.RegisteredTool): RuntimeToolActivation {
|
|
171
|
+
const blocker = getToolNameBlocker(cfg.name);
|
|
172
|
+
if (blocker) throw new Error(blocker);
|
|
160
173
|
const fingerprint = getToolFingerprint(cfg);
|
|
161
174
|
if (runtimeToolFingerprints.get(cfg.name) !== fingerprint) {
|
|
162
175
|
deps.registerTool(ToolsLocal.createRuntimeToolDefinition(cfg, deps.exec));
|
|
163
176
|
runtimeTools.add(cfg.name);
|
|
177
|
+
runtimeToolSources.set(cfg.name, deps.getAllTools?.().find((tool) => tool.name === cfg.name)?.sourceInfo?.path);
|
|
164
178
|
runtimeToolFingerprints.set(cfg.name, fingerprint);
|
|
165
179
|
}
|
|
166
180
|
if (deps.getActiveTools && deps.setActiveTools) {
|
|
@@ -215,7 +229,7 @@ export function createAutoToolsRuntime(
|
|
|
215
229
|
lines.push(...other.map((warning) => `• ${warning}`));
|
|
216
230
|
groups[groups.length] = ["other_diagnostics", start, lines.length];
|
|
217
231
|
}
|
|
218
|
-
lines.push("Next:
|
|
232
|
+
lines.push("Next: actors_inspect target=recipes view=doctor");
|
|
219
233
|
// Preserve the original layout join/coercion and its faults before projecting owned warning slots.
|
|
220
234
|
void `${lines.join("\n")}\n`;
|
|
221
235
|
let text = ToolsResponse.formatMarkdownField("report", "pi-actors recipe registry warning");
|
|
@@ -227,7 +241,7 @@ export function createAutoToolsRuntime(
|
|
|
227
241
|
: " - warning:\n - result: unavailable\n - reason: malformed_selected_text");
|
|
228
242
|
}
|
|
229
243
|
}
|
|
230
|
-
return text + "\n" + ToolsResponse.formatMarkdownField("instruction", "Next:
|
|
244
|
+
return text + "\n" + ToolsResponse.formatMarkdownField("instruction", "Next: actors_inspect target=recipes view=doctor") + "\n";
|
|
231
245
|
}
|
|
232
246
|
function loadTools(
|
|
233
247
|
ctx: RuntimeContext,
|
|
@@ -259,6 +273,7 @@ export function createAutoToolsRuntime(
|
|
|
259
273
|
const blocker = getToolNameBlocker(cfg.name);
|
|
260
274
|
if (blocker) {
|
|
261
275
|
warnings.push(blocker);
|
|
276
|
+
tools.delete(cfg.name);
|
|
262
277
|
continue;
|
|
263
278
|
}
|
|
264
279
|
registerRuntimeTool(cfg);
|
|
@@ -284,7 +299,7 @@ export function createAutoToolsRuntime(
|
|
|
284
299
|
}),
|
|
285
300
|
getToolStatus: (name) => {
|
|
286
301
|
const cfg = tools.get(name);
|
|
287
|
-
if (!cfg) return undefined;
|
|
302
|
+
if (!cfg || getToolNameBlocker(name)) return undefined;
|
|
288
303
|
const usage = cfg.sourcePath
|
|
289
304
|
? RecipesUsage.readRecipeUsage(cfg.sourcePath)
|
|
290
305
|
: undefined;
|
|
@@ -305,8 +320,8 @@ export function createAutoToolsRuntime(
|
|
|
305
320
|
next_actions: activation.callable_now
|
|
306
321
|
? [`call tool ${name}`]
|
|
307
322
|
: [
|
|
308
|
-
`
|
|
309
|
-
`
|
|
323
|
+
`actors_tool_register name=${name} update=true`,
|
|
324
|
+
`actors_inspect target=tool:${name} view=status`,
|
|
310
325
|
],
|
|
311
326
|
...(usage?.launch_kind ? { launch_kind: usage.launch_kind } : {}),
|
|
312
327
|
spawn_calls: Number(usage?.spawn_calls ?? 0),
|
|
@@ -372,7 +387,7 @@ export function createRecipeToolReloadWatcher(
|
|
|
372
387
|
setWatchStatus("failed");
|
|
373
388
|
try {
|
|
374
389
|
ctx.ui.notify(
|
|
375
|
-
"- report: Recipe live reload watcher failed\n- instruction: restart the session or use
|
|
390
|
+
"- report: Recipe live reload watcher failed\n- instruction: restart the session or use actors_tool_register again to refresh recipe tools.",
|
|
376
391
|
"warning",
|
|
377
392
|
);
|
|
378
393
|
} catch (error) {
|
|
@@ -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
|
}
|
|
@@ -538,16 +538,18 @@ export function compactYamlDocument(value: Record<string, unknown>): string {
|
|
|
538
538
|
return `\n${text.replace(/\n$/u, "")}`;
|
|
539
539
|
}
|
|
540
540
|
|
|
541
|
+
function recipeInspectionHint(action: string): { view: "doctor" | "imports" | "summary"; verbose?: true } | undefined {
|
|
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
|
+
return undefined;
|
|
546
|
+
}
|
|
547
|
+
|
|
541
548
|
/** Only the closed read-only Recipe inspect literals become typed next; other advice stays opaque content. */
|
|
542
549
|
export function nextActionMetadata(action: string, byteBudget: number): YamlPart {
|
|
543
|
-
const
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
["inspect target=recipes view=summary verbose=true", "summary", true],
|
|
547
|
-
] as const;
|
|
548
|
-
const match = recognized.find(([literal]) => literal === action);
|
|
549
|
-
if (match) {
|
|
550
|
-
const typed = { next: { tool: "inspect", target: "recipes", view: match[1], ...(match[2] ? { verbose: true } : {}) } };
|
|
550
|
+
const hint = recipeInspectionHint(action);
|
|
551
|
+
if (hint) {
|
|
552
|
+
const typed = { next: { tool: "actors_inspect", target: "recipes", ...hint } };
|
|
551
553
|
return { full: typed, selected: typed };
|
|
552
554
|
}
|
|
553
555
|
const instruction = selectYamlField("instruction", action, byteBudget);
|
|
@@ -556,10 +558,8 @@ export function nextActionMetadata(action: string, byteBudget: number): YamlPart
|
|
|
556
558
|
|
|
557
559
|
/** Only these existing read-only inspection hints become action nodes; other advice stays content. */
|
|
558
560
|
export function formatInspectionHint(action: string): string {
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
if (action === "inspect target=recipes view=summary verbose=true") return formatInspectNextAction("recipes", "summary", true);
|
|
562
|
-
return formatMarkdownField("instruction", action);
|
|
561
|
+
const hint = recipeInspectionHint(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[] {
|