@llblab/pi-actors 0.45.0 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +10 -6
- package/CHANGELOG.md +14 -1
- package/README.md +28 -12
- package/dist/fixtures/protocol/recipe-summary.json +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +10 -110
- package/dist/lib/async-runs.d.ts +4 -1
- package/dist/lib/async-runs.js +22 -23
- package/dist/lib/automatic-review-runtime.d.ts +2 -0
- package/dist/lib/automatic-review-runtime.js +12 -5
- package/dist/lib/draft-sleep.js +0 -1
- package/dist/lib/extension-runtime.d.ts +21 -0
- package/dist/lib/extension-runtime.js +122 -0
- package/dist/lib/inspector.js +45 -7
- package/dist/lib/paths.d.ts +0 -1
- package/dist/lib/paths.js +0 -7
- package/dist/lib/prompts.d.ts +1 -1
- package/dist/lib/prompts.js +2 -2
- package/dist/lib/recipes-context.js +2 -2
- package/dist/lib/recipes-references.d.ts +24 -9
- package/dist/lib/recipes-references.js +152 -126
- package/dist/lib/runtime.d.ts +0 -1
- package/dist/lib/runtime.js +1 -3
- package/dist/lib/tools-inspect.d.ts +0 -1
- package/dist/lib/tools-inspect.js +35 -8
- package/dist/lib/tools-local.d.ts +2 -0
- package/dist/lib/tools-local.js +1 -1
- package/dist/lib/tools-spawn.d.ts +2 -0
- package/dist/lib/tools-spawn.js +24 -52
- package/dist/scripts/async-runner.mjs +0 -16
- package/dist/scripts/build-dist.mjs +13 -4
- package/dist/skills/actors/SKILL.md +6 -6
- package/dist/skills/actors/recipes/recipe-validate.json +11 -0
- package/{recipes/utility-coordinator-lock-snapshot.json → dist/skills/actors/recipes/resource-locker-snapshot.json} +1 -3
- package/dist/{recipes → skills/actors/recipes}/resource-locker.json +1 -3
- package/dist/{recipes/utility-run-ops-snapshot.json → skills/actors/recipes/run-ops-snapshot.json} +1 -3
- package/dist/skills/actors/recipes/run-summary.json +9 -0
- package/dist/{scripts/locker.mjs → skills/actors/scripts/resource-locker.mjs} +2 -23
- package/dist/skills/actors/scripts/run-utils.mjs +164 -0
- package/{scripts → dist/skills/actors/scripts}/validate-recipe.mjs +134 -18
- package/dist/skills/artifacts/SKILL.md +16 -0
- package/{recipes/pipeline-artifact-bundle.json → dist/skills/artifacts/recipes/bundle.json} +4 -4
- package/dist/{recipes/utility-artifact-write.json → skills/artifacts/recipes/file-write.json} +1 -3
- package/dist/{recipes/utility-artifact-manifest.json → skills/artifacts/recipes/manifest.json} +1 -3
- package/{recipes/pipeline-artifact-report.json → dist/skills/artifacts/recipes/report.json} +2 -2
- package/dist/{recipes/pipeline-artifact-write.json → skills/artifacts/recipes/write.json} +3 -3
- package/dist/skills/artifacts/scripts/artifact-utils.mjs +63 -0
- package/dist/skills/media/SKILL.md +16 -0
- package/dist/{recipes/pipeline-media-library.json → skills/media/recipes/library.json} +2 -2
- package/{recipes/music-player.json → dist/skills/media/recipes/player.json} +1 -3
- package/dist/{recipes/utility-playlist-build.json → skills/media/recipes/playlist-build.json} +1 -3
- package/dist/skills/media/scripts/media-utils.mjs +47 -0
- package/dist/{scripts → skills/media/scripts}/music-player.mjs +9 -3
- package/dist/skills/project-work/SKILL.md +16 -0
- package/dist/skills/project-work/recipes/changelog-section.json +11 -0
- package/{recipes/pipeline-docs-maintenance.json → dist/skills/project-work/recipes/docs-maintenance.json} +4 -4
- package/dist/skills/project-work/recipes/package-summary.json +9 -0
- package/{recipes/pipeline-release-readiness.json → dist/skills/project-work/recipes/release-readiness.json} +6 -6
- package/dist/{recipes/pipeline-release-summary.json → skills/project-work/recipes/release-summary.json} +5 -5
- package/{recipes/pipeline-repo-health.json → dist/skills/project-work/recipes/repo-health.json} +6 -6
- package/{recipes/pipeline-async-run-ops.json → dist/skills/project-work/recipes/run-ops.json} +3 -3
- package/dist/skills/project-work/recipes/skill-summary.json +11 -0
- package/dist/skills/project-work/scripts/project-utils.mjs +89 -0
- package/dist/skills/recipe-memory/SKILL.md +16 -0
- package/dist/skills/swarm/SKILL.md +4 -4
- package/{recipes/pipeline-architect-coordinator.json → dist/skills/swarm/recipes/architect.json} +5 -5
- package/{recipes/pipeline-checkpoint-continuation.json → dist/skills/swarm/recipes/checkpoint-continuation.json} +3 -3
- package/dist/{recipes/pipeline-development-tasking.json → skills/swarm/recipes/development-tasking.json} +4 -4
- package/dist/{recipes/lens-swarm.json → skills/swarm/recipes/lens-review.json} +1 -1
- package/dist/{recipes/pipeline-quorum-review.json → skills/swarm/recipes/quorum-review.json} +4 -4
- package/{recipes/pipeline-research-synthesis.json → dist/skills/swarm/recipes/research-synthesis.json} +6 -6
- package/{recipes/pipeline-review-readiness.json → dist/skills/swarm/recipes/review-readiness.json} +1 -1
- package/{recipes/subagents-prompts.json → dist/skills/swarm/recipes/subagent-prompts.json} +1 -1
- package/{recipes → dist/skills/swarm/recipes}/subagent-quorum.json +1 -1
- package/dist/{recipes → skills/swarm/recipes}/subagent-review-coordinator.json +6 -6
- package/docs/actor-inspector.md +4 -3
- package/docs/async-runs.md +2 -2
- package/docs/recipe-library.md +23 -23
- package/docs/releasing.md +2 -2
- package/docs/template-recipes.md +30 -14
- package/docs/tool-registry.md +2 -2
- package/fixtures/protocol/recipe-summary.json +1 -1
- package/index.ts +18 -112
- package/lib/async-runs.ts +47 -24
- package/lib/automatic-review-runtime.ts +16 -3
- package/lib/draft-sleep.ts +0 -1
- package/lib/extension-runtime.ts +158 -0
- package/lib/inspector.ts +56 -11
- package/lib/paths.ts +0 -7
- package/lib/prompts.ts +2 -2
- package/lib/recipes-context.ts +2 -2
- package/lib/recipes-references.ts +223 -134
- package/lib/runtime.ts +1 -5
- package/lib/tools-inspect.ts +42 -9
- package/lib/tools-local.ts +2 -0
- package/lib/tools-spawn.ts +37 -74
- package/package.json +3 -5
- package/scripts/async-runner.mjs +0 -16
- package/scripts/build-dist.mjs +13 -4
- package/skills/actors/SKILL.md +6 -6
- package/skills/actors/recipes/recipe-validate.json +11 -0
- package/{dist/recipes/utility-coordinator-lock-snapshot.json → skills/actors/recipes/resource-locker-snapshot.json} +1 -3
- package/{recipes → skills/actors/recipes}/resource-locker.json +1 -3
- package/{recipes/utility-run-ops-snapshot.json → skills/actors/recipes/run-ops-snapshot.json} +1 -3
- package/skills/actors/recipes/run-summary.json +9 -0
- package/{scripts/locker.mjs → skills/actors/scripts/resource-locker.mjs} +2 -23
- package/skills/actors/scripts/run-utils.mjs +164 -0
- package/{dist → skills/actors}/scripts/validate-recipe.mjs +134 -18
- package/skills/artifacts/SKILL.md +16 -0
- package/{dist/recipes/pipeline-artifact-bundle.json → skills/artifacts/recipes/bundle.json} +4 -4
- package/{recipes/utility-artifact-write.json → skills/artifacts/recipes/file-write.json} +1 -3
- package/{recipes/utility-artifact-manifest.json → skills/artifacts/recipes/manifest.json} +1 -3
- package/{dist/recipes/pipeline-artifact-report.json → skills/artifacts/recipes/report.json} +2 -2
- package/{recipes/pipeline-artifact-write.json → skills/artifacts/recipes/write.json} +3 -3
- package/skills/artifacts/scripts/artifact-utils.mjs +63 -0
- package/skills/media/SKILL.md +16 -0
- package/{recipes/pipeline-media-library.json → skills/media/recipes/library.json} +2 -2
- package/{dist/recipes/music-player.json → skills/media/recipes/player.json} +1 -3
- package/{recipes/utility-playlist-build.json → skills/media/recipes/playlist-build.json} +1 -3
- package/skills/media/scripts/media-utils.mjs +47 -0
- package/{scripts → skills/media/scripts}/music-player.mjs +9 -3
- package/skills/project-work/SKILL.md +16 -0
- package/skills/project-work/recipes/changelog-section.json +11 -0
- package/{dist/recipes/pipeline-docs-maintenance.json → skills/project-work/recipes/docs-maintenance.json} +4 -4
- package/skills/project-work/recipes/package-summary.json +9 -0
- package/{dist/recipes/pipeline-release-readiness.json → skills/project-work/recipes/release-readiness.json} +6 -6
- package/{recipes/pipeline-release-summary.json → skills/project-work/recipes/release-summary.json} +5 -5
- package/{dist/recipes/pipeline-repo-health.json → skills/project-work/recipes/repo-health.json} +6 -6
- package/{dist/recipes/pipeline-async-run-ops.json → skills/project-work/recipes/run-ops.json} +3 -3
- package/skills/project-work/recipes/skill-summary.json +11 -0
- package/skills/project-work/scripts/project-utils.mjs +89 -0
- package/skills/recipe-memory/SKILL.md +16 -0
- package/skills/swarm/SKILL.md +4 -4
- package/{dist/recipes/pipeline-architect-coordinator.json → skills/swarm/recipes/architect.json} +5 -5
- package/{dist/recipes/pipeline-checkpoint-continuation.json → skills/swarm/recipes/checkpoint-continuation.json} +3 -3
- package/{recipes/pipeline-development-tasking.json → skills/swarm/recipes/development-tasking.json} +4 -4
- package/{recipes/lens-swarm.json → skills/swarm/recipes/lens-review.json} +1 -1
- package/{recipes/pipeline-quorum-review.json → skills/swarm/recipes/quorum-review.json} +4 -4
- package/{dist/recipes/pipeline-research-synthesis.json → skills/swarm/recipes/research-synthesis.json} +6 -6
- package/{dist/recipes/pipeline-review-readiness.json → skills/swarm/recipes/review-readiness.json} +1 -1
- package/{dist/recipes/subagents-prompts.json → skills/swarm/recipes/subagent-prompts.json} +1 -1
- package/{dist → skills/swarm}/recipes/subagent-quorum.json +1 -1
- package/{recipes → skills/swarm/recipes}/subagent-review-coordinator.json +6 -6
- package/dist/recipes/utility-changelog-section.json +0 -13
- package/dist/recipes/utility-package-summary.json +0 -11
- package/dist/recipes/utility-run-summary.json +0 -11
- package/dist/recipes/utility-skill-summary.json +0 -13
- package/dist/recipes/utility-validate-recipe.json +0 -13
- package/dist/scripts/recipe-utils.mjs +0 -405
- package/dist/scripts/release-gates.mjs +0 -278
- package/recipes/utility-changelog-section.json +0 -13
- package/recipes/utility-package-summary.json +0 -11
- package/recipes/utility-run-summary.json +0 -11
- package/recipes/utility-skill-summary.json +0 -13
- package/recipes/utility-validate-recipe.json +0 -13
- package/scripts/recipe-utils.mjs +0 -405
- package/scripts/release-gates.mjs +0 -278
- /package/dist/{recipes/utility-validation-wrapper.json → skills/actors/recipes/command-validate.json} +0 -0
- /package/dist/{recipes/utility-jsonl-tail.json → skills/actors/recipes/jsonl-tail.json} +0 -0
- /package/dist/{recipes/utility-run-state-files.json → skills/actors/recipes/run-state-files.json} +0 -0
- /package/dist/{recipes/utility-playlist-scan.json → skills/media/recipes/playlist-scan.json} +0 -0
- /package/dist/{recipes/utility-changelog-head.json → skills/project-work/recipes/changelog-head.json} +0 -0
- /package/dist/{recipes/utility-git-log.json → skills/project-work/recipes/git-log.json} +0 -0
- /package/dist/{recipes/utility-git-status.json → skills/project-work/recipes/git-status.json} +0 -0
- /package/dist/{recipes/utility-markdown-index.json → skills/project-work/recipes/markdown-index.json} +0 -0
- /package/dist/{recipes → skills/recipe-memory/recipes}/draft-review.json +0 -0
- /package/dist/{recipes → skills/recipe-memory/recipes}/tool-review.json +0 -0
- /package/dist/{recipes → skills/swarm/recipes}/subagent-artifact.json +0 -0
- /package/dist/{recipes → skills/swarm/recipes}/subagent-checkpoint.json +0 -0
- /package/dist/{recipes → skills/swarm/recipes}/subagent-conflict-report.json +0 -0
- /package/dist/{recipes → skills/swarm/recipes}/subagent-contradiction-map.json +0 -0
- /package/dist/{recipes → skills/swarm/recipes}/subagent-critic.json +0 -0
- /package/dist/{recipes → skills/swarm/recipes}/subagent-evidence-map.json +0 -0
- /package/dist/{recipes → skills/swarm/recipes}/subagent-followup.json +0 -0
- /package/dist/{recipes → skills/swarm/recipes}/subagent-judge.json +0 -0
- /package/dist/{recipes → skills/swarm/recipes}/subagent-merge.json +0 -0
- /package/dist/{recipes → skills/swarm/recipes}/subagent-normalize.json +0 -0
- /package/dist/{recipes → skills/swarm/recipes}/subagent-plan.json +0 -0
- /package/dist/{recipes → skills/swarm/recipes}/subagent-preflight.json +0 -0
- /package/dist/{recipes → skills/swarm/recipes}/subagent-prompt.json +0 -0
- /package/dist/{recipes → skills/swarm/recipes}/subagent-review.json +0 -0
- /package/dist/{recipes → skills/swarm/recipes}/subagent-task-card.json +0 -0
- /package/dist/{recipes → skills/swarm/recipes}/subagent-tools.json +0 -0
- /package/dist/{recipes → skills/swarm/recipes}/subagent-verify.json +0 -0
- /package/{recipes/utility-validation-wrapper.json → skills/actors/recipes/command-validate.json} +0 -0
- /package/{recipes/utility-jsonl-tail.json → skills/actors/recipes/jsonl-tail.json} +0 -0
- /package/{recipes/utility-run-state-files.json → skills/actors/recipes/run-state-files.json} +0 -0
- /package/{recipes/utility-playlist-scan.json → skills/media/recipes/playlist-scan.json} +0 -0
- /package/{recipes/utility-changelog-head.json → skills/project-work/recipes/changelog-head.json} +0 -0
- /package/{recipes/utility-git-log.json → skills/project-work/recipes/git-log.json} +0 -0
- /package/{recipes/utility-git-status.json → skills/project-work/recipes/git-status.json} +0 -0
- /package/{recipes/utility-markdown-index.json → skills/project-work/recipes/markdown-index.json} +0 -0
- /package/{recipes → skills/recipe-memory/recipes}/draft-review.json +0 -0
- /package/{recipes → skills/recipe-memory/recipes}/tool-review.json +0 -0
- /package/{recipes → skills/swarm/recipes}/subagent-artifact.json +0 -0
- /package/{recipes → skills/swarm/recipes}/subagent-checkpoint.json +0 -0
- /package/{recipes → skills/swarm/recipes}/subagent-conflict-report.json +0 -0
- /package/{recipes → skills/swarm/recipes}/subagent-contradiction-map.json +0 -0
- /package/{recipes → skills/swarm/recipes}/subagent-critic.json +0 -0
- /package/{recipes → skills/swarm/recipes}/subagent-evidence-map.json +0 -0
- /package/{recipes → skills/swarm/recipes}/subagent-followup.json +0 -0
- /package/{recipes → skills/swarm/recipes}/subagent-judge.json +0 -0
- /package/{recipes → skills/swarm/recipes}/subagent-merge.json +0 -0
- /package/{recipes → skills/swarm/recipes}/subagent-normalize.json +0 -0
- /package/{recipes → skills/swarm/recipes}/subagent-plan.json +0 -0
- /package/{recipes → skills/swarm/recipes}/subagent-preflight.json +0 -0
- /package/{recipes → skills/swarm/recipes}/subagent-prompt.json +0 -0
- /package/{recipes → skills/swarm/recipes}/subagent-review.json +0 -0
- /package/{recipes → skills/swarm/recipes}/subagent-task-card.json +0 -0
- /package/{recipes → skills/swarm/recipes}/subagent-tools.json +0 -0
- /package/{recipes → skills/swarm/recipes}/subagent-verify.json +0 -0
package/lib/runtime.ts
CHANGED
|
@@ -23,7 +23,6 @@ export interface RuntimeContext {
|
|
|
23
23
|
export interface ToolRegistryRuntimeDeps {
|
|
24
24
|
configPath: string;
|
|
25
25
|
exec: RegisteredToolExec;
|
|
26
|
-
packagedRecipeRoot?: string;
|
|
27
26
|
recipeRoot?: string;
|
|
28
27
|
getActiveTools?: () => string[];
|
|
29
28
|
registerTool: (
|
|
@@ -125,7 +124,7 @@ export function createAutoToolsRuntime(
|
|
|
125
124
|
);
|
|
126
125
|
const lines = ["pi-actors recipe registry warning"];
|
|
127
126
|
if (shadowed.length > 0) {
|
|
128
|
-
lines.push("User recipes
|
|
127
|
+
lines.push("User recipes shadow lower-priority user sources:");
|
|
129
128
|
lines.push(...shadowed.map((warning) => `• ${warning}`));
|
|
130
129
|
}
|
|
131
130
|
if (skipped.length > 0) {
|
|
@@ -141,11 +140,8 @@ export function createAutoToolsRuntime(
|
|
|
141
140
|
function loadTools(ctx: RuntimeContext) {
|
|
142
141
|
const warnings: string[] = [];
|
|
143
142
|
const recipeRoot = deps.recipeRoot ?? Paths.getRecipeRoot();
|
|
144
|
-
const packagedRecipeRoot =
|
|
145
|
-
deps.packagedRecipeRoot ?? Paths.getPackagedRecipeRoot();
|
|
146
143
|
const discovered = RecipesDiscovery.discoverRecipeSources([
|
|
147
144
|
{ root: recipeRoot, defaultTool: true, mutableUsage: true },
|
|
148
|
-
{ root: packagedRecipeRoot },
|
|
149
145
|
]);
|
|
150
146
|
warnings.push(...discovered.diagnostics);
|
|
151
147
|
tools.clear();
|
package/lib/tools-inspect.ts
CHANGED
|
@@ -33,7 +33,6 @@ export interface InspectToolDeps<TContext = unknown> {
|
|
|
33
33
|
getRunStatus?: (runOrDir: string) => Record<string, any>;
|
|
34
34
|
getTool?: (name: string) => any | undefined;
|
|
35
35
|
listRuns?: () => Array<Record<string, any>>;
|
|
36
|
-
packagedRecipeRoot?: string;
|
|
37
36
|
recipeRoot?: string;
|
|
38
37
|
}
|
|
39
38
|
|
|
@@ -195,6 +194,7 @@ function inspectRuntime(
|
|
|
195
194
|
function inspectRecipes(
|
|
196
195
|
view: string,
|
|
197
196
|
deps: InspectToolDeps,
|
|
197
|
+
context: unknown,
|
|
198
198
|
): Record<string, unknown> {
|
|
199
199
|
if (
|
|
200
200
|
view !== "status" &&
|
|
@@ -213,18 +213,51 @@ function inspectRecipes(
|
|
|
213
213
|
}
|
|
214
214
|
const discovered = RecipesDiscovery.discoverRecipeSources([
|
|
215
215
|
{ root: recipeRoot, defaultTool: true, mutableUsage: true },
|
|
216
|
-
{ root: deps.packagedRecipeRoot ?? Paths.getPackagedRecipeRoot() },
|
|
217
216
|
]);
|
|
218
|
-
const
|
|
219
|
-
|
|
217
|
+
const skillContext =
|
|
218
|
+
context && typeof context === "object" && "activeSkillRecipeContext" in context
|
|
219
|
+
? (context as {
|
|
220
|
+
activeSkillRecipeContext?: RecipesReferences.ActiveSkillRecipeContext;
|
|
221
|
+
}).activeSkillRecipeContext
|
|
222
|
+
: undefined;
|
|
223
|
+
const activeSkillContext =
|
|
224
|
+
skillContext ?? RecipesReferences.EMPTY_ACTIVE_SKILL_RECIPE_CONTEXT;
|
|
225
|
+
const skillRecipeNamespaces = RecipesReferences.getActiveSkillRecipeNamespaces(
|
|
226
|
+
activeSkillContext,
|
|
227
|
+
);
|
|
228
|
+
let skillRecipeComponents: Array<Record<string, unknown>> = [];
|
|
229
|
+
const skillRecipeComponentDiagnostics: Array<Record<string, unknown>> = [];
|
|
230
|
+
try {
|
|
231
|
+
skillRecipeComponents = RecipesReferences.listActiveSkillRecipeComponents(
|
|
232
|
+
activeSkillContext,
|
|
233
|
+
).map((component) => ({
|
|
234
|
+
identity: component.identity,
|
|
235
|
+
source_kind: "active_skill_component",
|
|
236
|
+
skill: component.skill,
|
|
237
|
+
stem: component.stem,
|
|
238
|
+
imports: component.imports,
|
|
239
|
+
}));
|
|
240
|
+
} catch (error) {
|
|
241
|
+
skillRecipeComponentDiagnostics.push({
|
|
242
|
+
error: error instanceof Error ? error.message : String(error),
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
const discoverySummary = RecipesDiscovery.summarizeDiscovery(discovered);
|
|
220
246
|
const summary = {
|
|
221
|
-
...
|
|
222
|
-
|
|
247
|
+
...discoverySummary,
|
|
248
|
+
active: Array.isArray(discoverySummary.active)
|
|
249
|
+
? discoverySummary.active.map((entry) => ({
|
|
250
|
+
...(entry as Record<string, unknown>),
|
|
251
|
+
source_kind: "user_registry_capability",
|
|
252
|
+
}))
|
|
253
|
+
: discoverySummary.active,
|
|
254
|
+
skill_recipe_components: skillRecipeComponents,
|
|
255
|
+
skill_recipe_component_diagnostics: skillRecipeComponentDiagnostics,
|
|
256
|
+
active_skill_recipe_identities: Object.keys(skillRecipeNamespaces).sort(),
|
|
223
257
|
skill_recipe_namespace_diagnostics: Object.entries(skillRecipeNamespaces)
|
|
224
258
|
.filter(([, roots]) => roots.length > 1)
|
|
225
|
-
.map(([name
|
|
259
|
+
.map(([name]) => ({
|
|
226
260
|
name,
|
|
227
|
-
roots,
|
|
228
261
|
error: `Ambiguous active Skill Recipe namespace ${name}`,
|
|
229
262
|
})),
|
|
230
263
|
drafts: RecipesDiscovery.listDraftRecipes(join(recipeRoot, "drafts")),
|
|
@@ -386,7 +419,7 @@ export function createInspectToolDefinition<TContext = unknown>(
|
|
|
386
419
|
if (target === "runtime") {
|
|
387
420
|
details = inspectRuntime(view, input, ctx, deps);
|
|
388
421
|
} else if (target === "recipes") {
|
|
389
|
-
details = inspectRecipes(view, deps);
|
|
422
|
+
details = inspectRecipes(view, deps, ctx);
|
|
390
423
|
} else {
|
|
391
424
|
const run = parseRunTarget(target);
|
|
392
425
|
if (run) details = inspectRun(run, view, input, ctx, deps);
|
package/lib/tools-local.ts
CHANGED
|
@@ -18,6 +18,7 @@ import * as ToolsResponse from "./tools-response.ts";
|
|
|
18
18
|
type JsonSchema = Schema.JsonSchema;
|
|
19
19
|
|
|
20
20
|
export interface RuntimeToolContext extends ModelContext.CurrentModelContext {
|
|
21
|
+
activeSkillRecipeContext?: RecipesReferences.ActiveSkillRecipeContext;
|
|
21
22
|
cwd: string;
|
|
22
23
|
sessionManager?: { getSessionId?: () => string };
|
|
23
24
|
}
|
|
@@ -243,6 +244,7 @@ export function createRuntimeToolDefinition(
|
|
|
243
244
|
values: resolveRecipeToolValues(cfg, values, ctx),
|
|
244
245
|
},
|
|
245
246
|
ctx.cwd,
|
|
247
|
+
{ skillContext: ctx.activeSkillRecipeContext },
|
|
246
248
|
);
|
|
247
249
|
return {
|
|
248
250
|
content: [
|
package/lib/tools-spawn.ts
CHANGED
|
@@ -11,12 +11,13 @@ import * as AsyncRuns from "./async-runs.ts";
|
|
|
11
11
|
import { withFileMutationLock } from "./file-state.ts";
|
|
12
12
|
import * as ModelContext from "./model-context.ts";
|
|
13
13
|
import * as Paths from "./paths.ts";
|
|
14
|
-
import * as
|
|
14
|
+
import * as RecipesReferences from "./recipes-references.ts";
|
|
15
15
|
import * as RecipesUsage from "./recipes-usage.ts";
|
|
16
16
|
import * as Schema from "./schema.ts";
|
|
17
17
|
import * as ToolsResponse from "./tools-response.ts";
|
|
18
18
|
|
|
19
19
|
export interface SpawnToolContext extends ModelContext.CurrentModelContext {
|
|
20
|
+
activeSkillRecipeContext?: RecipesReferences.ActiveSkillRecipeContext;
|
|
20
21
|
cwd: string;
|
|
21
22
|
sessionManager?: { getSessionId?: () => string };
|
|
22
23
|
}
|
|
@@ -28,22 +29,6 @@ function getRunOwnerId(ctx: SpawnToolContext): string | undefined {
|
|
|
28
29
|
return ctx.sessionManager?.getSessionId?.();
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
function shadowedRecipeLaunchDiagnostic(
|
|
32
|
-
recipe: unknown,
|
|
33
|
-
): Record<string, unknown> | undefined {
|
|
34
|
-
if (
|
|
35
|
-
typeof recipe !== "string" ||
|
|
36
|
-
recipe.includes("/") ||
|
|
37
|
-
recipe.includes("~")
|
|
38
|
-
)
|
|
39
|
-
return undefined;
|
|
40
|
-
const discovery = RecipesDiscovery.discoverRecipeSources([
|
|
41
|
-
{ root: Paths.getRecipeRoot(), defaultTool: true, mutableUsage: true },
|
|
42
|
-
{ root: Paths.getPackagedRecipeRoot(), defaultTool: false },
|
|
43
|
-
]);
|
|
44
|
-
return RecipesDiscovery.getShadowedLaunchDiagnostic(discovery, recipe);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
32
|
function draftRecipeName(run: string): string {
|
|
48
33
|
return `${run.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "spawn"}.json`;
|
|
49
34
|
}
|
|
@@ -93,22 +78,6 @@ function writeSpawnDraftRecipe(
|
|
|
93
78
|
return path;
|
|
94
79
|
}
|
|
95
80
|
|
|
96
|
-
function enhanceSpawnRecipeError(error: unknown, recipe: unknown): Error {
|
|
97
|
-
const diagnostic = shadowedRecipeLaunchDiagnostic(recipe);
|
|
98
|
-
if (!diagnostic)
|
|
99
|
-
return error instanceof Error ? error : new Error(String(error));
|
|
100
|
-
const original = error instanceof Error ? error.message : String(error);
|
|
101
|
-
return Object.assign(
|
|
102
|
-
new Error(
|
|
103
|
-
`${original} reason=${diagnostic.reason} active_path=${diagnostic.active_path} blocked_fallback=${diagnostic.blocked_fallback} hint=${diagnostic.hint}`,
|
|
104
|
-
),
|
|
105
|
-
{
|
|
106
|
-
...diagnostic,
|
|
107
|
-
original_error: original,
|
|
108
|
-
},
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
81
|
function runIdFromTarget(target: string | undefined): string | undefined {
|
|
113
82
|
if (!target) return undefined;
|
|
114
83
|
if (!target.startsWith("run:")) {
|
|
@@ -138,11 +107,9 @@ export function createSpawnToolDefinition<
|
|
|
138
107
|
"Optional Run identity in exact run:<id> form.",
|
|
139
108
|
),
|
|
140
109
|
file: Schema.stringSchema(
|
|
141
|
-
"Optional
|
|
142
|
-
),
|
|
143
|
-
recipe: Schema.stringSchema(
|
|
144
|
-
"Alias for file; qualified Skill/std or ordinary Recipe reference to spawn.",
|
|
110
|
+
"Optional Recipe reference as <skill>/<recipe> or an explicit .json/.md file path.",
|
|
145
111
|
),
|
|
112
|
+
recipe: Schema.stringSchema("Alias for file."),
|
|
146
113
|
template: Schema.unionSchema([
|
|
147
114
|
Schema.stringSchema("Inline command template string"),
|
|
148
115
|
Schema.arraySchema(
|
|
@@ -186,43 +153,39 @@ export function createSpawnToolDefinition<
|
|
|
186
153
|
: typeof input.recipe === "string"
|
|
187
154
|
? input.recipe
|
|
188
155
|
: undefined;
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
);
|
|
223
|
-
} catch (error) {
|
|
224
|
-
throw enhanceSpawnRecipeError(error, recipe);
|
|
225
|
-
}
|
|
156
|
+
const meta = AsyncRuns.startRun(
|
|
157
|
+
{
|
|
158
|
+
file: recipe,
|
|
159
|
+
launch_source: "spawn",
|
|
160
|
+
launch_correlation: { tool_call_id: toolCallId },
|
|
161
|
+
ownerId: getRunOwnerId(ctx),
|
|
162
|
+
...(input.transport_context
|
|
163
|
+
? { transport_context: asRecord(input.transport_context) } : {}),
|
|
164
|
+
run_id: runId,
|
|
165
|
+
...(input.template !== undefined
|
|
166
|
+
? {
|
|
167
|
+
template:
|
|
168
|
+
input.template as AsyncRuns.AsyncRunStartParams["template"],
|
|
169
|
+
}
|
|
170
|
+
: {}),
|
|
171
|
+
values: ModelContext.withCurrentModelValues(
|
|
172
|
+
asRecord(input.values),
|
|
173
|
+
ctx,
|
|
174
|
+
),
|
|
175
|
+
...(input.artifacts &&
|
|
176
|
+
typeof input.artifacts === "object" &&
|
|
177
|
+
!Array.isArray(input.artifacts)
|
|
178
|
+
? {
|
|
179
|
+
artifacts: input.artifacts as Record<
|
|
180
|
+
string,
|
|
181
|
+
AsyncRuns.RunArtifactDeclaration
|
|
182
|
+
>,
|
|
183
|
+
}
|
|
184
|
+
: {}),
|
|
185
|
+
},
|
|
186
|
+
ctx.cwd,
|
|
187
|
+
{ skillContext: ctx.activeSkillRecipeContext },
|
|
188
|
+
);
|
|
226
189
|
const draftRecipe = writeSpawnDraftRecipe(input, meta);
|
|
227
190
|
const nextActions = ToolsResponse.runNextActions(meta.run);
|
|
228
191
|
const details = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llblab/pi-actors",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.46.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Local Actor Kernel for Pi",
|
|
6
6
|
"keywords": [
|
|
@@ -30,8 +30,7 @@
|
|
|
30
30
|
"test": "node --experimental-strip-types --test --test-concurrency=1 tests/*.test.ts",
|
|
31
31
|
"test:preservation": "node --experimental-strip-types --test --test-concurrency=1 tests/async-runs.test.ts tests/observability.test.ts tests/session-evidence.test.ts tests/inspector-security.test.ts tests/inspector-overlay.test.ts tests/review-control.test.ts",
|
|
32
32
|
"pack:dry": "npm pack --dry-run",
|
|
33
|
-
"recipes:qa": "node scripts/validate-recipe.mjs
|
|
34
|
-
"release:validate": "npm run validate && node scripts/release-gates.mjs",
|
|
33
|
+
"recipes:qa": "node skills/actors/scripts/validate-recipe.mjs skills --skills --qa --summary",
|
|
35
34
|
"validate": "npx tsc --noEmit && npm run recipes:qa && npm run build && npm run check && npm test && npm run conformance && npm run pack:dry",
|
|
36
35
|
"audit:dependencies": "npm audit --audit-level=high --omit=peer",
|
|
37
36
|
"build": "node scripts/build-dist.mjs",
|
|
@@ -42,7 +41,6 @@
|
|
|
42
41
|
"dist",
|
|
43
42
|
"lib",
|
|
44
43
|
"scripts",
|
|
45
|
-
"recipes",
|
|
46
44
|
"skills",
|
|
47
45
|
"README.md",
|
|
48
46
|
"AGENTS.md",
|
|
@@ -65,7 +63,7 @@
|
|
|
65
63
|
"sourceSkills": [
|
|
66
64
|
"./skills"
|
|
67
65
|
],
|
|
68
|
-
"image": "https://
|
|
66
|
+
"image": "https://raw.githubusercontent.com/llblab/pi-actors/main/banner.jpg"
|
|
69
67
|
},
|
|
70
68
|
"peerDependencies": {
|
|
71
69
|
"@earendil-works/pi-coding-agent": "*",
|
package/scripts/async-runner.mjs
CHANGED
|
@@ -74,7 +74,6 @@ function summarizeCommandDetail(commandDetail) {
|
|
|
74
74
|
|
|
75
75
|
export async function runAsyncRunner(stateDir = process.argv[2]) {
|
|
76
76
|
if (!stateDir) throw new Error("missing state dir");
|
|
77
|
-
|
|
78
77
|
const runPath = join(stateDir, "run.json");
|
|
79
78
|
const progressPath = join(stateDir, "progress.json");
|
|
80
79
|
const resultPath = join(stateDir, "result.json");
|
|
@@ -83,11 +82,9 @@ export async function runAsyncRunner(stateDir = process.argv[2]) {
|
|
|
83
82
|
const stderrPath = join(stateDir, "stderr.log");
|
|
84
83
|
const executionPath = join(stateDir, "execution.json");
|
|
85
84
|
const meta = JSON.parse(readFileSync(runPath, "utf8"));
|
|
86
|
-
|
|
87
85
|
function event(kind, data = {}) {
|
|
88
86
|
appendRunTraceEvent(stateDir, { kind, data });
|
|
89
87
|
}
|
|
90
|
-
|
|
91
88
|
function observation(kind, summary, data = {}, delivery = "log", level = "info") {
|
|
92
89
|
appendRunTraceEvent(stateDir, {
|
|
93
90
|
kind,
|
|
@@ -97,7 +94,6 @@ export async function runAsyncRunner(stateDir = process.argv[2]) {
|
|
|
97
94
|
...(level === "error" ? { level: "error" } : {}),
|
|
98
95
|
});
|
|
99
96
|
}
|
|
100
|
-
|
|
101
97
|
function progress(phase, extra = {}) {
|
|
102
98
|
writeJsonAtomic(progressPath, {
|
|
103
99
|
...(meta.model_policy ? { model_policy: meta.model_policy } : {}),
|
|
@@ -106,7 +102,6 @@ export async function runAsyncRunner(stateDir = process.argv[2]) {
|
|
|
106
102
|
...extra,
|
|
107
103
|
});
|
|
108
104
|
}
|
|
109
|
-
|
|
110
105
|
let activeSubagents = 0;
|
|
111
106
|
let completedSubagents = 0;
|
|
112
107
|
let promptCounter = 0;
|
|
@@ -115,7 +110,6 @@ export async function runAsyncRunner(stateDir = process.argv[2]) {
|
|
|
115
110
|
const evidenceRecords = [];
|
|
116
111
|
const stageOccurrences = new Map();
|
|
117
112
|
let reportEvidence;
|
|
118
|
-
|
|
119
113
|
function writeExecutionManifest(status) {
|
|
120
114
|
writeJsonAtomic(executionPath, {
|
|
121
115
|
version: 1,
|
|
@@ -129,7 +123,6 @@ export async function runAsyncRunner(stateDir = process.argv[2]) {
|
|
|
129
123
|
updated_at: new Date().toISOString(),
|
|
130
124
|
});
|
|
131
125
|
}
|
|
132
|
-
|
|
133
126
|
function commandSessionFiles(sessionDir) {
|
|
134
127
|
if (!sessionDir) return [];
|
|
135
128
|
try {
|
|
@@ -141,7 +134,6 @@ export async function runAsyncRunner(stateDir = process.argv[2]) {
|
|
|
141
134
|
return [];
|
|
142
135
|
}
|
|
143
136
|
}
|
|
144
|
-
|
|
145
137
|
function commandEvidenceStartRecord({
|
|
146
138
|
commandDetail,
|
|
147
139
|
commandId,
|
|
@@ -181,7 +173,6 @@ export async function runAsyncRunner(stateDir = process.argv[2]) {
|
|
|
181
173
|
: "not_required",
|
|
182
174
|
};
|
|
183
175
|
}
|
|
184
|
-
|
|
185
176
|
function commandEvidenceRecord({
|
|
186
177
|
captureDir,
|
|
187
178
|
commandDetail,
|
|
@@ -273,7 +264,6 @@ export async function runAsyncRunner(stateDir = process.argv[2]) {
|
|
|
273
264
|
: "rejected",
|
|
274
265
|
};
|
|
275
266
|
}
|
|
276
|
-
|
|
277
267
|
function auditReviewReport(text) {
|
|
278
268
|
const required = evidenceRecords
|
|
279
269
|
.filter((record) =>
|
|
@@ -294,11 +284,9 @@ export async function runAsyncRunner(stateDir = process.argv[2]) {
|
|
|
294
284
|
complete_allowed: missing.length === 0,
|
|
295
285
|
};
|
|
296
286
|
}
|
|
297
|
-
|
|
298
287
|
function getCommandDoneDelivery(result) {
|
|
299
288
|
return result.code !== 0 || activeSubagents > 0 ? "followup" : "log";
|
|
300
289
|
}
|
|
301
|
-
|
|
302
290
|
function progressRunning() {
|
|
303
291
|
progress("running", {
|
|
304
292
|
activeSubagents,
|
|
@@ -306,14 +294,12 @@ export async function runAsyncRunner(stateDir = process.argv[2]) {
|
|
|
306
294
|
failures: subagentFailures,
|
|
307
295
|
});
|
|
308
296
|
}
|
|
309
|
-
|
|
310
297
|
function promptFilePath() {
|
|
311
298
|
promptCounter += 1;
|
|
312
299
|
const dir = join(stateDir, "prompts");
|
|
313
300
|
mkdirSync(dir, { recursive: true });
|
|
314
301
|
return join(dir, `command-${String(promptCounter).padStart(3, "0")}.md`);
|
|
315
302
|
}
|
|
316
|
-
|
|
317
303
|
function readPromptText(promptFile) {
|
|
318
304
|
if (!promptFile) return undefined;
|
|
319
305
|
try {
|
|
@@ -322,7 +308,6 @@ export async function runAsyncRunner(stateDir = process.argv[2]) {
|
|
|
322
308
|
return undefined;
|
|
323
309
|
}
|
|
324
310
|
}
|
|
325
|
-
|
|
326
311
|
async function observedExec(command, args, options) {
|
|
327
312
|
captureCounter += 1;
|
|
328
313
|
const commandId = `command-${String(captureCounter).padStart(3, "0")}`;
|
|
@@ -485,7 +470,6 @@ export async function runAsyncRunner(stateDir = process.argv[2]) {
|
|
|
485
470
|
progressRunning();
|
|
486
471
|
return result;
|
|
487
472
|
}
|
|
488
|
-
|
|
489
473
|
try {
|
|
490
474
|
event("run.runner.start", { pid: process.pid });
|
|
491
475
|
progressRunning();
|
package/scripts/build-dist.mjs
CHANGED
|
@@ -40,12 +40,21 @@ writeFileSync(
|
|
|
40
40
|
"utf8",
|
|
41
41
|
);
|
|
42
42
|
|
|
43
|
-
for (const dir of ["scripts", "
|
|
43
|
+
for (const dir of ["scripts", "fixtures", "skills"]) {
|
|
44
44
|
cpSync(dir, join("dist", dir), { recursive: true });
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
.
|
|
49
|
-
|
|
47
|
+
function listModuleScripts(root) {
|
|
48
|
+
return readdirSync(root, { withFileTypes: true }).flatMap((entry) => {
|
|
49
|
+
const path = join(root, entry.name);
|
|
50
|
+
if (entry.isDirectory()) return listModuleScripts(path);
|
|
51
|
+
return entry.isFile() && entry.name.endsWith(".mjs") ? [path] : [];
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const builtScripts = [
|
|
56
|
+
...listModuleScripts(join("dist", "scripts")),
|
|
57
|
+
...listModuleScripts(join("dist", "skills")),
|
|
58
|
+
];
|
|
50
59
|
|
|
51
60
|
run(process.execPath, ["--check", ...builtScripts]);
|
package/skills/actors/SKILL.md
CHANGED
|
@@ -29,7 +29,7 @@ A Recipe defines execution. It may declare named typed args, inline fallbacks, c
|
|
|
29
29
|
|
|
30
30
|
Do not declare Control for ordinary one-shot work. Runtime lifecycle actions such as `kill` stay runtime-owned and must not appear in Recipe Control declarations. Imported Recipes act as local definitions inside one Run; they do not create nested Runs unless execution explicitly spawns them.
|
|
31
31
|
|
|
32
|
-
Prefer maintained
|
|
32
|
+
Prefer maintained Skill-owned Recipes over ad hoc wrappers. Skill Recipe identity is `<active Skill name>/<Recipe filename stem>`; Recipe files have no top-level `name`. `SKILL.md` `name` is Pi host metadata matching its directory, not an additional pi-actors identity field. Use `<skill>/<recipe>` for an exact direct component or an explicit `.json` / `.md` path. Entry paths resolve from invocation `cwd`; relative imports resolve from the importing Recipe directory. File-backed Recipes own `{recipe_dir}` and Skill Recipes own `{skill_dir}`; callers never pass or override these origins. Skill Recipes are components, not automatic tools. Keep model, thinking, mission, concurrency, quorum, and timeout choices caller-owned unless a Recipe documents a stable policy.
|
|
33
33
|
|
|
34
34
|
## Trace
|
|
35
35
|
|
|
@@ -90,11 +90,11 @@ If work may outlive the current turn, needs steering, produces artifacts, fans o
|
|
|
90
90
|
|
|
91
91
|
## Top Recipes
|
|
92
92
|
|
|
93
|
-
- [Repository health](
|
|
94
|
-
- [Quorum review](
|
|
95
|
-
- [Artifact bundle](
|
|
96
|
-
- [Music player service](
|
|
97
|
-
- [Resource locker service](
|
|
93
|
+
- [Repository health](../project-work/recipes/repo-health.json)
|
|
94
|
+
- [Quorum review](../swarm/recipes/quorum-review.json)
|
|
95
|
+
- [Artifact bundle](../artifacts/recipes/bundle.json)
|
|
96
|
+
- [Music player service](../media/recipes/player.json)
|
|
97
|
+
- [Resource locker service](./recipes/resource-locker.json)
|
|
98
98
|
|
|
99
99
|
## Deep References
|
|
100
100
|
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"args": [
|
|
3
|
-
"repo:path",
|
|
4
3
|
"state_dir:path",
|
|
5
4
|
"lines:int"
|
|
6
5
|
],
|
|
7
6
|
"defaults": {
|
|
8
|
-
"repo": "~/.pi/agent/extensions/pi-actors",
|
|
9
7
|
"state_dir": "~/.pi/agent/tmp/pi-actors/runs/coordinator-locker",
|
|
10
8
|
"lines": "20"
|
|
11
9
|
},
|
|
12
|
-
"template": "{
|
|
10
|
+
"template": "{skill_dir}/scripts/resource-locker.mjs snapshot --state-dir {state_dir} --lines {lines}"
|
|
13
11
|
}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"async": true,
|
|
3
3
|
"args": [
|
|
4
|
-
"repo:path",
|
|
5
4
|
"lease_ms:int"
|
|
6
5
|
],
|
|
7
6
|
"defaults": {
|
|
8
|
-
"repo": "~/.pi/agent/extensions/pi-actors",
|
|
9
7
|
"lease_ms": "600000"
|
|
10
8
|
},
|
|
11
9
|
"control": [
|
|
@@ -23,5 +21,5 @@
|
|
|
23
21
|
"locks": "{state_dir}/locks.json",
|
|
24
22
|
"journal": "{state_dir}/journal.jsonl"
|
|
25
23
|
},
|
|
26
|
-
"template": "{
|
|
24
|
+
"template": "{skill_dir}/scripts/resource-locker.mjs serve --state-dir {state_dir} --lease-ms {lease_ms}"
|
|
27
25
|
}
|
package/{recipes/utility-run-ops-snapshot.json → skills/actors/recipes/run-ops-snapshot.json}
RENAMED
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"args": [
|
|
3
|
-
"repo:path",
|
|
4
3
|
"state_root:path",
|
|
5
4
|
"run_id:string",
|
|
6
5
|
"lines:int",
|
|
7
6
|
"stale_minutes:int"
|
|
8
7
|
],
|
|
9
8
|
"defaults": {
|
|
10
|
-
"repo": "~/.pi/agent/extensions/pi-actors",
|
|
11
9
|
"state_root": "~/.pi/agent/tmp/pi-actors/runs",
|
|
12
10
|
"run_id": "music",
|
|
13
11
|
"lines": "80",
|
|
14
12
|
"stale_minutes": "60"
|
|
15
13
|
},
|
|
16
|
-
"template": "{
|
|
14
|
+
"template": "{skill_dir}/scripts/run-utils.mjs run-ops-snapshot {state_root} {run_id} {lines} {stale_minutes}"
|
|
17
15
|
}
|