@llblab/pi-actors 0.44.0 → 0.45.1
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 -0
- package/CHANGELOG.md +13 -0
- package/README.md +5 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +10 -106
- package/dist/lib/async-runs.d.ts +2 -0
- package/dist/lib/async-runs.js +33 -4
- package/dist/lib/config.js +1 -0
- package/dist/lib/extension-runtime.d.ts +21 -0
- package/dist/lib/extension-runtime.js +116 -0
- package/dist/lib/inspector.js +8 -2
- package/dist/lib/recipes-discovery.js +20 -3
- package/dist/lib/recipes-references.d.ts +10 -0
- package/dist/lib/recipes-references.js +168 -5
- package/dist/lib/schema.d.ts +3 -0
- package/dist/lib/schema.js +34 -1
- package/dist/lib/tools-inspect.js +10 -0
- package/dist/lib/tools-local.js +27 -10
- package/dist/lib/tools-spawn.js +2 -2
- package/dist/scripts/async-runner.mjs +0 -16
- package/dist/scripts/executable-block-style.d.mts +1 -0
- package/dist/scripts/executable-block-style.mjs +73 -0
- package/dist/scripts/locker.mjs +0 -21
- package/dist/scripts/recipe-utils.mjs +0 -1
- package/dist/scripts/release-gates.mjs +14 -11
- package/dist/scripts/validate-recipe.mjs +0 -1
- package/dist/skills/actors/SKILL.md +2 -2
- package/docs/command-templates.md +2 -2
- package/docs/recipe-library.md +2 -0
- package/docs/template-recipes.md +10 -4
- package/docs/tool-registry.md +1 -1
- package/index.ts +18 -107
- package/lib/async-runs.ts +43 -9
- package/lib/config.ts +4 -0
- package/lib/extension-runtime.ts +139 -0
- package/lib/inspector.ts +16 -2
- package/lib/recipes-discovery.ts +23 -3
- package/lib/recipes-references.ts +227 -7
- package/lib/schema.ts +53 -1
- package/lib/tools-inspect.ts +11 -0
- package/lib/tools-local.ts +49 -19
- package/lib/tools-spawn.ts +2 -2
- package/package.json +2 -2
- package/scripts/async-runner.mjs +0 -16
- package/scripts/executable-block-style.d.mts +1 -0
- package/scripts/executable-block-style.mjs +73 -0
- package/scripts/locker.mjs +0 -21
- package/scripts/recipe-utils.mjs +0 -1
- package/scripts/release-gates.mjs +14 -11
- package/scripts/validate-recipe.mjs +0 -1
- package/skills/actors/SKILL.md +2 -2
package/AGENTS.md
CHANGED
|
@@ -44,6 +44,7 @@ Pi host
|
|
|
44
44
|
|
|
45
45
|
## Key Domains
|
|
46
46
|
|
|
47
|
+
- `extension-runtime.ts`: low-level Pi session lifecycle, tool adaptation, and runtime service composition behind the thin `index.ts` event-registration root.
|
|
47
48
|
- `command-templates.ts`: portable synchronous execution graph.
|
|
48
49
|
- `recipes-references.ts`, `recipes-discovery.ts`, `recipe-control.ts`: Recipe resolution, imports, shadowing, and Control declarations.
|
|
49
50
|
- `async-runs.ts`: lifecycle facade.
|
|
@@ -135,6 +136,7 @@ When a deferred Run result gates the next step, wait for its terminal follow-up.
|
|
|
135
136
|
## Documentation and Release Discipline
|
|
136
137
|
|
|
137
138
|
- Keep published text portable: use `~`, `<repo>`, or relative paths.
|
|
139
|
+
- Keep executable JavaScript and TypeScript blocks compact: no blank lines inside function bodies or control-flow blocks. Structural object, type, interface, class, and module bodies are exempt.
|
|
138
140
|
- Update `skills/actors/SKILL.md` when durable operating mechanics change.
|
|
139
141
|
- Keep `skills/swarm/SKILL.md` focused on multi-agent methodology rather than kernel internals.
|
|
140
142
|
- Recipe `description` is optional because discovery supplies stable fallback tool copy; packaged Recipe QA must report zero diagnostics and zero release-blocking warnings without component boilerplate.
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
> Each release keeps at most 8 outcome records of at most 512 characters.
|
|
4
4
|
|
|
5
|
+
## 0.45.1: Entrypoint and Release Policy
|
|
6
|
+
|
|
7
|
+
- `Architecture`: Keeps `index.ts` as a thin Pi event-registration and composition root while moving session lifecycle, runtime service composition, Skill discovery, and tool adaptation into the acyclic `extension-runtime.ts` domain.
|
|
8
|
+
- `Release Policy`: Raises the fixed shipped-source ceiling to 32,000 lines and rejects blank lines inside executable JavaScript/TypeScript blocks across the complete source and test tree while exempting structural declarations.
|
|
9
|
+
- `Package Metadata`: Moves the package image to the new raw-content endpoint to restore cross-origin loading.
|
|
10
|
+
|
|
11
|
+
## 0.45.0: Skill Recipe Standard Library
|
|
12
|
+
|
|
13
|
+
- `Recipe Values`: Makes inline argument defaults optional, applies caller > values > defaults > inline precedence across tools, Runs, imports, and delegation, and validates final typed/enum values plus duplicate, unknown-default, and conflicting-type declarations.
|
|
14
|
+
- `Recipe Origins`: Gives file-backed Recipes immutable `{recipe_dir}` and active-Skill Recipes `{skill_dir}` across templates, defaults, artifacts, tools, and Runs while retaining local provenance and hiding machine-local origins from model-facing launch values.
|
|
15
|
+
- `Skill Recipe Library`: Adds exact `std:<name>` and Pi-active `skill:<skill>/<path>` component lookup for imports, delegation, spawn, validation, Inspect diagnostics, captured qualified identity, and installed dist without automatically registering Skill Recipes as tools.
|
|
16
|
+
- `Validation`: Covers source, composed async execution, installed dist, namespace collisions/reload, path redaction, and migrated Skill wrappers while resetting the shipped-line ceiling to the validated 29,767-line release tree.
|
|
17
|
+
|
|
5
18
|
## 0.44.0: Bounded Run Evidence
|
|
6
19
|
|
|
7
20
|
- `Trace`: Bounds each Run to 2,048 events and 4 MiB, atomically retaining the newest suffix with one cumulative `runtime.trace_compacted` marker so discarded history is explicit while terminal, result, execution, and artifact evidence remains authoritative.
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# pi-actors
|
|
2
2
|
|
|
3
|
+

|
|
4
|
+
|
|
3
5
|
Local Run kernel and persistent tool registry for [Pi](https://github.com/badlogic/pi-mono).
|
|
4
6
|
|
|
5
7
|
```text
|
|
@@ -84,7 +86,7 @@ Persist a trusted command template or Recipe-backed capability under `~/.pi/agen
|
|
|
84
86
|
|
|
85
87
|
Recipes can declare:
|
|
86
88
|
|
|
87
|
-
- args and
|
|
89
|
+
- named typed args, inline fallbacks, configuration `defaults`, and composition `values`;
|
|
88
90
|
- imports and command-template composition;
|
|
89
91
|
- retry, failure, recovery, repeat, concurrency, and timeout policy;
|
|
90
92
|
- artifact paths;
|
|
@@ -103,6 +105,8 @@ Example controlled Recipe:
|
|
|
103
105
|
|
|
104
106
|
Ordinary one-shot Recipes should omit `control`. Recipe imports compose definitions inside one Run; they do not create peer actors.
|
|
105
107
|
|
|
108
|
+
File-backed Recipes receive immutable `{recipe_dir}`; Recipes under a Pi-active Skill also receive `{skill_dir}`. Use `std:<recipe>` for an exact packaged component and `skill:<skill>/<recipe-path>` for an exact active-Skill component. Skill Recipes are namespaced reusable components and do not become tools automatically.
|
|
109
|
+
|
|
106
110
|
String command-template leaves execute directly without shell interpretation. Use template arrays for sequencing or an explicit trusted shell/script when shell semantics matter.
|
|
107
111
|
|
|
108
112
|
## Trace
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* pi-actors — actor runtime and persistent local tool registry for pi.
|
|
3
3
|
* Zones: composition root, pi agent, actor runtime
|
|
4
|
-
*
|
|
5
|
-
* Wraps command templates as callable pi tools, stores durable user tools as recipe files, and exposes actor orchestration across reloads and sessions.
|
|
4
|
+
* Owns extension composition and Pi event registration, not domain behavior.
|
|
6
5
|
*/
|
|
7
6
|
import * as Pi from "./lib/pi.ts";
|
|
8
7
|
export default function toolRegistryExtension(pi: Pi.ExtensionAPI): void;
|
package/dist/index.js
CHANGED
|
@@ -1,113 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* pi-actors — actor runtime and persistent local tool registry for pi.
|
|
3
3
|
* Zones: composition root, pi agent, actor runtime
|
|
4
|
-
*
|
|
5
|
-
* Wraps command templates as callable pi tools, stores durable user tools as recipe files, and exposes actor orchestration across reloads and sessions.
|
|
4
|
+
* Owns extension composition and Pi event registration, not domain behavior.
|
|
6
5
|
*/
|
|
7
|
-
import * as
|
|
8
|
-
import * as CommandTemplates from "./lib/command-templates.js";
|
|
6
|
+
import * as ExtensionRuntime from "./lib/extension-runtime.js";
|
|
9
7
|
import * as InspectorCommand from "./lib/inspector-command.js";
|
|
10
|
-
import * as Paths from "./lib/paths.js";
|
|
11
|
-
import * as Pi from "./lib/pi.js";
|
|
12
|
-
import * as Prompts from "./lib/prompts.js";
|
|
13
|
-
import * as RunUiRuntime from "./lib/run-ui-runtime.js";
|
|
14
|
-
import * as Runtime from "./lib/runtime.js";
|
|
15
|
-
import * as Temp from "./lib/temp.js";
|
|
16
|
-
import * as Tools from "./lib/tools.js";
|
|
17
|
-
import * as ToolsResponse from "./lib/tools-response.js";
|
|
18
8
|
export default function toolRegistryExtension(pi) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
getActiveContext: () => activeRunContext,
|
|
28
|
-
getRunOwnerId,
|
|
29
|
-
onRunEvent: automaticReview.schedule,
|
|
30
|
-
pi,
|
|
31
|
-
});
|
|
32
|
-
const actorToolDefinitions = new Map();
|
|
33
|
-
const withCurrentThinkingContext = (definition) => {
|
|
34
|
-
if (typeof definition.execute !== "function")
|
|
35
|
-
return definition;
|
|
36
|
-
const execute = definition.execute;
|
|
37
|
-
return {
|
|
38
|
-
...definition,
|
|
39
|
-
execute: async (...args) => {
|
|
40
|
-
const nextArgs = [...args];
|
|
41
|
-
const ctx = nextArgs[4];
|
|
42
|
-
if (ctx && typeof ctx === "object") {
|
|
43
|
-
nextArgs[4] = {
|
|
44
|
-
...ctx,
|
|
45
|
-
getThinkingLevel: () => pi.getThinkingLevel(),
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
try {
|
|
49
|
-
return ToolsResponse.spaceToolResult(await execute(...nextArgs));
|
|
50
|
-
}
|
|
51
|
-
catch (error) {
|
|
52
|
-
throw ToolsResponse.spaceToolError(error);
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
};
|
|
56
|
-
};
|
|
57
|
-
const runtime = Runtime.createAutoToolsRuntime({
|
|
58
|
-
configPath: Paths.EXTENSION_RUNTIME_PATHS.configPath,
|
|
59
|
-
exec: CommandTemplates.execCommandTemplate,
|
|
60
|
-
getActiveTools: () => pi.getActiveTools(),
|
|
61
|
-
registerTool: (definition) => {
|
|
62
|
-
const wrapped = withCurrentThinkingContext(definition);
|
|
63
|
-
actorToolDefinitions.set(wrapped.name, wrapped);
|
|
64
|
-
pi.registerTool(wrapped);
|
|
65
|
-
},
|
|
66
|
-
reservedToolNames: Tools.RESERVED_TOOL_NAMES,
|
|
67
|
-
setActiveTools: (toolNames) => pi.setActiveTools(toolNames),
|
|
68
|
-
});
|
|
69
|
-
const recipeReload = Runtime.createRecipeToolReloadWatcher(runtime);
|
|
70
|
-
pi.on("resources_discover", async () => {
|
|
71
|
-
const skillPaths = Paths.getExistingExtensionSkillPaths(import.meta.url);
|
|
72
|
-
if (skillPaths.length === 0)
|
|
73
|
-
return;
|
|
74
|
-
return { skillPaths };
|
|
75
|
-
});
|
|
76
|
-
pi.on("session_start", async (_event, ctx) => {
|
|
77
|
-
// Clear the pre-overlay widget after hot reloads from older pi-actors builds.
|
|
78
|
-
ctx.ui.setWidget("zz-pi-actors-comms", undefined);
|
|
79
|
-
activeRunContext = ctx;
|
|
80
|
-
runUiRuntime.close();
|
|
81
|
-
automaticReview.close();
|
|
82
|
-
recipeReload.close();
|
|
83
|
-
await Temp.prepareExtensionTempDir(Paths.EXTENSION_RUNTIME_PATHS.tempDir);
|
|
84
|
-
if (activeRunContext !== ctx)
|
|
85
|
-
return;
|
|
86
|
-
automaticReview.start(ctx);
|
|
87
|
-
runtime.loadTools(ctx);
|
|
88
|
-
runUiRuntime.start(ctx);
|
|
89
|
-
recipeReload.watch(ctx);
|
|
90
|
-
});
|
|
91
|
-
pi.on("agent_end", async (_event, ctx) => {
|
|
92
|
-
if (activeRunContext === ctx)
|
|
93
|
-
automaticReview.schedule();
|
|
94
|
-
});
|
|
95
|
-
pi.on("session_shutdown", async (event, ctx) => {
|
|
96
|
-
activeRunContext = undefined;
|
|
97
|
-
automaticReview.close();
|
|
98
|
-
recipeReload.close();
|
|
99
|
-
runUiRuntime.shutdown(event.reason, ctx);
|
|
100
|
-
});
|
|
101
|
-
InspectorCommand.registerActorInspectorCommand(pi, getRunOwnerId);
|
|
102
|
-
pi.on("before_agent_start", async (event) => ({
|
|
103
|
-
systemPrompt: `${event.systemPrompt}\n\n${Prompts.ONBOARDING_SYSTEM_PROMPT}`,
|
|
104
|
-
}));
|
|
105
|
-
Pi.registerToolDefinitions(pi, Tools.createCoreActorToolDefinitions({
|
|
106
|
-
configPath: Paths.EXTENSION_RUNTIME_PATHS.configPath,
|
|
107
|
-
getActiveTools: () => pi.getActiveTools(),
|
|
108
|
-
getRuntimeTool: (name) => Tools.resolveActiveRuntimeTool(name, runtime.getTools(), (activeName) => actorToolDefinitions.get(activeName)),
|
|
109
|
-
handleRuntimeControl: automaticReview.handleControl,
|
|
110
|
-
registryRuntime: runtime,
|
|
111
|
-
setActiveTools: (toolNames) => pi.setActiveTools(toolNames),
|
|
112
|
-
}).map(withCurrentThinkingContext));
|
|
9
|
+
const runtime = ExtensionRuntime.createActorExtensionRuntime(pi);
|
|
10
|
+
pi.on("resources_discover", async () => runtime.discoverResources(import.meta.url));
|
|
11
|
+
pi.on("session_start", async (_event, ctx) => runtime.onSessionStart(ctx));
|
|
12
|
+
pi.on("agent_end", async (_event, ctx) => runtime.onAgentEnd(ctx));
|
|
13
|
+
pi.on("session_shutdown", async (event, ctx) => runtime.onSessionShutdown(event.reason, ctx));
|
|
14
|
+
pi.on("before_agent_start", async (event) => runtime.beforeAgentStart(event.systemPrompt, event.systemPromptOptions.skills ?? []));
|
|
15
|
+
InspectorCommand.registerActorInspectorCommand(pi, runtime.getRunOwnerId);
|
|
16
|
+
runtime.registerCoreTools();
|
|
113
17
|
}
|
package/dist/lib/async-runs.d.ts
CHANGED
|
@@ -38,6 +38,8 @@ export interface AsyncRunStartParams {
|
|
|
38
38
|
template?: CommandTemplateValue;
|
|
39
39
|
args?: string[];
|
|
40
40
|
defaults?: Record<string, unknown>;
|
|
41
|
+
recipe_dir?: string;
|
|
42
|
+
skill_dir?: string;
|
|
41
43
|
parallel?: boolean;
|
|
42
44
|
concurrency?: number | string;
|
|
43
45
|
min_successful?: number | string;
|
package/dist/lib/async-runs.js
CHANGED
|
@@ -12,6 +12,7 @@ import { CURRENT_MODEL_VALUE_KEY, CURRENT_THINKING_VALUE_KEY, describeCurrentPol
|
|
|
12
12
|
import * as Paths from "./paths.js";
|
|
13
13
|
import * as RecipesReferences from "./recipes-references.js";
|
|
14
14
|
import * as RecipesUsage from "./recipes-usage.js";
|
|
15
|
+
import * as Schema from "./schema.js";
|
|
15
16
|
import { resolveArtifactPaths, } from "./runs-artifacts.js";
|
|
16
17
|
import { safeRunId } from "./runs-identity.js";
|
|
17
18
|
import { buildTerminalProgress, markTerminalHandled, signalOwnedRunProcess, } from "./runs-control.js";
|
|
@@ -151,7 +152,14 @@ function resolveStartParams(params) {
|
|
|
151
152
|
fileParams.run_id ||
|
|
152
153
|
fileParams.name ||
|
|
153
154
|
getRunIdFromFile(fileParams.file),
|
|
154
|
-
values: {
|
|
155
|
+
values: {
|
|
156
|
+
...(fileParams.values ?? {}),
|
|
157
|
+
...(params.values ?? {}),
|
|
158
|
+
...(fileParams.recipe_dir
|
|
159
|
+
? { recipe_dir: fileParams.recipe_dir }
|
|
160
|
+
: {}),
|
|
161
|
+
...(fileParams.skill_dir ? { skill_dir: fileParams.skill_dir } : {}),
|
|
162
|
+
},
|
|
155
163
|
};
|
|
156
164
|
}
|
|
157
165
|
function readJson(path) {
|
|
@@ -249,13 +257,34 @@ export function startRun(params, cwd) {
|
|
|
249
257
|
!isAbsolute(recipeRelation)
|
|
250
258
|
? dirname(packagedRecipeRoot)
|
|
251
259
|
: undefined;
|
|
252
|
-
const
|
|
260
|
+
const argSpec = Schema.parseToolArgDeclarationList(startParams.args ?? []);
|
|
261
|
+
if (argSpec.error)
|
|
262
|
+
throw new Error(argSpec.error);
|
|
263
|
+
const declaredArgs = new Set(argSpec.args);
|
|
264
|
+
for (const key of Object.keys(startParams.defaults ?? {})) {
|
|
265
|
+
if (declaredArgs.size > 0 && !declaredArgs.has(key))
|
|
266
|
+
throw new Error(`Unknown Recipe default argument: ${key}`);
|
|
267
|
+
}
|
|
268
|
+
const values = Schema.normalizeRuntimeValues({
|
|
269
|
+
...argSpec.defaults,
|
|
270
|
+
...(startParams.defaults || {}),
|
|
253
271
|
...(packagedRepo ? { repo: packagedRepo } : {}),
|
|
254
272
|
...(startParams.values || {}),
|
|
255
273
|
run_id: run,
|
|
256
274
|
state_dir: stateDir,
|
|
257
275
|
trace_file: join(stateDir, "trace.jsonl"),
|
|
258
|
-
};
|
|
276
|
+
}, argSpec.argTypes);
|
|
277
|
+
const runtimeTemplate = resolved.template &&
|
|
278
|
+
typeof resolved.template === "object" &&
|
|
279
|
+
!Array.isArray(resolved.template)
|
|
280
|
+
? {
|
|
281
|
+
...resolved.template,
|
|
282
|
+
defaults: {
|
|
283
|
+
...(resolved.template.defaults ?? {}),
|
|
284
|
+
...values,
|
|
285
|
+
},
|
|
286
|
+
}
|
|
287
|
+
: resolved.template;
|
|
259
288
|
const modelPolicy = describeCurrentPolicyProvenance({
|
|
260
289
|
defaults: startParams.defaults,
|
|
261
290
|
template: resolved.template,
|
|
@@ -312,7 +341,7 @@ export function startRun(params, cwd) {
|
|
|
312
341
|
state_schema: RuntimeIdentity.RUN_STATE_SCHEMA,
|
|
313
342
|
status: "running",
|
|
314
343
|
...(startParams.tool ? { tool: startParams.tool } : {}),
|
|
315
|
-
template:
|
|
344
|
+
template: runtimeTemplate,
|
|
316
345
|
values,
|
|
317
346
|
model_policy: modelPolicy,
|
|
318
347
|
...(artifacts ? { artifacts } : {}),
|
package/dist/lib/config.js
CHANGED
|
@@ -149,6 +149,7 @@ export function normalizeStoredTool(key, value, reservedToolNames) {
|
|
|
149
149
|
template: argTemplate,
|
|
150
150
|
};
|
|
151
151
|
const inferredArgTypes = Schema.getTemplateArgTypes(argTemplateConfig);
|
|
152
|
+
Schema.assertCompatibleToolArgTypes(inferredArgTypes, declarations.argTypes);
|
|
152
153
|
const argTypes = { ...inferredArgTypes, ...declarations.argTypes };
|
|
153
154
|
const cfg = {
|
|
154
155
|
name,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pi actor extension runtime coordinator.
|
|
3
|
+
* Zones: extension session lifecycle, host tool adaptation, runtime service composition
|
|
4
|
+
* Owns low-level Pi lifecycle effects and tool wrapping without owning event registration.
|
|
5
|
+
*/
|
|
6
|
+
import * as Pi from "./pi.ts";
|
|
7
|
+
import * as RecipesReferences from "./recipes-references.ts";
|
|
8
|
+
export interface ActorExtensionRuntime {
|
|
9
|
+
beforeAgentStart(systemPrompt: string, skills: RecipesReferences.ActiveSkillRecipeSource[]): {
|
|
10
|
+
systemPrompt: string;
|
|
11
|
+
};
|
|
12
|
+
discoverResources(metaUrl: string): {
|
|
13
|
+
skillPaths: string[];
|
|
14
|
+
} | undefined;
|
|
15
|
+
getRunOwnerId(ctx: Pi.ExtensionContext): string;
|
|
16
|
+
onAgentEnd(ctx: Pi.ExtensionContext): void;
|
|
17
|
+
onSessionShutdown(reason: string, ctx: Pi.ExtensionContext): void;
|
|
18
|
+
onSessionStart(ctx: Pi.ExtensionContext): Promise<void>;
|
|
19
|
+
registerCoreTools(): void;
|
|
20
|
+
}
|
|
21
|
+
export declare function createActorExtensionRuntime(pi: Pi.ExtensionAPI): ActorExtensionRuntime;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pi actor extension runtime coordinator.
|
|
3
|
+
* Zones: extension session lifecycle, host tool adaptation, runtime service composition
|
|
4
|
+
* Owns low-level Pi lifecycle effects and tool wrapping without owning event registration.
|
|
5
|
+
*/
|
|
6
|
+
import * as AutomaticReviewRuntime from "./automatic-review-runtime.js";
|
|
7
|
+
import * as CommandTemplates from "./command-templates.js";
|
|
8
|
+
import * as Paths from "./paths.js";
|
|
9
|
+
import * as Pi from "./pi.js";
|
|
10
|
+
import * as Prompts from "./prompts.js";
|
|
11
|
+
import * as RecipesReferences from "./recipes-references.js";
|
|
12
|
+
import * as RunUiRuntime from "./run-ui-runtime.js";
|
|
13
|
+
import * as Runtime from "./runtime.js";
|
|
14
|
+
import * as Temp from "./temp.js";
|
|
15
|
+
import * as Tools from "./tools.js";
|
|
16
|
+
import * as ToolsResponse from "./tools-response.js";
|
|
17
|
+
export function createActorExtensionRuntime(pi) {
|
|
18
|
+
let activeRunContext;
|
|
19
|
+
const getRunOwnerId = Pi.getSessionId;
|
|
20
|
+
const automaticReview = AutomaticReviewRuntime.createAutomaticReviewRuntime({
|
|
21
|
+
getActiveContext: () => activeRunContext,
|
|
22
|
+
getRunOwnerId,
|
|
23
|
+
getThinkingLevel: () => pi.getThinkingLevel(),
|
|
24
|
+
});
|
|
25
|
+
const runUiRuntime = RunUiRuntime.createRunUiRuntime({
|
|
26
|
+
getActiveContext: () => activeRunContext,
|
|
27
|
+
getRunOwnerId,
|
|
28
|
+
onRunEvent: automaticReview.schedule,
|
|
29
|
+
pi,
|
|
30
|
+
});
|
|
31
|
+
const actorToolDefinitions = new Map();
|
|
32
|
+
const withCurrentThinkingContext = (definition) => {
|
|
33
|
+
if (typeof definition.execute !== "function")
|
|
34
|
+
return definition;
|
|
35
|
+
const execute = definition.execute;
|
|
36
|
+
return {
|
|
37
|
+
...definition,
|
|
38
|
+
execute: async (...args) => {
|
|
39
|
+
const nextArgs = [...args];
|
|
40
|
+
const ctx = nextArgs[4];
|
|
41
|
+
if (ctx && typeof ctx === "object") {
|
|
42
|
+
nextArgs[4] = {
|
|
43
|
+
...ctx,
|
|
44
|
+
getThinkingLevel: () => pi.getThinkingLevel(),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
return ToolsResponse.spaceToolResult(await execute(...nextArgs));
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
throw ToolsResponse.spaceToolError(error);
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
const runtime = Runtime.createAutoToolsRuntime({
|
|
57
|
+
configPath: Paths.EXTENSION_RUNTIME_PATHS.configPath,
|
|
58
|
+
exec: CommandTemplates.execCommandTemplate,
|
|
59
|
+
getActiveTools: () => pi.getActiveTools(),
|
|
60
|
+
registerTool: (definition) => {
|
|
61
|
+
const wrapped = withCurrentThinkingContext(definition);
|
|
62
|
+
actorToolDefinitions.set(wrapped.name, wrapped);
|
|
63
|
+
pi.registerTool(wrapped);
|
|
64
|
+
},
|
|
65
|
+
reservedToolNames: Tools.RESERVED_TOOL_NAMES,
|
|
66
|
+
setActiveTools: (toolNames) => pi.setActiveTools(toolNames),
|
|
67
|
+
});
|
|
68
|
+
const recipeReload = Runtime.createRecipeToolReloadWatcher(runtime);
|
|
69
|
+
return {
|
|
70
|
+
beforeAgentStart(systemPrompt, skills) {
|
|
71
|
+
RecipesReferences.setActiveSkillRecipeSources(skills);
|
|
72
|
+
return {
|
|
73
|
+
systemPrompt: `${systemPrompt}\n\n${Prompts.ONBOARDING_SYSTEM_PROMPT}`,
|
|
74
|
+
};
|
|
75
|
+
},
|
|
76
|
+
discoverResources(metaUrl) {
|
|
77
|
+
const skillPaths = Paths.getExistingExtensionSkillPaths(metaUrl);
|
|
78
|
+
return skillPaths.length > 0 ? { skillPaths } : undefined;
|
|
79
|
+
},
|
|
80
|
+
getRunOwnerId,
|
|
81
|
+
onAgentEnd(ctx) {
|
|
82
|
+
if (activeRunContext === ctx)
|
|
83
|
+
automaticReview.schedule();
|
|
84
|
+
},
|
|
85
|
+
onSessionShutdown(reason, ctx) {
|
|
86
|
+
activeRunContext = undefined;
|
|
87
|
+
automaticReview.close();
|
|
88
|
+
recipeReload.close();
|
|
89
|
+
runUiRuntime.shutdown(reason, ctx);
|
|
90
|
+
},
|
|
91
|
+
async onSessionStart(ctx) {
|
|
92
|
+
ctx.ui.setWidget("zz-pi-actors-comms", undefined);
|
|
93
|
+
activeRunContext = ctx;
|
|
94
|
+
runUiRuntime.close();
|
|
95
|
+
automaticReview.close();
|
|
96
|
+
recipeReload.close();
|
|
97
|
+
await Temp.prepareExtensionTempDir(Paths.EXTENSION_RUNTIME_PATHS.tempDir);
|
|
98
|
+
if (activeRunContext !== ctx)
|
|
99
|
+
return;
|
|
100
|
+
automaticReview.start(ctx);
|
|
101
|
+
runtime.loadTools(ctx);
|
|
102
|
+
runUiRuntime.start(ctx);
|
|
103
|
+
recipeReload.watch(ctx);
|
|
104
|
+
},
|
|
105
|
+
registerCoreTools() {
|
|
106
|
+
Pi.registerToolDefinitions(pi, Tools.createCoreActorToolDefinitions({
|
|
107
|
+
configPath: Paths.EXTENSION_RUNTIME_PATHS.configPath,
|
|
108
|
+
getActiveTools: () => pi.getActiveTools(),
|
|
109
|
+
getRuntimeTool: (name) => Tools.resolveActiveRuntimeTool(name, runtime.getTools(), (activeName) => actorToolDefinitions.get(activeName)),
|
|
110
|
+
handleRuntimeControl: automaticReview.handleControl,
|
|
111
|
+
registryRuntime: runtime,
|
|
112
|
+
setActiveTools: (toolNames) => pi.setActiveTools(toolNames),
|
|
113
|
+
}).map(withCurrentThinkingContext));
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
}
|
package/dist/lib/inspector.js
CHANGED
|
@@ -56,7 +56,12 @@ export function readActorInspectorRecipe(stateDir) {
|
|
|
56
56
|
!Array.isArray(primary.recipe)
|
|
57
57
|
? primary.recipe
|
|
58
58
|
: undefined;
|
|
59
|
-
const redactedRecord = (value) => SessionEvidence.redactSessionEvidenceValue(Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined
|
|
59
|
+
const redactedRecord = (value) => SessionEvidence.redactSessionEvidenceValue(Object.fromEntries(Object.entries(value).filter(([key, entry]) => entry !== undefined &&
|
|
60
|
+
key !== "recipe_dir" &&
|
|
61
|
+
key !== "skill_dir")));
|
|
62
|
+
const launchValues = meta.values && typeof meta.values === "object" && !Array.isArray(meta.values)
|
|
63
|
+
? Object.fromEntries(Object.entries(meta.values).filter(([key]) => key !== "recipe_dir" && key !== "skill_dir"))
|
|
64
|
+
: meta.values;
|
|
60
65
|
return {
|
|
61
66
|
composition: contexts.map((entry) => redactedRecord({
|
|
62
67
|
...(typeof entry.alias === "string" ? { alias: entry.alias } : {}),
|
|
@@ -64,6 +69,7 @@ export function readActorInspectorRecipe(stateDir) {
|
|
|
64
69
|
file: entry.file,
|
|
65
70
|
import_path: entry.import_path,
|
|
66
71
|
name: entry.name,
|
|
72
|
+
qualified_name: entry.qualified_name,
|
|
67
73
|
})),
|
|
68
74
|
...(definition ? { definition: redactedRecord(definition) } : {}),
|
|
69
75
|
diagnostics: result.diagnostics.map((diagnostic) => diagnostic.message),
|
|
@@ -76,7 +82,7 @@ export function readActorInspectorRecipe(stateDir) {
|
|
|
76
82
|
launch: redactedRecord({
|
|
77
83
|
cwd: meta.cwd,
|
|
78
84
|
template: meta.template,
|
|
79
|
-
values:
|
|
85
|
+
values: launchValues,
|
|
80
86
|
model_policy: meta.model_policy,
|
|
81
87
|
control: meta.control,
|
|
82
88
|
artifacts: meta.artifacts,
|
|
@@ -53,17 +53,33 @@ function getRecipeCommandTemplateConfig(config) {
|
|
|
53
53
|
? config.template
|
|
54
54
|
: config);
|
|
55
55
|
}
|
|
56
|
+
function getRecipeDiagnosticTemplateConfig(config) {
|
|
57
|
+
const templateConfig = getRecipeCommandTemplateConfig(config);
|
|
58
|
+
return typeof templateConfig === "object" && !Array.isArray(templateConfig)
|
|
59
|
+
? {
|
|
60
|
+
...templateConfig,
|
|
61
|
+
defaults: {
|
|
62
|
+
...(templateConfig.defaults ?? {}),
|
|
63
|
+
...(config.defaults ?? {}),
|
|
64
|
+
...(config.values ?? {}),
|
|
65
|
+
},
|
|
66
|
+
}
|
|
67
|
+
: {
|
|
68
|
+
defaults: { ...(config.defaults ?? {}), ...(config.values ?? {}) },
|
|
69
|
+
template: templateConfig,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
56
72
|
function getRecipeConfigDiagnostics(file, config) {
|
|
57
73
|
if (!config) {
|
|
58
74
|
const reason = RecipesReferences.diagnoseRawRecipeConfigFailure(file);
|
|
59
75
|
return [`Invalid recipe: ${file}${reason ? `: ${reason}` : ""}`];
|
|
60
76
|
}
|
|
61
|
-
return CommandTemplates.getCommandTemplateWarnings(
|
|
77
|
+
return CommandTemplates.getCommandTemplateWarnings(getRecipeDiagnosticTemplateConfig(config)).map((warning) => `Recipe ${file}: ${warning}`);
|
|
62
78
|
}
|
|
63
79
|
function getRecipeRiskLabels(config) {
|
|
64
80
|
if (!config)
|
|
65
81
|
return [];
|
|
66
|
-
const labels = new Set(CommandTemplates.getCommandTemplateRiskLabels(
|
|
82
|
+
const labels = new Set(CommandTemplates.getCommandTemplateRiskLabels(getRecipeDiagnosticTemplateConfig(config)));
|
|
67
83
|
if (config.async === true)
|
|
68
84
|
labels.add("risk.long_running");
|
|
69
85
|
return [
|
|
@@ -652,8 +668,9 @@ export function toRegisteredTool(entry) {
|
|
|
652
668
|
const parsed = Schema.parseToolArgToken(String(arg));
|
|
653
669
|
return [parsed.arg, parsed.type];
|
|
654
670
|
}));
|
|
655
|
-
assertToolSafeRepeatConfig(argTemplateConfig, explicitArgTypes, cfg.defaults ?? {});
|
|
671
|
+
assertToolSafeRepeatConfig(argTemplateConfig, explicitArgTypes, { ...(cfg.defaults ?? {}), ...(cfg.values ?? {}) });
|
|
656
672
|
const argTypes = Schema.getTemplateArgTypes(argTemplateConfig);
|
|
673
|
+
Schema.assertCompatibleToolArgTypes(explicitArgTypes, argTypes);
|
|
657
674
|
return {
|
|
658
675
|
name: entry.id,
|
|
659
676
|
description,
|
|
@@ -40,6 +40,8 @@ export interface TemplateRecipeDefinition {
|
|
|
40
40
|
}
|
|
41
41
|
export interface TemplateRecipeConfig extends TemplateRecipeDefinition {
|
|
42
42
|
async?: boolean;
|
|
43
|
+
recipe_dir?: string;
|
|
44
|
+
skill_dir?: string;
|
|
43
45
|
}
|
|
44
46
|
export interface TemplateRecipeContextRecord {
|
|
45
47
|
alias?: string;
|
|
@@ -47,12 +49,20 @@ export interface TemplateRecipeContextRecord {
|
|
|
47
49
|
file: string;
|
|
48
50
|
import_path: string[];
|
|
49
51
|
name: string;
|
|
52
|
+
qualified_name?: string;
|
|
50
53
|
recipe: Record<string, unknown>;
|
|
51
54
|
role: "entry" | "import";
|
|
52
55
|
}
|
|
53
56
|
export interface ReadResolvedRecipeConfigOptions {
|
|
54
57
|
includeActorRecipeContext?: boolean;
|
|
55
58
|
}
|
|
59
|
+
export interface ActiveSkillRecipeSource {
|
|
60
|
+
name: string;
|
|
61
|
+
filePath?: string;
|
|
62
|
+
baseDir?: string;
|
|
63
|
+
}
|
|
64
|
+
export declare function setActiveSkillRecipeSources(skills: ActiveSkillRecipeSource[]): void;
|
|
65
|
+
export declare function getActiveSkillRecipeNamespaces(): Record<string, string[]>;
|
|
56
66
|
export declare function resolveRecipePath(value: string, recipeRoot?: string): string;
|
|
57
67
|
export declare function resolveRecipeReferencePath(value: unknown, currentRecipeRoot?: string): string | undefined;
|
|
58
68
|
export declare function getRecipePath(value: unknown, recipeRoot?: string): string | undefined;
|