@llblab/pi-actors 0.45.1 → 0.46.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 +9 -7
- package/BACKLOG.md +582 -0
- package/CHANGELOG.md +17 -1
- package/README.md +27 -13
- package/dist/fixtures/protocol/recipe-summary.json +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/async-runs.d.ts +5 -1
- package/dist/lib/async-runs.js +26 -24
- 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/execution.d.ts +1 -0
- package/dist/lib/execution.js +1 -0
- package/dist/lib/extension-runtime.d.ts +1 -1
- package/dist/lib/extension-runtime.js +26 -4
- package/dist/lib/inspector.js +46 -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 +4 -4
- package/dist/lib/recipes-context.d.ts +12 -3
- package/dist/lib/recipes-context.js +30 -6
- package/dist/lib/recipes-discovery.d.ts +18 -0
- package/dist/lib/recipes-discovery.js +95 -22
- package/dist/lib/recipes-references.d.ts +42 -9
- package/dist/lib/recipes-references.js +248 -135
- package/dist/lib/registry.d.ts +14 -1
- package/dist/lib/registry.js +110 -87
- package/dist/lib/runtime.d.ts +30 -4
- package/dist/lib/runtime.js +74 -12
- package/dist/lib/tools-inspect.d.ts +3 -1
- package/dist/lib/tools-inspect.js +56 -9
- package/dist/lib/tools-local.d.ts +2 -0
- package/dist/lib/tools-local.js +5 -2
- package/dist/lib/tools-response.js +2 -0
- package/dist/lib/tools-spawn.d.ts +2 -0
- package/dist/lib/tools-spawn.js +24 -52
- package/dist/lib/tools.d.ts +4 -1
- package/dist/lib/tools.js +2 -0
- package/dist/scripts/build-dist.mjs +13 -4
- package/dist/skills/actors/SKILL.md +8 -8
- 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 -2
- package/dist/skills/actors/scripts/run-utils.mjs +164 -0
- package/{scripts → dist/skills/actors/scripts}/validate-recipe.mjs +134 -17
- 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 +32 -14
- package/docs/tool-registry.md +10 -4
- package/fixtures/protocol/recipe-summary.json +1 -1
- package/index.ts +2 -1
- package/lib/async-runs.ts +52 -25
- package/lib/automatic-review-runtime.ts +16 -3
- package/lib/draft-sleep.ts +0 -1
- package/lib/execution.ts +2 -0
- package/lib/extension-runtime.ts +42 -4
- package/lib/inspector.ts +57 -11
- package/lib/paths.ts +0 -7
- package/lib/prompts.ts +4 -4
- package/lib/recipes-context.ts +51 -6
- package/lib/recipes-discovery.ts +164 -24
- package/lib/recipes-references.ts +359 -146
- package/lib/registry.ts +185 -94
- package/lib/runtime.ts +109 -17
- package/lib/tools-inspect.ts +77 -10
- package/lib/tools-local.ts +9 -1
- package/lib/tools-response.ts +2 -0
- package/lib/tools-spawn.ts +38 -74
- package/lib/tools.ts +4 -1
- package/package.json +2 -4
- package/scripts/build-dist.mjs +13 -4
- package/skills/actors/SKILL.md +8 -8
- 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 -2
- package/skills/actors/scripts/run-utils.mjs +164 -0
- package/{dist → skills/actors}/scripts/validate-recipe.mjs +134 -17
- 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/executable-block-style.d.mts +0 -1
- package/dist/scripts/executable-block-style.mjs +0 -73
- package/dist/scripts/recipe-utils.mjs +0 -404
- package/dist/scripts/release-gates.mjs +0 -281
- 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/executable-block-style.d.mts +0 -1
- package/scripts/executable-block-style.mjs +0 -73
- package/scripts/recipe-utils.mjs +0 -404
- package/scripts/release-gates.mjs +0 -281
- /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/dist/lib/tools-local.js
CHANGED
|
@@ -44,7 +44,8 @@ function shouldAddRuntimeToolUsageHint(error) {
|
|
|
44
44
|
return (/^Argument \S+ must /.test(message) || /^Missing .* value: /.test(message));
|
|
45
45
|
}
|
|
46
46
|
function formatRuntimeToolUsageHint(cfg, required, includeRunId) {
|
|
47
|
-
const optional = cfg.args.filter((arg) => !
|
|
47
|
+
const optional = cfg.args.filter((arg) => !RecipesReferences.isRuntimeOwnedRecipeInput(arg) &&
|
|
48
|
+
!required.includes(arg));
|
|
48
49
|
const exampleDefaults = {
|
|
49
50
|
...Schema.getExplicitToolArgDefaults(cfg.recipe?.args),
|
|
50
51
|
...cfg.defaults,
|
|
@@ -115,6 +116,8 @@ export function createRuntimeToolDefinition(cfg, exec) {
|
|
|
115
116
|
? new Set(cfg.args.filter((arg) => !Object.hasOwn(cfg.defaults, arg)))
|
|
116
117
|
: Schema.getRequiredToolArgNames(requiredTemplateConfig);
|
|
117
118
|
for (const arg of cfg.args) {
|
|
119
|
+
if (RecipesReferences.isRuntimeOwnedRecipeInput(arg))
|
|
120
|
+
continue;
|
|
118
121
|
paramSchema[arg] = typedArgSchema(arg, cfg.argTypes?.[arg]);
|
|
119
122
|
if (requiredArgs.has(arg))
|
|
120
123
|
required.push(arg);
|
|
@@ -160,7 +163,7 @@ export function createRuntimeToolDefinition(cfg, exec) {
|
|
|
160
163
|
tool: cfg.name,
|
|
161
164
|
policy_values: ModelContext.withCurrentModelValues({ ...(cfg.recipe?.values ?? {}), ...values }, ctx),
|
|
162
165
|
values: resolveRecipeToolValues(cfg, values, ctx),
|
|
163
|
-
}, ctx.cwd);
|
|
166
|
+
}, ctx.cwd, { skillContext: ctx.recipeResolutionContext?.activeSkills });
|
|
164
167
|
return {
|
|
165
168
|
content: [
|
|
166
169
|
{
|
|
@@ -91,6 +91,8 @@ export function compactAsyncRunStatus(value) {
|
|
|
91
91
|
const result = asRecord(status.result);
|
|
92
92
|
const run = String(status.run ?? "<unknown>");
|
|
93
93
|
const tokens = [`run=${run}`, `status=${String(status.status ?? "unknown")}`];
|
|
94
|
+
if (status.launch_kind)
|
|
95
|
+
tokens.push(`launch_kind=${String(status.launch_kind)}`);
|
|
94
96
|
tokens.push(...compactModelPolicy(status.model_policy ?? progress.model_policy));
|
|
95
97
|
if (status.tool)
|
|
96
98
|
tokens.push(`tool=${String(status.tool)}`);
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
* Owns the public spawn execution path for run-backed actors
|
|
5
5
|
*/
|
|
6
6
|
import * as ModelContext from "./model-context.ts";
|
|
7
|
+
import type * as RecipeResolution from "./recipes-context.ts";
|
|
7
8
|
export interface SpawnToolContext extends ModelContext.CurrentModelContext {
|
|
9
|
+
recipeResolutionContext?: RecipeResolution.RecipeResolutionContext;
|
|
8
10
|
cwd: string;
|
|
9
11
|
sessionManager?: {
|
|
10
12
|
getSessionId?: () => string;
|
package/dist/lib/tools-spawn.js
CHANGED
|
@@ -9,7 +9,6 @@ import * as AsyncRuns from "./async-runs.js";
|
|
|
9
9
|
import { withFileMutationLock } from "./file-state.js";
|
|
10
10
|
import * as ModelContext from "./model-context.js";
|
|
11
11
|
import * as Paths from "./paths.js";
|
|
12
|
-
import * as RecipesDiscovery from "./recipes-discovery.js";
|
|
13
12
|
import * as RecipesUsage from "./recipes-usage.js";
|
|
14
13
|
import * as Schema from "./schema.js";
|
|
15
14
|
import * as ToolsResponse from "./tools-response.js";
|
|
@@ -18,17 +17,6 @@ const maybeJsonText = ToolsResponse.maybeJsonText;
|
|
|
18
17
|
function getRunOwnerId(ctx) {
|
|
19
18
|
return ctx.sessionManager?.getSessionId?.();
|
|
20
19
|
}
|
|
21
|
-
function shadowedRecipeLaunchDiagnostic(recipe) {
|
|
22
|
-
if (typeof recipe !== "string" ||
|
|
23
|
-
recipe.includes("/") ||
|
|
24
|
-
recipe.includes("~"))
|
|
25
|
-
return undefined;
|
|
26
|
-
const discovery = RecipesDiscovery.discoverRecipeSources([
|
|
27
|
-
{ root: Paths.getRecipeRoot(), defaultTool: true, mutableUsage: true },
|
|
28
|
-
{ root: Paths.getPackagedRecipeRoot(), defaultTool: false },
|
|
29
|
-
]);
|
|
30
|
-
return RecipesDiscovery.getShadowedLaunchDiagnostic(discovery, recipe);
|
|
31
|
-
}
|
|
32
20
|
function draftRecipeName(run) {
|
|
33
21
|
return `${run.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "spawn"}.json`;
|
|
34
22
|
}
|
|
@@ -60,16 +48,6 @@ function writeSpawnDraftRecipe(input, meta) {
|
|
|
60
48
|
RecipesUsage.recordRecipeLaunch(path, new Date(), "spawn", Paths.getRecipeRoot());
|
|
61
49
|
return path;
|
|
62
50
|
}
|
|
63
|
-
function enhanceSpawnRecipeError(error, recipe) {
|
|
64
|
-
const diagnostic = shadowedRecipeLaunchDiagnostic(recipe);
|
|
65
|
-
if (!diagnostic)
|
|
66
|
-
return error instanceof Error ? error : new Error(String(error));
|
|
67
|
-
const original = error instanceof Error ? error.message : String(error);
|
|
68
|
-
return Object.assign(new Error(`${original} reason=${diagnostic.reason} active_path=${diagnostic.active_path} blocked_fallback=${diagnostic.blocked_fallback} hint=${diagnostic.hint}`), {
|
|
69
|
-
...diagnostic,
|
|
70
|
-
original_error: original,
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
51
|
function runIdFromTarget(target) {
|
|
74
52
|
if (!target)
|
|
75
53
|
return undefined;
|
|
@@ -90,8 +68,8 @@ export function createSpawnToolDefinition() {
|
|
|
90
68
|
parameters: Schema.objectSchema({
|
|
91
69
|
artifacts: Schema.looseObjectSchema("Optional named artifact paths for the spawned Run."),
|
|
92
70
|
as: Schema.stringSchema("Optional Run identity in exact run:<id> form."),
|
|
93
|
-
file: Schema.stringSchema("Optional
|
|
94
|
-
recipe: Schema.stringSchema("Alias for file
|
|
71
|
+
file: Schema.stringSchema("Optional Recipe reference as <skill>/<recipe> or an explicit .json/.md file path."),
|
|
72
|
+
recipe: Schema.stringSchema("Alias for file."),
|
|
95
73
|
template: Schema.unionSchema([
|
|
96
74
|
Schema.stringSchema("Inline command template string"),
|
|
97
75
|
Schema.arraySchema("Inline command-template sequence or parallel tree"),
|
|
@@ -112,34 +90,28 @@ export function createSpawnToolDefinition() {
|
|
|
112
90
|
: typeof input.recipe === "string"
|
|
113
91
|
? input.recipe
|
|
114
92
|
: undefined;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
: {}),
|
|
138
|
-
}, ctx.cwd);
|
|
139
|
-
}
|
|
140
|
-
catch (error) {
|
|
141
|
-
throw enhanceSpawnRecipeError(error, recipe);
|
|
142
|
-
}
|
|
93
|
+
const meta = AsyncRuns.startRun({
|
|
94
|
+
file: recipe,
|
|
95
|
+
launch_source: "spawn",
|
|
96
|
+
launch_correlation: { tool_call_id: toolCallId },
|
|
97
|
+
ownerId: getRunOwnerId(ctx),
|
|
98
|
+
...(input.transport_context
|
|
99
|
+
? { transport_context: asRecord(input.transport_context) } : {}),
|
|
100
|
+
run_id: runId,
|
|
101
|
+
...(input.template !== undefined
|
|
102
|
+
? {
|
|
103
|
+
template: input.template,
|
|
104
|
+
}
|
|
105
|
+
: {}),
|
|
106
|
+
values: ModelContext.withCurrentModelValues(asRecord(input.values), ctx),
|
|
107
|
+
...(input.artifacts &&
|
|
108
|
+
typeof input.artifacts === "object" &&
|
|
109
|
+
!Array.isArray(input.artifacts)
|
|
110
|
+
? {
|
|
111
|
+
artifacts: input.artifacts,
|
|
112
|
+
}
|
|
113
|
+
: {}),
|
|
114
|
+
}, ctx.cwd, { skillContext: ctx.recipeResolutionContext?.activeSkills });
|
|
143
115
|
const draftRecipe = writeSpawnDraftRecipe(input, meta);
|
|
144
116
|
const nextActions = ToolsResponse.runNextActions(meta.run);
|
|
145
117
|
const details = {
|
package/dist/lib/tools.d.ts
CHANGED
|
@@ -15,8 +15,11 @@ export interface CoreActorToolDefinitionDeps<TContext extends RuntimeToolContext
|
|
|
15
15
|
configPath: string;
|
|
16
16
|
getActiveTools: () => string[];
|
|
17
17
|
getRuntimeTool: (name: string) => unknown;
|
|
18
|
+
getRuntimeToolStatus: (name: string) => Record<string, unknown> | undefined;
|
|
18
19
|
handleRuntimeControl?: (action: string, input: unknown) => Record<string, unknown>;
|
|
19
|
-
registryRuntime: Pick<RegisterToolRuntimeDeps<TContext>, "getToolNameBlocker" | "getTools" | "notify" | "registerRuntimeTool"
|
|
20
|
+
registryRuntime: Pick<RegisterToolRuntimeDeps<TContext>, "getToolNameBlocker" | "getTools" | "notify" | "registerRuntimeTool"> & {
|
|
21
|
+
getStatus(): import("./runtime.ts").RecipeRegistryStatus;
|
|
22
|
+
};
|
|
20
23
|
setActiveTools: (toolNames: string[]) => void;
|
|
21
24
|
}
|
|
22
25
|
export declare function resolveActiveRuntimeTool(name: string, activeTools: Pick<Map<string, unknown>, "has">, getDefinition: (name: string) => unknown): unknown;
|
package/dist/lib/tools.js
CHANGED
|
@@ -41,6 +41,8 @@ export function createCoreActorToolDefinitions(deps) {
|
|
|
41
41
|
}),
|
|
42
42
|
ToolsInspect.createInspectToolDefinition({
|
|
43
43
|
getTool: (name) => deps.getRuntimeTool(name),
|
|
44
|
+
getToolStatus: deps.getRuntimeToolStatus,
|
|
45
|
+
registryStatus: deps.registryRuntime.getStatus,
|
|
44
46
|
}),
|
|
45
47
|
];
|
|
46
48
|
}
|
|
@@ -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]);
|
|
@@ -19,9 +19,9 @@ Use the swarm skill separately for decomposition, quorum design, reviewer lenses
|
|
|
19
19
|
- `spawn`: create one Run from a Recipe or inline command template.
|
|
20
20
|
- `message`: send one actor-local Control to `run:<id>`, or the reserved review actions to `runtime`.
|
|
21
21
|
- `inspect`: inspect `run:<id>`, `runtime`, `recipes`, or `tool:<name>`.
|
|
22
|
-
- `register_tool`: persist a trusted capability; it does not address a running actor.
|
|
22
|
+
- `register_tool`: persist a trusted capability; it does not address a running actor. Trust current-session callability only when its result says `callable_now: true`.
|
|
23
23
|
|
|
24
|
-
A Run target exposes exactly three inspect views: `recipe`, `trace`, and `control`.
|
|
24
|
+
A Run target exposes exactly three inspect views: `recipe`, `trace`, and `control`. Spawning a user Recipe is still a Recipe launch (`launch_kind: "spawn"`), not evidence that its registered tool was exposed or invoked; registered-tool execution reports `launch_kind: "tool"`, and `inspect target=tool:<name> view=status` separates both usage counts.
|
|
25
25
|
|
|
26
26
|
## Recipe
|
|
27
27
|
|
|
@@ -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. A rejected component makes catalog inspection partial without blocking exact resolution of unrelated valid components in the same live session context. 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/dist/{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
|
}
|
|
@@ -21,12 +21,12 @@ import readline from "node:readline";
|
|
|
21
21
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
22
22
|
|
|
23
23
|
function packageRoot() {
|
|
24
|
-
return dirname(dirname(fileURLToPath(import.meta.url)));
|
|
24
|
+
return dirname(dirname(dirname(dirname(fileURLToPath(import.meta.url)))));
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
async function importRuntimeModule(name) {
|
|
28
28
|
const root = packageRoot();
|
|
29
|
-
const compiled = join(root, "
|
|
29
|
+
const compiled = join(root, "lib", `${name}.js`);
|
|
30
30
|
const source = join(root, "lib", `${name}.ts`);
|
|
31
31
|
return await import(pathToFileURL(existsSync(compiled) ? compiled : source).href);
|
|
32
32
|
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/** Actor-owned Run summary utilities. */
|
|
4
|
+
|
|
5
|
+
// @ts-nocheck
|
|
6
|
+
|
|
7
|
+
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
8
|
+
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
9
|
+
|
|
10
|
+
function fail(message) {
|
|
11
|
+
console.error(message);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function usage() {
|
|
16
|
+
console.error(`Usage:
|
|
17
|
+
run-utils.mjs run-summary <state-root>
|
|
18
|
+
run-utils.mjs run-ops-snapshot <state-root> <run-id> [lines] [stale-minutes]`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function walkFiles(dir, maxDepth = 2, depth = 0, out = []) {
|
|
22
|
+
if (depth > maxDepth || !existsSync(dir)) return out;
|
|
23
|
+
for (const entry of readdirSync(dir)) {
|
|
24
|
+
const path = join(dir, entry);
|
|
25
|
+
const stat = statSync(path);
|
|
26
|
+
if (stat.isDirectory()) walkFiles(path, maxDepth, depth + 1, out);
|
|
27
|
+
else if (stat.isFile()) out.push(path);
|
|
28
|
+
}
|
|
29
|
+
return out;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function readJson(file) {
|
|
33
|
+
if (!existsSync(file)) return undefined;
|
|
34
|
+
try {
|
|
35
|
+
return JSON.parse(readFileSync(file, "utf8"));
|
|
36
|
+
} catch {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function getRunStatus(run, progress, result) {
|
|
42
|
+
if (progress?.phase) return progress.phase;
|
|
43
|
+
if (result?.code !== undefined) return result.code === 0 ? "done" : "failed";
|
|
44
|
+
return run.status ?? "unknown";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function collectRunSummary(rootValue) {
|
|
48
|
+
const root = resolve(rootValue.replace(/^~(?=\/|$)/, process.env.HOME ?? "~"));
|
|
49
|
+
const files = walkFiles(root, 2).filter((file) => basename(file) === "run.json");
|
|
50
|
+
const rows = [];
|
|
51
|
+
for (const file of files) {
|
|
52
|
+
const run = readJson(file);
|
|
53
|
+
if (!run) {
|
|
54
|
+
rows.push({ run: relative(root, file), status: "invalid-json", recipe: "", updated: "" });
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const runDir = dirname(file);
|
|
58
|
+
const progress = readJson(join(runDir, "progress.json"));
|
|
59
|
+
const result = readJson(join(runDir, "result.json"));
|
|
60
|
+
rows.push({
|
|
61
|
+
run: run.run_id ?? run.run ?? relative(root, file).split(sep)[0],
|
|
62
|
+
status: getRunStatus(run, progress, result),
|
|
63
|
+
recipe: run.recipe ?? run.recipe_file ?? "",
|
|
64
|
+
updated:
|
|
65
|
+
progress?.updatedAt ??
|
|
66
|
+
result?.completedAt ??
|
|
67
|
+
run.updated_at ??
|
|
68
|
+
run.completed_at ??
|
|
69
|
+
run.started_at ??
|
|
70
|
+
"",
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
rows.sort((a, b) => `${a.status}:${a.run}`.localeCompare(`${b.status}:${b.run}`));
|
|
74
|
+
return rows;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function tailJsonl(fileValue, linesValue = "80") {
|
|
78
|
+
const file = resolve(fileValue.replace(/^~(?=\/|$)/, process.env.HOME ?? "~"));
|
|
79
|
+
if (!existsSync(file)) return [];
|
|
80
|
+
const lines = Number.parseInt(linesValue, 10);
|
|
81
|
+
const count = Number.isFinite(lines) && lines > 0 ? lines : 80;
|
|
82
|
+
return readFileSync(file, "utf8")
|
|
83
|
+
.trimEnd()
|
|
84
|
+
.split("\n")
|
|
85
|
+
.filter(Boolean)
|
|
86
|
+
.slice(-count)
|
|
87
|
+
.map((line) => {
|
|
88
|
+
try {
|
|
89
|
+
return JSON.parse(line);
|
|
90
|
+
} catch {
|
|
91
|
+
return { raw: line };
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function runOpsSnapshot(
|
|
97
|
+
rootValue,
|
|
98
|
+
runIdValue = "music",
|
|
99
|
+
linesValue = "80",
|
|
100
|
+
staleMinutesValue = "60",
|
|
101
|
+
) {
|
|
102
|
+
const runs = collectRunSummary(rootValue);
|
|
103
|
+
const root = resolve(rootValue.replace(/^~(?=\/|$)/, process.env.HOME ?? "~"));
|
|
104
|
+
const inspectedRun = String(runIdValue || "music");
|
|
105
|
+
const staleMs = Number(staleMinutesValue) * 60 * 1000;
|
|
106
|
+
const now = Date.now();
|
|
107
|
+
const recommendations = runs.flatMap((run) => {
|
|
108
|
+
const updatedMs = Date.parse(run.updated || "");
|
|
109
|
+
const stale =
|
|
110
|
+
Number.isFinite(updatedMs) &&
|
|
111
|
+
Number.isFinite(staleMs) &&
|
|
112
|
+
now - updatedMs > staleMs;
|
|
113
|
+
if (run.status === "running" && stale) {
|
|
114
|
+
return [{
|
|
115
|
+
run: run.run,
|
|
116
|
+
reason: "running-stale",
|
|
117
|
+
suggested_inspect: { target: `run:${run.run}`, view: "control" },
|
|
118
|
+
}];
|
|
119
|
+
}
|
|
120
|
+
if (["failed", "exited", "killed"].includes(run.status)) {
|
|
121
|
+
return [{
|
|
122
|
+
run: run.run,
|
|
123
|
+
reason: `terminal-${run.status}`,
|
|
124
|
+
suggested_inspect: { target: `run:${run.run}`, view: "trace" },
|
|
125
|
+
}];
|
|
126
|
+
}
|
|
127
|
+
return [];
|
|
128
|
+
});
|
|
129
|
+
console.log(JSON.stringify({
|
|
130
|
+
runs,
|
|
131
|
+
inspectedRun,
|
|
132
|
+
trace: tailJsonl(join(root, inspectedRun, "trace.jsonl"), linesValue),
|
|
133
|
+
recommendations,
|
|
134
|
+
}, null, 2));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function runSummary(rootValue) {
|
|
138
|
+
console.log(JSON.stringify(collectRunSummary(rootValue), null, 2));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function run(argv = process.argv.slice(2)) {
|
|
142
|
+
const [command, ...args] = argv;
|
|
143
|
+
if (command === "run-summary") {
|
|
144
|
+
runSummary(args[0] ?? "~/.pi/agent/tmp/pi-actors/runs");
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (command === "run-ops-snapshot") {
|
|
148
|
+
runOpsSnapshot(
|
|
149
|
+
args[0] ?? "~/.pi/agent/tmp/pi-actors/runs",
|
|
150
|
+
args[1] ?? "music",
|
|
151
|
+
args[2],
|
|
152
|
+
args[3],
|
|
153
|
+
);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
usage();
|
|
157
|
+
fail(`Unknown command: ${command ?? ""}`);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
run();
|
|
162
|
+
} catch (error) {
|
|
163
|
+
fail(error instanceof Error ? error.message : String(error));
|
|
164
|
+
}
|