@desplega.ai/agent-swarm 1.147.0 → 1.149.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 (185) hide show
  1. package/README.md +13 -1
  2. package/dist/{acp-adapter-9n319wqc.js → acp-adapter-4jncb126.js} +12 -5
  3. package/dist/{actions-2vxqvpr9.js → actions-31vp3ae7.js} +10 -9
  4. package/dist/{app-w066xfy0.js → app-1hh67x8w.js} +6 -6
  5. package/dist/{assistant-kt31dj2h.js → assistant-z66dmz6p.js} +13 -11
  6. package/dist/{boot-reembed-az5rassp.js → boot-reembed-fqzxxzjh.js} +7 -7
  7. package/dist/{boot-reembed-j3mm3rfz.js → boot-reembed-wxa8ya0s.js} +8 -8
  8. package/dist/{boot-scrub-logs-b6h54817.js → boot-scrub-logs-jnyndh79.js} +5 -5
  9. package/dist/{claude-adapter-w1z04ann.js → claude-adapter-3qpa9w0j.js} +9 -9
  10. package/dist/{claude-managed-adapter-sactwn31.js → claude-managed-adapter-qvsmh6mv.js} +2 -2
  11. package/dist/{claude-sdk-session-f0cc1kec.js → claude-sdk-session-2yxgjs5d.js} +9 -9
  12. package/dist/{cli-y6b6fb76.js → cli-08b07b4r.js} +1 -1
  13. package/dist/{cli-8fc8de14.js → cli-0z2v4nhw.js} +1 -1
  14. package/dist/{cli-de14znh8.js → cli-19f354qr.js} +2 -2
  15. package/dist/{cli-hbv0kq6w.js → cli-2qts1hys.js} +3 -3
  16. package/dist/{cli-kpv03zhj.js → cli-3apbzgyk.js} +27 -15
  17. package/dist/{cli-1th1728g.js → cli-3q5ejx9p.js} +2 -2
  18. package/dist/{cli-d8brzxjb.js → cli-4wtq5jjv.js} +2 -2
  19. package/dist/{cli-ct0et58h.js → cli-5my3bjsd.js} +1 -1
  20. package/dist/{cli-cn6mmc7f.js → cli-6664w7y4.js} +1 -1
  21. package/dist/{cli-yz3djrm0.js → cli-6pqcb4q0.js} +53 -13
  22. package/dist/{cli-719k9j2c.js → cli-7smrsr25.js} +3 -3
  23. package/dist/{cli-rw51bq3j.js → cli-9fy6nk6g.js} +1 -1
  24. package/dist/{cli-zhjmqxzh.js → cli-9hspd3dp.js} +2 -2
  25. package/dist/{cli-3tgwnf43.js → cli-aae6hz6a.js} +4 -4
  26. package/dist/{cli-89xfd7f9.js → cli-cr12paw2.js} +5 -5
  27. package/dist/{cli-b5bq9crk.js → cli-d8ftsp62.js} +8 -8
  28. package/dist/{cli-4nr988h6.js → cli-e95cx1eb.js} +3 -3
  29. package/dist/{cli-n8508nre.js → cli-gjhjfeeg.js} +1 -1
  30. package/dist/{cli-p1d5b073.js → cli-gv88e1vf.js} +1 -1
  31. package/dist/{cli-rvqz34y5.js → cli-jecc01cb.js} +1 -1
  32. package/dist/{cli-8v0g1yc8.js → cli-k0cr4kat.js} +1 -1
  33. package/dist/{cli-mmemxxdc.js → cli-kgz4np97.js} +4 -4
  34. package/dist/{cli-w9kb3bk1.js → cli-kjwt6hdf.js} +3 -1
  35. package/dist/{cli-f7dsy61y.js → cli-mnmsfd1w.js} +6 -2
  36. package/dist/{cli-54wwve05.js → cli-n3dz2942.js} +37 -26
  37. package/dist/{cli-12fz972k.js → cli-nye12xk5.js} +8 -5
  38. package/dist/{cli-tzvk9haz.js → cli-phsxnkp6.js} +20 -20
  39. package/dist/{cli-53s590z8.js → cli-q50ef8g0.js} +1 -1
  40. package/dist/{cli-f146mn5s.js → cli-qaacms9y.js} +7 -6
  41. package/dist/{cli-xqcq9y5e.js → cli-r2ap2czm.js} +1 -0
  42. package/dist/{cli-m8yrsg97.js → cli-sd5pv3b1.js} +3 -3
  43. package/dist/{cli-0b6y7kxm.js → cli-xm87hzbw.js} +1 -1
  44. package/dist/{cli-ftht3zzj.js → cli-yab68w40.js} +285 -11
  45. package/dist/{cli-atcve9y8.js → cli-yb9qhqam.js} +227 -59
  46. package/dist/{cli-smby5m17.js → cli-ygweqcn4.js} +133 -22
  47. package/dist/{cli-dttph1bw.js → cli-ykxrnd1q.js} +2 -2
  48. package/dist/{cli-m9sxbkhm.js → cli-zvz62chv.js} +3 -3
  49. package/dist/cli.js +16 -14
  50. package/dist/{codex-adapter-zw4dwsx7.js → codex-adapter-8meawydj.js} +4 -4
  51. package/dist/{codex-hook-bw8p5nh4.js → codex-hook-hfrt9shr.js} +2 -2
  52. package/dist/{codex-session-runner-k981s65v.js → codex-session-runner-gjgxyp5j.js} +4 -4
  53. package/dist/{commands-sykrxx7e.js → commands-hz3nb95f.js} +5 -5
  54. package/dist/{db-sfbsc8wt.js → db-ggz97zbm.js} +5 -5
  55. package/dist/{e2b-6hb103d8.js → e2b-p04vmtx0.js} +1 -1
  56. package/dist/{handlers-0aspcejm.js → handlers-nbzdzn9k.js} +14 -11
  57. package/dist/{hook-hxccs7m5.js → hook-bks2q1f6.js} +7 -7
  58. package/dist/{hook-4nvqj2sb.js → hook-kq9wp0ep.js} +8 -8
  59. package/dist/{http-y06z517d.js → http-hrf77v87.js} +96 -45
  60. package/dist/{index-tce1rss4.js → index-6nsbg88z.js} +443 -144
  61. package/dist/{index-x5j894zf.js → index-8hmeg8j1.js} +14 -14
  62. package/dist/{index-k8znfx0z.js → index-cqtebbhb.js} +13 -13
  63. package/dist/{index-hssww7kj.js → index-n28pw1zt.js} +15 -15
  64. package/dist/{keepalive-w733ax66.js → keepalive-dxc12gvg.js} +7 -7
  65. package/dist/{lead-75bjqa9d.js → lead-yckfn18d.js} +32 -32
  66. package/dist/{maintenance-w4f1zjck.js → maintenance-6kfb2m5e.js} +8 -8
  67. package/dist/{oauth-refresh-sweep-wdetky26.js → oauth-refresh-sweep-1x1ac722.js} +6 -6
  68. package/dist/{onboard-bb5net8s.js → onboard-dcyt1609.js} +4 -3
  69. package/dist/{opencode-adapter-fef1mrn2.js → opencode-adapter-dce4wskd.js} +2 -2
  70. package/dist/{otel-impl-0w7c14ap.js → otel-impl-tbk3e5dr.js} +2 -2
  71. package/dist/{pi-mono-adapter-2has4gnp.js → pi-mono-adapter-zvshk5cj.js} +2 -2
  72. package/dist/{pricing-refresh-9nzsrgcq.js → pricing-refresh-kaqg567e.js} +7 -7
  73. package/dist/{rbac-roles-z1jrffbt.js → rbac-roles-ammq6rd2.js} +5 -5
  74. package/dist/{rbac-roles-r3hqjp09.js → rbac-roles-cf97v1vd.js} +6 -6
  75. package/dist/{render-v2-vbr89fnb.js → render-v2-80w603vy.js} +6 -6
  76. package/dist/{seed-pricing-g62hy1pk.js → seed-pricing-zbrn83xv.js} +6 -6
  77. package/dist/{setup-gnfqnptp.js → setup-fe66kczs.js} +2 -2
  78. package/dist/{worker-kznxp4qm.js → worker-qmb2d1e2.js} +32 -32
  79. package/dist/{x-n2phr5vm.js → x-n3e0v3xa.js} +2 -2
  80. package/openapi.json +46 -4
  81. package/package.json +3 -1
  82. package/src/agentmail/handlers.ts +5 -0
  83. package/src/automation-preflight-alert.ts +41 -0
  84. package/src/be/automation-preflight.ts +3 -3
  85. package/src/be/budget-refusal-notify.ts +1 -0
  86. package/src/be/db/tasks/read.ts +5 -0
  87. package/src/be/db.ts +132 -2
  88. package/src/be/migrations/150_deferred_task_waits.sql +18 -0
  89. package/src/be/migrations/151_repair_scheduled_task_required_params.sql +39 -0
  90. package/src/be/migrations/152_routing_decisions.sql +44 -0
  91. package/src/be/scripts/typecheck.ts +33 -22
  92. package/src/be/seed-scripts/catalog/delegate.ts +5 -1
  93. package/src/be/seed-skills/bundled-files.generated.json +10 -0
  94. package/src/be/seed-skills/index.ts +3 -0
  95. package/src/be/steering.ts +1 -0
  96. package/src/be/swarm-config-guard.ts +11 -0
  97. package/src/commands/onboard/steps/post-task.tsx +1 -0
  98. package/src/github/handlers.ts +9 -0
  99. package/src/gitlab/handlers.ts +4 -0
  100. package/src/heartbeat/heartbeat.ts +8 -0
  101. package/src/http/approval-requests.ts +1 -0
  102. package/src/http/apps.ts +1 -0
  103. package/src/http/config.ts +15 -6
  104. package/src/http/mcp.ts +31 -4
  105. package/src/http/script-runs.ts +6 -0
  106. package/src/http/tasks.ts +52 -30
  107. package/src/integrations/kapso/inbound.ts +1 -0
  108. package/src/jira/sync.ts +2 -0
  109. package/src/linear/sync.ts +2 -0
  110. package/src/prompts/session-templates.ts +29 -15
  111. package/src/scheduler/deferred-task-waits.ts +123 -0
  112. package/src/scheduler/schedule-task.ts +42 -0
  113. package/src/scheduler/scheduler.ts +22 -31
  114. package/src/script-workflows/workflow-ctx.ts +2 -0
  115. package/src/scripts-runtime/types/stdlib.d.ts +38 -24
  116. package/src/scripts-runtime/types/swarm-sdk.d.ts +38 -24
  117. package/src/server.ts +10 -1
  118. package/src/slack/actions.ts +1 -0
  119. package/src/slack/assistant.ts +2 -0
  120. package/src/slack/handlers.ts +3 -0
  121. package/src/slack/thread-buffer.ts +2 -0
  122. package/src/tasks/worker-follow-up.ts +9 -0
  123. package/src/tests/acp-adapter.test.ts +35 -6
  124. package/src/tests/acp-session-token.test.ts +67 -0
  125. package/src/tests/asset-key-api.test.ts +15 -2
  126. package/src/tests/asset-key-mcp.test.ts +2 -0
  127. package/src/tests/automation-preflight-alert.test.ts +91 -0
  128. package/src/tests/claude-worker-parity.test.ts +3 -0
  129. package/src/tests/config-session-auth.test.ts +143 -0
  130. package/src/tests/defer-task.test.ts +117 -6
  131. package/src/tests/deferred-task-wake.test.ts +456 -0
  132. package/src/tests/heartbeat-reroute-decision.test.ts +1 -0
  133. package/src/tests/http-api-integration.test.ts +33 -4
  134. package/src/tests/mcp-input-ergonomics.test.ts +386 -0
  135. package/src/tests/model-control.test.ts +18 -5
  136. package/src/tests/opencode-adapter.test.ts +2 -2
  137. package/src/tests/promote-draft-task-route.test.ts +4 -0
  138. package/src/tests/prompt-template-session.test.ts +13 -4
  139. package/src/tests/rbac-wire-e2e.test.ts +2 -2
  140. package/src/tests/routing-decision-persistence.test.ts +520 -0
  141. package/src/tests/routing-reason-contract.test.ts +89 -0
  142. package/src/tests/routing-reason-inventory.test.ts +55 -0
  143. package/src/tests/schedule-target-type.test.ts +48 -1
  144. package/src/tests/scheduled-task-required-params-migration.test.ts +182 -0
  145. package/src/tests/scheduled-tasks.test.ts +9 -5
  146. package/src/tests/script-connections.test.ts +4 -0
  147. package/src/tests/script-runs-http.test.ts +31 -0
  148. package/src/tests/scripts-typecheck.test.ts +11 -0
  149. package/src/tests/secret-scrubber.test.ts +12 -0
  150. package/src/tests/send-task-output-schema.test.ts +66 -1
  151. package/src/tests/send-task-requested-by.test.ts +1 -0
  152. package/src/tests/send-task-slack-routing-guard.test.ts +2 -0
  153. package/src/tests/store-progress-blocked-waiting-gate.test.ts +151 -0
  154. package/src/tests/swarm-tool-result-gate.test.ts +24 -0
  155. package/src/tests/task-tool-manifest.test.ts +47 -0
  156. package/src/tests/task-tool-preload-mcp.test.ts +125 -0
  157. package/src/tests/task-tools-ctx.test.ts +2 -0
  158. package/src/tests/tool-output-agent-id.test.ts +1 -0
  159. package/src/tests/ui-followup-lead-delegation.test.ts +6 -1
  160. package/src/tests/workflow-agent-task.test.ts +24 -1
  161. package/src/tests/workflow-engine-v2.test.ts +58 -2
  162. package/src/tools/accept-steer.ts +0 -1
  163. package/src/tools/defer-task.ts +73 -21
  164. package/src/tools/memory-get.ts +10 -3
  165. package/src/tools/memory-rate.ts +19 -7
  166. package/src/tools/memory-search.ts +2 -1
  167. package/src/tools/memory-store.ts +25 -5
  168. package/src/tools/send-task.ts +40 -2
  169. package/src/tools/skills/skill-publish.ts +1 -0
  170. package/src/tools/store-progress.ts +78 -4
  171. package/src/tools/templates.ts +2 -1
  172. package/src/tools/utils.ts +33 -2
  173. package/src/types.ts +14 -1
  174. package/src/utils/acp-session-token.ts +14 -4
  175. package/src/utils/secret-scrubber.ts +2 -0
  176. package/src/utils/task-tool-manifest.ts +33 -0
  177. package/src/workflows/engine.ts +4 -1
  178. package/src/workflows/executors/agent-task.ts +7 -1
  179. package/templates/ai-toolbox.manifest.json +6 -1
  180. package/templates/skills/comms/config.json +18 -0
  181. package/templates/skills/comms/content.md +74 -0
  182. package/templates/skills/comms/files/references/ste-rules.md +73 -0
  183. package/templates/skills/comms/files/references/visual-shapes.md +112 -0
  184. package/templates/skills/swarm-scripts/SKILL.md +3 -2
  185. package/templates/skills/swarm-scripts/content.md +3 -2
@@ -2,7 +2,7 @@ import {
2
2
  COMPOSIO_HTTP_METHODS,
3
3
  composioArgsFromParts,
4
4
  executeComposioRequest
5
- } from "./cli-8fc8de14.js";
5
+ } from "./cli-0z2v4nhw.js";
6
6
  import {
7
7
  LlmRater,
8
8
  REFERENCES_SOURCE_MAX_LENGTH,
@@ -10,18 +10,19 @@ import {
10
10
  } from "./cli-xvkmedgn.js";
11
11
  import {
12
12
  calculateNextRun,
13
+ reconcileDeferredTaskWaits,
13
14
  runScheduleNow
14
- } from "./cli-smby5m17.js";
15
+ } from "./cli-ygweqcn4.js";
15
16
  import {
16
17
  startPricingRefreshLoop
17
- } from "./cli-m8yrsg97.js";
18
+ } from "./cli-sd5pv3b1.js";
18
19
  import {
19
20
  seedPricingFromModelsDev
20
- } from "./cli-rw51bq3j.js";
21
+ } from "./cli-9fy6nk6g.js";
21
22
  import {
22
23
  ensureRbacSeedsSynced,
23
24
  getUserGrant
24
- } from "./cli-8v0g1yc8.js";
25
+ } from "./cli-k0cr4kat.js";
25
26
  import {
26
27
  can,
27
28
  decideAdmission,
@@ -48,7 +49,7 @@ import {
48
49
  runSavedScriptAsAgent,
49
50
  updateApp,
50
51
  upgradeAppDefinition
51
- } from "./cli-de14znh8.js";
52
+ } from "./cli-19f354qr.js";
52
53
  import {
53
54
  require_dist as require_dist2
54
55
  } from "./cli-qgm2pfpq.js";
@@ -72,7 +73,7 @@ import {
72
73
  updateTrackerSync,
73
74
  updateTrackerSyncSwarmId,
74
75
  upsertSwarmConfigWithPolicyMirror
75
- } from "./cli-f7dsy61y.js";
76
+ } from "./cli-mnmsfd1w.js";
76
77
  import {
77
78
  isMultiRuntimeEnabled
78
79
  } from "./cli-07jd68a1.js";
@@ -86,7 +87,7 @@ import {
86
87
  snapshotWorkflow,
87
88
  startWorkflowExecution,
88
89
  validateJsonSchema
89
- } from "./cli-yz3djrm0.js";
90
+ } from "./cli-6pqcb4q0.js";
90
91
  import {
91
92
  ConnectionAuthInputSchema,
92
93
  SCRIPT_LONG_TIMEOUT_HINT_MS,
@@ -109,7 +110,7 @@ import {
109
110
  upsertCredentialBinding,
110
111
  upsertScriptConnection,
111
112
  validateDefinition
112
- } from "./cli-3tgwnf43.js";
113
+ } from "./cli-aae6hz6a.js";
113
114
  import {
114
115
  CANDIDATE_SET_MULTIPLIER,
115
116
  computeScore,
@@ -121,7 +122,7 @@ import {
121
122
  isGraphExpansionEnabled,
122
123
  rerank,
123
124
  rowToCandidate
124
- } from "./cli-1th1728g.js";
125
+ } from "./cli-3q5ejx9p.js";
125
126
  import {
126
127
  getApiKey
127
128
  } from "./cli-f14fvzag.js";
@@ -139,7 +140,7 @@ import {
139
140
  listAuthorizationsForApp,
140
141
  onAuthorizationRefreshed,
141
142
  upsertOAuthApp
142
- } from "./cli-zhjmqxzh.js";
143
+ } from "./cli-9hspd3dp.js";
143
144
  import {
144
145
  ZodFirstPartyTypeKind,
145
146
  objectType
@@ -158,7 +159,7 @@ import {
158
159
  getFileInfo,
159
160
  parseSlackTs,
160
161
  uploadFile
161
- } from "./cli-mmemxxdc.js";
162
+ } from "./cli-kgz4np97.js";
162
163
  import {
163
164
  AgentFsProvider
164
165
  } from "./cli-jsp14b6c.js";
@@ -178,10 +179,10 @@ import {
178
179
  resolveIdentityByEmail,
179
180
  resolveUserByToken,
180
181
  unlinkIdentity
181
- } from "./cli-p1d5b073.js";
182
+ } from "./cli-gv88e1vf.js";
182
183
  import {
183
184
  createTaskWithSiblingAwareness
184
- } from "./cli-53s590z8.js";
185
+ } from "./cli-q50ef8g0.js";
185
186
  import {
186
187
  ensure,
187
188
  getAgentDisplayName,
@@ -192,7 +193,7 @@ import {
192
193
  startSlackApp,
193
194
  stopSlackApp,
194
195
  withSpan
195
- } from "./cli-b5bq9crk.js";
196
+ } from "./cli-d8ftsp62.js";
196
197
  import {
197
198
  $OpenAPIRegistry,
198
199
  $OpenApiGeneratorV31,
@@ -225,6 +226,7 @@ import {
225
226
  ReasoningEffortSchema,
226
227
  RepoGuidelinesInputSchema,
227
228
  RepoHooksSchema,
229
+ RoutingReasonSchema,
228
230
  ScheduledTaskTargetTypeSchema,
229
231
  ScriptRunStatusSchema,
230
232
  ServiceStatusSchema,
@@ -254,6 +256,7 @@ import {
254
256
  createAppVersion,
255
257
  createApprovalRequest,
256
258
  createChannel,
259
+ createLogEntry,
257
260
  createMcpServer,
258
261
  createMetric,
259
262
  createMetricVersion,
@@ -439,13 +442,13 @@ import {
439
442
  upsertPromptTemplate,
440
443
  upsertService,
441
444
  validateConfigValue
442
- } from "./cli-ftht3zzj.js";
445
+ } from "./cli-yab68w40.js";
443
446
  import {
444
447
  generateDefaultClaudeMd,
445
448
  generateDefaultIdentityMd,
446
449
  generateDefaultSoulMd,
447
450
  init_defaults
448
- } from "./cli-y6b6fb76.js";
451
+ } from "./cli-08b07b4r.js";
449
452
  import {
450
453
  getTemplateDefinition,
451
454
  init_registry,
@@ -454,7 +457,7 @@ import {
454
457
  interpolate,
455
458
  registerTemplate,
456
459
  resolveTemplate
457
- } from "./cli-kpv03zhj.js";
460
+ } from "./cli-3apbzgyk.js";
458
461
  import {
459
462
  MAX_PROFILE_FILE_LENGTH,
460
463
  getAppUrl,
@@ -515,14 +518,14 @@ import {
515
518
  import {
516
519
  init_package,
517
520
  package_default
518
- } from "./cli-w9kb3bk1.js";
521
+ } from "./cli-kjwt6hdf.js";
519
522
  import {
520
523
  init_secret_scrubber,
521
524
  refreshSecretScrubberCache,
522
525
  registerVolatileSecret,
523
526
  scrubObject,
524
527
  scrubSecrets
525
- } from "./cli-xqcq9y5e.js";
528
+ } from "./cli-r2ap2czm.js";
526
529
  import {
527
530
  init_event_bus,
528
531
  workflowEventBus
@@ -19306,6 +19309,7 @@ ${combinedPreview}`
19306
19309
  return;
19307
19310
  const task = await createTaskWithSiblingAwareness(followupResult.text, {
19308
19311
  agentId: first.agentId,
19312
+ routingReason: "continuity",
19309
19313
  source: "agentmail",
19310
19314
  taskType: "agentmail-reply",
19311
19315
  agentmailInboxId: first.inboxId,
@@ -19432,6 +19436,7 @@ async function handleMessageReceived(payload) {
19432
19436
  }
19433
19437
  const task2 = await createTaskWithSiblingAwareness(followupResult.text, {
19434
19438
  agentId: existingTask.agentId,
19439
+ routingReason: existingTask.agentId ? "continuity" : undefined,
19435
19440
  source: "agentmail",
19436
19441
  taskType: "agentmail-reply",
19437
19442
  agentmailInboxId: inbox_id,
@@ -19462,6 +19467,7 @@ async function handleMessageReceived(payload) {
19462
19467
  }
19463
19468
  const task3 = await createTaskWithSiblingAwareness(leadResult.text, {
19464
19469
  agentId: agent.id,
19470
+ routingReason: "human_pinned",
19465
19471
  source: "agentmail",
19466
19472
  taskType: "agentmail-message",
19467
19473
  agentmailInboxId: inbox_id,
@@ -19485,6 +19491,7 @@ async function handleMessageReceived(payload) {
19485
19491
  }
19486
19492
  const task2 = await createTaskWithSiblingAwareness(workerResult.text, {
19487
19493
  agentId: agent.id,
19494
+ routingReason: "human_pinned",
19488
19495
  source: "agentmail",
19489
19496
  taskType: "agentmail-message",
19490
19497
  agentmailInboxId: inbox_id,
@@ -19512,6 +19519,7 @@ async function handleMessageReceived(payload) {
19512
19519
  }
19513
19520
  const task2 = await createTaskWithSiblingAwareness(unmappedResult.text, {
19514
19521
  agentId: lead.id,
19522
+ routingReason: "skill",
19515
19523
  source: "agentmail",
19516
19524
  taskType: "agentmail-message",
19517
19525
  agentmailInboxId: inbox_id,
@@ -20319,6 +20327,7 @@ async function handlePullRequest(event) {
20319
20327
  }
20320
20328
  const task2 = await createTaskWithSiblingAwareness(result2.text, {
20321
20329
  agentId: lead2?.id ?? "",
20330
+ routingReason: lead2 ? "skill" : undefined,
20322
20331
  source: "github",
20323
20332
  vcsProvider: "github",
20324
20333
  taskType: "github-pr",
@@ -20391,6 +20400,7 @@ async function handlePullRequest(event) {
20391
20400
  }
20392
20401
  const task2 = await createTaskWithSiblingAwareness(result2.text, {
20393
20402
  agentId: lead2?.id ?? "",
20403
+ routingReason: lead2 ? "skill" : undefined,
20394
20404
  source: "github",
20395
20405
  vcsProvider: "github",
20396
20406
  taskType: "github-pr",
@@ -20459,6 +20469,7 @@ async function handlePullRequest(event) {
20459
20469
  }
20460
20470
  const task2 = await createTaskWithSiblingAwareness(result2.text, {
20461
20471
  agentId: lead2?.id ?? "",
20472
+ routingReason: lead2 ? "skill" : undefined,
20462
20473
  source: "github",
20463
20474
  vcsProvider: "github",
20464
20475
  taskType: "github-pr",
@@ -20517,6 +20528,7 @@ async function handlePullRequest(event) {
20517
20528
  }
20518
20529
  const task = await createTaskWithSiblingAwareness(result.text, {
20519
20530
  agentId: lead?.id ?? "",
20531
+ routingReason: lead ? "skill" : undefined,
20520
20532
  source: "github",
20521
20533
  vcsProvider: "github",
20522
20534
  taskType: "github-pr",
@@ -20565,6 +20577,7 @@ async function handleIssue(event) {
20565
20577
  }
20566
20578
  const task2 = await createTaskWithSiblingAwareness(result2.text, {
20567
20579
  agentId: lead2?.id ?? "",
20580
+ routingReason: lead2 ? "skill" : undefined,
20568
20581
  source: "github",
20569
20582
  vcsProvider: "github",
20570
20583
  taskType: "github-issue",
@@ -20631,6 +20644,7 @@ async function handleIssue(event) {
20631
20644
  }
20632
20645
  const task2 = await createTaskWithSiblingAwareness(result2.text, {
20633
20646
  agentId: lead2?.id ?? "",
20647
+ routingReason: lead2 ? "skill" : undefined,
20634
20648
  source: "github",
20635
20649
  vcsProvider: "github",
20636
20650
  taskType: "github-issue",
@@ -20679,6 +20693,7 @@ async function handleIssue(event) {
20679
20693
  }
20680
20694
  const task = await createTaskWithSiblingAwareness(result.text, {
20681
20695
  agentId: lead?.id ?? "",
20696
+ routingReason: lead ? "skill" : undefined,
20682
20697
  source: "github",
20683
20698
  vcsProvider: "github",
20684
20699
  taskType: "github-issue",
@@ -20742,6 +20757,7 @@ async function handleComment(event, eventType) {
20742
20757
  }
20743
20758
  const task = await createTaskWithSiblingAwareness(result.text, {
20744
20759
  agentId: lead?.id ?? "",
20760
+ routingReason: lead ? "skill" : undefined,
20745
20761
  source: "github",
20746
20762
  vcsProvider: "github",
20747
20763
  taskType: "github-comment",
@@ -20941,6 +20957,7 @@ ${review.body}` : "";
20941
20957
  }
20942
20958
  const task = await createTaskWithSiblingAwareness(result.text, {
20943
20959
  agentId: lead?.id ?? "",
20960
+ routingReason: lead ? "skill" : undefined,
20944
20961
  source: "github",
20945
20962
  vcsProvider: "github",
20946
20963
  taskType: "github-review",
@@ -21287,6 +21304,7 @@ async function handleMergeRequest(event) {
21287
21304
  }
21288
21305
  const task = await createTaskWithSiblingAwareness(result.text, {
21289
21306
  agentId: lead?.id ?? null,
21307
+ routingReason: lead ? "skill" : undefined,
21290
21308
  source: "gitlab",
21291
21309
  vcsProvider: "gitlab",
21292
21310
  taskType: "gitlab-mr",
@@ -21369,6 +21387,7 @@ async function handleIssue2(event) {
21369
21387
  }
21370
21388
  const task = await createTaskWithSiblingAwareness(result.text, {
21371
21389
  agentId: lead?.id ?? null,
21390
+ routingReason: lead ? "skill" : undefined,
21372
21391
  source: "gitlab",
21373
21392
  vcsProvider: "gitlab",
21374
21393
  taskType: "gitlab-issue",
@@ -21451,6 +21470,7 @@ _Note: There's an active task (${existingTask.id}) for this ${entityLabel}._` :
21451
21470
  }
21452
21471
  const task = await createTaskWithSiblingAwareness(noteResult.text, {
21453
21472
  agentId: lead?.id ?? null,
21473
+ routingReason: lead ? "skill" : undefined,
21454
21474
  source: "gitlab",
21455
21475
  vcsProvider: "gitlab",
21456
21476
  taskType: "gitlab-comment",
@@ -21507,6 +21527,7 @@ async function handlePipeline(event) {
21507
21527
  }
21508
21528
  const task = await createTaskWithSiblingAwareness(pipelineResult.text, {
21509
21529
  agentId: lead?.id ?? null,
21530
+ routingReason: lead ? "skill" : undefined,
21510
21531
  source: "gitlab",
21511
21532
  vcsProvider: "gitlab",
21512
21533
  taskType: "gitlab-ci",
@@ -22235,6 +22256,7 @@ ${input.descriptionText}
22235
22256
  }
22236
22257
  const task = await createTaskWithSiblingAwareness(result.text, {
22237
22258
  agentId: lead?.id ?? "",
22259
+ routingReason: lead ? "skill" : undefined,
22238
22260
  source: "jira",
22239
22261
  taskType: "jira-issue",
22240
22262
  requestedByUserId: input.requestedByUserId,
@@ -22264,6 +22286,7 @@ ${input.descriptionText}
22264
22286
  }
22265
22287
  const task = await createTaskWithSiblingAwareness(result.text, {
22266
22288
  agentId: lead?.id ?? "",
22289
+ routingReason: lead ? "skill" : undefined,
22267
22290
  source: "jira",
22268
22291
  taskType: "jira-issue",
22269
22292
  requestedByUserId: input.requestedByUserId,
@@ -22303,7 +22326,7 @@ async function notifySlack(text) {
22303
22326
  return;
22304
22327
  }
22305
22328
  try {
22306
- const { getSlackApp: getSlackApp2 } = await import("./app-w066xfy0.js");
22329
+ const { getSlackApp: getSlackApp2 } = await import("./app-1hh67x8w.js");
22307
22330
  const app = getSlackApp2();
22308
22331
  if (!app) {
22309
22332
  console.warn("[Jira webhook keepalive] Slack not available, cannot send notification");
@@ -22374,7 +22397,7 @@ async function deleteJiraWebhook(webhookId) {
22374
22397
  console.log(`[Jira webhook keepalive] Deleted webhook id=${webhookId}`);
22375
22398
  }
22376
22399
  async function overwriteWebhookIds(next) {
22377
- const { getDbClient: getDbClient2 } = await import("./db-sfbsc8wt.js");
22400
+ const { getDbClient: getDbClient2 } = await import("./db-ggz97zbm.js");
22378
22401
  await getDbClient2().transaction(async (tx) => {
22379
22402
  const row = await tx.get("SELECT metadata FROM oauth_apps WHERE provider = 'jira'");
22380
22403
  if (!row) {
@@ -94557,6 +94580,7 @@ ${issueDescription}
94557
94580
  }
94558
94581
  const task = await createTaskWithSiblingAwareness(templateResult.text, {
94559
94582
  agentId: lead?.id ?? "",
94583
+ routingReason: lead ? "skill" : undefined,
94560
94584
  source: "linear",
94561
94585
  taskType: "linear-issue",
94562
94586
  requestedByUserId,
@@ -94750,6 +94774,7 @@ async function handleAgentSessionPrompted(event) {
94750
94774
  }
94751
94775
  const task = await createTaskWithSiblingAwareness(followupResult.text, {
94752
94776
  agentId: lead?.id ?? "",
94777
+ routingReason: lead ? "skill" : undefined,
94753
94778
  source: "linear",
94754
94779
  taskType: "linear-issue",
94755
94780
  requestedByUserId: promptedRequestedByUserId,
@@ -96199,6 +96224,9 @@ async function handleCore(req, res, myAgentId, apiKey) {
96199
96224
  return false;
96200
96225
  }
96201
96226
 
96227
+ // src/server.ts
96228
+ init_resolver();
96229
+
96202
96230
  // src/tools/accept-steer.ts
96203
96231
  init_zod();
96204
96232
  init_db();
@@ -96344,6 +96372,22 @@ var slackReadNudge = (r) => {
96344
96372
  const messages = r.data?.messages;
96345
96373
  return messages?.some((m) => m.files?.some((f) => Boolean(f.localPath))) ? SLACK_API_DISK_NUDGE : undefined;
96346
96374
  };
96375
+ function formatIdleDuration(ms) {
96376
+ const minutes = Math.round(ms / 60000);
96377
+ if (minutes < 60)
96378
+ return `${minutes}m`;
96379
+ const hours = Math.floor(minutes / 60);
96380
+ const remMinutes = minutes % 60;
96381
+ return remMinutes > 0 ? `${hours}h${remMinutes}m` : `${hours}h`;
96382
+ }
96383
+ var storeProgressBlockedWaitingNudge = (r) => {
96384
+ if (!r.ok)
96385
+ return;
96386
+ const ms = r.data?.blockedWaitingElapsedMs;
96387
+ if (typeof ms !== "number")
96388
+ return;
96389
+ return `That reads as blocked-waiting, ${formatIdleDuration(ms)} since your last update — call defer-task so a wake-up task resumes you instead of polling manually.`;
96390
+ };
96347
96391
  var workflowLongScriptTimeoutNudge = (r) => {
96348
96392
  if (!r.ok)
96349
96393
  return;
@@ -96352,6 +96396,7 @@ var workflowLongScriptTimeoutNudge = (r) => {
96352
96396
  };
96353
96397
  var NUDGES = {
96354
96398
  "defer-task": (r) => r.ok ? "Stop working on this task now; the wake-up task will carry your note." : undefined,
96399
+ "store-progress": storeProgressBlockedWaitingNudge,
96355
96400
  "script-run": scriptRunNudge,
96356
96401
  "script-upsert": scriptAuthoringNudge,
96357
96402
  "launch-script-run": scriptAuthoringNudge,
@@ -96660,10 +96705,15 @@ async function finalizeSwarmToolResult(toolName, result, requestInfo = {
96660
96705
  }
96661
96706
  return composeWireResult(r);
96662
96707
  }
96708
+ var preloadedToolsByServer = new WeakMap;
96709
+ function setPreloadedTools(server, names) {
96710
+ preloadedToolsByServer.set(server, new Set(names));
96711
+ }
96663
96712
  var createToolRegistrar = (server) => {
96664
96713
  return (name, config, cb) => {
96714
+ const toolConfig = preloadedToolsByServer.get(server)?.has(name) ? { ...config, _meta: { ...config._meta, "anthropic/alwaysLoad": true } } : config;
96665
96715
  if (config.inputSchema === undefined) {
96666
- return server.registerTool(name, config, async (meta2) => {
96716
+ return server.registerTool(name, toolConfig, async (meta2) => {
96667
96717
  const requestInfo = getRequestInfo(meta2);
96668
96718
  return withSpan("mcp.tool", async (span) => {
96669
96719
  const outcome = await cb(requestInfo, meta2);
@@ -96673,7 +96723,7 @@ var createToolRegistrar = (server) => {
96673
96723
  }, toolRequestAttributes(name, requestInfo));
96674
96724
  });
96675
96725
  }
96676
- return server.registerTool(name, config, async (args, meta2) => {
96726
+ return server.registerTool(name, toolConfig, async (args, meta2) => {
96677
96727
  const requestInfo = getRequestInfo(meta2);
96678
96728
  return withSpan(`mcp.tool ${name}`, async (span) => {
96679
96729
  const outcome = await cb(args, requestInfo, meta2);
@@ -96722,7 +96772,7 @@ function assertOwnsTask(ctx, task, verb = "task.read.own") {
96722
96772
  init_secret_scrubber();
96723
96773
  var acceptSteerInputSchema = object({
96724
96774
  steeringMessageId: uuid().describe("The steering message ID to acknowledge."),
96725
- note: string().max(500).optional().describe("Optional short note describing how the steering was incorporated.")
96775
+ note: string().optional().describe("Optional short note describing how the steering was incorporated.")
96726
96776
  });
96727
96777
  var looseSteeringMessageSchema = looseObject({
96728
96778
  id: string().optional(),
@@ -99940,6 +99990,7 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
99940
99990
  const task = await createTaskWithSiblingAwareness(taskPrompt.text, {
99941
99991
  source: "api",
99942
99992
  agentId: action.agentId ?? lead?.id,
99993
+ routingReason: action.agentId ? "human_pinned" : lead ? "skill" : undefined,
99943
99994
  key: normalizeAssetKey(`shared/app:${app.id}/action:${parsed.params.name}/`),
99944
99995
  ...actor.startsWith("user:") ? { requestedByUserId: actor.slice("user:".length) } : {}
99945
99996
  });
@@ -103156,12 +103207,17 @@ var registerDeferTaskTool = (server) => {
103156
103207
  createToolRegistrar(server)("defer-task", {
103157
103208
  title: "Defer Task",
103158
103209
  annotations: { destructiveHint: false, idempotentHint: false },
103159
- description: "Completes this task now with status `completed` and books a wake-up for you. Use when the result needs time: a build, a deploy, a reply. The task reaches its final state on this call; the lead sees your summary as its output. A one-off schedule wakes you up later with a child task that carries this task as its parent. Provide delayMs or runAt, a summary of what you did, and a note that says what is pending and what to check.",
103210
+ description: "Completes this task now with status `completed` and books a wake-up for you. Use when the result needs time: a build, a deploy, a reply. The task reaches its final state on this call; the lead sees your summary as its output unless the task has an outputSchema. For a task with an outputSchema, provide output as a JSON string matching that schema; it is stored verbatim as terminal output, while deferral details remain visible in the task log. A one-off schedule wakes you up later with a child task that carries this task as its parent. Optionally provide wakeOn to wake early when another task completes or fails; delayMs or runAt remains required as the ceiling. Provide delayMs or runAt, a summary of what you did, and a note that says what is pending and what to check.",
103160
103211
  inputSchema: object({
103161
103212
  taskId: string().describe("The ID of the task you are working on."),
103162
103213
  delayMs: number().int().positive().optional().describe("Wake up after this many milliseconds (e.g. 1800000 for 30 min)."),
103163
103214
  runAt: string().datetime().optional().describe("Wake up at this ISO datetime (e.g. '2026-03-06T15:00:00Z'). Must be future."),
103164
- summary: string().min(1).max(4000).describe("What you did so far and where things stand. This becomes the task's output; the lead and your wake-up run both read it."),
103215
+ wakeOn: object({
103216
+ event: _enum(["task.completed", "task.failed", "settled"]),
103217
+ taskId: string().min(1)
103218
+ }).strict().optional().describe("Wake early on this task event. settled covers completed or failed. Already-terminal tasks are rejected; a delayMs/runAt ceiling is still required."),
103219
+ summary: string().min(1).max(4000).describe("What you did so far and where things stand. Stored in the task log for tasks with an outputSchema; otherwise becomes the task's output."),
103220
+ output: string().optional().describe("Required when the task has an outputSchema: a JSON string matching that schema, stored verbatim as terminal output. Ignored for tasks without an outputSchema."),
103165
103221
  note: string().min(1).max(2000).describe("What is pending, and what to check on wake-up."),
103166
103222
  checks: array(string().min(1)).max(20).optional().describe("Concrete things to verify on wake-up, one per entry.")
103167
103223
  }),
@@ -103171,7 +103227,7 @@ var registerDeferTaskTool = (server) => {
103171
103227
  scheduleId: string().optional(),
103172
103228
  nextRunAt: string().optional()
103173
103229
  })
103174
- }, async ({ taskId, delayMs, runAt, summary, note, checks: checks2 }, requestInfo, _meta) => {
103230
+ }, async ({ taskId, delayMs, runAt, wakeOn, summary, output, note, checks: checks2 }, requestInfo, _meta) => {
103175
103231
  if (!requestInfo.agentId) {
103176
103232
  return toolErr('Agent ID not found. Set the "X-Agent-ID" header.');
103177
103233
  }
@@ -103205,18 +103261,29 @@ var registerDeferTaskTool = (server) => {
103205
103261
  return toolErr("runAt must be in the future.");
103206
103262
  }
103207
103263
  const nextRunAt = delayMs ? new Date(Date.now() + delayMs).toISOString() : runAt;
103264
+ const wakeDescription = wakeOn ? `on ${wakeOn.event} for task ${wakeOn.taskId}, or by ${nextRunAt}` : `at ${nextRunAt}`;
103208
103265
  const checksBlock = renderChecks(checks2);
103209
103266
  const taskTemplate = `Resume task ${taskId}: ${note}${checksBlock}`;
103210
103267
  const createdBy = await resolveTaskAuditUserId(requestInfo.sourceTaskId, requestInfo.agentId) ?? undefined;
103211
- const previewOutput = `${summary}
103212
-
103213
- Deferred until ${nextRunAt} (schedule pending). Pending: ${note}${checksBlock}`;
103214
- const outputValidationError = getTaskOutputValidationError(task.outputSchema, previewOutput);
103215
- if (outputValidationError) {
103216
- return toolErr(`Task ${taskId} has an outputSchema; its terminal output must satisfy it, but a deferral note cannot. ${outputValidationError}`);
103268
+ if (task.outputSchema) {
103269
+ if (!output) {
103270
+ return toolErr(`Task ${taskId} has an outputSchema. Call defer-task with output: a JSON string matching that schema. Summary and note are stored separately in the task log.`);
103271
+ }
103272
+ const outputValidationError = getTaskOutputValidationError(task.outputSchema, output);
103273
+ if (outputValidationError)
103274
+ return toolErr(outputValidationError);
103217
103275
  }
103218
103276
  try {
103219
103277
  const committed = await getDbClient().transaction(async () => {
103278
+ if (wakeOn) {
103279
+ if (wakeOn.taskId === taskId)
103280
+ throw new DeferAbortedError("Cannot wake on the task being deferred.");
103281
+ const watched = await getTaskById(wakeOn.taskId);
103282
+ if (!watched)
103283
+ throw new DeferAbortedError(`Watched task ${wakeOn.taskId} not found.`);
103284
+ if (isTerminalTaskStatus(watched.status))
103285
+ throw new DeferAbortedError(`Watched task ${wakeOn.taskId} is already ${watched.status}; read its result instead of deferring.`);
103286
+ }
103220
103287
  const schedule = await createScheduledTask({
103221
103288
  name: `deferred-${taskId.slice(0, 8)}-${Date.now()}-${crypto.randomUUID()}`,
103222
103289
  description: note,
@@ -103233,13 +103300,30 @@ Deferred until ${nextRunAt} (schedule pending). Pending: ${note}${checksBlock}`;
103233
103300
  parentTaskId: taskId,
103234
103301
  createdBy
103235
103302
  });
103236
- const output = `${summary}
103303
+ if (wakeOn) {
103304
+ await getDbClient().run("INSERT INTO deferred_task_waits (scheduleId, taskId, eventName, created_by, updated_by) VALUES (?, ?, ?, ?, ?)", [schedule.id, wakeOn.taskId, wakeOn.event, createdBy ?? null, createdBy ?? null]);
103305
+ getDbClient().afterCommit(() => {
103306
+ reconcileDeferredTaskWaits(wakeOn.taskId).catch((err) => {
103307
+ console.error("[defer-task] Event wake reconciliation failed:", err);
103308
+ });
103309
+ });
103310
+ }
103311
+ const deferralDetails = `${summary}
103237
103312
 
103238
103313
  Deferred until ${nextRunAt} (schedule ${schedule.id}). Pending: ${note}${checksBlock}`;
103239
- const completed = await completeTask(taskId, output);
103314
+ const terminalOutput = task.outputSchema ? output : deferralDetails;
103315
+ const completed = await completeTask(taskId, terminalOutput);
103240
103316
  if (!completed) {
103241
103317
  throw new DeferAbortedError(`Task ${taskId} reached a terminal state before this deferral committed.`);
103242
103318
  }
103319
+ if (task.outputSchema) {
103320
+ await createLogEntry({
103321
+ eventType: "task_progress",
103322
+ taskId,
103323
+ agentId: requestInfo.agentId,
103324
+ newValue: deferralDetails
103325
+ });
103326
+ }
103243
103327
  getDbClient().afterCommit(() => {
103244
103328
  ensure({
103245
103329
  id: "completed",
@@ -103260,7 +103344,7 @@ Deferred until ${nextRunAt} (schedule ${schedule.id}). Pending: ${note}${checksB
103260
103344
  if (task.agentId) {
103261
103345
  await updateAgentStatusFromCapacity(task.agentId);
103262
103346
  }
103263
- return { scheduleId: schedule.id, output, completed };
103347
+ return { scheduleId: schedule.id, output: terminalOutput, completed };
103264
103348
  });
103265
103349
  await runTaskTerminalEffects({
103266
103350
  task: committed.completed,
@@ -103268,7 +103352,7 @@ Deferred until ${nextRunAt} (schedule ${schedule.id}). Pending: ${note}${checksB
103268
103352
  output: committed.output,
103269
103353
  agentId: requestInfo.agentId
103270
103354
  });
103271
- return toolOk(`Task ${taskId} completed and deferred. Wake-up at ${nextRunAt} (schedule ${committed.scheduleId}). This task is final; the wake-up task continues the work.`, {
103355
+ return toolOk(`Task ${taskId} completed and deferred. Wake-up ${wakeDescription} (schedule ${committed.scheduleId}). This task is final; the wake-up task continues the work.`, {
103272
103356
  data: {
103273
103357
  yourAgentId: requestInfo.agentId,
103274
103358
  taskId,
@@ -105505,8 +105589,9 @@ var registerMemoryGetTool = (server) => {
105505
105589
  description: "Retrieve the full content of a specific memory by its ID. Use memory-search to find memory IDs first.",
105506
105590
  annotations: { readOnlyHint: true },
105507
105591
  inputSchema: object({
105508
- memoryId: uuid().describe("The ID of the memory to retrieve."),
105509
- intent: string().min(1).describe("Why you are retrieving this memory. Required. E.g. 'need full details of the auth fix pattern'.")
105592
+ memoryId: uuid().optional().describe("The ID of the memory to retrieve (or use id)."),
105593
+ id: uuid().optional().describe("Alias for memoryId, matching memory-search results."),
105594
+ intent: string().min(1).optional().describe("Optional reason for retrieving this memory. E.g. 'need full details of the auth fix pattern'.")
105510
105595
  }),
105511
105596
  outputSchema: swarmToolOutputSchema({
105512
105597
  yourAgentId: string().optional(),
@@ -105515,7 +105600,13 @@ var registerMemoryGetTool = (server) => {
105515
105600
  backlinks: array(MemoryBacklinkSchema).optional().describe("Other memories whose content links to this one (ACL-filtered)."),
105516
105601
  rateHint: string().optional()
105517
105602
  })
105518
- }, async ({ memoryId, intent }, requestInfo, _meta) => {
105603
+ }, async ({ memoryId: requestedMemoryId, id, intent }, requestInfo, _meta) => {
105604
+ if (requestedMemoryId && id && requestedMemoryId !== id) {
105605
+ return toolErr("memoryId and id must identify the same memory; supply only one.");
105606
+ }
105607
+ const memoryId = requestedMemoryId ?? id;
105608
+ if (!memoryId)
105609
+ return toolErr("Supply memoryId (or its alias id) from memory-search.");
105519
105610
  const store = getMemoryStore();
105520
105611
  const memoryForAuth = await store.peek(memoryId);
105521
105612
  if (!memoryForAuth) {
@@ -105573,13 +105664,20 @@ var registerMemoryRateTool = (server) => {
105573
105664
  description: "Rate a memory you used in the current task. Call this when a " + "retrieved memory was clearly useful (or actively misleading) so " + "the swarm learns to surface better memories next time.",
105574
105665
  annotations: { destructiveHint: false },
105575
105666
  inputSchema: object({
105576
- id: string().describe("Memory ID returned by memory_search."),
105667
+ id: string().min(1).optional().describe("Memory ID returned by memory-search (or use memoryId)."),
105668
+ memoryId: string().min(1).optional().describe("Alias for id, matching memory-get."),
105577
105669
  useful: boolean().describe("true = this memory helped solve the task; false = misled or wasted time."),
105578
- note: string().max(280).optional().describe("Short reason. Captured for telemetry; not surfaced to other agents."),
105670
+ note: string().optional().describe("Reason, stored up to 500 characters for telemetry; not surfaced to other agents."),
105579
105671
  referencesSource: string().min(1).max(REFERENCES_SOURCE_MAX_LENGTH).optional().describe(REFERENCES_SOURCE_DESCRIPTION)
105580
105672
  }),
105581
105673
  outputSchema: swarmToolOutputSchema()
105582
- }, async ({ id, useful, note, referencesSource }, requestInfo, _meta) => {
105674
+ }, async ({ id, memoryId, useful, note, referencesSource }, requestInfo, _meta) => {
105675
+ if (id && memoryId && id !== memoryId) {
105676
+ return toolErr("id and memoryId must identify the same memory; supply only one.");
105677
+ }
105678
+ const resolvedMemoryId = id ?? memoryId;
105679
+ if (!resolvedMemoryId)
105680
+ return toolErr("Supply id (or its alias memoryId) from memory-search.");
105583
105681
  if (!requestInfo.agentId) {
105584
105682
  return toolErr("Agent ID required. Are you registered in the swarm?");
105585
105683
  }
@@ -105597,11 +105695,11 @@ var registerMemoryRateTool = (server) => {
105597
105695
  const apiUrl = getMcpBaseUrl();
105598
105696
  const apiKey = getApiKey();
105599
105697
  const event = {
105600
- memoryId: id,
105698
+ memoryId: resolvedMemoryId,
105601
105699
  signal: useful ? 1 : -1,
105602
105700
  weight: 1,
105603
105701
  source: "explicit-self",
105604
- reasoning: note ?? "",
105702
+ reasoning: (note ?? "").slice(0, 500),
105605
105703
  taskId: requestInfo.sourceTaskId,
105606
105704
  ...cleanedReferencesSource !== undefined ? { referencesSource: cleanedReferencesSource } : {}
105607
105705
  };
@@ -105630,7 +105728,7 @@ var registerMemoryRateTool = (server) => {
105630
105728
  if (!response.ok) {
105631
105729
  return toolErr(`Memory rating failed (HTTP ${response.status}).`);
105632
105730
  }
105633
- return toolOk(`Memory ${id} rated as ${useful ? "useful" : "not useful"}.`);
105731
+ return toolOk(`Memory ${resolvedMemoryId} rated as ${useful ? "useful" : "not useful"}.`);
105634
105732
  } catch (err) {
105635
105733
  return toolErr(`Memory rating failed: ${err.message}`);
105636
105734
  }
@@ -105777,7 +105875,7 @@ var registerMemorySearchTool = (server) => {
105777
105875
  annotations: { readOnlyHint: false },
105778
105876
  inputSchema: object({
105779
105877
  query: string().min(1).describe("Natural language search query."),
105780
- intent: string().min(1).describe("Why you are searching for this memory. Required. E.g. 'looking for auth pattern to fix login bug'."),
105878
+ intent: string().min(1).optional().describe("Optional reason for searching for this memory. E.g. 'looking for auth pattern to fix login bug'."),
105781
105879
  scope: _enum(["all", "agent", "swarm"]).default("all").describe("Search scope: 'all' (own + swarm), 'agent' (own only), 'swarm' (shared only)."),
105782
105880
  limit: number().int().min(1).max(50).default(10).describe("Max results to return."),
105783
105881
  source: AgentMemorySourceSchema.optional().describe("Filter by memory source type.")
@@ -106116,9 +106214,9 @@ var registerMemoryStoreTool = (server) => {
106116
106214
  annotations: { destructiveHint: false },
106117
106215
  inputSchema: object({
106118
106216
  content: string().min(1).describe("The memory body. Markdown is fine. State the fact, the context it applies to, and the evidence."),
106119
- name: string().min(1).max(200).describe("Short title, one line, used in search results and the UI."),
106217
+ name: string().min(1).max(200).optional().describe("Short title used in search results and the UI. Defaults to the first non-empty content line (up to 200 characters)."),
106120
106218
  scope: AgentMemoryScopeSchema.default("agent").describe("'agent' (default): only you can recall it. 'swarm': every agent can recall it."),
106121
- tags: array(string()).optional().describe("Free-form tags, for example a repo name or a topic."),
106219
+ tags: union([array(string()), string()]).optional().describe("Free-form tags as an array or a comma-separated string, for example a repo name or a topic."),
106122
106220
  taskId: uuid().optional().describe("The task this learning came from, when there is one."),
106123
106221
  intent: string().min(1).optional().describe("Why this is worth remembering. Kept in the audit trail.")
106124
106222
  }),
@@ -106128,7 +106226,9 @@ var registerMemoryStoreTool = (server) => {
106128
106226
  chunks: number().int().optional(),
106129
106227
  queued: boolean().optional()
106130
106228
  })
106131
- }, async ({ content, name, scope, tags, taskId, intent }, requestInfo, _meta) => {
106229
+ }, async ({ content, name: requestedName, scope, tags, taskId, intent }, requestInfo, _meta) => {
106230
+ const name = requestedName ?? content.split(/\r?\n/).find((line) => line.trim())?.trim().slice(0, 200) ?? "Untitled memory";
106231
+ const normalizedTags = typeof tags === "string" ? tags.split(",").map((tag) => tag.trim()).filter(Boolean) : tags;
106132
106232
  if (!requestInfo.agentId) {
106133
106233
  return toolErr("Agent ID required. Are you registered in the swarm?");
106134
106234
  }
@@ -106140,7 +106240,7 @@ var registerMemoryStoreTool = (server) => {
106140
106240
  scope,
106141
106241
  source: "manual",
106142
106242
  sourceTaskId: taskId ?? null,
106143
- tags,
106243
+ tags: normalizedTags,
106144
106244
  intent
106145
106245
  });
106146
106246
  return toolOk(`Memory "${name}" stored as ${result.chunks} chunk(s) in ${scope} scope. Embedding runs in the background.`, {
@@ -116170,6 +116270,8 @@ function checkOutputSchemaShape(outputSchema, ctx) {
116170
116270
  }
116171
116271
  var sendTaskInputSchema = object({
116172
116272
  agentId: string().optional().describe("The agent to assign/offer task to. Omit to create unassigned task for pool."),
116273
+ routingReason: RoutingReasonSchema.optional().describe("Why this agent was selected. Required when agentId is supplied; omit for pool routing."),
116274
+ routingNote: string().max(200).optional().describe("Optional routing context (maximum 200 characters)."),
116173
116275
  task: string().min(1).describe("The task description to send."),
116174
116276
  key: AssetKeySchema.optional().describe("Logical namespace key. Child tasks inherit their parent namespace when provided."),
116175
116277
  offerMode: boolean().default(false).describe("If true, offer the task instead of direct assign (agent must accept/reject)."),
@@ -116190,7 +116292,7 @@ var sendTaskInputSchema = object({
116190
116292
  slackThreadTs: string().optional().describe("Slack thread timestamp. Required with slackChannelId for thread-level updates."),
116191
116293
  slackUserId: string().optional().describe("Slack user ID of the original requester."),
116192
116294
  overrideSlackContext: boolean().default(false).describe("Explicitly route this task's Slack updates to a different channel/thread than its parent/contextKey. Requires slackChannelId AND slackThreadTs. Use only for deliberate cross-channel dispatch (e.g. escalation to another human's DM); logged for audit. Without this flag, a slackChannelId/slackThreadTs that disagrees with the parent task or inherited contextKey is rejected — omit the three Slack fields to inherit them from the parent as a unit instead."),
116193
- requestedByUserId: string().uuid().optional().describe("ID of the human user who originally requested this task chain. When omitted, inherited from the caller's current task so the attribution flows through multi-hop delegation automatically."),
116295
+ requestedByUserId: string().regex(/^[a-f0-9]{32}$/, "Expected a registry user ID (32 lowercase hexadecimal characters).").optional().describe("Registered requester ID (32 lowercase hexadecimal characters). When omitted, inherited from the caller's current task so the attribution flows through multi-hop delegation automatically."),
116194
116296
  followUpConfig: FollowUpConfigSchema.optional().describe("Control the lead follow-up created when this task finishes. When to use `followUpConfig`: set `disabled: true` when you'll wait for this task to complete inline and no follow-up is needed; set `onCompleted` / `onFailed` with specific instructions when you need to follow up effectively on a particular outcome of a long-running flow; for normal one-shot tasks, leave it unset because defaults are fine. It is most valuable for long-running / complex flows."),
116195
116297
  outputSchema: record(string(), unknown()).optional().describe("Optional JSON Schema the assignee's final output must satisfy. store-progress rejects a completion that does not match. Supported keywords: type, required, properties, enum, const, items.")
116196
116298
  }).superRefine((data, ctx) => {
@@ -116203,6 +116305,13 @@ var sendTaskInputSchema = object({
116203
116305
  path: [hasChannel ? "slackThreadTs" : "slackChannelId"]
116204
116306
  });
116205
116307
  }
116308
+ if (data.agentId !== undefined && data.routingReason === undefined) {
116309
+ ctx.addIssue({
116310
+ code: ZodIssueCode.custom,
116311
+ message: "routingReason is required when agentId is supplied.",
116312
+ path: ["routingReason"]
116313
+ });
116314
+ }
116206
116315
  checkOutputSchemaShape(data.outputSchema, ctx);
116207
116316
  });
116208
116317
  var sendTaskOutputSchema = swarmToolOutputSchema({
@@ -116228,6 +116337,8 @@ async function transferTrackerSyncToResumeChild(args2) {
116228
116337
  }
116229
116338
  async function sendTaskHandler(ctx, {
116230
116339
  agentId,
116340
+ routingReason,
116341
+ routingNote,
116231
116342
  task,
116232
116343
  key,
116233
116344
  offerMode,
@@ -116252,6 +116363,9 @@ async function sendTaskHandler(ctx, {
116252
116363
  followUpConfig,
116253
116364
  outputSchema
116254
116365
  }) {
116366
+ if (agentId !== undefined && routingReason === undefined) {
116367
+ return toolErr("routingReason is required when agentId is supplied.");
116368
+ }
116255
116369
  if (ctx.kind === "owner" && !ctx.agentId) {
116256
116370
  return toolErr('Agent ID not found. The MCP client should define the "X-Agent-ID" header.', {
116257
116371
  data: { yourAgentId: ctx.agentId }
@@ -116260,6 +116374,11 @@ async function sendTaskHandler(ctx, {
116260
116374
  const creatorAgentId = ctx.kind === "owner" ? ctx.agentId : undefined;
116261
116375
  const sourceTaskId = ctx.kind === "owner" ? ctx.sourceTaskId : undefined;
116262
116376
  const requestedByUserId = ctx.kind === "user" ? ctx.userId : inputRequestedByUserId ?? undefined;
116377
+ if (ctx.kind === "owner" && requestedByUserId && !await getUserById(requestedByUserId)) {
116378
+ return toolErr("requestedByUserId must identify an existing registered user.", {
116379
+ data: { yourAgentId: creatorAgentId }
116380
+ });
116381
+ }
116263
116382
  if (ctx.kind === "owner" && agentId === ctx.agentId) {
116264
116383
  return toolErr("Cannot send a task to yourself, are you drunk?", {
116265
116384
  data: { yourAgentId: ctx.agentId }
@@ -116304,6 +116423,8 @@ async function sendTaskHandler(ctx, {
116304
116423
  effectiveAgentId = effectiveParentTask.agentId;
116305
116424
  }
116306
116425
  }
116426
+ const effectiveRoutingReason = agentId !== undefined ? routingReason : effectiveAgentId ? "continuity" : undefined;
116427
+ const effectiveRoutingNote = effectiveRoutingReason ? routingNote : undefined;
116307
116428
  const evaluateDedupGuards = async () => {
116308
116429
  const existingTrackerWork = await findExistingLinearTrackerContextWork(effectiveParentTask?.contextKey);
116309
116430
  if (existingTrackerWork) {
@@ -116377,6 +116498,8 @@ async function sendTaskHandler(ctx, {
116377
116498
  overrideSlackContext,
116378
116499
  followUpConfig,
116379
116500
  outputSchema,
116501
+ routingReason: effectiveRoutingReason,
116502
+ routingNote: effectiveRoutingNote,
116380
116503
  routingAffinity: effectiveLeadOnly || requiredCapabilities?.length ? { leadOnly: effectiveLeadOnly, capabilities: requiredCapabilities ?? [] } : undefined
116381
116504
  });
116382
116505
  await transferTrackerSyncToResumeChild({
@@ -116433,6 +116556,8 @@ async function sendTaskHandler(ctx, {
116433
116556
  overrideSlackContext,
116434
116557
  followUpConfig,
116435
116558
  outputSchema,
116559
+ routingReason: effectiveRoutingReason,
116560
+ routingNote: effectiveRoutingNote,
116436
116561
  routingAffinity: effectiveLeadOnly || requiredCapabilities?.length ? { leadOnly: effectiveLeadOnly, capabilities: requiredCapabilities ?? [] } : undefined
116437
116562
  });
116438
116563
  await transferTrackerSyncToResumeChild({
@@ -116468,6 +116593,8 @@ async function sendTaskHandler(ctx, {
116468
116593
  overrideSlackContext,
116469
116594
  followUpConfig,
116470
116595
  outputSchema,
116596
+ routingReason: effectiveRoutingReason,
116597
+ routingNote: effectiveRoutingNote,
116471
116598
  routingAffinity: effectiveLeadOnly || requiredCapabilities?.length ? { leadOnly: effectiveLeadOnly, capabilities: requiredCapabilities ?? [] } : undefined
116472
116599
  });
116473
116600
  await transferTrackerSyncToResumeChild({
@@ -117007,6 +117134,7 @@ To approve: update the skill's scope to "swarm" using skill-update.
117007
117134
  To reject: close this task with a rejection reason.`;
117008
117135
  const task = await createTaskExtended(taskDescription, {
117009
117136
  agentId: leadAgent.id,
117137
+ routingReason: "skill",
117010
117138
  creatorAgentId: requestInfo.agentId,
117011
117139
  source: "mcp",
117012
117140
  taskType: "skill-approval",
@@ -118761,6 +118889,8 @@ init_zod();
118761
118889
  init_db();
118762
118890
  init_types();
118763
118891
  init_secret_scrubber();
118892
+ var BLOCKED_WAITING_PATTERN = /\b(waiting (for|on)|blocked (on|until|by)|still waiting|awaiting)\b/i;
118893
+ var BLOCKED_WAITING_MIN_ELAPSED_MS = 3 * 60 * 1000;
118764
118894
  var storeProgressOutputSchema = swarmToolOutputSchema({
118765
118895
  task: looseObject({
118766
118896
  id: string(),
@@ -118769,7 +118899,8 @@ var storeProgressOutputSchema = swarmToolOutputSchema({
118769
118899
  }).optional(),
118770
118900
  yourAgentId: string().optional(),
118771
118901
  wasNoOp: boolean().optional().describe("True when the call was a no-op because the task was already in a terminal state (completed/failed/cancelled). First-call-wins."),
118772
- wasForcedOverwrite: boolean().optional().describe("True when force: true replaced output and/or failureReason on an already-terminal task without replaying completion side effects.")
118902
+ wasForcedOverwrite: boolean().optional().describe("True when force: true replaced output and/or failureReason on an already-terminal task without replaying completion side effects."),
118903
+ blockedWaitingElapsedMs: number().optional().describe("Present only when this progress text reads as blocked-waiting: milliseconds since the task's prior update. Drives the store-progress nudge toward defer-task.")
118773
118904
  });
118774
118905
  var registerStoreProgressTool = (server) => {
118775
118906
  createToolRegistrar(server)("store-progress", {
@@ -118777,9 +118908,9 @@ var registerStoreProgressTool = (server) => {
118777
118908
  description: "Stores the progress of a specific task. Can also mark task as completed or failed, which will set the agent back to idle.",
118778
118909
  annotations: { idempotentHint: true },
118779
118910
  inputSchema: object({
118780
- taskId: uuid().describe("The ID of the task to update progress for."),
118911
+ taskId: uuid().optional().describe("Full task UUID. Defaults to the caller-owned task in X-Source-Task-Id; required outside task context."),
118781
118912
  progress: string().optional().describe("The progress update to store."),
118782
- status: _enum(["completed", "failed"]).optional().describe("Set to 'completed' or 'failed' to finish the task."),
118913
+ status: _enum(["completed", "failed", "in_progress", "pending"]).optional().describe("Set to 'completed' or 'failed' to finish the task. 'in_progress' and 'pending' store progress only and do not change task status."),
118783
118914
  output: string().optional().describe("The task result (used when completing). For Slack-originated tasks, this is published verbatim in the thread's outcome card: provide a concrete summary scaled to what was asked, including only the outcome and any links or IDs the human needs—not process narration, a transcript, or a restatement of the brief."),
118784
118915
  failureReason: string().optional().describe("The reason for failure (used when failing)."),
118785
118916
  attachments: array(AttachmentInputSchema).max(20).optional().describe("Pointer-based artifacts produced by this step — agent-fs path, URL, shared-fs path, or swarm Page. No inline file data; upload to agent-fs first and attach by path. Agent-fs pointers are verified before task state changes, using the explicit org/drive pair or the registering agent's configured defaults. May be sent on any call (progress or completion) and accumulates across calls; duplicates are de-duped by sha256 (when present) or by (kind, pointer, name)."),
@@ -118787,10 +118918,30 @@ var registerStoreProgressTool = (server) => {
118787
118918
  force: boolean().optional().describe("On an already-terminal task, overwrite explicitly provided output and/or failureReason text while preserving status and finishedAt and without replaying events, memory writes, follow-up creation, business-use ensure, or capacity updates. Differing terminal text is otherwise discarded and reported as a failure.")
118788
118919
  }),
118789
118920
  outputSchema: storeProgressOutputSchema
118790
- }, async ({ taskId, progress, status, output, failureReason, attachments, persistMemory, force }, requestInfo, _meta) => {
118921
+ }, async ({
118922
+ taskId: requestedTaskId,
118923
+ progress,
118924
+ status: requestedStatus,
118925
+ output,
118926
+ failureReason,
118927
+ attachments,
118928
+ persistMemory,
118929
+ force
118930
+ }, requestInfo, _meta) => {
118791
118931
  if (!requestInfo.agentId) {
118792
118932
  return toolErr('Agent ID not found. The MCP client should define the "X-Agent-ID" header.');
118793
118933
  }
118934
+ const taskId = requestedTaskId ?? requestInfo.sourceTaskId;
118935
+ if (!taskId || !uuid().safeParse(taskId).success) {
118936
+ return toolErr("Supply taskId as the full task UUID; no valid task context is available.");
118937
+ }
118938
+ if (!requestedTaskId) {
118939
+ const contextTask = await getTaskById(taskId);
118940
+ if (!contextTask || contextTask.agentId !== requestInfo.agentId) {
118941
+ return toolErr("Omitted taskId requires a source task assigned to the calling agent.");
118942
+ }
118943
+ }
118944
+ const status = requestedStatus === "completed" || requestedStatus === "failed" ? requestedStatus : undefined;
118794
118945
  const agentFsScopes = new Map;
118795
118946
  const agentFsAttachments = attachments?.filter((a) => a.kind === "agent-fs") ?? [];
118796
118947
  if (agentFsAttachments.length > 0) {
@@ -118862,6 +119013,17 @@ var registerStoreProgressTool = (server) => {
118862
119013
  }
118863
119014
  let updatedTask = existingTask;
118864
119015
  const isTerminal2 = isTerminalTaskStatus(existingTask.status);
119016
+ const goingTerminal = status !== undefined && isTerminalTaskStatus(status);
119017
+ let blockedWaitingElapsedMs;
119018
+ if (progress && !isTerminal2 && !goingTerminal && BLOCKED_WAITING_PATTERN.test(progress)) {
119019
+ const referenceIso = existingTask.lastUpdatedAt ?? existingTask.createdAt;
119020
+ if (referenceIso) {
119021
+ const elapsed = Date.now() - new Date(referenceIso).getTime();
119022
+ if (elapsed >= BLOCKED_WAITING_MIN_ELAPSED_MS) {
119023
+ blockedWaitingElapsedMs = elapsed;
119024
+ }
119025
+ }
119026
+ }
118865
119027
  if (attachments && attachments.length > 0) {
118866
119028
  for (const a of attachments) {
118867
119029
  let orgId = a.kind === "agent-fs" ? a.orgId : undefined;
@@ -118974,7 +119136,8 @@ var registerStoreProgressTool = (server) => {
118974
119136
  return {
118975
119137
  success: true,
118976
119138
  message: status ? `Task "${taskId}" marked as ${status}.` : `Progress stored for task "${taskId}".`,
118977
- task: updatedTask
119139
+ task: updatedTask,
119140
+ blockedWaitingElapsedMs
118978
119141
  };
118979
119142
  });
118980
119143
  const shouldRunTerminalSideEffects = (status === "completed" || status === "failed") && result.success && result.task && !(("wasNoOp" in result) && result.wasNoOp) && !(("wasForcedOverwrite" in result) && result.wasForcedOverwrite);
@@ -118998,7 +119161,8 @@ var registerStoreProgressTool = (server) => {
118998
119161
  yourAgentId: requestInfo.agentId,
118999
119162
  ...task ? { task } : {},
119000
119163
  ..."wasNoOp" in result && result.wasNoOp ? { wasNoOp: true } : {},
119001
- ..."wasForcedOverwrite" in result && result.wasForcedOverwrite ? { wasForcedOverwrite: true } : {}
119164
+ ..."wasForcedOverwrite" in result && result.wasForcedOverwrite ? { wasForcedOverwrite: true } : {},
119165
+ ..."blockedWaitingElapsedMs" in result && typeof result.blockedWaitingElapsedMs === "number" ? { blockedWaitingElapsedMs: result.blockedWaitingElapsedMs } : {}
119002
119166
  };
119003
119167
  return success ? toolOk(message, { data }) : toolErr(message, { data });
119004
119168
  });
@@ -119517,6 +119681,7 @@ async function emitBudgetRefusalSideEffects(ctx, inserted) {
119517
119681
  }, { agentId: ctx.agentId });
119518
119682
  const followUp = await createTaskExtended(resolved.text, {
119519
119683
  agentId: leadAgent.id,
119684
+ routingReason: "skill",
119520
119685
  source: "system",
119521
119686
  taskType: "follow-up",
119522
119687
  parentTaskId: ctx.task.id,
@@ -121364,10 +121529,13 @@ async function createServer(opts = {}) {
121364
121529
  version: package_default.version,
121365
121530
  description: package_default.description
121366
121531
  }, {
121532
+ ...opts.preloadedTools?.length ? { instructions: resolveTemplate("system.agent.tool_preload", {}).text } : {},
121367
121533
  capabilities: {
121368
121534
  logging: {}
121369
121535
  }
121370
121536
  });
121537
+ if (opts.preloadedTools?.length)
121538
+ setPreloadedTools(server, opts.preloadedTools);
121371
121539
  if (opts.scriptsOnly ?? isScriptsOnlyMcp()) {
121372
121540
  registerScriptSearchTool(server);
121373
121541
  registerScriptRunTool(server);