@timqi/pier 0.1.3 → 0.1.5

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 (136) hide show
  1. package/README.md +12 -7
  2. package/dist/agent/config.js +9 -3
  3. package/dist/agent/events.js +13 -5
  4. package/dist/agent/listing.js +10 -2
  5. package/dist/agent/packages.js +4 -20
  6. package/dist/agent/pi.js +18 -86
  7. package/dist/channels/attach.js +2 -2
  8. package/dist/channels/commands.js +10 -8
  9. package/dist/channels/config.js +32 -24
  10. package/dist/channels/control.js +60 -14
  11. package/dist/channels/conversations.js +60 -13
  12. package/dist/channels/handoff.js +90 -0
  13. package/dist/channels/lark-api.js +7 -0
  14. package/dist/channels/lark-outbound.js +19 -0
  15. package/dist/channels/lark-panel.js +41 -26
  16. package/dist/channels/lark-render.js +2 -1
  17. package/dist/channels/lark.js +35 -26
  18. package/dist/channels/lines.js +1 -1
  19. package/dist/channels/panel.js +324 -115
  20. package/dist/channels/receipts.js +25 -12
  21. package/dist/channels/routes.js +21 -7
  22. package/dist/channels/runtime.js +21 -7
  23. package/dist/channels/slack-api.js +19 -10
  24. package/dist/channels/slack-cli.js +503 -0
  25. package/dist/channels/slack-directory.js +2 -2
  26. package/dist/channels/slack-outbound.js +11 -1
  27. package/dist/channels/slack-panel.js +81 -40
  28. package/dist/channels/slack-render.js +3 -1
  29. package/dist/channels/slack-thread.js +41 -0
  30. package/dist/channels/slack-transcript.js +107 -0
  31. package/dist/channels/slack.js +38 -31
  32. package/dist/channels/types.js +1 -3
  33. package/dist/cli.js +166 -7
  34. package/dist/core/identity.js +61 -17
  35. package/dist/core/reply.js +19 -15
  36. package/dist/core/router.js +23 -3
  37. package/dist/db.js +33 -0
  38. package/dist/main.js +61 -41
  39. package/dist/paths.js +3 -0
  40. package/dist/secrets.js +2 -1
  41. package/dist/settings.js +3 -12
  42. package/dist/socket.js +99 -0
  43. package/dist/tasks/agent.js +5 -6
  44. package/dist/tasks/callbacks.js +2 -2
  45. package/dist/tasks/cli.js +225 -0
  46. package/dist/tasks/definitions.js +3 -3
  47. package/dist/tasks/execution.js +1 -3
  48. package/dist/tasks/groups.js +2 -5
  49. package/dist/tasks/messages.js +18 -158
  50. package/dist/tasks/operations.js +335 -0
  51. package/dist/tasks/routes.js +1 -11
  52. package/dist/tasks/runs.js +5 -20
  53. package/dist/tasks/service.js +18 -43
  54. package/dist/tasks/store.js +15 -15
  55. package/dist/tools.js +18 -3
  56. package/dist/vault.js +107 -0
  57. package/dist/web/auth.js +2 -1
  58. package/dist/web/public/assets/{activity-BSMeRcN2.js → activity-CrybM-E8.js} +2 -2
  59. package/dist/web/public/assets/activity-CrybM-E8.js.br +0 -0
  60. package/dist/web/public/assets/activity-CrybM-E8.js.gz +0 -0
  61. package/dist/web/public/assets/{boards-BCWQMZry.js → boards-Cw7_6J6L.js} +1 -1
  62. package/dist/web/public/assets/boards-Cw7_6J6L.js.br +0 -0
  63. package/dist/web/public/assets/boards-Cw7_6J6L.js.gz +0 -0
  64. package/dist/web/public/assets/{explorer-Cr4XTi4j.js → explorer-DV066dUD.js} +1 -1
  65. package/dist/web/public/assets/explorer-DV066dUD.js.br +0 -0
  66. package/dist/web/public/assets/explorer-DV066dUD.js.gz +0 -0
  67. package/dist/web/public/assets/index-BrNHu2qj.js +85 -0
  68. package/dist/web/public/assets/index-BrNHu2qj.js.br +0 -0
  69. package/dist/web/public/assets/index-BrNHu2qj.js.gz +0 -0
  70. package/dist/web/public/assets/index-DLszkDUV.css +2 -0
  71. package/dist/web/public/assets/index-DLszkDUV.css.br +0 -0
  72. package/dist/web/public/assets/index-DLszkDUV.css.gz +0 -0
  73. package/dist/web/public/assets/{runs-DdERzeac.js → runs-DDagTNaM.js} +1 -1
  74. package/dist/web/public/assets/runs-DDagTNaM.js.br +0 -0
  75. package/dist/web/public/assets/runs-DDagTNaM.js.gz +0 -0
  76. package/dist/web/public/assets/settings-BEdSeXpm.js +5 -0
  77. package/dist/web/public/assets/settings-BEdSeXpm.js.br +0 -0
  78. package/dist/web/public/assets/settings-BEdSeXpm.js.gz +0 -0
  79. package/dist/web/public/assets/{task-runs-C-dGUDsH.js → task-runs-BnMack9t.js} +1 -1
  80. package/dist/web/public/assets/task-runs-BnMack9t.js.br +0 -0
  81. package/dist/web/public/assets/task-runs-BnMack9t.js.gz +0 -0
  82. package/dist/web/public/assets/{tasks-CY30H1u1.js → tasks-BkW7YShZ.js} +1 -1
  83. package/dist/web/public/assets/tasks-BkW7YShZ.js.br +0 -0
  84. package/dist/web/public/assets/tasks-BkW7YShZ.js.gz +0 -0
  85. package/dist/web/public/index.html +2 -2
  86. package/dist/web/public/index.html.br +0 -0
  87. package/dist/web/public/index.html.gz +0 -0
  88. package/dist/web/push.js +4 -10
  89. package/dist/web/vault.js +68 -0
  90. package/dist/{extensions/web → websearch}/artifacts.js +2 -2
  91. package/dist/websearch/cli.js +73 -0
  92. package/dist/websearch/run.js +273 -0
  93. package/docs/deploy.md +34 -11
  94. package/package.json +2 -3
  95. package/skills/pier-help/SKILL.md +32 -16
  96. package/skills/pier-slack/SKILL.md +52 -71
  97. package/skills/pier-tasks/SKILL.md +60 -148
  98. package/skills/pier-vault/SKILL.md +36 -0
  99. package/skills/pier-web/SKILL.md +50 -0
  100. package/dist/channels/slack-tool.js +0 -416
  101. package/dist/channels/telegram-api.js +0 -86
  102. package/dist/channels/telegram-panel.js +0 -97
  103. package/dist/channels/telegram-render.js +0 -69
  104. package/dist/channels/telegram.js +0 -421
  105. package/dist/extensions/index.js +0 -10
  106. package/dist/extensions/web/index.js +0 -9
  107. package/dist/extensions/web/tools.js +0 -265
  108. package/dist/tasks/tool.js +0 -416
  109. package/dist/web/public/assets/activity-BSMeRcN2.js.br +0 -0
  110. package/dist/web/public/assets/activity-BSMeRcN2.js.gz +0 -0
  111. package/dist/web/public/assets/boards-BCWQMZry.js.br +0 -0
  112. package/dist/web/public/assets/boards-BCWQMZry.js.gz +0 -0
  113. package/dist/web/public/assets/explorer-Cr4XTi4j.js.br +0 -0
  114. package/dist/web/public/assets/explorer-Cr4XTi4j.js.gz +0 -0
  115. package/dist/web/public/assets/index-C7tA0Ufu.js +0 -85
  116. package/dist/web/public/assets/index-C7tA0Ufu.js.br +0 -0
  117. package/dist/web/public/assets/index-C7tA0Ufu.js.gz +0 -0
  118. package/dist/web/public/assets/index-DVIt5Gio.css +0 -2
  119. package/dist/web/public/assets/index-DVIt5Gio.css.br +0 -0
  120. package/dist/web/public/assets/index-DVIt5Gio.css.gz +0 -0
  121. package/dist/web/public/assets/runs-DdERzeac.js.br +0 -0
  122. package/dist/web/public/assets/runs-DdERzeac.js.gz +0 -0
  123. package/dist/web/public/assets/settings-CQDAHoMM.js +0 -5
  124. package/dist/web/public/assets/settings-CQDAHoMM.js.br +0 -0
  125. package/dist/web/public/assets/settings-CQDAHoMM.js.gz +0 -0
  126. package/dist/web/public/assets/task-runs-C-dGUDsH.js.br +0 -0
  127. package/dist/web/public/assets/task-runs-C-dGUDsH.js.gz +0 -0
  128. package/dist/web/public/assets/tasks-CY30H1u1.js.br +0 -0
  129. package/dist/web/public/assets/tasks-CY30H1u1.js.gz +0 -0
  130. /package/dist/{extensions/web → websearch}/anthropic.js +0 -0
  131. /package/dist/{extensions/web → websearch}/content.js +0 -0
  132. /package/dist/{extensions/web → websearch}/http.js +0 -0
  133. /package/dist/{extensions/web → websearch}/json.js +0 -0
  134. /package/dist/{extensions/web → websearch}/language.js +0 -0
  135. /package/dist/{extensions/web → websearch}/openai.js +0 -0
  136. /package/dist/{extensions/web → websearch}/provider.js +0 -0
@@ -1,6 +1,6 @@
1
1
  // What a task *is* before it ever runs: the id it is minted with, the draft
2
2
  // validated into a definition, and when its trigger is next due. Every way a
3
- // definition can be created — HTTP, the task tool, Pier's own owned task —
3
+ // definition can be created — HTTP, `pier task`, Pier's own owned task —
4
4
  // arrives here, so a field is checked in one place or nowhere.
5
5
  import { randomBytes } from "node:crypto";
6
6
  import { stat } from "node:fs/promises";
@@ -24,7 +24,7 @@ export const idSymbol = (byte) => ID_ALPHABET.charAt(byte & 31);
24
24
  * not an error — `saveRun`'s ON CONFLICT DO UPDATE would quietly overwrite. */
25
25
  export const newId = () => Array.from(randomBytes(16), idSymbol).join("");
26
26
  /** A definition Pier's own code created is reconciled by that code and edited
27
- * by nobody: `creator` is `"http"` (Console) or `session:<id>` (task tool);
27
+ * by nobody: `creator` is `"http"` (Console) or `session:<id>` (`pier task`);
28
28
  * anything else is an instance-layer owner, which names itself in `by`.
29
29
  * Otherwise a public surface could repoint the tools task while its switch
30
30
  * went on claiming Pier keeps the tools current. */
@@ -258,7 +258,7 @@ export class TaskDefinitions {
258
258
  if (trigger.type === "watch")
259
259
  await this.assertDirectory(trigger.cwd);
260
260
  const actionRaw = record(value.action);
261
- // Self-documenting: tool callers (models) recover from this in one retry.
261
+ // Self-documenting: a model recovers from this in one retry.
262
262
  if (!actionRaw) {
263
263
  throw new Error('action required, e.g. {"type":"agent","session":{"mode":"fresh","cwd":"/abs/path"},"prompt":"..."}');
264
264
  }
@@ -92,9 +92,7 @@ export class TaskExecution {
92
92
  log.debug(`${settled} (watch did not match)`);
93
93
  else
94
94
  log.info(settled);
95
- // A run that ends awaiting a supervisor decision suppresses its
96
- // completion callback: the pending question is the notification.
97
- if (run.callbackSessionId && !this.host.openDecisionId(run.id))
95
+ if (run.callbackSessionId)
98
96
  run.callbackState = "pending";
99
97
  this.controllers.delete(run.id);
100
98
  try {
@@ -35,12 +35,12 @@ export class TaskGroups {
35
35
  }
36
36
  /** Enqueues every member or none: a partially started group is worse than
37
37
  * a rejected one. */
38
- runAll(definitions, join, callerSessionId, parentRunId, callbackSessionId, callbackMode) {
38
+ runAll(definitions, join, callerSessionId, callbackSessionId, callbackMode) {
39
39
  if (definitions.length < 2)
40
40
  throw new Error("a task group needs at least 2 members");
41
41
  const { group, runs } = this.store.transact(() => {
42
42
  const group = this.create(join, callerSessionId, callbackSessionId, callbackMode);
43
- const runs = definitions.map((definition) => this.host.prepareMember(definition.id, group.id, callerSessionId, parentRunId));
43
+ const runs = definitions.map((definition) => this.host.prepareMember(definition.id, group.id, callerSessionId));
44
44
  group.memberRunIds = runs.map((run) => run.id);
45
45
  this.store.saveGroup(group);
46
46
  return { group, runs };
@@ -150,9 +150,6 @@ export class TaskGroups {
150
150
  `- "${run.context.definition.name}" \u2014 state: ${run.state}`,
151
151
  ` ${runRef(run)}`,
152
152
  ];
153
- const decision = this.host.openDecisionId(run.id);
154
- if (decision)
155
- head.push(` Needs a decision: reply to message ${decision}`);
156
153
  if (group.join === "first" && run.id !== group.winnerRunId) {
157
154
  head.push(" Cancelled after the winning run; resume its session to recover partial work.");
158
155
  return head.join("\n");
@@ -1,15 +1,15 @@
1
- // What a parent and a child say to each other while a run is going. Every
2
- // message is a durable row before it is a delivery: either end may be mid-turn
3
- // or gone, and an undelivered message is retried, expired and said, never
4
- // dropped (§5). Delivery itself belongs to outbox.ts.
1
+ // What a parent says to a child while a run is going. Every message is a
2
+ // durable row before it is a delivery: the child may be mid-turn or gone, and
3
+ // an undelivered message is retried, expired and said, never dropped (§5).
4
+ // Delivery itself belongs to outbox.ts.
5
5
  import { runSource } from "./callbacks.js";
6
6
  import { newId } from "./definitions.js";
7
7
  import { Outbox } from "./outbox.js";
8
8
  import { isTerminal } from "./types.js";
9
9
  const MAX_MESSAGE_LENGTH = 16 * 1024;
10
- /** `answered` is a delivery that was read; `expired` is one given up on. */
10
+ /** `expired` is a delivery given up on. */
11
11
  const ENGINE_STATE = {
12
- pending: "pending", failed: "failed", delivered: "delivered", answered: "delivered", expired: "abandoned",
12
+ pending: "pending", failed: "failed", delivered: "delivered", expired: "abandoned",
13
13
  };
14
14
  function bounded(content) {
15
15
  const text = content.trim();
@@ -22,20 +22,14 @@ function bounded(content) {
22
22
  export class TaskMessenger {
23
23
  store;
24
24
  hub;
25
- prepareResume;
26
25
  unreachable;
27
- startRun;
28
26
  outbox;
29
27
  constructor(store, router, hub,
30
- /** Prepares a continuation; it starts only after the reply commits. */
31
- prepareResume,
32
28
  /** Reports a delivery nobody can complete (service.ts owns the surfaces). */
33
- unreachable, startRun) {
29
+ unreachable) {
34
30
  this.store = store;
35
31
  this.hub = hub;
36
- this.prepareResume = prepareResume;
37
32
  this.unreachable = unreachable;
38
- this.startRun = startRun;
39
33
  this.outbox = new Outbox(router, {
40
34
  id: ({ message }) => message.id,
41
35
  reload: (id) => {
@@ -50,10 +44,8 @@ export class TaskMessenger {
50
44
  message.state = "delivered";
51
45
  message.deliveredAt = Date.now();
52
46
  }
53
- else if (callbackState === "abandoned") {
47
+ else if (callbackState === "abandoned")
54
48
  message.state = "expired";
55
- message.answeredAt = Date.now();
56
- }
57
49
  else
58
50
  message.state = callbackState ?? "pending";
59
51
  this.store.saveMessage(message);
@@ -76,25 +68,6 @@ export class TaskMessenger {
76
68
  for (const message of this.store.expirePendingMessages())
77
69
  this.changed(message);
78
70
  }
79
- /** The unanswered decision on a run, if any. */
80
- openDecisionId(runId) {
81
- return this.store.listMessages(runId).find((m) => m.kind === "decision" && (m.state === "pending" || m.state === "delivered"))?.id ?? null;
82
- }
83
- /** A manual continuation supersedes an unanswered decision (design 04):
84
- * one continuation per run, never two racing ones. */
85
- expireDecisions(runId, reason) {
86
- const expired = [];
87
- for (const message of this.store.listMessages(runId)) {
88
- if (message.kind !== "decision" || (message.state !== "pending" && message.state !== "delivered"))
89
- continue;
90
- message.state = "expired";
91
- message.error = reason;
92
- message.answeredAt = Date.now();
93
- this.store.saveMessage(message);
94
- expired.push(message);
95
- }
96
- return expired;
97
- }
98
71
  list(runId) {
99
72
  return this.store.listMessages(runId);
100
73
  }
@@ -102,7 +75,7 @@ export class TaskMessenger {
102
75
  return this.store.listRecentMessages(since);
103
76
  }
104
77
  async control(run, fromSessionId, kind, content) {
105
- const message = this.create(run, kind, fromSessionId, run.targetSessionId ?? "", content, null);
78
+ const message = this.create(run, kind, fromSessionId, run.targetSessionId ?? "", content);
106
79
  this.changed(message);
107
80
  if (run.targetSessionId)
108
81
  this.deliver(message, run.targetSessionId);
@@ -112,9 +85,8 @@ export class TaskMessenger {
112
85
  if (!run.targetSessionId)
113
86
  return;
114
87
  for (const message of this.store.listMessages(run.id)) {
115
- if (message.state !== "pending" || (message.kind !== "steer" && message.kind !== "follow_up"))
116
- continue;
117
- this.deliver(message, run.targetSessionId);
88
+ if (message.state === "pending")
89
+ this.deliver(message, run.targetSessionId);
118
90
  }
119
91
  }
120
92
  /** Delivery is fire-and-forget, so this sweep is what closes a failed one.
@@ -124,30 +96,13 @@ export class TaskMessenger {
124
96
  if (!run)
125
97
  continue;
126
98
  // Expiring a dead control is not a retry, so it ignores the backoff.
127
- if ((message.kind === "steer" || message.kind === "follow_up") && isTerminal(run.state)) {
99
+ if (isTerminal(run.state)) {
128
100
  message.state = "expired";
129
101
  message.error = "run finished before delivery completed";
130
102
  this.store.saveMessage(message);
131
103
  this.changed(message);
132
104
  continue;
133
105
  }
134
- // A reply that resumed a terminal run is the continuation's prompt, not a
135
- // system input: the transcript read would re-inject it and start a turn no
136
- // run owns. The continuation's `startedAt` is the proof instead.
137
- if (message.kind === "reply" && isTerminal(run.state)) {
138
- const resumed = message.resumeRunId ? this.store.getRun(message.resumeRunId) : undefined;
139
- if (resumed?.startedAt)
140
- this.delivered(message);
141
- else if (!resumed)
142
- this.abandon(message, `continuation ${message.resumeRunId ?? "(none)"} is gone`);
143
- else if (isTerminal(resumed.state)) {
144
- // Never started and never will: said now, not four minutes later at
145
- // the ceiling. A duplicate report beats a special case that could
146
- // suppress the only one.
147
- this.abandon(message, `continuation ${resumed.id} ${resumed.state} before it started`);
148
- }
149
- continue;
150
- }
151
106
  if ((message.nextAttemptAt ?? 0) > now)
152
107
  continue;
153
108
  const target = message.toSessionId || run.targetSessionId;
@@ -155,76 +110,17 @@ export class TaskMessenger {
155
110
  this.deliver(message, target);
156
111
  }
157
112
  }
158
- /** Returns the receipt immediately; the reply arrives as a follow-up (active
159
- * run) or resumes the session (terminal run). A decision steers the
160
- * supervisor, or a blocked child would wait out its whole turn. */
161
- async contact(run, fromSessionId, reason, content) {
162
- if (!run.invokedBySessionId)
163
- throw new Error("run has no supervisor session");
164
- if (reason === "decision" && this.openDecisionId(run.id)) {
165
- throw new Error("run already has a pending supervisor decision");
166
- }
167
- const message = this.create(run, reason, fromSessionId, run.invokedBySessionId, content, null);
168
- this.changed(message);
169
- this.deliver(message, run.invokedBySessionId);
170
- return this.require(message.id);
171
- }
172
- async reply(questionId, fromSessionId, content) {
173
- const question = this.require(questionId);
174
- if (question.kind !== "decision")
175
- throw new Error("message is not a decision request");
176
- if (question.toSessionId !== fromSessionId)
177
- throw new Error("only the addressed supervisor may reply");
178
- const existing = this.store.listMessages(question.runId).find((m) => m.kind === "reply" && m.replyTo === question.id);
179
- const text = bounded(content);
180
- if (existing) {
181
- if (existing.content !== text)
182
- throw new Error("decision already answered with different content");
183
- return existing;
184
- }
185
- if (question.state !== "delivered" && question.state !== "pending") {
186
- throw new Error(`decision is ${question.state}`);
187
- }
188
- const run = this.store.getRun(question.runId);
189
- if (!run)
190
- throw new Error(`unknown task run: ${question.runId}`);
191
- // A rejected continuation must leave the question answerable. Persist the
192
- // answer and its queued run together, before either publishes or executes.
193
- const { reply, continuation } = this.store.transact(() => {
194
- const reply = this.create(run, "reply", fromSessionId, question.fromSessionId, text, question.id);
195
- question.state = "answered";
196
- question.answeredAt = Date.now();
197
- this.store.saveMessage(question);
198
- const continuation = isTerminal(run.state)
199
- ? this.prepareResume(run.id, this.format(reply, run), fromSessionId)
200
- : undefined;
201
- if (continuation) {
202
- reply.resumeRunId = continuation.id;
203
- this.store.saveMessage(reply);
204
- }
205
- return { reply, continuation };
206
- });
207
- this.changed(question);
208
- this.changed(reply);
209
- if (continuation)
210
- this.startRun(continuation);
211
- else if (run.targetSessionId)
212
- this.deliver(reply, run.targetSessionId);
213
- return this.require(reply.id);
214
- }
215
- create(run, kind, fromSessionId, toSessionId, content, replyTo) {
113
+ create(run, kind, fromSessionId, toSessionId, content) {
216
114
  const message = {
217
115
  id: newId(),
218
116
  runId: run.id,
219
117
  kind,
220
118
  fromSessionId,
221
119
  toSessionId,
222
- replyTo,
223
120
  state: "pending",
224
121
  content: bounded(content),
225
122
  createdAt: Date.now(),
226
123
  deliveredAt: null,
227
- answeredAt: null,
228
124
  error: null,
229
125
  attempts: 0,
230
126
  nextAttemptAt: null,
@@ -247,56 +143,20 @@ export class TaskMessenger {
247
143
  callbackAttempts: message.attempts,
248
144
  callbackError: message.error,
249
145
  callbackNextAttemptAt: message.nextAttemptAt,
250
- // Steer whatever someone is blocked on: a follow-up lands only once the
251
- // recipient runs out of tool calls. Progress is a follow-up because nobody waits.
252
- ...(message.kind === "follow_up" || message.kind === "progress" ? {} : { callbackMode: "steer" }),
146
+ // A steer interrupts; a follow-up lands only once the recipient runs out
147
+ // of tool calls.
148
+ ...(message.kind === "follow_up" ? {} : { callbackMode: "steer" }),
253
149
  };
254
150
  }
255
- /** Proven by something other than the recipient's transcript. */
256
- delivered(message) {
257
- message.state = "delivered";
258
- message.deliveredAt = Date.now();
259
- message.error = null;
260
- message.nextAttemptAt = null;
261
- this.store.saveMessage(message);
262
- this.changed(message);
263
- }
264
- abandon(message, why) {
265
- message.state = "expired";
266
- message.error = why;
267
- message.answeredAt = Date.now();
268
- message.nextAttemptAt = null;
269
- this.store.saveMessage(message);
270
- this.changed(message);
271
- this.told(message, why);
272
- }
273
- /** Both ends are told, and an expired decision stops suppressing its run's
274
- * completion callback, which `execution.ts` decided once and never revisits. */
151
+ /** Both ends are told. */
275
152
  told(message, why) {
276
153
  this.unreachable(message.toSessionId, `a ${message.kind} from run ${message.runId}`, why);
277
154
  if (message.fromSessionId && message.fromSessionId !== message.toSessionId) {
278
155
  this.unreachable(message.fromSessionId, `your ${message.kind} on run ${message.runId}`, why);
279
156
  }
280
- const run = this.store.getRun(message.runId);
281
- if (message.kind !== "decision" || !run?.callbackSessionId)
282
- return;
283
- if (run.callbackState === null && isTerminal(run.state)) {
284
- run.callbackState = "pending"; // the tick sweep delivers it
285
- this.store.saveRun(run);
286
- }
287
157
  }
288
158
  format(message, run) {
289
- const title = run.context.definition.name;
290
- if (message.kind === "progress") {
291
- return `Subagent progress for task "${title}"\nRun: ${run.id}\nMessage: ${message.id}\n\n${message.content}`;
292
- }
293
- if (message.kind === "decision") {
294
- return `Subagent needs a decision for task "${title}"\nRun: ${run.id}\nMessage: ${message.id}\nReply with the Task reply operation.\n\n${message.content}`;
295
- }
296
- if (message.kind === "reply") {
297
- return `Supervisor reply for task "${title}"\nRun: ${run.id}\nReply to: ${message.replyTo ?? "-"}\n\n${message.content}`;
298
- }
299
- return `Task guidance for "${title}"\nRun: ${run.id}\nMessage: ${message.id}\n\n${message.content}`;
159
+ return `Task guidance for "${run.context.definition.name}"\nRun: ${run.id}\nMessage: ${message.id}\n\n${message.content}`;
300
160
  }
301
161
  origin(message, run) {
302
162
  return {