@llblab/pi-actors 0.20.2 → 0.22.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.
Files changed (41) hide show
  1. package/BACKLOG.md +34 -80
  2. package/CHANGELOG.md +29 -0
  3. package/README.md +7 -1
  4. package/dist/index.js +11 -0
  5. package/dist/lib/actor-rooms.d.ts +1 -0
  6. package/dist/lib/actor-rooms.js +33 -1
  7. package/dist/lib/async-runs.d.ts +35 -1
  8. package/dist/lib/async-runs.js +318 -36
  9. package/dist/lib/command-templates.js +8 -1
  10. package/dist/lib/observability.d.ts +15 -0
  11. package/dist/lib/observability.js +103 -18
  12. package/dist/lib/recipe-discovery.js +13 -5
  13. package/dist/lib/recipe-references.js +137 -11
  14. package/dist/lib/runtime-notifier.d.ts +48 -0
  15. package/dist/lib/runtime-notifier.js +137 -0
  16. package/dist/lib/tools.js +18 -9
  17. package/docs/README.md +1 -1
  18. package/docs/actor-messages.md +8 -3
  19. package/docs/async-runs.md +7 -5
  20. package/docs/recipe-library.md +25 -8
  21. package/docs/template-recipes.md +37 -7
  22. package/docs/tool-registry.md +4 -3
  23. package/index.ts +14 -0
  24. package/lib/actor-rooms.ts +46 -1
  25. package/lib/async-runs.ts +433 -49
  26. package/lib/command-templates.ts +8 -1
  27. package/lib/observability.ts +133 -20
  28. package/lib/recipe-discovery.ts +21 -6
  29. package/lib/recipe-references.ts +141 -17
  30. package/lib/runtime-notifier.ts +207 -0
  31. package/lib/tools.ts +36 -13
  32. package/package.json +2 -3
  33. package/recipes/music-player.json +1 -1
  34. package/recipes/pipeline-room-swarm.json +1 -1
  35. package/scripts/coordinator.mjs +276 -135
  36. package/scripts/locker.mjs +87 -28
  37. package/scripts/music-player.mjs +401 -94
  38. package/scripts/validate-recipe.mjs +2 -2
  39. package/skills/actors/SKILL.md +10 -9
  40. package/skills/swarm/SKILL.md +1 -1
  41. package/index.js +0 -19
package/lib/tools.ts CHANGED
@@ -287,8 +287,11 @@ function compactCommunicationSnapshot(
287
287
  return `\nself=${snapshot.self} root=${snapshot.root} rooms=${snapshot.rooms.length} updated_at=${snapshot.updated_at}`;
288
288
  }
289
289
 
290
- function compactBranchInbox(messages: Array<Record<string, unknown>>): string {
291
- if (messages.length === 0) return "\n(no branch inbox messages)";
290
+ function compactInboxMessages(
291
+ messages: Array<Record<string, unknown>>,
292
+ emptyLabel: string,
293
+ ): string {
294
+ if (messages.length === 0) return `\n(no ${emptyLabel} messages)`;
292
295
  return `\n${messages
293
296
  .map((message) =>
294
297
  [
@@ -298,6 +301,7 @@ function compactBranchInbox(messages: Array<Record<string, unknown>>): string {
298
301
  `from=${String(message.from ?? "")}`,
299
302
  `to=${String(message.to ?? "")}`,
300
303
  ...(message.queued_at ? [`queued_at=${String(message.queued_at)}`] : []),
304
+ ...(message.sent_at ? [`sent_at=${String(message.sent_at)}`] : []),
301
305
  ...(message.claimed_at ? [`claimed_at=${String(message.claimed_at)}`] : []),
302
306
  ...(message.handled_at ? [`handled_at=${String(message.handled_at)}`] : []),
303
307
  ...(message.failed_at ? [`failed_at=${String(message.failed_at)}`] : []),
@@ -306,6 +310,18 @@ function compactBranchInbox(messages: Array<Record<string, unknown>>): string {
306
310
  .join("\n")}`;
307
311
  }
308
312
 
313
+ function compactBranchInbox(messages: Array<Record<string, unknown>>): string {
314
+ return compactInboxMessages(messages, "branch inbox");
315
+ }
316
+
317
+ function compactRunMailbox(
318
+ run: string,
319
+ mailbox: Record<string, unknown>,
320
+ messages: Array<Record<string, unknown>>,
321
+ ): string {
322
+ return `\nrun=${run} accepts=${Array.isArray(mailbox.accepts) ? mailbox.accepts.join(",") : ""} emits=${Array.isArray(mailbox.emits) ? mailbox.emits.join(",") : ""}${compactInboxMessages(messages, "run inbox")}`;
323
+ }
324
+
309
325
  function compactActorFiles(status: Record<string, unknown>): string {
310
326
  const run = String(status.run ?? "<unknown>");
311
327
  const artifacts = asRecord(status.artifacts);
@@ -984,18 +1000,23 @@ export function createInspectToolDefinition<TContext = unknown>(
984
1000
  case "mailbox": {
985
1001
  const status = assertRunAccessibleToContext(runId, ctx);
986
1002
  const mailbox = asRecord(status.mailbox);
1003
+ const messages = AsyncRuns.readRunInboxMessages(
1004
+ runId,
1005
+ Number(input.lines || 40),
1006
+ );
1007
+ const details = { mailbox, messages };
987
1008
  return {
988
1009
  content: [
989
1010
  {
990
1011
  type: "text" as const,
991
1012
  text: maybeJsonText(
992
- mailbox,
1013
+ details,
993
1014
  input.verbose === true,
994
- `\nrun=${String(status.run ?? runId)} accepts=${Array.isArray(mailbox.accepts) ? mailbox.accepts.join(",") : ""} emits=${Array.isArray(mailbox.emits) ? mailbox.emits.join(",") : ""}`,
1015
+ compactRunMailbox(String(status.run ?? runId), mailbox, messages),
995
1016
  ),
996
1017
  },
997
1018
  ],
998
- details: { mailbox },
1019
+ details,
999
1020
  };
1000
1021
  }
1001
1022
  case "communication": {
@@ -1089,7 +1110,7 @@ export function createActorMessageToolDefinition<TContext = unknown>(
1089
1110
  } else if (message.type === "control.kill") {
1090
1111
  result = AsyncRuns.killRun(address.value);
1091
1112
  } else {
1092
- result = AsyncRuns.sendRunMessage(
1113
+ result = await AsyncRuns.sendRunMessage(
1093
1114
  address.value,
1094
1115
  messageBodyToRunLine(message),
1095
1116
  );
@@ -1131,7 +1152,7 @@ export function createActorMessageToolDefinition<TContext = unknown>(
1131
1152
  ActorRooms.writeCommunicationSnapshot(stateDir, runId);
1132
1153
  ActorRooms.appendBranchInboxMessage(stateDir, runId, message.to, message);
1133
1154
  }
1134
- result = AsyncRuns.sendRunMessage(
1155
+ result = await AsyncRuns.sendRunMessage(
1135
1156
  address.value,
1136
1157
  JSON.stringify(message),
1137
1158
  );
@@ -1143,16 +1164,18 @@ export function createActorMessageToolDefinition<TContext = unknown>(
1143
1164
  if (!stateDir) throw new Error(`${message.to} has no run state directory.`);
1144
1165
  const recipients = getRoomMulticastRecipients(message, runId);
1145
1166
  const roomResult = ActorRooms.appendRoomMessage(stateDir, address.room, message);
1146
- const multicast = recipients.map((recipient) =>
1147
- AsyncRuns.sendRunMessage(
1148
- runId,
1149
- JSON.stringify({ ...message, to: recipient }),
1167
+ await Promise.all(
1168
+ recipients.map((recipient) =>
1169
+ AsyncRuns.sendRunMessage(
1170
+ runId,
1171
+ JSON.stringify({ ...message, to: recipient }),
1172
+ ),
1150
1173
  ),
1151
1174
  );
1152
1175
  result = {
1153
1176
  ...roomResult,
1154
- ...(multicast.length > 0
1155
- ? { multicast: recipients, multicast_count: multicast.length }
1177
+ ...(recipients.length > 0
1178
+ ? { multicast: recipients, multicast_count: recipients.length }
1156
1179
  : {}),
1157
1180
  };
1158
1181
  } else if (address.kind === "tool" && address.value) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llblab/pi-actors",
3
- "version": "0.20.2",
3
+ "version": "0.22.0",
4
4
  "private": false,
5
5
  "description": "Local Actor Kernel for Pi",
6
6
  "keywords": [
@@ -33,7 +33,6 @@
33
33
  "prepack": "npm run build"
34
34
  },
35
35
  "files": [
36
- "index.js",
37
36
  "index.ts",
38
37
  "lib",
39
38
  "scripts",
@@ -49,7 +48,7 @@
49
48
  ],
50
49
  "pi": {
51
50
  "extensions": [
52
- "./index.js"
51
+ "./dist/index.js"
53
52
  ],
54
53
  "skills": [
55
54
  "./skills/actors/SKILL.md",
@@ -6,7 +6,7 @@
6
6
  "source:string",
7
7
  "loop:bool",
8
8
  "volume:int",
9
- "player:enum(auto,mpv,ffplay,cvlc,play)",
9
+ "player:enum(auto,mpv,afplay,ffplay,cvlc,play,wmp)",
10
10
  "state_dir:path"
11
11
  ],
12
12
  "defaults": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "async": true,
3
3
  "args": [
4
- "mode:string",
4
+ "mode:enum(consensus,pipeline,fanout,pool)",
5
5
  "mission:string",
6
6
  "model:string",
7
7
  "thinking:string",