@llblab/pi-actors 0.19.0 → 0.19.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.19.1: Actor Inspector Hotfix
4
+
5
+ - `[Actor Inspector]` Fixed the live communications roster and row numbering controls after real swarm usage. `/actors-inspector-toggle <rows>` now keeps the room preview cap aligned with the requested row count, current-run sequence numbers are assigned before row limiting so the visible tail keeps its full-log positions, and roster role labels use concise `name/role` text instead of slugifying full role descriptions.
6
+ - `[Coordinator]` Preserved explicit `--thinking off` forwarding in `scripts/coordinator.mjs` so packaged room-swarm launches keep caller-selected thinking policy instead of silently relying on CLI defaults.
7
+ - `[Package]` Bumped package metadata, lockfile metadata, and packaged skill metadata to `0.19.1` for the hotfix release.
8
+
3
9
  ## 0.19.0: Modular Coordination And Active Mailboxes
4
10
 
5
11
  - `[Coordination]` Decoupled the overloaded `coordinator-locker.mjs` script into two completely independent, single-purpose components: a dedicated stateful `locker.mjs` (recipes `locker.json` and `coordinator-locker.json`) that manages resource locking, task queueing, and lease expirations; and a powerful, modular `coordinator.mjs` orchestrator. The coordinator manages execution lifecycles and process pools, supporting four distinct pluggable strategies via `--mode`: `consensus` (chat-swarm), `pipeline` (sequential), `fanout` (parallel review), and `pool` (worker pool pulling from locker).
package/index.ts CHANGED
@@ -54,7 +54,7 @@ export default function toolRegistryExtension(pi: ExtensionAPI) {
54
54
  | ActorInspectorTui.ActorInspectorPreview["channel"][]
55
55
  | undefined;
56
56
  let actorInspectorMention: string | undefined;
57
- const actorInspectorRoomLimitPerRun = 6;
57
+ let actorInspectorRoomLimitPerRun = 12;
58
58
  let selectedInspectorSequence: number | undefined;
59
59
  let recipeWatcherFailureNotified = false;
60
60
  const getRunOwnerId = (ctx: ExtensionContext): string =>
@@ -307,6 +307,7 @@ export default function toolRegistryExtension(pi: ExtensionAPI) {
307
307
  return;
308
308
  }
309
309
  actorInspectorRows = rows;
310
+ actorInspectorRoomLimitPerRun = rows;
310
311
  selectedInspectorSequence = undefined;
311
312
  communicationWidgetVisible = true;
312
313
  updateRunUi(ctx);
@@ -324,6 +325,7 @@ export default function toolRegistryExtension(pi: ExtensionAPI) {
324
325
  communicationWidgetVisible = false;
325
326
  } else {
326
327
  actorInspectorRows = 12;
328
+ actorInspectorRoomLimitPerRun = 12;
327
329
  communicationWidgetVisible = true;
328
330
  }
329
331
  updateRunUi(ctx);
@@ -164,7 +164,6 @@ function readRoomDisplayNames(stateDir: string, room: string): Record<string, st
164
164
  function readRoomPreviews(
165
165
  run: string,
166
166
  stateDir: string,
167
- limitPerRun?: number,
168
167
  ): ActorInspectorPreview[] {
169
168
  const roomsDir = path.join(stateDir, "rooms");
170
169
  try {
@@ -186,8 +185,7 @@ function readRoomPreviews(
186
185
  Boolean(preview),
187
186
  );
188
187
  });
189
- const limit = Number.isFinite(limitPerRun) ? Math.max(0, Number(limitPerRun)) : undefined;
190
- return limit === undefined ? previews : previews.slice(-limit);
188
+ return previews;
191
189
  } catch (error) {
192
190
  if ((error as NodeJS.ErrnoException).code === "ENOENT") return [];
193
191
  return [];
@@ -259,6 +257,31 @@ function matchesPreviewFilter(
259
257
  ].some((value) => value?.toLowerCase().includes(mention));
260
258
  }
261
259
 
260
+ function limitRoomPreviewsPerRun(
261
+ previews: ActorInspectorPreview[],
262
+ limitPerRun?: number,
263
+ ): ActorInspectorPreview[] {
264
+ if (!Number.isFinite(limitPerRun)) return previews;
265
+ const limit = Math.max(0, Number(limitPerRun));
266
+ const remainingByRun = new Map<string, number>();
267
+ const keep = new Set<ActorInspectorPreview>();
268
+ for (let index = previews.length - 1; index >= 0; index -= 1) {
269
+ const preview = previews[index];
270
+ if (preview.channel !== "room") {
271
+ keep.add(preview);
272
+ continue;
273
+ }
274
+ const remaining = remainingByRun.get(preview.run) ?? limit;
275
+ if (remaining <= 0) {
276
+ remainingByRun.set(preview.run, 0);
277
+ continue;
278
+ }
279
+ keep.add(preview);
280
+ remainingByRun.set(preview.run, remaining - 1);
281
+ }
282
+ return previews.filter((preview) => keep.has(preview));
283
+ }
284
+
262
285
  export function readActorInspectorPreviews(
263
286
  stateRoot = Paths.getRunStateRoot(),
264
287
  limit = 8,
@@ -272,7 +295,7 @@ export function readActorInspectorPreviews(
272
295
  const stateDir = path.join(stateRoot, entry.name);
273
296
  if (!matchesOwner(stateDir, options.ownerId)) return [];
274
297
  return [
275
- ...readRoomPreviews(entry.name, stateDir, options.roomLimitPerRun),
298
+ ...readRoomPreviews(entry.name, stateDir),
276
299
  ...readInboxPreviews(entry.name, stateDir),
277
300
  ...readOutboxPreviews(entry.name, stateDir),
278
301
  ];
@@ -282,15 +305,17 @@ export function readActorInspectorPreviews(
282
305
  const currentRun = options.currentRunOnly
283
306
  ? previews.at(-1)?.run
284
307
  : undefined;
285
- return previews
308
+ const sequenced = previews
286
309
  .filter((preview) => !currentRun || preview.run === currentRun)
287
310
  .filter((preview) => matchesPreviewFilter(preview, options))
288
311
  .map((preview, index) => ({
289
312
  ...preview,
290
313
  sequence: index + 1,
291
314
  stripe: index % 2 === 1,
292
- }))
293
- .slice(-Math.max(1, limit));
315
+ }));
316
+ return limitRoomPreviewsPerRun(sequenced, options.roomLimitPerRun).slice(
317
+ -Math.max(1, limit),
318
+ );
294
319
  } catch (error) {
295
320
  if ((error as NodeJS.ErrnoException).code === "ENOENT") return [];
296
321
  return [];
@@ -505,7 +530,8 @@ export function readActorInspectorRoster(
505
530
  }
506
531
 
507
532
  function rosterRoleText(role: string | undefined): string | undefined {
508
- const cleaned = role?.replaceAll(/\s*\([^)]*\)\s*$/g, "").trim().toLowerCase();
533
+ const roleLabel = role?.split(";")[0] ?? "";
534
+ const cleaned = roleLabel.replaceAll(/\s*\([^)]*\)\s*$/g, "").trim().toLowerCase();
509
535
  if (!cleaned || cleaned === "actor") return undefined;
510
536
  return cleaned.replaceAll(/\s+/g, "-");
511
537
  }
@@ -513,7 +539,8 @@ function rosterRoleText(role: string | undefined): string | undefined {
513
539
  function rosterMemberText(member: ActorInspectorRosterMember): string {
514
540
  const name = member.display || actorName(member.address);
515
541
  const role = rosterRoleText(member.role);
516
- return role ? `${role}/${name}` : name;
542
+ if (role === "run") return `run/${name}`;
543
+ return role ? `${name}/${role}` : name;
517
544
  }
518
545
 
519
546
  function isRosterMemberActive(member: ActorInspectorRosterMember): boolean {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llblab/pi-actors",
3
- "version": "0.19.0",
3
+ "version": "0.19.1",
4
4
  "private": false,
5
5
  "description": "Actor runtime and orchestrator for agent-managed local processes",
6
6
  "keywords": [
@@ -112,16 +112,21 @@ async function stopLocker(locker) {
112
112
 
113
113
  function runPi(prompt, model, thinking) {
114
114
  return new Promise((resolve) => {
115
- const child = spawn("pi", [
116
- "--model", model,
117
- "--thinking", thinking,
115
+ const args = [
118
116
  "--tools", "inspect,message",
119
117
  "--no-context-files",
120
118
  "--no-skills",
121
119
  "--no-session",
122
- "-p",
123
- prompt,
124
- ], { stdio: ["ignore", "pipe", "pipe"] });
120
+ ];
121
+ if (model) {
122
+ args.push("--model", model);
123
+ }
124
+ if (thinking) {
125
+ args.push("--thinking", thinking);
126
+ }
127
+ args.push("-p", prompt);
128
+
129
+ const child = spawn("pi", args, { stdio: ["ignore", "pipe", "pipe"] });
125
130
  let stdout = "";
126
131
  let stderr = "";
127
132
  child.stdout.on("data", (chunk) => { stdout += chunk; });
@@ -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.19.0
5
+ version: 0.19.1
6
6
  ---
7
7
 
8
8
  # Actors (pi-actors)
@@ -2,7 +2,7 @@
2
2
  name: swarm
3
3
  description: Subagent orchestration with scoped locks and quorum consensus. Use for multi-model review, parallel scoped work, delegated audit, and coordinated subagent execution.
4
4
  metadata:
5
- version: 0.19.0
5
+ version: 0.19.1
6
6
  ---
7
7
 
8
8
  # Swarm