@llblab/pi-actors 0.42.2 → 0.43.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 (254) hide show
  1. package/AGENTS.md +121 -175
  2. package/CHANGELOG.md +16 -0
  3. package/README.md +113 -276
  4. package/dist/fixtures/protocol/control-endpoint.json +6 -0
  5. package/dist/fixtures/protocol/control-record.json +9 -0
  6. package/dist/fixtures/protocol/recipe-summary.json +4 -12
  7. package/dist/fixtures/protocol/trace-event.json +9 -0
  8. package/dist/lib/async-runs.d.ts +14 -38
  9. package/dist/lib/async-runs.js +158 -108
  10. package/dist/lib/control.d.ts +12 -0
  11. package/dist/lib/control.js +84 -0
  12. package/dist/lib/execution-sessions.d.ts +17 -0
  13. package/dist/lib/execution-sessions.js +85 -0
  14. package/dist/lib/file-state.d.ts +1 -0
  15. package/dist/lib/file-state.js +17 -5
  16. package/dist/lib/inspector-actions.d.ts +2 -2
  17. package/dist/lib/inspector-actions.js +2 -2
  18. package/dist/lib/inspector-command.js +3 -3
  19. package/dist/lib/inspector-overlay.d.ts +52 -70
  20. package/dist/lib/inspector-overlay.js +532 -905
  21. package/dist/lib/inspector.d.ts +3 -71
  22. package/dist/lib/inspector.js +19 -665
  23. package/dist/lib/limits.d.ts +4 -2
  24. package/dist/lib/limits.js +4 -2
  25. package/dist/lib/observability.d.ts +17 -17
  26. package/dist/lib/observability.js +45 -84
  27. package/dist/lib/pi.d.ts +1 -1
  28. package/dist/lib/prompts.d.ts +1 -1
  29. package/dist/lib/prompts.js +2 -2
  30. package/dist/lib/recipe-control.d.ts +7 -0
  31. package/dist/lib/recipe-control.js +39 -0
  32. package/dist/lib/recipes-discovery.js +2 -0
  33. package/dist/lib/recipes-references.d.ts +1 -14
  34. package/dist/lib/recipes-references.js +6 -21
  35. package/dist/lib/review-projection.js +1 -5
  36. package/dist/lib/run-ui-runtime.js +2 -2
  37. package/dist/lib/runs-control-delivery.d.ts +21 -0
  38. package/dist/lib/runs-control-delivery.js +127 -0
  39. package/dist/lib/runs-controls.d.ts +35 -0
  40. package/dist/lib/runs-controls.js +144 -0
  41. package/dist/lib/runs-retention.d.ts +7 -0
  42. package/dist/lib/runs-retention.js +27 -3
  43. package/dist/lib/runs-start.js +4 -2
  44. package/dist/lib/runs-status.js +11 -6
  45. package/dist/lib/runs-trace.d.ts +24 -0
  46. package/dist/lib/runs-trace.js +98 -0
  47. package/dist/lib/runtime-notifier.d.ts +1 -1
  48. package/dist/lib/runtime-notifier.js +1 -1
  49. package/dist/lib/tools-inspect.d.ts +3 -3
  50. package/dist/lib/tools-inspect.js +203 -708
  51. package/dist/lib/tools-local.js +2 -10
  52. package/dist/lib/tools-message.d.ts +7 -7
  53. package/dist/lib/tools-message.js +95 -396
  54. package/dist/lib/tools-response.d.ts +1 -4
  55. package/dist/lib/tools-response.js +5 -39
  56. package/dist/lib/tools-spawn.js +16 -28
  57. package/dist/lib/tools.js +1 -2
  58. package/dist/lib/trace-projection.d.ts +22 -0
  59. package/dist/lib/trace-projection.js +165 -0
  60. package/dist/recipes/draft-review.json +0 -10
  61. package/dist/recipes/lens-swarm.json +0 -14
  62. package/dist/recipes/music-player.json +10 -19
  63. package/dist/recipes/pipeline-architect-coordinator.json +0 -11
  64. package/dist/recipes/pipeline-artifact-bundle.json +1 -22
  65. package/dist/recipes/pipeline-artifact-report.json +1 -18
  66. package/dist/recipes/pipeline-artifact-write.json +1 -18
  67. package/dist/recipes/pipeline-async-run-ops.json +0 -12
  68. package/dist/recipes/pipeline-checkpoint-continuation.json +0 -14
  69. package/dist/recipes/pipeline-development-tasking.json +0 -12
  70. package/dist/recipes/pipeline-docs-maintenance.json +0 -12
  71. package/dist/recipes/pipeline-media-library.json +0 -12
  72. package/dist/recipes/pipeline-quorum-review.json +0 -12
  73. package/dist/recipes/pipeline-release-readiness.json +0 -12
  74. package/dist/recipes/pipeline-release-summary.json +0 -12
  75. package/dist/recipes/pipeline-repo-health.json +0 -12
  76. package/dist/recipes/pipeline-research-synthesis.json +0 -11
  77. package/dist/recipes/pipeline-review-readiness.json +0 -12
  78. package/dist/recipes/resource-locker.json +27 -0
  79. package/dist/recipes/subagent-artifact.json +0 -9
  80. package/dist/recipes/subagent-checkpoint.json +0 -10
  81. package/dist/recipes/subagent-conflict-report.json +0 -11
  82. package/dist/recipes/subagent-contradiction-map.json +0 -11
  83. package/dist/recipes/subagent-critic.json +0 -11
  84. package/dist/recipes/subagent-evidence-map.json +0 -11
  85. package/dist/recipes/subagent-followup.json +0 -10
  86. package/dist/recipes/subagent-judge.json +0 -11
  87. package/dist/recipes/subagent-merge.json +0 -11
  88. package/dist/recipes/subagent-normalize.json +0 -11
  89. package/dist/recipes/subagent-plan.json +0 -11
  90. package/dist/recipes/subagent-preflight.json +0 -11
  91. package/dist/recipes/subagent-prompt.json +0 -10
  92. package/dist/recipes/subagent-quorum.json +0 -10
  93. package/dist/recipes/subagent-review-coordinator.json +0 -14
  94. package/dist/recipes/subagent-review.json +0 -11
  95. package/dist/recipes/subagent-task-card.json +0 -11
  96. package/dist/recipes/subagent-tools.json +0 -10
  97. package/dist/recipes/subagent-verify.json +0 -11
  98. package/dist/recipes/subagents-prompts.json +0 -10
  99. package/dist/recipes/tool-review.json +0 -10
  100. package/dist/scripts/async-runner.mjs +25 -25
  101. package/dist/scripts/conformance.mjs +4 -2
  102. package/dist/scripts/locker.mjs +200 -66
  103. package/dist/scripts/music-player.mjs +159 -150
  104. package/dist/scripts/recipe-utils.mjs +6 -96
  105. package/dist/scripts/release-gates.mjs +60 -0
  106. package/dist/scripts/validate-recipe.mjs +3 -53
  107. package/dist/skills/actors/SKILL.md +53 -266
  108. package/dist/skills/swarm/SKILL.md +11 -33
  109. package/docs/0.43-baseline.md +44 -0
  110. package/docs/README.md +3 -3
  111. package/docs/actor-inspector.md +26 -64
  112. package/docs/actors-deep-reference.md +92 -50
  113. package/docs/async-runs.md +81 -328
  114. package/docs/command-templates.md +2 -2
  115. package/docs/component-recipes.md +30 -133
  116. package/docs/recipe-library.md +57 -182
  117. package/docs/task-first-recipes.md +10 -12
  118. package/docs/template-recipes.md +76 -289
  119. package/docs/tool-registry.md +41 -161
  120. package/fixtures/protocol/control-endpoint.json +6 -0
  121. package/fixtures/protocol/control-record.json +9 -0
  122. package/fixtures/protocol/recipe-summary.json +4 -12
  123. package/fixtures/protocol/trace-event.json +9 -0
  124. package/lib/async-runs.ts +202 -201
  125. package/lib/control.ts +102 -0
  126. package/lib/execution-sessions.ts +111 -0
  127. package/lib/file-state.ts +17 -4
  128. package/lib/inspector-actions.ts +2 -2
  129. package/lib/inspector-command.ts +3 -3
  130. package/lib/inspector-overlay.ts +577 -1121
  131. package/lib/inspector.ts +46 -979
  132. package/lib/limits.ts +4 -2
  133. package/lib/observability.ts +63 -104
  134. package/lib/pi.ts +1 -1
  135. package/lib/prompts.ts +2 -2
  136. package/lib/recipe-control.ts +45 -0
  137. package/lib/recipes-discovery.ts +2 -0
  138. package/lib/recipes-references.ts +9 -45
  139. package/lib/review-projection.ts +1 -5
  140. package/lib/run-ui-runtime.ts +2 -2
  141. package/lib/runs-control-delivery.ts +181 -0
  142. package/lib/runs-controls.ts +204 -0
  143. package/lib/runs-retention.ts +38 -3
  144. package/lib/runs-start.ts +4 -2
  145. package/lib/runs-status.ts +11 -6
  146. package/lib/runs-trace.ts +132 -0
  147. package/lib/runtime-notifier.ts +1 -1
  148. package/lib/tools-inspect.ts +240 -901
  149. package/lib/tools-local.ts +2 -12
  150. package/lib/tools-message.ts +112 -519
  151. package/lib/tools-response.ts +5 -52
  152. package/lib/tools-spawn.ts +16 -32
  153. package/lib/tools.ts +1 -2
  154. package/lib/trace-projection.ts +221 -0
  155. package/package.json +2 -1
  156. package/recipes/draft-review.json +0 -10
  157. package/recipes/lens-swarm.json +0 -14
  158. package/recipes/music-player.json +10 -19
  159. package/recipes/pipeline-architect-coordinator.json +0 -11
  160. package/recipes/pipeline-artifact-bundle.json +1 -22
  161. package/recipes/pipeline-artifact-report.json +1 -18
  162. package/recipes/pipeline-artifact-write.json +1 -18
  163. package/recipes/pipeline-async-run-ops.json +0 -12
  164. package/recipes/pipeline-checkpoint-continuation.json +0 -14
  165. package/recipes/pipeline-development-tasking.json +0 -12
  166. package/recipes/pipeline-docs-maintenance.json +0 -12
  167. package/recipes/pipeline-media-library.json +0 -12
  168. package/recipes/pipeline-quorum-review.json +0 -12
  169. package/recipes/pipeline-release-readiness.json +0 -12
  170. package/recipes/pipeline-release-summary.json +0 -12
  171. package/recipes/pipeline-repo-health.json +0 -12
  172. package/recipes/pipeline-research-synthesis.json +0 -11
  173. package/recipes/pipeline-review-readiness.json +0 -12
  174. package/recipes/resource-locker.json +27 -0
  175. package/recipes/subagent-artifact.json +0 -9
  176. package/recipes/subagent-checkpoint.json +0 -10
  177. package/recipes/subagent-conflict-report.json +0 -11
  178. package/recipes/subagent-contradiction-map.json +0 -11
  179. package/recipes/subagent-critic.json +0 -11
  180. package/recipes/subagent-evidence-map.json +0 -11
  181. package/recipes/subagent-followup.json +0 -10
  182. package/recipes/subagent-judge.json +0 -11
  183. package/recipes/subagent-merge.json +0 -11
  184. package/recipes/subagent-normalize.json +0 -11
  185. package/recipes/subagent-plan.json +0 -11
  186. package/recipes/subagent-preflight.json +0 -11
  187. package/recipes/subagent-prompt.json +0 -10
  188. package/recipes/subagent-quorum.json +0 -10
  189. package/recipes/subagent-review-coordinator.json +0 -14
  190. package/recipes/subagent-review.json +0 -11
  191. package/recipes/subagent-task-card.json +0 -11
  192. package/recipes/subagent-tools.json +0 -10
  193. package/recipes/subagent-verify.json +0 -11
  194. package/recipes/subagents-prompts.json +0 -10
  195. package/recipes/tool-review.json +0 -10
  196. package/scripts/async-runner.mjs +25 -25
  197. package/scripts/conformance.mjs +4 -2
  198. package/scripts/locker.mjs +200 -66
  199. package/scripts/music-player.mjs +159 -150
  200. package/scripts/recipe-utils.mjs +6 -96
  201. package/scripts/release-gates.mjs +60 -0
  202. package/scripts/validate-recipe.mjs +3 -53
  203. package/skills/actors/SKILL.md +53 -266
  204. package/skills/swarm/SKILL.md +11 -33
  205. package/dist/fixtures/protocol/actor-message-branch.json +0 -13
  206. package/dist/fixtures/protocol/mailbox-contract.json +0 -15
  207. package/dist/fixtures/protocol/room-message.json +0 -11
  208. package/dist/fixtures/protocol/room-roster.json +0 -11
  209. package/dist/fixtures/protocol/run-inbox-message.json +0 -9
  210. package/dist/fixtures/protocol/run-outbox-event.json +0 -9
  211. package/dist/lib/mailbox-loop.d.ts +0 -41
  212. package/dist/lib/mailbox-loop.js +0 -60
  213. package/dist/lib/messages.d.ts +0 -25
  214. package/dist/lib/messages.js +0 -122
  215. package/dist/lib/rooms.d.ts +0 -104
  216. package/dist/lib/rooms.js +0 -647
  217. package/dist/lib/runs-mailbox.d.ts +0 -25
  218. package/dist/lib/runs-mailbox.js +0 -146
  219. package/dist/lib/runs-messages.d.ts +0 -15
  220. package/dist/lib/runs-messages.js +0 -179
  221. package/dist/lib/runs-outbox.d.ts +0 -41
  222. package/dist/lib/runs-outbox.js +0 -87
  223. package/dist/lib/tools-mailbox.d.ts +0 -8
  224. package/dist/lib/tools-mailbox.js +0 -48
  225. package/dist/recipes/actor-worker.json +0 -39
  226. package/dist/recipes/coordinator-locker.json +0 -45
  227. package/dist/recipes/locker.json +0 -45
  228. package/dist/recipes/pipeline-room-swarm.json +0 -50
  229. package/dist/recipes/subagent-message.json +0 -32
  230. package/dist/recipes/utility-actor-message.json +0 -23
  231. package/dist/scripts/actor-worker.mjs +0 -214
  232. package/dist/scripts/coordinator.mjs +0 -799
  233. package/docs/actor-messages.md +0 -225
  234. package/fixtures/protocol/actor-message-branch.json +0 -13
  235. package/fixtures/protocol/mailbox-contract.json +0 -15
  236. package/fixtures/protocol/room-message.json +0 -11
  237. package/fixtures/protocol/room-roster.json +0 -11
  238. package/fixtures/protocol/run-inbox-message.json +0 -9
  239. package/fixtures/protocol/run-outbox-event.json +0 -9
  240. package/lib/mailbox-loop.ts +0 -144
  241. package/lib/messages.ts +0 -151
  242. package/lib/rooms.ts +0 -939
  243. package/lib/runs-mailbox.ts +0 -208
  244. package/lib/runs-messages.ts +0 -252
  245. package/lib/runs-outbox.ts +0 -144
  246. package/lib/tools-mailbox.ts +0 -56
  247. package/recipes/actor-worker.json +0 -39
  248. package/recipes/coordinator-locker.json +0 -45
  249. package/recipes/locker.json +0 -45
  250. package/recipes/pipeline-room-swarm.json +0 -50
  251. package/recipes/subagent-message.json +0 -32
  252. package/recipes/utility-actor-message.json +0 -23
  253. package/scripts/actor-worker.mjs +0 -214
  254. package/scripts/coordinator.mjs +0 -799
@@ -4,7 +4,6 @@
4
4
  * Owns model-facing response helpers shared by public tool execution paths
5
5
  */
6
6
  import * as Limits from "./limits.js";
7
- import * as ToolsMailbox from "./tools-mailbox.js";
8
7
  export function withLeadingLineBreak(text) {
9
8
  return `\n${text.replace(/^\n+/, "")}`;
10
9
  }
@@ -76,14 +75,14 @@ function compactModelPolicy(value) {
76
75
  compactPolicyAxis("thinking", policy.thinking),
77
76
  ].filter((token) => Boolean(token));
78
77
  }
79
- export function actorRunNextActions(run) {
78
+ export function runNextActions(run) {
80
79
  const id = String(run ?? "").trim();
81
80
  if (!id)
82
81
  return [];
83
82
  return [
84
- `inspect target=run:${id} view=status`,
85
- `inspect target=run:${id} view=messages`,
86
- `message to=run:${id} type=<actor.action>`,
83
+ `inspect target=run:${id} view=recipe`,
84
+ `inspect target=run:${id} view=trace`,
85
+ `inspect target=run:${id} view=control`,
87
86
  ];
88
87
  }
89
88
  export function compactAsyncRunStatus(value) {
@@ -117,44 +116,11 @@ export function compactAsyncRunStatus(value) {
117
116
  const draftRecipe = status.draft_recipe;
118
117
  if (draftRecipe)
119
118
  tokens.push(`draft_recipe=${String(draftRecipe)}`);
120
- const nextActions = actorRunNextActions(run);
119
+ const nextActions = runNextActions(run);
121
120
  if (nextActions.length > 0)
122
121
  tokens.push(`next=${nextActions.map((action) => action.replaceAll(/\s+/g, "_")).join("|")}`);
123
122
  return `\n${tokens.join(" ")}`;
124
123
  }
125
- export function compactInboxMessages(messages, emptyLabel) {
126
- if (messages.length === 0)
127
- return `\n(no ${emptyLabel} messages)`;
128
- return `\n${messages
129
- .map((message) => [
130
- ...(message.id ? [`id=${String(message.id)}`] : []),
131
- `status=${String(message.status ?? "")}`,
132
- `type=${String(message.type ?? "")}`,
133
- `from=${String(message.from ?? "")}`,
134
- `to=${String(message.to ?? "")}`,
135
- ...(message.queued_at
136
- ? [`queued_at=${String(message.queued_at)}`]
137
- : []),
138
- ...(message.sent_at ? [`sent_at=${String(message.sent_at)}`] : []),
139
- ...(message.claimed_at
140
- ? [`claimed_at=${String(message.claimed_at)}`]
141
- : []),
142
- ...(message.handled_at
143
- ? [`handled_at=${String(message.handled_at)}`]
144
- : []),
145
- ...(message.failed_at
146
- ? [`failed_at=${String(message.failed_at)}`]
147
- : []),
148
- ].join(" "))
149
- .join("\n")}`;
150
- }
151
- export function compactBranchInbox(messages) {
152
- return compactInboxMessages(messages, "branch inbox");
153
- }
154
- export function compactRunMailbox(run, mailbox, messages) {
155
- const normalized = ToolsMailbox.normalizeMailboxContracts(mailbox);
156
- return `\nrun=${run} accepts=${ToolsMailbox.mailboxTypes(normalized.accepts).join(",")} emits=${ToolsMailbox.mailboxTypes(normalized.emits).join(",")}${compactInboxMessages(messages, "run inbox")}`;
157
- }
158
124
  export function artifactNextActions(run, artifacts) {
159
125
  const id = String(run ?? "").trim();
160
126
  if (!id || Object.keys(artifacts).length === 0)
@@ -7,12 +7,10 @@ import { mkdirSync, writeFileSync } from "node:fs";
7
7
  import { join } from "node:path";
8
8
  import * as AsyncRuns from "./async-runs.js";
9
9
  import { withFileMutationLock } from "./file-state.js";
10
- import * as Messages from "./messages.js";
11
10
  import * as ModelContext from "./model-context.js";
12
11
  import * as Paths from "./paths.js";
13
12
  import * as RecipesDiscovery from "./recipes-discovery.js";
14
13
  import * as RecipesUsage from "./recipes-usage.js";
15
- import * as Rooms from "./rooms.js";
16
14
  import * as Schema from "./schema.js";
17
15
  import * as ToolsResponse from "./tools-response.js";
18
16
  const asRecord = ToolsResponse.asRecord;
@@ -35,13 +33,7 @@ function draftRecipeName(run) {
35
33
  return `${run.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "spawn"}.json`;
36
34
  }
37
35
  function draftRecipeDefaults(values) {
38
- const ignored = new Set([
39
- "actor_address",
40
- "communication_file",
41
- "default_room",
42
- "run_id",
43
- "state_dir",
44
- ]);
36
+ const ignored = new Set(["run_id", "state_dir", "trace_file"]);
45
37
  const defaults = Object.fromEntries(Object.entries(values).filter(([key]) => !ignored.has(key)));
46
38
  return Object.keys(defaults).length > 0 ? defaults : undefined;
47
39
  }
@@ -78,24 +70,26 @@ function enhanceSpawnRecipeError(error, recipe) {
78
70
  original_error: original,
79
71
  });
80
72
  }
81
- function runIdFromActorAddress(address) {
82
- if (!address)
73
+ function runIdFromTarget(target) {
74
+ if (!target)
83
75
  return undefined;
84
- const parsed = Messages.parseActorAddress(address);
85
- if (parsed.kind !== "run" || !parsed.value) {
86
- throw new Error(`Expected run:<id> actor address, received: ${address}`);
76
+ if (!target.startsWith("run:")) {
77
+ throw new Error(`spawn.as accepts only run:<id>; received: ${target}`);
78
+ }
79
+ const run = target.slice(4);
80
+ if (!run || !/^[A-Za-z0-9_.-]+$/.test(run)) {
81
+ throw new Error(`invalid spawn Run target: ${target}`);
87
82
  }
88
- return parsed.value;
83
+ return run;
89
84
  }
90
85
  export function createSpawnToolDefinition() {
91
86
  return {
92
87
  name: "spawn",
93
88
  label: "Spawn",
94
- description: "Create an addressable actor from a recipe file or inline command template. Use instead of ad hoc shell backgrounding for work that may outlive this turn, needs steering/follow-up/artifacts, runs as a service, fans out, or should be inspected later. Currently spawns run:<id> actors backed by async runs.",
89
+ description: "Create one controllable Run from a Recipe file or inline command template.",
95
90
  parameters: Schema.objectSchema({
96
- artifacts: Schema.looseObjectSchema("Optional named artifact paths for the spawned actor."),
97
- as: Schema.stringSchema("Optional actor address for the spawned run, e.g. run:<id>."),
98
- correlation_id: Schema.stringSchema("Optional workflow correlation id preserved in terminal follow-up delivery."),
91
+ artifacts: Schema.looseObjectSchema("Optional named artifact paths for the spawned Run."),
92
+ as: Schema.stringSchema("Optional Run identity in exact run:<id> form."),
99
93
  file: Schema.stringSchema("Optional template recipe JSON file. Bare names resolve under ~/.pi/agent/recipes."),
100
94
  recipe: Schema.stringSchema("Alias for file; template recipe JSON file/name to spawn."),
101
95
  template: Schema.unionSchema([
@@ -112,7 +106,7 @@ export function createSpawnToolDefinition() {
112
106
  if (input.state_dir !== undefined) {
113
107
  throw new Error("spawn.state_dir is not supported; run state is runtime-owned so run:<id> remains addressable and retention-safe.");
114
108
  }
115
- const runId = runIdFromActorAddress(typeof input.as === "string" ? input.as : undefined);
109
+ const runId = runIdFromTarget(typeof input.as === "string" ? input.as : undefined);
116
110
  const recipe = typeof input.file === "string"
117
111
  ? input.file
118
112
  : typeof input.recipe === "string"
@@ -123,11 +117,7 @@ export function createSpawnToolDefinition() {
123
117
  meta = AsyncRuns.startRun({
124
118
  file: recipe,
125
119
  launch_source: "spawn",
126
- launch_correlation: {
127
- ...(typeof input.correlation_id === "string"
128
- ? { correlation_id: input.correlation_id } : {}),
129
- tool_call_id: toolCallId,
130
- },
120
+ launch_correlation: { tool_call_id: toolCallId },
131
121
  ownerId: getRunOwnerId(ctx),
132
122
  ...(input.transport_context
133
123
  ? { transport_context: asRecord(input.transport_context) } : {}),
@@ -151,14 +141,12 @@ export function createSpawnToolDefinition() {
151
141
  throw enhanceSpawnRecipeError(error, recipe);
152
142
  }
153
143
  const draftRecipe = writeSpawnDraftRecipe(input, meta);
154
- const nextActions = ToolsResponse.actorRunNextActions(meta.run);
144
+ const nextActions = ToolsResponse.runNextActions(meta.run);
155
145
  const details = {
156
146
  ...meta,
157
147
  ...(draftRecipe ? { draft_recipe: draftRecipe } : {}),
158
148
  next_actions: nextActions,
159
149
  };
160
- Rooms.ensureDefaultRoom(meta.state_dir, String(meta.run));
161
- Rooms.writeCommunicationSnapshot(meta.state_dir, String(meta.run));
162
150
  return {
163
151
  content: [
164
152
  {
package/dist/lib/tools.js CHANGED
@@ -36,8 +36,7 @@ export function createCoreActorToolDefinitions(deps) {
36
36
  setActiveTools: deps.setActiveTools,
37
37
  }),
38
38
  ToolsSpawn.createSpawnToolDefinition(),
39
- ToolsMessage.createActorMessageToolDefinition({
40
- getTool: (name) => deps.getRuntimeTool(name),
39
+ ToolsMessage.createControlToolDefinition({
41
40
  handleRuntimeMessage: deps.handleRuntimeMessage,
42
41
  }),
43
42
  ToolsInspect.createInspectToolDefinition({
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Unified bounded Run Trace projection.
3
+ * Zones: causal evidence merge, source filtering, redaction, deterministic ordering
4
+ * Owns public Trace items; source journals and session parsing remain in their domains.
5
+ */
6
+ import { type RunArtifactDeclaration } from "./runs-artifacts.ts";
7
+ export type TraceSource = "lifecycle" | "control" | "process" | "agent" | "artifact" | "runtime";
8
+ export type TraceSourceFilter = TraceSource | "all";
9
+ export interface TraceItem {
10
+ id: string;
11
+ ts: string;
12
+ source: TraceSource;
13
+ kind: string;
14
+ summary: string;
15
+ level?: "info" | "warning" | "error";
16
+ detail: unknown;
17
+ }
18
+ export declare function projectRunTrace(stateDir: string, options?: {
19
+ artifacts?: Record<string, RunArtifactDeclaration>;
20
+ limit?: number;
21
+ source?: TraceSourceFilter;
22
+ }): TraceItem[];
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Unified bounded Run Trace projection.
3
+ * Zones: causal evidence merge, source filtering, redaction, deterministic ordering
4
+ * Owns public Trace items; source journals and session parsing remain in their domains.
5
+ */
6
+ import { existsSync, statSync } from "node:fs";
7
+ import { join, relative } from "node:path";
8
+ import * as ExecutionSessions from "./execution-sessions.js";
9
+ import * as Limits from "./limits.js";
10
+ import { resolveArtifactManifest, } from "./runs-artifacts.js";
11
+ import { tailFile } from "./runs-status.js";
12
+ import * as SessionEvidence from "./session-evidence.js";
13
+ import { readJsonFileResilient, readJsonlFileResilient, } from "./state-readers.js";
14
+ const LIFECYCLE_PREFIXES = ["run.", "command."];
15
+ const SOURCE_LIMIT = 100;
16
+ function redact(value) {
17
+ return SessionEvidence.redactSessionEvidenceValue(value);
18
+ }
19
+ function sourceForEvent(event) {
20
+ return LIFECYCLE_PREFIXES.some((prefix) => event.kind.startsWith(prefix))
21
+ ? "lifecycle"
22
+ : "runtime";
23
+ }
24
+ function latestControlTimestamp(control) {
25
+ return (control.failed_at ??
26
+ control.handled_at ??
27
+ control.claimed_at ??
28
+ control.delivered_at ??
29
+ control.queued_at);
30
+ }
31
+ function diagnosticItems(diagnostics) {
32
+ return diagnostics.slice(-SOURCE_LIMIT).map((diagnostic, index) => ({
33
+ id: `diagnostic:${diagnostic.path}:${diagnostic.line ?? 0}:${index}`,
34
+ ts: new Date(0).toISOString(),
35
+ source: "runtime",
36
+ kind: "state.read_error",
37
+ summary: "Malformed or unreadable Run evidence",
38
+ level: "warning",
39
+ detail: redact(diagnostic),
40
+ }));
41
+ }
42
+ function traceEventItems(stateDir) {
43
+ const read = readJsonlFileResilient(join(stateDir, "trace.jsonl"));
44
+ return [
45
+ ...read.records.slice(-SOURCE_LIMIT).map((event) => ({
46
+ id: event.id,
47
+ ts: event.ts,
48
+ source: sourceForEvent(event),
49
+ kind: event.kind,
50
+ summary: event.summary ?? event.kind,
51
+ ...(event.level ? { level: event.level } : {}),
52
+ detail: redact({
53
+ ...(event.attention ? { attention: event.attention } : {}),
54
+ ...(event.data !== undefined ? { data: event.data } : {}),
55
+ }),
56
+ })),
57
+ ...diagnosticItems(read.diagnostics),
58
+ ];
59
+ }
60
+ function controlItems(stateDir) {
61
+ const read = readJsonlFileResilient(join(stateDir, "controls.jsonl"));
62
+ return [
63
+ ...read.records.slice(-SOURCE_LIMIT).map((control) => ({
64
+ id: `control:${control.id}`,
65
+ ts: latestControlTimestamp(control),
66
+ source: "control",
67
+ kind: `control.${control.status}`,
68
+ summary: `${control.action} ${control.status}`,
69
+ ...(control.status === "failed" ? { level: "error" } : {}),
70
+ detail: redact(control),
71
+ })),
72
+ ...diagnosticItems(read.diagnostics),
73
+ ];
74
+ }
75
+ function agentItems(stateDir) {
76
+ return ExecutionSessions.readExecutionTurns(stateDir)
77
+ .slice(-SOURCE_LIMIT)
78
+ .map((turn) => {
79
+ const text = turn.assistantText ?? turn.userText ?? "Agent turn";
80
+ const summary = text.replaceAll(/\s+/g, " ").trim().slice(0, 160);
81
+ return {
82
+ id: `agent:${turn.commandId}:${turn.sessionFile}:${turn.index}`,
83
+ ts: turn.timestamp ?? new Date(0).toISOString(),
84
+ source: "agent",
85
+ kind: "agent.turn",
86
+ summary: summary || "Agent turn",
87
+ ...(turn.error ? { level: "error" } : {}),
88
+ detail: redact(turn),
89
+ };
90
+ });
91
+ }
92
+ function processItems(stateDir) {
93
+ return ["stdout", "stderr"].flatMap((stream) => {
94
+ const path = join(stateDir, `${stream}.log`);
95
+ if (!existsSync(path))
96
+ return [];
97
+ const stat = statSync(path);
98
+ const tail = tailFile(path, Limits.DEFAULT_INSPECT_LINES);
99
+ if (!tail && stat.size === 0)
100
+ return [];
101
+ return [{
102
+ id: `process:${stream}`,
103
+ ts: stat.mtime.toISOString(),
104
+ source: "process",
105
+ kind: `process.${stream}`,
106
+ summary: `${stream} (${stat.size} bytes)`,
107
+ ...(stream === "stderr" ? { level: "warning" } : {}),
108
+ detail: redact({ bytes: stat.size, path, tail }),
109
+ }];
110
+ });
111
+ }
112
+ function resultItems(stateDir) {
113
+ const path = join(stateDir, "result.json");
114
+ const read = readJsonFileResilient(path, {});
115
+ if (Object.keys(read.value).length === 0)
116
+ return diagnosticItems(read.diagnostics);
117
+ const stat = statSync(path);
118
+ const failed = Number(read.value.code ?? 0) !== 0;
119
+ return [{
120
+ id: "process:result",
121
+ ts: typeof read.value.completedAt === "string"
122
+ ? read.value.completedAt
123
+ : stat.mtime.toISOString(),
124
+ source: "process",
125
+ kind: failed ? "process.failed" : "process.result",
126
+ summary: failed ? "Run process failed" : "Run process completed",
127
+ ...(failed ? { level: "error" } : {}),
128
+ detail: redact(read.value),
129
+ }, ...diagnosticItems(read.diagnostics)];
130
+ }
131
+ function artifactItems(stateDir, declarations) {
132
+ const manifest = resolveArtifactManifest(declarations);
133
+ if (!manifest)
134
+ return [];
135
+ return Object.entries(manifest).slice(0, SOURCE_LIMIT).map(([name, artifact]) => ({
136
+ id: `artifact:${name}`,
137
+ ts: artifact.exists && existsSync(artifact.path)
138
+ ? statSync(artifact.path).mtime.toISOString()
139
+ : new Date(0).toISOString(),
140
+ source: "artifact",
141
+ kind: artifact.exists ? "artifact.ready" : "artifact.missing",
142
+ summary: `${name}: ${artifact.exists ? "ready" : "missing"}`,
143
+ ...(artifact.required && !artifact.exists ? { level: "warning" } : {}),
144
+ detail: redact({
145
+ exists: artifact.exists,
146
+ path: relative(stateDir, artifact.path).replaceAll("\\", "/"),
147
+ required: artifact.required,
148
+ ...(artifact.size !== undefined ? { size: artifact.size } : {}),
149
+ }),
150
+ }));
151
+ }
152
+ export function projectRunTrace(stateDir, options = {}) {
153
+ const source = options.source ?? "all";
154
+ const items = [
155
+ ...traceEventItems(stateDir),
156
+ ...controlItems(stateDir),
157
+ ...agentItems(stateDir),
158
+ ...processItems(stateDir),
159
+ ...resultItems(stateDir),
160
+ ...artifactItems(stateDir, options.artifacts),
161
+ ]
162
+ .filter((item) => source === "all" || item.source === source)
163
+ .sort((left, right) => right.ts.localeCompare(left.ts) || right.id.localeCompare(left.id));
164
+ return items.slice(0, Math.max(1, Math.min(options.limit ?? 100, 200)));
165
+ }
@@ -10,15 +10,5 @@
10
10
  "thinking": "{current_thinking}"
11
11
  },
12
12
  "description": "Read-only background reviewer for one immutable automatic draft-memory batch.",
13
- "mailbox": {
14
- "accepts": [
15
- "control.kill"
16
- ],
17
- "emits": [
18
- "command.done",
19
- "run.done",
20
- "run.failed"
21
- ]
22
- },
23
13
  "template": "pi -p --model {model} --thinking {thinking} --no-tools @{input_path} Review the attached immutable pi-actors draft batch. Evaluate every draft independently using launch history, universality, flexibility, parameterization, duplication, safety, and likely future usefulness. Treat draft and sha256 fields as batch-local opaque occurrence/content-group identifiers and return them verbatim. Choose exactly one promote or discard decision per draft; there is no selection quota. Promotion requires a unique absent snake_case target and targetSha256 null. Never return recipe content: the executor derives the exact immutable captured source. Invalid or secret-touching drafts must be discarded. Include assessment with launches, universality, flexibility, futureUsefulness, and safety. Do not mutate, move, register, or delete recipes. End stdout with DRAFT_REVIEW_RESULT on its own line followed by exactly one JSON object with batchId, createdAt, and decisions."
24
14
  }
@@ -37,20 +37,6 @@
37
37
  "risk_policy": "Preserve minority high-impact risks and ideas; separate confirmed issues from hypotheses.",
38
38
  "output_format": "Markdown sections: Status (complete/degraded/insufficient_data), Summary, Consensus Findings, Minority Findings, Verification, Judge Notes, Risks, Next Actions."
39
39
  },
40
- "mailbox": {
41
- "accepts": [
42
- "control.kill"
43
- ],
44
- "emits": [
45
- "review.completed",
46
- "verification.completed",
47
- "merge.completed",
48
- "judge.completed",
49
- "command.done",
50
- "run.done",
51
- "run.failed"
52
- ]
53
- },
54
40
  "template": [
55
41
  {
56
42
  "name": "coordinator",
@@ -16,24 +16,15 @@
16
16
  "volume": "70",
17
17
  "player": "auto"
18
18
  },
19
- "mailbox": {
20
- "accepts": [
21
- "control.stop",
22
- "control.cancel",
23
- "control.kill",
24
- "player.play",
25
- "player.pause",
26
- "player.resume",
27
- "player.toggle",
28
- "player.next",
29
- "player.previous",
30
- "player.stop",
31
- "player.status"
32
- ],
33
- "emits": [
34
- "player.track",
35
- "player.stopped"
36
- ]
37
- },
19
+ "control": [
20
+ "play",
21
+ "pause",
22
+ "resume",
23
+ "toggle",
24
+ "next",
25
+ "previous",
26
+ "stop",
27
+ "status"
28
+ ],
38
29
  "template": "{repo}/scripts/music-player.mjs {command} {source} {loop} {volume} {player} {state_dir}"
39
30
  }
@@ -24,17 +24,6 @@
24
24
  "constraints": "Prefer small composable pieces, explicit contracts, and no broad workflow DSL.",
25
25
  "tools": ""
26
26
  },
27
- "mailbox": {
28
- "accepts": [
29
- "control.kill"
30
- ],
31
- "emits": [
32
- "pipeline.completed",
33
- "command.done",
34
- "run.done",
35
- "run.failed"
36
- ]
37
- },
38
27
  "template": [
39
28
  {
40
29
  "parallel": true,
@@ -4,8 +4,7 @@
4
4
  "artifactWrite": "pipeline-artifact-write.json",
5
5
  "manifest": "utility-artifact-manifest.json",
6
6
  "manifestWrite": "utility-artifact-write.json",
7
- "validation": "utility-validation-wrapper.json",
8
- "message": "utility-actor-message.json"
7
+ "validation": "utility-validation-wrapper.json"
9
8
  },
10
9
  "args": [
11
10
  "input:string",
@@ -33,18 +32,6 @@
33
32
  "validation_timeout_ms": "300000",
34
33
  "tools": ""
35
34
  },
36
- "mailbox": {
37
- "accepts": [
38
- "control.kill"
39
- ],
40
- "emits": [
41
- "artifact.bundle_ready",
42
- "artifact.written",
43
- "artifact.blocked",
44
- "run.done",
45
- "run.failed"
46
- ]
47
- },
48
35
  "artifacts": {
49
36
  "artifact": "{artifact_path}",
50
37
  "manifest": "{manifest_path}"
@@ -85,14 +72,6 @@
85
72
  "artifact_path": "{manifest_path}",
86
73
  "mode": "{write_mode}"
87
74
  }
88
- },
89
- {
90
- "name": "message",
91
- "values": {
92
- "type": "artifact.bundle_ready",
93
- "summary": "Artifact bundle ready: {artifact_path} with manifest {manifest_path}.",
94
- "metadata": "{\"artifact\":\"{artifact_path}\",\"manifest\":\"{manifest_path}\"}"
95
- }
96
75
  }
97
76
  ]
98
77
  }
@@ -2,8 +2,7 @@
2
2
  "async": true,
3
3
  "imports": {
4
4
  "normalizer": "subagent-normalize.json",
5
- "artifact": "subagent-artifact.json",
6
- "message": "utility-actor-message.json"
5
+ "artifact": "subagent-artifact.json"
7
6
  },
8
7
  "args": [
9
8
  "input:string",
@@ -16,15 +15,6 @@
16
15
  "artifact_format": "Markdown sections: Summary, Findings, Evidence, Risks, Next Actions.",
17
16
  "tools": ""
18
17
  },
19
- "mailbox": {
20
- "accepts": [
21
- "control.kill"
22
- ],
23
- "emits": [
24
- "artifact.prepared",
25
- "artifact.blocked"
26
- ]
27
- },
28
18
  "template": [
29
19
  {
30
20
  "name": "normalizer",
@@ -44,13 +34,6 @@
44
34
  "model": "{model}",
45
35
  "tools": "{tools}"
46
36
  }
47
- },
48
- {
49
- "name": "message",
50
- "values": {
51
- "type": "artifact.prepared",
52
- "summary": "Artifact prepared for path {artifact_path}."
53
- }
54
37
  }
55
38
  ]
56
39
  }
@@ -3,8 +3,7 @@
3
3
  "imports": {
4
4
  "normalizer": "subagent-normalize.json",
5
5
  "artifact": "subagent-artifact.json",
6
- "writer": "utility-artifact-write.json",
7
- "message": "utility-actor-message.json"
6
+ "writer": "utility-artifact-write.json"
8
7
  },
9
8
  "args": [
10
9
  "input:string",
@@ -19,15 +18,6 @@
19
18
  "write_mode": "create",
20
19
  "tools": ""
21
20
  },
22
- "mailbox": {
23
- "accepts": [
24
- "control.kill"
25
- ],
26
- "emits": [
27
- "artifact.written",
28
- "artifact.blocked"
29
- ]
30
- },
31
21
  "artifacts": {
32
22
  "artifact": "{artifact_path}"
33
23
  },
@@ -58,13 +48,6 @@
58
48
  "artifact_path": "{artifact_path}",
59
49
  "mode": "{write_mode}"
60
50
  }
61
- },
62
- {
63
- "name": "message",
64
- "values": {
65
- "type": "artifact.written",
66
- "summary": "Artifact written to path {artifact_path} using mode {write_mode}."
67
- }
68
51
  }
69
52
  ]
70
53
  }
@@ -22,18 +22,6 @@
22
22
  "artifact_path": "./async-run-ops.md",
23
23
  "tools": ""
24
24
  },
25
- "mailbox": {
26
- "accepts": [
27
- "control.kill"
28
- ],
29
- "emits": [
30
- "operations.completed",
31
- "artifact.prepared",
32
- "command.done",
33
- "run.done",
34
- "run.failed"
35
- ]
36
- },
37
25
  "template": [
38
26
  {
39
27
  "name": "snapshot",
@@ -18,20 +18,6 @@
18
18
  "mode": "degraded-new-branch",
19
19
  "tools": ""
20
20
  },
21
- "mailbox": {
22
- "accepts": [
23
- "control.reply",
24
- "control.revise",
25
- "control.kill"
26
- ],
27
- "emits": [
28
- "checkpoint.needs_input",
29
- "checkpoint.continued",
30
- "command.done",
31
- "run.done",
32
- "run.failed"
33
- ]
34
- },
35
21
  "template": [
36
22
  {
37
23
  "name": "checkpoint",
@@ -22,18 +22,6 @@
22
22
  "constraints": "Split into bounded mutation zones and preserve integrator ownership of shared contracts.",
23
23
  "tools": ""
24
24
  },
25
- "mailbox": {
26
- "accepts": [
27
- "control.kill"
28
- ],
29
- "emits": [
30
- "task_card.completed",
31
- "pipeline.completed",
32
- "command.done",
33
- "run.done",
34
- "run.failed"
35
- ]
36
- },
37
25
  "template": [
38
26
  {
39
27
  "name": "planner",
@@ -21,18 +21,6 @@
21
21
  "artifact_path": "./docs-maintenance.md",
22
22
  "tools": ""
23
23
  },
24
- "mailbox": {
25
- "accepts": [
26
- "control.kill"
27
- ],
28
- "emits": [
29
- "docs.completed",
30
- "artifact.prepared",
31
- "command.done",
32
- "run.done",
33
- "run.failed"
34
- ]
35
- },
36
24
  "template": [
37
25
  {
38
26
  "name": "docs_index",