@desplega.ai/agent-swarm 1.136.0 → 1.138.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 (210) hide show
  1. package/README.md +12 -3
  2. package/dist/acp-adapter-6nttxe2q.js +4787 -0
  3. package/dist/{actions-agcbc8nd.js → actions-z9dzgh3f.js} +7 -8
  4. package/dist/{app-g2s78xya.js → app-wb6bc7tt.js} +4 -5
  5. package/dist/{assistant-yd3jkb9d.js → assistant-08pd6pgy.js} +9 -10
  6. package/dist/{boot-reembed-6spqw4q0.js → boot-reembed-hstr4e2c.js} +4 -4
  7. package/dist/{boot-reembed-b22s9w5x.js → boot-reembed-y7p7qjbf.js} +5 -5
  8. package/dist/{boot-scrub-logs-6h3cqkc0.js → boot-scrub-logs-azbnxwhn.js} +3 -3
  9. package/dist/{claude-adapter-ng5y8zd7.js → claude-adapter-rwaq6eda.js} +10 -9
  10. package/dist/{claude-managed-adapter-5zr3n86v.js → claude-managed-adapter-vtseey1x.js} +3 -3
  11. package/dist/{cli-qckgdqmr.js → cli-005yr57a.js} +2 -2
  12. package/dist/{cli-54ht104h.js → cli-0cka8dnm.js} +3 -3
  13. package/dist/{cli-gpdtxzar.js → cli-23cpnqk9.js} +1 -1
  14. package/dist/{cli-qhfkxrpg.js → cli-2ypjdmqg.js} +223 -474
  15. package/dist/{cli-bnq8h7ea.js → cli-3719ggyf.js} +17 -10
  16. package/dist/cli-390sgxn5.js +257 -0
  17. package/dist/{cli-z6e8eqrm.js → cli-47esr8ht.js} +2 -2
  18. package/dist/{cli-jjhnma34.js → cli-4jaj24py.js} +248 -101
  19. package/dist/{cli-6gwgzdgw.js → cli-69377c2a.js} +5 -5
  20. package/dist/{cli-ads0hfw2.js → cli-6v4d8r8c.js} +205 -75
  21. package/dist/{cli-mgef08pc.js → cli-8rtyss6g.js} +1 -1
  22. package/dist/{cli-35jknh9e.js → cli-9w7vsmbm.js} +5 -5
  23. package/dist/{cli-m3z53bed.js → cli-b4zdc3x6.js} +1 -1
  24. package/dist/{cli-fpjmcbhz.js → cli-ba87cw29.js} +4 -4
  25. package/dist/{cli-4gzv54ss.js → cli-bzk75kdc.js} +43 -11
  26. package/dist/{cli-d5ygfv18.js → cli-cywkhzqs.js} +35 -11
  27. package/dist/{cli-0crn5kaz.js → cli-d62cd9qs.js} +16 -4
  28. package/dist/{cli-5bnz1t86.js → cli-f9skf1v7.js} +51 -7
  29. package/dist/{cli-06ghj6pe.js → cli-fytpjraz.js} +4 -4
  30. package/dist/{cli-j7qp8gtf.js → cli-h7c5dam1.js} +16 -11
  31. package/dist/{cli-4r4jkqep.js → cli-kkn46gfr.js} +9 -3
  32. package/dist/{cli-tmn19cdz.js → cli-kq9htgbr.js} +415 -62
  33. package/dist/{cli-8v57p983.js → cli-pkmqqxp8.js} +45 -69
  34. package/dist/{cli-84vrhesc.js → cli-qf34ej1d.js} +1 -1
  35. package/dist/{cli-v3qda694.js → cli-rnyttbh0.js} +0 -5
  36. package/dist/cli-rx5cxzn2.js +7 -0
  37. package/dist/{cli-cw70hymf.js → cli-s25avqg9.js} +2 -0
  38. package/dist/{cli-tee8w7tq.js → cli-s6t1qv67.js} +15 -10
  39. package/dist/{cli-68vayryq.js → cli-tb4csb08.js} +2 -2
  40. package/dist/{cli-y16cesaq.js → cli-vy48y9bx.js} +2 -2
  41. package/dist/{cli-3y553gws.js → cli-y294regh.js} +1 -1
  42. package/dist/{cli-spf767vc.js → cli-y43043ws.js} +1 -1
  43. package/dist/{cli-hz5hp6wn.js → cli-yh2eybyt.js} +1 -1
  44. package/dist/{cli-edwrx42s.js → cli-zmyxt25p.js} +5 -5
  45. package/dist/cli.js +40 -18
  46. package/dist/{codex-adapter-kw11ps3j.js → codex-adapter-yzep6mvb.js} +7 -6
  47. package/dist/{codex-session-runner-sffb69v7.js → codex-session-runner-25e8tn72.js} +7 -6
  48. package/dist/{commands-0xxp4tz8.js → commands-0vv72d6a.js} +3 -3
  49. package/dist/{db-0npp39zd.js → db-x61ncfa1.js} +19 -3
  50. package/dist/{google-generative-ai-6xxdj4t3.js → google-generative-ai-zyhy3dab.js} +1 -1
  51. package/dist/{google-vertex-zma18wb0.js → google-vertex-t25h65yd.js} +1 -1
  52. package/dist/{handlers-5p7a1jx6.js → handlers-fwdcaahf.js} +9 -10
  53. package/dist/{hook-jjpxn4se.js → hook-mpwfgynm.js} +6 -5
  54. package/dist/{hook-hpefr0a8.js → hook-x18504ja.js} +8 -7
  55. package/dist/{http-wfp33653.js → http-83m6qdds.js} +590 -192
  56. package/dist/{index-pe58mf1r.js → index-1nsdwvn5.js} +2 -1
  57. package/dist/{index-17h657rg.js → index-38f98ck3.js} +9 -9
  58. package/dist/{index-m2p7ctyh.js → index-7kxvtd38.js} +24 -12
  59. package/dist/{index-racb4wfq.js → index-a4naswjn.js} +23 -10
  60. package/dist/{index-p13cfsc2.js → index-agykc6k2.js} +2 -1
  61. package/dist/{index-zh66wm65.js → index-dawtzfhw.js} +22 -9
  62. package/dist/{keepalive-wxjd633a.js → keepalive-y0m8g5wn.js} +5 -5
  63. package/dist/{lead-359ec2z0.js → lead-ka18ef6a.js} +36 -36
  64. package/dist/{maintenance-rr03qjtb.js → maintenance-x585p56c.js} +5 -5
  65. package/dist/{oauth-refresh-sweep-jwj22yb8.js → oauth-refresh-sweep-kdm9vj7a.js} +4 -4
  66. package/dist/{onboard-asnhchcv.js → onboard-5v229nvt.js} +664 -248
  67. package/dist/{opencode-adapter-sx38y7f7.js → opencode-adapter-46nnmnvv.js} +3 -3
  68. package/dist/{otel-impl-54cra6mw.js → otel-impl-k47aj4sd.js} +73 -4
  69. package/dist/{pi-mono-adapter-29g7axgj.js → pi-mono-adapter-wawfj09v.js} +42 -40
  70. package/dist/{pricing-refresh-mkyy7c2y.js → pricing-refresh-ky2gjp05.js} +5 -5
  71. package/dist/{rbac-roles-kb3afm95.js → rbac-roles-0j0f7s8r.js} +4 -4
  72. package/dist/{rbac-roles-ak56tr75.js → rbac-roles-az4wc15e.js} +3 -3
  73. package/dist/{render-v2-434asg49.js → render-v2-seyxq61z.js} +4 -5
  74. package/dist/{seed-pricing-nbmd7ah8.js → seed-pricing-fev611hx.js} +4 -4
  75. package/dist/{setup-wh4qmjs4.js → setup-hy404zwh.js} +2 -2
  76. package/dist/{worker-j1d27tjv.js → worker-g1j5hn16.js} +36 -36
  77. package/openapi.json +197 -27
  78. package/package.json +9 -3
  79. package/src/be/db-client.ts +58 -5
  80. package/src/be/db-retention.ts +550 -121
  81. package/src/be/db.ts +367 -55
  82. package/src/be/memory/raters/retrieval.ts +40 -0
  83. package/src/be/migrations/140_approval_request_cancelled_status.sql +64 -0
  84. package/src/be/pricing-normalize.ts +3 -0
  85. package/src/be/script-connections.ts +26 -6
  86. package/src/be/seed-pricing.ts +18 -8
  87. package/src/be/swarm-config-guard.ts +33 -0
  88. package/src/cli.tsx +20 -1
  89. package/src/commands/onboard/compose-generator.ts +63 -7
  90. package/src/commands/onboard/env-generator.ts +32 -4
  91. package/src/commands/onboard/manifest.ts +4 -1
  92. package/src/commands/onboard/non-interactive.ts +159 -0
  93. package/src/commands/onboard/steps/generate.tsx +1 -34
  94. package/src/commands/onboard/steps/harness-credentials.tsx +181 -1
  95. package/src/commands/onboard/steps/harness.tsx +20 -6
  96. package/src/commands/onboard/steps/review.tsx +3 -2
  97. package/src/commands/onboard/types.ts +48 -1
  98. package/src/commands/onboard.tsx +18 -13
  99. package/src/commands/provider-credentials.ts +17 -3
  100. package/src/commands/runner.ts +1 -0
  101. package/src/heartbeat/heartbeat.ts +47 -7
  102. package/src/http/approval-requests.ts +53 -8
  103. package/src/http/index.ts +9 -1
  104. package/src/http/mcp-servers.ts +2 -0
  105. package/src/http/memory.ts +27 -1
  106. package/src/http/oauth-callback.ts +33 -0
  107. package/src/http/repos.ts +6 -0
  108. package/src/http/script-connections.ts +77 -0
  109. package/src/http/session-data.ts +5 -1
  110. package/src/http/stats.ts +21 -30
  111. package/src/http/tasks.ts +10 -0
  112. package/src/oauth/presets.ts +29 -0
  113. package/src/otel-impl.ts +96 -1
  114. package/src/otel.ts +34 -0
  115. package/src/prompts/memories.ts +2 -2
  116. package/src/providers/acp-adapter.ts +325 -0
  117. package/src/providers/acp-swarm-events.ts +113 -0
  118. package/src/providers/acp-targets.ts +103 -0
  119. package/src/providers/claude-managed-models.ts +17 -1
  120. package/src/providers/codex-adapter.ts +3 -3
  121. package/src/providers/codex-oauth/auth-json-fs.ts +2 -2
  122. package/src/providers/codex-oauth/home.ts +13 -0
  123. package/src/providers/index.ts +5 -1
  124. package/src/providers/types.ts +1 -1
  125. package/src/server-user.ts +1 -0
  126. package/src/slack/app.ts +5 -1
  127. package/src/tasks/worker-follow-up.ts +78 -7
  128. package/src/telemetry.ts +151 -0
  129. package/src/tests/acp-adapter.test.ts +192 -0
  130. package/src/tests/acp-swarm-events.test.ts +132 -0
  131. package/src/tests/agents-list-model-display.test.ts +20 -0
  132. package/src/tests/approval-cancellation-migration.test.ts +134 -0
  133. package/src/tests/approval-requests.test.ts +456 -2
  134. package/src/tests/apps-spike2.test.ts +4 -1
  135. package/src/tests/apps-sync-engine.test.ts +22 -18
  136. package/src/tests/claude-managed-adapter.test.ts +12 -0
  137. package/src/tests/codex-oauth-auth-json-fs.test.ts +19 -0
  138. package/src/tests/connection-embedded-auth.test.ts +4 -1
  139. package/src/tests/context-window.test.ts +2 -0
  140. package/src/tests/credential-check.test.ts +6 -0
  141. package/src/tests/db-client-busy-retry.test.ts +18 -0
  142. package/src/tests/db-client.test.ts +23 -0
  143. package/src/tests/db-retention-telemetry.test.ts +569 -0
  144. package/src/tests/db-retention.test.ts +456 -117
  145. package/src/tests/heartbeat.test.ts +140 -0
  146. package/src/tests/memory-http-recall-gating.test.ts +120 -13
  147. package/src/tests/memory-store.test.ts +41 -0
  148. package/src/tests/migration-046-budgets.test.ts +27 -5
  149. package/src/tests/oauth-presets.test.ts +17 -5
  150. package/src/tests/onboard-compose.test.ts +99 -0
  151. package/src/tests/onboard-env.test.ts +43 -0
  152. package/src/tests/onboard-manifest.test.ts +17 -1
  153. package/src/tests/onboard-non-interactive.test.ts +89 -0
  154. package/src/tests/pool-affinity.test.ts +100 -0
  155. package/src/tests/promote-draft-task-route.test.ts +32 -1
  156. package/src/tests/sandbox-spawn-test-helpers.ts +3 -0
  157. package/src/tests/sandboxed-process.test.ts +2 -2
  158. package/src/tests/schedule-target-type.test.ts +6 -3
  159. package/src/tests/script-connections-http.test.ts +4 -3
  160. package/src/tests/script-connections.test.ts +6 -1
  161. package/src/tests/script-workflows-runtime-e2e.test.ts +36 -28
  162. package/src/tests/scripts-external-api.test.ts +8 -5
  163. package/src/tests/scripts-http.test.ts +6 -3
  164. package/src/tests/scripts-mcp-e2e.test.ts +65 -60
  165. package/src/tests/scripts-retention.test.ts +6 -3
  166. package/src/tests/scripts-runtime-identity.test.ts +4 -2
  167. package/src/tests/scripts-runtime.test.ts +18 -16
  168. package/src/tests/session-costs-model-key-normalize.test.ts +2 -0
  169. package/src/tests/slack-read-boundaries.test.ts +3 -1
  170. package/src/tests/task-lifecycle-telemetry.test.ts +1 -0
  171. package/src/tests/task-tools-ctx.test.ts +88 -1
  172. package/src/tests/telemetry-init.test.ts +61 -0
  173. package/src/tests/tool-annotations.test.ts +4 -1
  174. package/src/tests/vendored-openapi.test.ts +15 -2
  175. package/src/tests/workflow-e2e.test.ts +4 -1
  176. package/src/tests/workflow-engine-v2.test.ts +5 -2
  177. package/src/tests/workflow-executors.test.ts +24 -19
  178. package/src/tests/workflow-http-v2.test.ts +17 -2
  179. package/src/tests/workflow-llm.test.ts +57 -0
  180. package/src/tests/workflow-retry-v2.test.ts +142 -1
  181. package/src/tests/workflow-swarm-script.test.ts +20 -17
  182. package/src/tools/get-task-details.ts +1 -0
  183. package/src/tools/mcp-servers/mcp-server-create.ts +7 -1
  184. package/src/tools/memory-search.ts +27 -2
  185. package/src/tools/send-task.ts +28 -10
  186. package/src/tools/task-action.ts +13 -5
  187. package/src/types.ts +31 -2
  188. package/src/utils/context-window.ts +2 -0
  189. package/src/workflows/approval-notifications.ts +72 -0
  190. package/src/workflows/checkpoint.ts +16 -9
  191. package/src/workflows/completed-step-routing.ts +31 -0
  192. package/src/workflows/engine.ts +59 -43
  193. package/src/workflows/executors/human-in-the-loop.ts +38 -4
  194. package/src/workflows/executors/raw-llm.ts +8 -6
  195. package/src/workflows/executors/validate.ts +6 -5
  196. package/src/workflows/executors/workflow-llm.ts +35 -0
  197. package/src/workflows/resume.ts +90 -13
  198. package/src/workflows/retry-poller.ts +8 -1
  199. package/vendored-openapi/README.md +4 -2
  200. package/vendored-openapi/manifest.json +33 -0
  201. package/vendored-openapi/microsoft-graph.json +781 -0
  202. package/dist/cli-5tnr64pm.js +0 -29
  203. package/dist/{anthropic-messages-pm7pp23c.js → anthropic-messages-tvgm75yc.js} +3 -3
  204. package/dist/{azure-openai-responses-cwesc845.js → azure-openai-responses-hed7waek.js} +4 -4
  205. package/dist/{cli-s9gpxh9q.js → cli-5kmzp1wx.js} +0 -0
  206. package/dist/{cli-s73zwwqn.js → cli-xjx3fbtn.js} +4 -4
  207. package/dist/{openai-codex-responses-xxca1qr1.js → openai-codex-responses-gv3n8rg0.js} +3 -3
  208. package/dist/{openai-completions-yzftqrft.js → openai-completions-dkrj9433.js} +8 -8
  209. package/dist/{openai-responses-e4dcwm9g.js → openai-responses-spk6t7kh.js} +11 -11
  210. package/dist/{openrouter-images-asqqnbvh.js → openrouter-images-71hthwh9.js} +3 -3
@@ -9,21 +9,23 @@ import {
9
9
  getNextResumeGeneration,
10
10
  getPinCandidateAgent,
11
11
  getResumeGeneration,
12
- repointTrackerSyncBySwarmId
13
- } from "./cli-5bnz1t86.js";
12
+ repointTrackerSyncBySwarmId,
13
+ resolveLeadOnlyRecoveryAssignment
14
+ } from "./cli-f9skf1v7.js";
14
15
  import {
15
16
  isMultiRuntimeEnabled
16
17
  } from "./cli-qh4sqfws.js";
17
18
  import {
18
19
  getExecutorRegistry,
19
20
  recoverIncompleteRuns
20
- } from "./cli-jjhnma34.js";
21
+ } from "./cli-4jaj24py.js";
21
22
  import {
22
23
  MAX_EMPTY_POLLS,
23
24
  assignUnassignedTaskPending,
24
25
  backfillSupersedeTaskResumeTaskId,
25
26
  buildRoutingAffinityFromAgent,
26
27
  cleanupStaleSessions,
28
+ createLogEntry,
27
29
  createTaskExtended,
28
30
  deleteActiveSession,
29
31
  failPendingResumeIfUnclaimed,
@@ -59,7 +61,7 @@ import {
59
61
  releaseStaleReviewingTasks,
60
62
  supersedeTask,
61
63
  updateAgentStatus
62
- } from "./cli-tmn19cdz.js";
64
+ } from "./cli-kq9htgbr.js";
63
65
  import {
64
66
  init_registry,
65
67
  init_resolver,
@@ -470,6 +472,11 @@ async function runRebootSweep() {
470
472
  continue;
471
473
  }
472
474
  let retryTaskId = null;
475
+ if (task.routingAffinityInvalid) {
476
+ console.error(`[Heartbeat] Reboot retry suppressed for ${task.id.slice(0, 8)}: invalid routing affinity`);
477
+ rebootAffectedTasks.push({ original: failed, retryTaskId: null });
478
+ continue;
479
+ }
473
480
  const existingRetry = await getDbClient().get(`SELECT id FROM agent_tasks
474
481
  WHERE parentTaskId = ?
475
482
  AND status NOT IN ('completed', 'failed', 'cancelled')
@@ -477,19 +484,31 @@ async function runRebootSweep() {
477
484
  if (!existingRetry) {
478
485
  try {
479
486
  let preferredAgentId;
480
- const candidate = await getPinCandidateAgent(task.agentId);
481
- if (candidate) {
482
- const activeCount = await getActiveTaskCount(candidate.id);
483
- const hasCap = activeCount < (candidate.maxTasks ?? 1);
487
+ let sourceCandidate = await getPinCandidateAgent(task.agentId);
488
+ if (sourceCandidate) {
489
+ const activeCount = await getActiveTaskCount(sourceCandidate.id);
490
+ const maxTasks = sourceCandidate.maxTasks ?? 1;
491
+ const hasCap = activeCount < maxTasks;
484
492
  if (hasCap) {
485
- preferredAgentId = candidate.id;
493
+ preferredAgentId = sourceCandidate.id;
486
494
  } else {
487
- console.warn(`[Heartbeat] Reboot retry for task ${task.id.slice(0, 8)} NOT pinned: agent ${candidate.id.slice(0, 8)} at capacity (${activeCount}/${candidate.maxTasks ?? 1}); falling back to affinity-gated pool`);
495
+ sourceCandidate = null;
496
+ console.warn(`[Heartbeat] Reboot retry for task ${task.id.slice(0, 8)} NOT pinned: agent ${task.agentId.slice(0, 8)} at capacity (${activeCount}/${maxTasks}); falling back to affinity-gated pool`);
488
497
  }
489
498
  }
499
+ const leadOnly = task.routingAffinity?.leadOnly === true;
500
+ const authorization = await resolveLeadOnlyRecoveryAssignment(task, sourceCandidate);
501
+ if (leadOnly)
502
+ preferredAgentId = authorization.agentId;
490
503
  const tags = ["reboot-retry", "auto-generated"];
491
504
  if (preferredAgentId !== undefined)
492
505
  tags.push(REBOOT_RETRY_PIN_TAG);
506
+ const sourceAffinity = await buildRoutingAffinityFromAgent(task.agentId) ?? undefined;
507
+ const routingAffinity = leadOnly ? {
508
+ ...sourceAffinity ?? task.routingAffinity,
509
+ capabilities: task.routingAffinity?.capabilities ?? sourceAffinity?.capabilities ?? [],
510
+ leadOnly: true
511
+ } : sourceAffinity;
493
512
  const retryTask = await createTaskExtended(task.task, {
494
513
  parentTaskId: task.id,
495
514
  agentId: preferredAgentId,
@@ -497,8 +516,21 @@ async function runRebootSweep() {
497
516
  priority: task.priority,
498
517
  source: task.source,
499
518
  taskType: task.taskType ?? undefined,
500
- routingAffinity: await buildRoutingAffinityFromAgent(task.agentId) ?? undefined
519
+ routingAffinity
501
520
  });
521
+ if (authorization.decision) {
522
+ await createLogEntry({
523
+ eventType: "task_recovery_authorization",
524
+ taskId: retryTask.id,
525
+ agentId: preferredAgentId,
526
+ metadata: {
527
+ leadOnly: true,
528
+ parentTaskId: task.id,
529
+ sourceAgentId: task.agentId,
530
+ decision: authorization.decision
531
+ }
532
+ });
533
+ }
502
534
  retryTaskId = retryTask.id;
503
535
  console.log(`[Heartbeat] Reboot retry created: ${retryTaskId} (parent: ${task.id})`);
504
536
  } catch (err) {
@@ -5,12 +5,10 @@ import {
5
5
  require_jws,
6
6
  require_p_retry
7
7
  } from "./cli-g2p9bd1z.js";
8
- import {
9
- taskAttachmentDisplayUrl
10
- } from "./cli-5tnr64pm.js";
11
8
  import {
12
9
  bindSlackMessageTimestamp,
13
10
  deleteSlackMessageRecord,
11
+ emitBuiltInIntegrationConnectedOnce,
14
12
  ensureSlackRenderV2Activation,
15
13
  getAgentById,
16
14
  getChildTasks,
@@ -37,8 +35,9 @@ import {
37
35
  setSlackMessageTracking,
38
36
  slackContextKey,
39
37
  updateSlackMessageRecord
40
- } from "./cli-tmn19cdz.js";
38
+ } from "./cli-kq9htgbr.js";
41
39
  import {
40
+ buildAgentFsLiveUrl,
42
41
  getAppUrl,
43
42
  init_constants
44
43
  } from "./cli-a1rrkrb4.js";
@@ -53969,6 +53968,28 @@ init_db();
53969
53968
  init_context_key();
53970
53969
  init_env_flag();
53971
53970
 
53971
+ // src/utils/task-attachment-links.ts
53972
+ init_constants();
53973
+ function taskAttachmentDisplayUrl(attachment) {
53974
+ if (attachment.kind === "url")
53975
+ return attachment.url ?? "";
53976
+ if (attachment.kind === "page") {
53977
+ return attachment.pageId ? `${getAppUrl()}/pages/${attachment.pageId}` : "page:";
53978
+ }
53979
+ if (attachment.providerId === "agent-fs" || attachment.kind === "agent-fs") {
53980
+ const liveUrl = buildAgentFsLiveUrl({
53981
+ path: attachment.path,
53982
+ orgId: attachment.orgId,
53983
+ driveId: attachment.driveId
53984
+ });
53985
+ return liveUrl ?? `agent-fs:${attachment.path ?? ""}`;
53986
+ }
53987
+ if (attachment.providerId === "local-fs" || attachment.kind === "shared-fs") {
53988
+ return `${getAppUrl()}/api/fs/tasks/${attachment.taskId}/files/${attachment.id}/raw`;
53989
+ }
53990
+ return attachment.path ?? attachment.providerKey ?? "";
53991
+ }
53992
+
53972
53993
  // src/slack/ack.ts
53973
53994
  init_db();
53974
53995
  init_types();
@@ -55177,19 +55198,21 @@ async function initSlackApp() {
55177
55198
  console.error(`[Slack] SOCKET MODE BLOCKED: ${socketModeBlockReason}. Set ${SLACK_DEV_SOCKET_MODE_OPT_IN}=true to opt in explicitly.`);
55178
55199
  return null;
55179
55200
  }
55201
+ const slackApiUrl = process.env.SLACK_API_URL;
55180
55202
  app = new import_bolt.App({
55181
55203
  token: botToken,
55182
55204
  appToken,
55183
55205
  socketMode: true,
55184
- logLevel: import_bolt.LogLevel.DEBUG
55206
+ logLevel: import_bolt.LogLevel.DEBUG,
55207
+ ...slackApiUrl ? { clientOptions: { slackApiUrl } } : {}
55185
55208
  });
55186
- const { registerMessageHandler } = await import("./handlers-5p7a1jx6.js");
55187
- const { registerCommandHandler } = await import("./commands-0xxp4tz8.js");
55188
- const { registerActionHandlers } = await import("./actions-agcbc8nd.js");
55209
+ const { registerMessageHandler } = await import("./handlers-fwdcaahf.js");
55210
+ const { registerCommandHandler } = await import("./commands-0vv72d6a.js");
55211
+ const { registerActionHandlers } = await import("./actions-z9dzgh3f.js");
55189
55212
  registerMessageHandler(app);
55190
55213
  registerCommandHandler(app);
55191
55214
  registerActionHandlers(app);
55192
- const { createAssistant } = await import("./assistant-yd3jkb9d.js");
55215
+ const { createAssistant } = await import("./assistant-08pd6pgy.js");
55193
55216
  app.assistant(createAssistant());
55194
55217
  return app;
55195
55218
  }
@@ -55198,11 +55221,12 @@ async function startSlackApp() {
55198
55221
  await initSlackApp();
55199
55222
  }
55200
55223
  if (app) {
55201
- const { isSlackRenderV2Enabled: isSlackRenderV2Enabled2 } = await import("./render-v2-434asg49.js");
55224
+ const { isSlackRenderV2Enabled: isSlackRenderV2Enabled2 } = await import("./render-v2-seyxq61z.js");
55202
55225
  if (isSlackRenderV2Enabled2())
55203
55226
  await ensureSlackRenderV2Activation();
55204
55227
  await app.start();
55205
55228
  console.log("[Slack] Bot connected via Socket Mode");
55229
+ await emitBuiltInIntegrationConnectedOnce("slack");
55206
55230
  await startTaskWatcher();
55207
55231
  }
55208
55232
  }
@@ -56041,4 +56065,4 @@ function _resetSlackRenderV2ForTests() {
56041
56065
  cachedTeamId = undefined;
56042
56066
  }
56043
56067
 
56044
- export { require_dist7 as require_dist, ackSlackMessage, getTaskLink, markdownToSlack, buildCancelledBlocks, buildBufferFlushBlocks, buildTreeBlocks, getAgentDisplayName, getAgentEmoji, isSlackRenderV2Enabled, callSlackWithRetry, formatV2Duration, renderThreadTree, ensureSlackThreadTree, streamOutcomeCard, processSlackRenderV2, _resetSlackRenderV2ForTests, registerTreeMessage, getSlackApp, initSlackApp, startSlackApp, stopSlackApp };
56068
+ export { require_dist7 as require_dist, ackSlackMessage, taskAttachmentDisplayUrl, getTaskLink, markdownToSlack, buildCancelledBlocks, buildBufferFlushBlocks, buildTreeBlocks, getAgentDisplayName, getAgentEmoji, isSlackRenderV2Enabled, callSlackWithRetry, formatV2Duration, renderThreadTree, ensureSlackThreadTree, streamOutcomeCard, processSlackRenderV2, _resetSlackRenderV2ForTests, registerTreeMessage, getSlackApp, initSlackApp, startSlackApp, stopSlackApp };
@@ -4,6 +4,9 @@ import {
4
4
  import {
5
5
  readPkgVersion
6
6
  } from "./cli-f64gdfxc.js";
7
+ import {
8
+ Anthropic
9
+ } from "./cli-jepmgn7r.js";
7
10
  import {
8
11
  checkToolLoop
9
12
  } from "./cli-hp1n6zq3.js";
@@ -12,10 +15,7 @@ import {
12
15
  clampContextPercent,
13
16
  computeContextUsedUnified,
14
17
  getContextWindowSize
15
- } from "./cli-cw70hymf.js";
16
- import {
17
- Anthropic
18
- } from "./cli-jepmgn7r.js";
18
+ } from "./cli-s25avqg9.js";
19
19
  import {
20
20
  init_secret_scrubber,
21
21
  scrubSecrets
@@ -26,6 +26,18 @@ init_secret_scrubber();
26
26
 
27
27
  // src/providers/claude-managed-models.ts
28
28
  var CLAUDE_MANAGED_MODEL_PRICING = {
29
+ "claude-fable-5-1": {
30
+ inputPerMillion: 10,
31
+ outputPerMillion: 50,
32
+ cacheReadPerMillion: 0.25,
33
+ cacheWritePerMillion: 12.5
34
+ },
35
+ "claude-mythos-5-1": {
36
+ inputPerMillion: 10,
37
+ outputPerMillion: 50,
38
+ cacheReadPerMillion: 0.25,
39
+ cacheWritePerMillion: 12.5
40
+ },
29
41
  "claude-opus-5": {
30
42
  inputPerMillion: 5,
31
43
  outputPerMillion: 25,
@@ -3,9 +3,10 @@ import {
3
3
  } from "./cli-qh4sqfws.js";
4
4
  import {
5
5
  taskAttachmentDisplayUrl
6
- } from "./cli-5tnr64pm.js";
6
+ } from "./cli-cywkhzqs.js";
7
7
  import {
8
8
  buildRoutingAffinityFromAgent,
9
+ createLogEntry,
9
10
  createTaskExtended,
10
11
  getActiveTaskCount,
11
12
  getAgentById,
@@ -19,11 +20,12 @@ import {
19
20
  init_date_utils,
20
21
  init_db,
21
22
  init_templates,
23
+ isAgentEligibleForTask,
22
24
  normalizeDateRequired,
23
25
  updateAgentMaxTasks,
24
26
  updateAgentStatus,
25
27
  upsertSwarmConfig
26
- } from "./cli-tmn19cdz.js";
28
+ } from "./cli-kq9htgbr.js";
27
29
  import {
28
30
  init_resolver,
29
31
  resolveTemplate
@@ -379,6 +381,18 @@ async function getPinCandidateAgent(agentId) {
379
381
  return null;
380
382
  return candidate;
381
383
  }
384
+ async function resolveLeadOnlyRecoveryAssignment(task, sourceCandidate) {
385
+ if (!task.routingAffinity?.leadOnly)
386
+ return {};
387
+ if (sourceCandidate?.isLead && isAgentEligibleForTask(sourceCandidate, task)) {
388
+ return { agentId: sourceCandidate.id, decision: "source_lead_pin" };
389
+ }
390
+ const lead = await getLeadAgent();
391
+ if (lead && lead.status !== "offline" && isAgentEligibleForTask(lead, task)) {
392
+ return { agentId: lead.id, decision: "rerouted_to_lead" };
393
+ }
394
+ return { decision: "escalated_unassigned" };
395
+ }
382
396
  function getResumeGeneration(task) {
383
397
  const tag = task.tags.find((value) => value.startsWith(RESUME_GENERATION_TAG_PREFIX));
384
398
  if (!tag)
@@ -478,6 +492,8 @@ async function createResumeFollowUp(args) {
478
492
  return { kind: "workflow-skip", stepId: parent.workflowRunStepId };
479
493
  }
480
494
  let preferredAgentId;
495
+ let authorizationDecision;
496
+ const leadOnly = parent.routingAffinity?.leadOnly === true;
481
497
  if (parent.agentId) {
482
498
  const candidate = await getPinCandidateAgent(parent.agentId);
483
499
  if (candidate) {
@@ -489,13 +505,21 @@ async function createResumeFollowUp(args) {
489
505
  const isGracefulShutdown = args.reason === "graceful_shutdown";
490
506
  const isGracefulPin = isGracefulShutdown && isGracefulResumePinEnabled();
491
507
  const isFreshPinnedReason = !isGracefulShutdown && fresh;
492
- if (hasCap && (isCrashRecovery || isGracefulPin || isFreshPinnedReason)) {
508
+ if (hasCap && (isCrashRecovery || isGracefulPin || isFreshPinnedReason) && (!leadOnly || candidate.isLead)) {
493
509
  preferredAgentId = candidate.id;
510
+ if (leadOnly)
511
+ authorizationDecision = "source_lead_pin";
494
512
  } else if ((isCrashRecovery || isGracefulPin) && !hasCap) {
495
513
  console.warn(`[Heartbeat] ${args.reason} resume for task ${parent.id.slice(0, 8)} NOT pinned: agent ${candidate.id.slice(0, 8)} at capacity (${activeCount}/${candidate.maxTasks ?? 1}); falling back to unassigned pool`);
496
514
  }
497
515
  }
498
516
  }
517
+ if (leadOnly) {
518
+ const source = preferredAgentId ? await getAgentById(preferredAgentId) : null;
519
+ const resolution = await resolveLeadOnlyRecoveryAssignment(parent, source);
520
+ preferredAgentId = resolution.agentId;
521
+ authorizationDecision = resolution.decision;
522
+ }
499
523
  const parentDesc = parent.task.slice(0, 200);
500
524
  const followUpDescription = [
501
525
  "Resume interrupted task.",
@@ -515,13 +539,18 @@ async function createResumeFollowUp(args) {
515
539
  `reason:${args.reason}`,
516
540
  `${RESUME_GENERATION_TAG_PREFIX}${getNextResumeGeneration(parent)}`
517
541
  ];
518
- if (args.reason === "crash_recovery" && preferredAgentId !== undefined) {
542
+ if (args.reason === "crash_recovery" && preferredAgentId === parent.agentId) {
519
543
  tags.push(CRASH_RECOVERY_PIN_TAG);
520
544
  }
521
- if (args.reason === "graceful_shutdown" && preferredAgentId !== undefined) {
545
+ if (args.reason === "graceful_shutdown" && preferredAgentId === parent.agentId) {
522
546
  tags.push(GRACEFUL_SHUTDOWN_PIN_TAG);
523
547
  }
524
- const routingAffinity = parent.agentId ? await buildRoutingAffinityFromAgent(parent.agentId) ?? undefined : undefined;
548
+ const sourceAffinity = parent.agentId ? await buildRoutingAffinityFromAgent(parent.agentId) ?? undefined : undefined;
549
+ const routingAffinity = leadOnly ? {
550
+ ...sourceAffinity ?? parent.routingAffinity,
551
+ capabilities: parent.routingAffinity?.capabilities ?? [],
552
+ leadOnly: true
553
+ } : sourceAffinity;
525
554
  const created = await createTaskExtended(followUpDescription, {
526
555
  agentId: preferredAgentId,
527
556
  creatorAgentId: parent.creatorAgentId,
@@ -532,6 +561,21 @@ async function createResumeFollowUp(args) {
532
561
  parentTaskId: parent.id,
533
562
  routingAffinity
534
563
  });
564
+ if (authorizationDecision) {
565
+ try {
566
+ await createLogEntry({
567
+ eventType: "task_recovery_authorization",
568
+ taskId: created.id,
569
+ agentId: preferredAgentId,
570
+ metadata: {
571
+ leadOnly: true,
572
+ parentTaskId: parent.id,
573
+ sourceAgentId: parent.agentId,
574
+ decision: authorizationDecision
575
+ }
576
+ });
577
+ } catch {}
578
+ }
535
579
  const repointed = await repointTrackerSyncBySwarmId(parent.id, created.id);
536
580
  if (repointed > 0) {
537
581
  console.log(`[ResumeFollowUp] Repointed ${repointed} tracker_sync row(s) from ${parent.id.slice(0, 8)} → ${created.id.slice(0, 8)}`);
@@ -604,4 +648,4 @@ async function createPoolStarvationDecisionTask(args) {
604
648
  return { kind: "created", task: created };
605
649
  }
606
650
 
607
- export { AGENT_MAX_TASKS_CONFIG_KEY, reconcileAgentMaxTasksPolicy, resetAgentMaxTasksMirror, upsertSwarmConfigWithPolicyMirror, runtimeStaleThresholdMinutes, upsertRuntimeInstance, getRuntimeInstanceById, touchRuntimeInstance, markRuntimeInstanceOffline, countActiveRuntimeInstancesForAgent, listRuntimeInstancesForAgent, setRuntimeCredentialReady, reconcileAgentStatusFromRuntimes, agentsWithLiveRuntime, expireStaleRuntimeInstances, getTrackerSync, getTrackerSyncByExternalId, createTrackerSyncIfAbsent, updateTrackerSyncSwarmId, repointTrackerSyncBySwarmId, createTrackerSync, updateTrackerSync, deleteTrackerSync, hasTrackerDelivery, markTrackerDelivery, getAllTrackerSyncs, createTrackerAgentMapping, REBOOT_RETRY_PIN_TAG, getPinCandidateAgent, getResumeGeneration, getNextResumeGeneration, createWorkerTaskFollowUp, createResumeFollowUp, createRerouteDecisionTask, createPoolStarvationDecisionTask };
651
+ export { AGENT_MAX_TASKS_CONFIG_KEY, reconcileAgentMaxTasksPolicy, resetAgentMaxTasksMirror, upsertSwarmConfigWithPolicyMirror, runtimeStaleThresholdMinutes, upsertRuntimeInstance, getRuntimeInstanceById, touchRuntimeInstance, markRuntimeInstanceOffline, countActiveRuntimeInstancesForAgent, listRuntimeInstancesForAgent, setRuntimeCredentialReady, reconcileAgentStatusFromRuntimes, agentsWithLiveRuntime, expireStaleRuntimeInstances, getTrackerSync, getTrackerSyncByExternalId, createTrackerSyncIfAbsent, updateTrackerSyncSwarmId, repointTrackerSyncBySwarmId, createTrackerSync, updateTrackerSync, deleteTrackerSync, hasTrackerDelivery, markTrackerDelivery, getAllTrackerSyncs, createTrackerAgentMapping, REBOOT_RETRY_PIN_TAG, getPinCandidateAgent, resolveLeadOnlyRecoveryAssignment, getResumeGeneration, getNextResumeGeneration, createWorkerTaskFollowUp, createResumeFollowUp, createRerouteDecisionTask, createPoolStarvationDecisionTask };
@@ -7,9 +7,6 @@ import {
7
7
  import {
8
8
  readPkgVersion
9
9
  } from "./cli-f64gdfxc.js";
10
- import {
11
- fetchInstalledMcpServers
12
- } from "./cli-tng3131n.js";
13
10
  import {
14
11
  CTX_MODE_NUDGE_EVERY
15
12
  } from "./cli-zm7njwzd.js";
@@ -17,7 +14,10 @@ import {
17
14
  CONTEXT_FORMULA,
18
15
  clampContextPercent,
19
16
  getContextWindowSize
20
- } from "./cli-cw70hymf.js";
17
+ } from "./cli-s25avqg9.js";
18
+ import {
19
+ fetchInstalledMcpServers
20
+ } from "./cli-tng3131n.js";
21
21
  import {
22
22
  applyReasoningEffort
23
23
  } from "./cli-8whqavk2.js";
@@ -13,7 +13,7 @@ import {
13
13
  } from "./cli-a3pkfpqs.js";
14
14
  import {
15
15
  summarizeSession
16
- } from "./cli-qhfkxrpg.js";
16
+ } from "./cli-390sgxn5.js";
17
17
  import {
18
18
  CTX_MODE_NUDGE_EVERY
19
19
  } from "./cli-zm7njwzd.js";
@@ -21,23 +21,23 @@ import {
21
21
  CONTEXT_FORMULA,
22
22
  clampContextPercent,
23
23
  computeContextUsedUnified
24
- } from "./cli-cw70hymf.js";
24
+ } from "./cli-s25avqg9.js";
25
25
  import {
26
26
  buildRatingsFromLlm,
27
27
  fetchRetrievalsForTask,
28
28
  postRatings
29
29
  } from "./cli-8p37s71j.js";
30
- import {
31
- CodexOAuthRefreshError,
32
- credentialsToAuthJson,
33
- getValidCodexOAuth
34
- } from "./cli-e7d20cty.js";
35
30
  import {
36
31
  applyReasoningEffort
37
32
  } from "./cli-8whqavk2.js";
38
33
  import {
39
34
  swarmRuntimeInstanceId
40
35
  } from "./cli-qh4sqfws.js";
36
+ import {
37
+ CodexOAuthRefreshError,
38
+ credentialsToAuthJson,
39
+ getValidCodexOAuth
40
+ } from "./cli-e7d20cty.js";
41
41
  import {
42
42
  getApiKey
43
43
  } from "./cli-f14fvzag.js";
@@ -51,7 +51,6 @@ import {
51
51
 
52
52
  // src/providers/codex-adapter.ts
53
53
  import { existsSync as nodeExistsSync } from "node:fs";
54
- import os2 from "node:os";
55
54
  import { join as join2 } from "node:path";
56
55
 
57
56
  // node_modules/@openai/codex-sdk/dist/index.js
@@ -253673,6 +253672,12 @@ function computeCodexCostUsd(model, inputTokens, cachedInputTokens, outputTokens
253673
253672
  return inputCost + cachedCost + outputCost;
253674
253673
  }
253675
253674
 
253675
+ // src/providers/codex-oauth/home.ts
253676
+ import os2 from "node:os";
253677
+ function codexUserHome() {
253678
+ return process.env.HOME || os2.homedir();
253679
+ }
253680
+
253676
253681
  // src/providers/codex-swarm-events.ts
253677
253682
  function createCodexSwarmEventHandler(opts) {
253678
253683
  return createSwarmEventHandler({
@@ -253713,7 +253718,7 @@ function checkCodexCredentials(env, opts = {}) {
253713
253718
  }
253714
253719
  async function resolveCodexAuthMode(config, emit, deps = {}) {
253715
253720
  const fsModule = await import("node:fs/promises");
253716
- const homedir = deps.homedir ?? os2.homedir.bind(os2);
253721
+ const homedir = deps.homedir ?? codexUserHome;
253717
253722
  const fs2 = deps.fs ?? {
253718
253723
  readFile: (path3, encoding) => fsModule.readFile(path3, encoding),
253719
253724
  mkdir: (path3, opts) => fsModule.mkdir(path3, opts),
@@ -253925,7 +253930,7 @@ class CodexSession {
253925
253930
  this.agentsMdHandle = agentsMdHandle;
253926
253931
  this.resolvedModel = resolvedModel;
253927
253932
  this.contextWindow = getCodexContextWindow(resolvedModel);
253928
- this.skillsDir = skillsDir ?? process.env.CODEX_SKILLS_DIR ?? join2(os2.homedir(), ".codex", "skills");
253933
+ this.skillsDir = skillsDir ?? process.env.CODEX_SKILLS_DIR ?? join2(codexUserHome(), ".codex", "skills");
253929
253934
  this.summarizeDeps = summarizeDeps;
253930
253935
  this.logFileHandle = Bun.file(config.logFile).writer();
253931
253936
  const reasoningApplication = applyReasoningEffort("codex", resolvedModel, config.reasoningEffort);
@@ -254713,4 +254718,4 @@ class CodexAdapter {
254713
254718
  }
254714
254719
  }
254715
254720
 
254716
- export { checkCodexCredentials, resolveCodexAuthMode, buildCodexConfig, CodexSession, createInProcessCodexSession, resolveCodexRunnerArgv, CodexAdapter };
254721
+ export { codexUserHome, checkCodexCredentials, resolveCodexAuthMode, buildCodexConfig, CodexSession, createInProcessCodexSession, resolveCodexRunnerArgv, CodexAdapter };
@@ -7,7 +7,7 @@ var package_default;
7
7
  var init_package = __esm(() => {
8
8
  package_default = {
9
9
  name: "@desplega.ai/agent-swarm",
10
- version: "1.136.0",
10
+ version: "1.138.0",
11
11
  description: "agent-swarm.dev — an open-source operating system for AI work: a lead agent breaks goals into tasks, routes them to specialized workers such as Claude Code or Codex, runs each worker in an isolated container, and preserves shared memory, tools, schedules, and review gates so delegated work compounds across sessions.",
12
12
  keywords: [
13
13
  "agent-swarm.dev",
@@ -92,6 +92,9 @@ var init_package = __esm(() => {
92
92
  "mono:lint": "turbo run lint",
93
93
  "mono:dev": "turbo run dev",
94
94
  "test:root": "bash scripts/run-bun-tests.sh",
95
+ e2e: "bun scripts/e2e/run.ts",
96
+ "e2e:codex-oauth-blob": "bun scripts/e2e/codex-oauth-blob.ts",
97
+ "e2e:tsc": "bun tsc --noEmit -p scripts/e2e/tsconfig.json",
95
98
  prepack: "bun run build:cli",
96
99
  "tsc:check": "bun tsc --noEmit",
97
100
  "check:db-boundary": "bash scripts/check-db-boundary.sh",
@@ -108,6 +111,7 @@ var init_package = __esm(() => {
108
111
  "prepare-release": "bun scripts/prepare-release.ts",
109
112
  "refresh:vendored-openapi": "bun scripts/refresh-vendored-openapi.ts",
110
113
  "sync-chart-version": "bun scripts/sync-chart-version.ts",
114
+ "bump:agent-fs": "bun scripts/bump-agent-fs.ts",
111
115
  "check-chart-version": "bun scripts/sync-chart-version.ts --check-if-package-version-changed",
112
116
  cli: "bun src/cli.tsx",
113
117
  hook: "bun src/hooks/hook.ts",
@@ -156,6 +160,7 @@ var init_package = __esm(() => {
156
160
  },
157
161
  devDependencies: {
158
162
  "@biomejs/biome": "^2.3.10",
163
+ "@desplega.ai/slack-mock": "^0.1.0",
159
164
  "@faker-js/faker": "^10.4.0",
160
165
  "@opencode-ai/plugin": "1.17.4",
161
166
  "@types/bun": "latest",
@@ -172,6 +177,7 @@ var init_package = __esm(() => {
172
177
  bun: ">=1.3.12"
173
178
  },
174
179
  dependencies: {
180
+ "@agentclientprotocol/sdk": "1.4.0",
175
181
  "@ai-sdk/openai": "^3.0.41",
176
182
  "@anthropic-ai/sdk": "^0.93.0",
177
183
  "@asteasolutions/zod-to-openapi": "^8.0.0",
@@ -184,8 +190,8 @@ var init_package = __esm(() => {
184
190
  "@inkjs/ui": "^2.0.0",
185
191
  "@linear/sdk": "^77.0.0",
186
192
  "@modelcontextprotocol/sdk": "^1.25.1",
187
- "@openai/codex-sdk": "^0.151.0",
188
- "@opencode-ai/sdk": "^1.18.25",
193
+ "@openai/codex-sdk": "^0.152.1",
194
+ "@opencode-ai/sdk": "^1.18.26",
189
195
  "@openfort/openfort-node": "^0.9.1",
190
196
  "@opentelemetry/api": "^1.9.1",
191
197
  "@opentelemetry/exporter-metrics-otlp-http": "^0.218.0",