@llblab/pi-actors 0.29.3 → 0.30.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/BACKLOG.md +118 -199
- package/CHANGELOG.md +10 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +71 -315
- package/dist/lib/actor-inspector-tui.d.ts +35 -0
- package/dist/lib/actor-inspector-tui.js +159 -1
- package/dist/lib/observability.d.ts +34 -0
- package/dist/lib/observability.js +103 -1
- package/dist/lib/paths.d.ts +9 -0
- package/dist/lib/paths.js +15 -0
- package/dist/lib/pi.d.ts +19 -0
- package/dist/lib/pi.js +21 -0
- package/dist/lib/runtime.d.ts +5 -0
- package/dist/lib/runtime.js +48 -0
- package/dist/lib/tools.d.ts +9 -0
- package/dist/lib/tools.js +58 -8
- package/dist/skills/actors/SKILL.md +1 -1
- package/dist/skills/swarm/SKILL.md +1 -1
- package/index.ts +99 -379
- package/lib/actor-inspector-tui.ts +221 -1
- package/lib/observability.ts +194 -34
- package/lib/paths.ts +27 -0
- package/lib/pi.ts +47 -0
- package/lib/runtime.ts +55 -0
- package/lib/tools.ts +119 -24
- package/package.json +1 -1
- package/skills/actors/SKILL.md +1 -1
- package/skills/swarm/SKILL.md +1 -1
package/lib/tools.ts
CHANGED
|
@@ -27,6 +27,34 @@ export type RegisterToolInput = Registry.RegisterToolInput;
|
|
|
27
27
|
export type RegisterToolRuntimeDeps<TContext> =
|
|
28
28
|
Registry.RegisterToolRuntimeDeps<TContext>;
|
|
29
29
|
|
|
30
|
+
export interface CoreActorToolDefinitionDeps<TContext extends AsyncRunToolContext> {
|
|
31
|
+
configPath: string;
|
|
32
|
+
getActiveTools: () => string[];
|
|
33
|
+
getRuntimeTool: (name: string) => unknown;
|
|
34
|
+
registryRuntime: Pick<
|
|
35
|
+
RegisterToolRuntimeDeps<TContext>,
|
|
36
|
+
| "getExternalToolConflict"
|
|
37
|
+
| "getTools"
|
|
38
|
+
| "notify"
|
|
39
|
+
| "registerRuntimeTool"
|
|
40
|
+
>;
|
|
41
|
+
setActiveTools: (toolNames: string[]) => void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const RESERVED_TOOL_NAMES = new Set([
|
|
45
|
+
"read",
|
|
46
|
+
"write",
|
|
47
|
+
"edit",
|
|
48
|
+
"bash",
|
|
49
|
+
"find",
|
|
50
|
+
"grep",
|
|
51
|
+
"ls",
|
|
52
|
+
"register_tool",
|
|
53
|
+
"message",
|
|
54
|
+
"spawn",
|
|
55
|
+
"inspect",
|
|
56
|
+
]);
|
|
57
|
+
|
|
30
58
|
type JsonSchema = Record<string, unknown>;
|
|
31
59
|
|
|
32
60
|
function stringSchema(description: string): JsonSchema {
|
|
@@ -183,7 +211,8 @@ function compactAsyncRunStatus(value: unknown): string {
|
|
|
183
211
|
tokens.push(`failures=${failures}`);
|
|
184
212
|
if (result.code !== undefined) tokens.push(`code=${String(result.code)}`);
|
|
185
213
|
if (result.killed === true) tokens.push("killed=true");
|
|
186
|
-
if (status.candidate_recipe)
|
|
214
|
+
if (status.candidate_recipe)
|
|
215
|
+
tokens.push(`candidate_recipe=${String(status.candidate_recipe)}`);
|
|
187
216
|
return `\n${tokens.join(" ")}`;
|
|
188
217
|
}
|
|
189
218
|
|
|
@@ -448,10 +477,17 @@ function compactSessionRuns(
|
|
|
448
477
|
summary: Record<string, unknown> = {},
|
|
449
478
|
): string {
|
|
450
479
|
const suffix = [
|
|
451
|
-
summary.other_sessions !== undefined
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
480
|
+
summary.other_sessions !== undefined
|
|
481
|
+
? `other_sessions=${String(summary.other_sessions)}`
|
|
482
|
+
: "",
|
|
483
|
+
summary.other_runs !== undefined
|
|
484
|
+
? `other_runs=${String(summary.other_runs)}`
|
|
485
|
+
: "",
|
|
486
|
+
]
|
|
487
|
+
.filter(Boolean)
|
|
488
|
+
.join(" ");
|
|
489
|
+
if (runs.length === 0)
|
|
490
|
+
return `\nsession=${session} runs=0${suffix ? ` ${suffix}` : ""}`;
|
|
455
491
|
return `\nsession=${session} runs=${runs.length}${suffix ? ` ${suffix}` : ""}\n${runs
|
|
456
492
|
.map((run) => {
|
|
457
493
|
const tokens = [
|
|
@@ -471,14 +507,21 @@ function getPiActorsRuntimeStatus(): Record<string, unknown> {
|
|
|
471
507
|
const packageRoot = dirname(packagedRecipeRoot);
|
|
472
508
|
const packageJsonPath = join(packageRoot, "package.json");
|
|
473
509
|
const packageJson = existsSync(packageJsonPath)
|
|
474
|
-
? JSON.parse(readFileSync(packageJsonPath, "utf8")) as Record<
|
|
510
|
+
? (JSON.parse(readFileSync(packageJsonPath, "utf8")) as Record<
|
|
511
|
+
string,
|
|
512
|
+
unknown
|
|
513
|
+
>)
|
|
475
514
|
: {};
|
|
476
515
|
let git_commit: string | undefined;
|
|
477
516
|
try {
|
|
478
|
-
git_commit = execFileSync(
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
517
|
+
git_commit = execFileSync(
|
|
518
|
+
"git",
|
|
519
|
+
["-C", packageRoot, "rev-parse", "--short", "HEAD"],
|
|
520
|
+
{
|
|
521
|
+
encoding: "utf8",
|
|
522
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
523
|
+
},
|
|
524
|
+
).trim();
|
|
482
525
|
} catch {
|
|
483
526
|
git_commit = undefined;
|
|
484
527
|
}
|
|
@@ -510,12 +553,13 @@ function compactToolActor(name: string, tool: Record<string, unknown>): string {
|
|
|
510
553
|
|
|
511
554
|
function compactRecipeImports(summary: Record<string, unknown>): string {
|
|
512
555
|
const active = Array.isArray(summary.active)
|
|
513
|
-
? summary.active as Array<Record<string, unknown>>
|
|
556
|
+
? (summary.active as Array<Record<string, unknown>>)
|
|
514
557
|
: [];
|
|
515
558
|
const lines = active.flatMap((entry) => {
|
|
516
559
|
const imports = asRecord(entry.imports);
|
|
517
560
|
return Object.entries(imports).map(([alias, value]) => {
|
|
518
|
-
const binding =
|
|
561
|
+
const binding =
|
|
562
|
+
typeof value === "string" ? { from: value } : asRecord(value);
|
|
519
563
|
return `recipe=${String(entry.id ?? "<unknown>")} alias=${alias} from=${String(binding.from ?? value)}`;
|
|
520
564
|
});
|
|
521
565
|
});
|
|
@@ -552,7 +596,10 @@ function compactRecipeDoctor(summary: Record<string, unknown>): string {
|
|
|
552
596
|
);
|
|
553
597
|
}
|
|
554
598
|
for (const item of remediations.slice(0, 8)) {
|
|
555
|
-
const action = compactPreview(
|
|
599
|
+
const action = compactPreview(
|
|
600
|
+
item.action,
|
|
601
|
+
Limits.DOCTOR_ACTION_PREVIEW_CHARS,
|
|
602
|
+
);
|
|
556
603
|
const blocked = item.blocked_candidate
|
|
557
604
|
? ` blocked=${compactPreview(item.blocked_candidate, Limits.DOCTOR_ACTION_PREVIEW_CHARS)}`
|
|
558
605
|
: "";
|
|
@@ -717,7 +764,11 @@ function formatToolActorFailure(
|
|
|
717
764
|
function shadowedRecipeLaunchDiagnostic(
|
|
718
765
|
recipe: unknown,
|
|
719
766
|
): Record<string, unknown> | undefined {
|
|
720
|
-
if (
|
|
767
|
+
if (
|
|
768
|
+
typeof recipe !== "string" ||
|
|
769
|
+
recipe.includes("/") ||
|
|
770
|
+
recipe.includes("~")
|
|
771
|
+
)
|
|
721
772
|
return undefined;
|
|
722
773
|
const discovery = RecipeDiscovery.discoverRecipeSources([
|
|
723
774
|
{ root: Paths.getRecipeRoot(), defaultTool: true, mutableUsage: true },
|
|
@@ -730,7 +781,9 @@ function candidateRecipeName(run: string): string {
|
|
|
730
781
|
return `${run.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "spawn"}.json`;
|
|
731
782
|
}
|
|
732
783
|
|
|
733
|
-
function candidateRecipeDefaults(
|
|
784
|
+
function candidateRecipeDefaults(
|
|
785
|
+
values: Record<string, unknown>,
|
|
786
|
+
): Record<string, unknown> | undefined {
|
|
734
787
|
const ignored = new Set([
|
|
735
788
|
"actor_address",
|
|
736
789
|
"communication_file",
|
|
@@ -753,7 +806,11 @@ function writeSpawnCandidateRecipe(
|
|
|
753
806
|
process.env.PI_ACTORS_ENABLE_SPAWN_CANDIDATES_IN_TEST !== "1"
|
|
754
807
|
)
|
|
755
808
|
return undefined;
|
|
756
|
-
if (
|
|
809
|
+
if (
|
|
810
|
+
input.template === undefined ||
|
|
811
|
+
input.file !== undefined ||
|
|
812
|
+
input.recipe !== undefined
|
|
813
|
+
)
|
|
757
814
|
return undefined;
|
|
758
815
|
const root = Paths.getRecipeCandidateRoot();
|
|
759
816
|
mkdirSync(root, { recursive: true });
|
|
@@ -772,7 +829,8 @@ function writeSpawnCandidateRecipe(
|
|
|
772
829
|
|
|
773
830
|
function enhanceSpawnRecipeError(error: unknown, recipe: unknown): Error {
|
|
774
831
|
const diagnostic = shadowedRecipeLaunchDiagnostic(recipe);
|
|
775
|
-
if (!diagnostic)
|
|
832
|
+
if (!diagnostic)
|
|
833
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
776
834
|
const original = error instanceof Error ? error.message : String(error);
|
|
777
835
|
return Object.assign(
|
|
778
836
|
new Error(
|
|
@@ -832,12 +890,17 @@ async function routeBranchEnvelope(
|
|
|
832
890
|
try {
|
|
833
891
|
return await AsyncRuns.sendRunMessage(runId, JSON.stringify(branchMessage));
|
|
834
892
|
} catch (error) {
|
|
835
|
-
const record =
|
|
893
|
+
const record =
|
|
894
|
+
error && typeof error === "object"
|
|
895
|
+
? (error as Record<string, unknown>)
|
|
896
|
+
: {};
|
|
836
897
|
if (record.queued === true) {
|
|
837
898
|
return {
|
|
838
899
|
control_path: record.control_path,
|
|
839
900
|
control_type: record.control_type,
|
|
840
|
-
delivery_error:
|
|
901
|
+
delivery_error:
|
|
902
|
+
record.delivery_error ??
|
|
903
|
+
(error instanceof Error ? error.message : String(error)),
|
|
841
904
|
inbox_id: record.inbox_id,
|
|
842
905
|
queued: true,
|
|
843
906
|
run: runId,
|
|
@@ -1070,7 +1133,12 @@ export function createInspectToolDefinition<TContext = unknown>(
|
|
|
1070
1133
|
const target = String(input.target ?? "");
|
|
1071
1134
|
const view = String(input.view ?? "");
|
|
1072
1135
|
if (target === "recipes" || target === "recipe-registry") {
|
|
1073
|
-
if (
|
|
1136
|
+
if (
|
|
1137
|
+
view !== "status" &&
|
|
1138
|
+
view !== "summary" &&
|
|
1139
|
+
view !== "doctor" &&
|
|
1140
|
+
view !== "imports"
|
|
1141
|
+
) {
|
|
1074
1142
|
throw new Error(
|
|
1075
1143
|
"inspect recipes supports view=status, view=summary, view=doctor, or view=imports.",
|
|
1076
1144
|
);
|
|
@@ -1086,7 +1154,9 @@ export function createInspectToolDefinition<TContext = unknown>(
|
|
|
1086
1154
|
const recipeRoot = deps.recipeRoot ?? Paths.getRecipeRoot();
|
|
1087
1155
|
const summary = {
|
|
1088
1156
|
...RecipeDiscovery.summarizeDiscovery(discovered),
|
|
1089
|
-
candidates: RecipeDiscovery.listCandidateRecipes(
|
|
1157
|
+
candidates: RecipeDiscovery.listCandidateRecipes(
|
|
1158
|
+
join(recipeRoot, "candidates"),
|
|
1159
|
+
),
|
|
1090
1160
|
};
|
|
1091
1161
|
return {
|
|
1092
1162
|
content: [
|
|
@@ -1147,9 +1217,10 @@ export function createInspectToolDefinition<TContext = unknown>(
|
|
|
1147
1217
|
const runs = allRuns.filter(
|
|
1148
1218
|
(run) => address.value === "all" || run.ownerId === address.value,
|
|
1149
1219
|
);
|
|
1150
|
-
const sessionSummary =
|
|
1151
|
-
|
|
1152
|
-
|
|
1220
|
+
const sessionSummary =
|
|
1221
|
+
address.value === "all"
|
|
1222
|
+
? {}
|
|
1223
|
+
: summarizeOtherSessions(address.value || "", allRuns);
|
|
1153
1224
|
return {
|
|
1154
1225
|
content: [
|
|
1155
1226
|
{
|
|
@@ -1725,6 +1796,30 @@ export function createActorMessageToolDefinition<TContext = unknown>(
|
|
|
1725
1796
|
};
|
|
1726
1797
|
}
|
|
1727
1798
|
|
|
1799
|
+
export function createCoreActorToolDefinitions<TContext extends AsyncRunToolContext>(
|
|
1800
|
+
deps: CoreActorToolDefinitionDeps<TContext>,
|
|
1801
|
+
): any[] {
|
|
1802
|
+
return [
|
|
1803
|
+
createRegisterToolDefinition<TContext>({
|
|
1804
|
+
configPath: deps.configPath,
|
|
1805
|
+
getActiveTools: deps.getActiveTools,
|
|
1806
|
+
getExternalToolConflict: deps.registryRuntime.getExternalToolConflict,
|
|
1807
|
+
getTools: deps.registryRuntime.getTools,
|
|
1808
|
+
notify: deps.registryRuntime.notify,
|
|
1809
|
+
registerRuntimeTool: deps.registryRuntime.registerRuntimeTool,
|
|
1810
|
+
reservedToolNames: RESERVED_TOOL_NAMES,
|
|
1811
|
+
setActiveTools: deps.setActiveTools,
|
|
1812
|
+
}),
|
|
1813
|
+
createSpawnToolDefinition<TContext>(),
|
|
1814
|
+
createActorMessageToolDefinition<TContext>({
|
|
1815
|
+
getTool: (name) => deps.getRuntimeTool(name),
|
|
1816
|
+
}),
|
|
1817
|
+
createInspectToolDefinition<TContext>({
|
|
1818
|
+
getTool: (name) => deps.getRuntimeTool(name),
|
|
1819
|
+
}),
|
|
1820
|
+
];
|
|
1821
|
+
}
|
|
1822
|
+
|
|
1728
1823
|
export function createRuntimeToolDefinition(
|
|
1729
1824
|
cfg: RegisteredTool,
|
|
1730
1825
|
exec: Execution.RegisteredToolExec,
|
package/package.json
CHANGED
package/skills/actors/SKILL.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: actors
|
|
3
3
|
description: Highest-density practical guide for pi-actors. Read this skill whenever prompt and tools are not enough for spawn, message, inspect, actor runs, tools, recipes, command templates, async lifecycle, mailboxes, artifacts, and local orchestration mechanics.
|
|
4
4
|
metadata:
|
|
5
|
-
version: 0.
|
|
5
|
+
version: 0.30.1
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Actors (pi-actors)
|
package/skills/swarm/SKILL.md
CHANGED