@desplega.ai/agent-swarm 1.102.0 → 1.104.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 (174) hide show
  1. package/README.md +2 -0
  2. package/dist/{actions-j9399ktm.js → actions-2expzt47.js} +6 -6
  3. package/dist/{app-tnq1pz27.js → app-dr8hwx7z.js} +3 -3
  4. package/dist/{assistant-c7y92gkw.js → assistant-9rhgsw7v.js} +9 -10
  5. package/dist/{boot-reembed-b97r699t.js → boot-reembed-3q1aywnz.js} +5 -4
  6. package/dist/{boot-reembed-k7e6fc1p.js → boot-reembed-9kt97g1z.js} +4 -3
  7. package/dist/{boot-scrub-logs-14kbc61y.js → boot-scrub-logs-vskq108e.js} +2 -2
  8. package/dist/{claude-managed-adapter-g07dbz3b.js → claude-managed-adapter-z29hjgzz.js} +3 -3
  9. package/dist/{cli-d0t4854c.js → cli-0jw6j755.js} +220 -478
  10. package/dist/{cli-vgck9mqq.js → cli-23zk7xqy.js} +171 -49
  11. package/dist/{cli-g5px3d7x.js → cli-2957pqpj.js} +24 -1
  12. package/dist/{cli-zmf7refz.js → cli-2g9jf9ek.js} +1 -1
  13. package/dist/{cli-mhj07xbq.js → cli-2hap19dv.js} +3 -3
  14. package/dist/{cli-wjyyv518.js → cli-3j01d33e.js} +9 -14
  15. package/dist/{cli-zk4gn40w.js → cli-54h5daha.js} +41 -31
  16. package/dist/{cli-2aaa9mqr.js → cli-5pf0b84v.js} +2 -2
  17. package/dist/{cli-stqqf5kh.js → cli-7v4y3hyd.js} +1 -1
  18. package/dist/{cli-7xdq3jg3.js → cli-92fqyjcv.js} +1 -1
  19. package/dist/{cli-g861fwjp.js → cli-d4z1csms.js} +30 -5
  20. package/dist/{cli-r68m8arr.js → cli-e7bwjntj.js} +1 -1
  21. package/dist/{cli-q6jzg6wj.js → cli-etvgz5x8.js} +5 -7
  22. package/dist/{cli-9qascwj7.js → cli-gj2n2ec1.js} +1 -1
  23. package/dist/{cli-axtg1zaa.js → cli-khe4x17a.js} +1 -1
  24. package/dist/{cli-zctkpdmd.js → cli-nzc0h54v.js} +121 -2
  25. package/dist/{cli-k81y1cjb.js → cli-p4cj4vhc.js} +351 -24
  26. package/dist/{cli-fjx4x7nn.js → cli-q5tshxd6.js} +1 -1
  27. package/dist/{http-eq6wxve6.js → cli-qvzgncd8.js} +85356 -77793
  28. package/dist/{cli-k1ghyj8b.js → cli-s42f54ja.js} +1 -1
  29. package/dist/{cli-dgab5x2h.js → cli-t9v14cnd.js} +23 -4
  30. package/dist/{cli-qbc6mncp.js → cli-v1syqkcb.js} +900 -352
  31. package/dist/{cli-xde8vhhp.js → cli-w1nfskkg.js} +2 -2
  32. package/dist/{cli-ap4md0gc.js → cli-y9p3e94h.js} +30 -5
  33. package/dist/{cli-hc4rd6sv.js → cli-yjt8a36k.js} +3 -3
  34. package/dist/{cli-s8jw5bmg.js → cli-yp2krx5r.js} +2 -2
  35. package/dist/{cli-5bqa41fd.js → cli-yvektv79.js} +1 -1
  36. package/dist/{cli-sygq3fhn.js → cli-zaxksbgj.js} +5 -5
  37. package/dist/{cli-t2jk33ta.js → cli-zghef0em.js} +18 -6
  38. package/dist/cli.js +11 -11
  39. package/dist/{codex-adapter-wf119mnw.js → codex-adapter-w0xharsg.js} +3 -3
  40. package/dist/{codex-session-runner-1gknw7mh.js → codex-session-runner-kzbjcm2k.js} +3 -3
  41. package/dist/{commands-2wyn3swb.js → commands-wfrkef57.js} +2 -2
  42. package/dist/{db-567ntpxv.js → db-c42pxt7h.js} +2 -2
  43. package/dist/{handlers-wvwpk2kj.js → handlers-n36zkfvx.js} +10 -12
  44. package/dist/{hook-fatkywc0.js → hook-gw3vhv6s.js} +8 -6
  45. package/dist/http-59ygpn2h.js +17263 -0
  46. package/dist/{index-d1rm4ea3.js → index-881c1baf.js} +9 -8
  47. package/dist/{index-400x6p3j.js → index-jca7jdpt.js} +23 -10
  48. package/dist/{index-6aj8966p.js → index-xf6fp4y1.js} +5 -5
  49. package/dist/{index-9wqh5352.js → index-xz8vaa5c.js} +14 -11
  50. package/dist/{keepalive-6x9nx92g.js → keepalive-mj4302vw.js} +4 -4
  51. package/dist/{lead-5fgqwe13.js → lead-qm0xjvkv.js} +23 -23
  52. package/dist/{maintenance-eajx5k1k.js → maintenance-xppxbe4t.js} +5 -4
  53. package/dist/{onboard-jc1w1edg.js → onboard-ejx6yxh8.js} +2 -2
  54. package/dist/{otel-impl-8k375amf.js → otel-impl-zs5exkpk.js} +1 -1
  55. package/dist/{pi-mono-adapter-hf8sw7hs.js → pi-mono-adapter-zf7dt1wg.js} +1 -1
  56. package/dist/{pricing-refresh-zed6916t.js → pricing-refresh-nqyf8bkb.js} +4 -4
  57. package/dist/{seed-pricing-5805qzkz.js → seed-pricing-w3x550cj.js} +3 -3
  58. package/dist/{setup-wz05vxh0.js → setup-7729ktfj.js} +2 -2
  59. package/dist/{worker-j359graf.js → worker-4ttemwhw.js} +23 -23
  60. package/openapi.json +159 -4
  61. package/package.json +3 -3
  62. package/src/be/db.ts +83 -13
  63. package/src/be/memory/constants.ts +6 -0
  64. package/src/be/memory/providers/sqlite-store.ts +468 -71
  65. package/src/be/memory/raters/retrieval.ts +4 -2
  66. package/src/be/memory/reranker.ts +5 -2
  67. package/src/be/memory/retrieval-store.ts +2 -0
  68. package/src/be/memory/types.ts +46 -0
  69. package/src/be/migrations/098_repo_hooks_config.sql +3 -0
  70. package/src/be/migrations/099_memory_structured_key_versioning.sql +41 -0
  71. package/src/be/migrations/100_memory_retrieval_source.sql +8 -0
  72. package/src/be/migrations/101_script_connections.sql +67 -0
  73. package/src/be/script-connections.ts +744 -0
  74. package/src/be/script-credential-broker.ts +38 -0
  75. package/src/be/scripts/typecheck.ts +23 -2
  76. package/src/be/seed-scripts/catalog/boot-triage.inline.ts +16 -4
  77. package/src/be/seed-scripts/catalog/boot-triage.ts +16 -4
  78. package/src/be/task-lifecycle-events.ts +42 -0
  79. package/src/commands/runner.ts +182 -31
  80. package/src/github/task-reactions.ts +21 -0
  81. package/src/heartbeat/heartbeat.ts +42 -1
  82. package/src/heartbeat/index.ts +7 -1
  83. package/src/hooks/tool-loop-detection.test.ts +40 -0
  84. package/src/hooks/tool-loop-detection.ts +37 -1
  85. package/src/http/agents.ts +7 -0
  86. package/src/http/index.ts +16 -2
  87. package/src/http/memory.ts +127 -14
  88. package/src/http/prompt-templates.ts +1 -1
  89. package/src/http/repos.ts +5 -1
  90. package/src/http/schedules.ts +1 -1
  91. package/src/http/scripts.ts +15 -14
  92. package/src/http/session-data.ts +2 -0
  93. package/src/http/tasks.ts +2 -1
  94. package/src/http/workflows.ts +1 -0
  95. package/src/prompts/resolver.ts +1 -1
  96. package/src/scheduler/scheduler.ts +25 -2
  97. package/src/scripts-runtime/api-client.ts +100 -0
  98. package/src/scripts-runtime/api-types.ts +45 -0
  99. package/src/scripts-runtime/credential-broker/README.md +40 -0
  100. package/src/scripts-runtime/credential-broker/broker.ts +51 -0
  101. package/src/scripts-runtime/credential-broker/default-bindings.ts +19 -0
  102. package/src/scripts-runtime/credential-broker/fetch-patch.ts +102 -0
  103. package/src/scripts-runtime/credential-broker/index.ts +17 -0
  104. package/src/scripts-runtime/credential-broker/store.ts +72 -0
  105. package/src/scripts-runtime/credential-broker/types.ts +54 -0
  106. package/src/scripts-runtime/ctx.ts +11 -1
  107. package/src/scripts-runtime/egress-secrets.ts +14 -76
  108. package/src/scripts-runtime/eval-harness.ts +1 -1
  109. package/src/scripts-runtime/executors/types.ts +5 -5
  110. package/src/scripts-runtime/loader.ts +6 -1
  111. package/src/scripts-runtime/sdk-allowlist.ts +1 -0
  112. package/src/scripts-runtime/types/stdlib.d.ts +11 -0
  113. package/src/scripts-runtime/types/swarm-sdk.d.ts +11 -0
  114. package/src/server-runtime-counters.ts +12 -0
  115. package/src/server-user.ts +1 -2
  116. package/src/server.ts +11 -0
  117. package/src/telemetry.ts +18 -1
  118. package/src/tests/credential-broker.test.ts +281 -0
  119. package/src/tests/heartbeat.test.ts +239 -0
  120. package/src/tests/http-api-integration.test.ts +4 -0
  121. package/src/tests/memory-edit.test.ts +177 -0
  122. package/src/tests/memory-hybrid.test.ts +212 -0
  123. package/src/tests/model-control.test.ts +6 -6
  124. package/src/tests/runner-repo-autostash.test.ts +39 -8
  125. package/src/tests/script-connections.test.ts +360 -0
  126. package/src/tests/scripts-http.test.ts +16 -10
  127. package/src/tests/scripts-runtime-secret-egress.test.ts +26 -5
  128. package/src/tests/swarm-config-reserved-keys.test.ts +23 -0
  129. package/src/tests/swarm-repos.test.ts +25 -2
  130. package/src/tests/task-lifecycle-events.test.ts +53 -0
  131. package/src/tests/task-lifecycle-telemetry.test.ts +37 -1
  132. package/src/tests/telemetry-init.test.ts +32 -0
  133. package/src/tests/update-schedule-mcp-tool.test.ts +83 -4
  134. package/src/tools/credential-bindings/index.ts +1 -0
  135. package/src/tools/credential-bindings/tool.ts +238 -0
  136. package/src/tools/memory-edit.ts +148 -0
  137. package/src/tools/memory-search.ts +17 -10
  138. package/src/tools/prompt-templates/preview.ts +1 -1
  139. package/src/tools/repos/update-repo.ts +6 -1
  140. package/src/tools/schedules/create-schedule.ts +1 -1
  141. package/src/tools/schedules/delete-schedule.ts +18 -8
  142. package/src/tools/schedules/update-schedule.ts +5 -10
  143. package/src/tools/script-connections/index.ts +1 -0
  144. package/src/tools/script-connections/tool.ts +167 -0
  145. package/src/tools/send-task.ts +7 -2
  146. package/src/tools/swarm-config/delete-config.ts +5 -0
  147. package/src/tools/swarm-config/set-config.ts +23 -1
  148. package/src/tools/task-action.ts +6 -2
  149. package/src/tools/tool-config.ts +6 -1
  150. package/src/types.ts +161 -1
  151. package/src/utils/template.ts +127 -0
  152. package/src/workflows/engine.ts +7 -0
  153. package/src/workflows/executors/agent-task.ts +1 -2
  154. package/src/workflows/executors/swarm-script.ts +2 -0
  155. package/src/workflows/template.ts +12 -121
  156. package/src/workflows/triggers.ts +6 -2
  157. package/templates/community/code-health-reports/PLAYBOOK.md +355 -0
  158. package/templates/community/code-health-reports/README.md +38 -0
  159. package/templates/community/code-health-reports/lead-prompt.md +52 -0
  160. package/templates/community/code-health-reports/report.mjs +378 -0
  161. package/templates/community/code-health-reports/run.sh +143 -0
  162. package/templates/community/dora-metrics/PLAYBOOK.md +294 -0
  163. package/templates/community/dora-metrics/README.md +39 -0
  164. package/templates/community/dora-metrics/lead-prompt.md +56 -0
  165. package/templates/community/dora-metrics/report.mjs +393 -0
  166. package/templates/community/dora-metrics/run.sh +113 -0
  167. package/templates/schedules/weekly-code-health-reports/config.json +13 -0
  168. package/templates/schedules/weekly-code-health-reports/content.md +60 -0
  169. package/templates/schedules/weekly-dora-metrics/config.json +13 -0
  170. package/templates/schedules/weekly-dora-metrics/content.md +61 -0
  171. package/dist/cli-2deg0cen.js +0 -120
  172. package/dist/cli-tsz1q7gk.js +0 -23871
  173. package/src/model-tiers.ts +0 -140
  174. package/templates/community/.gitkeep +0 -0
@@ -2,10 +2,14 @@ import {
2
2
  getApiKey
3
3
  } from "./cli-f14fvzag.js";
4
4
  import {
5
+ CredentialBroker,
6
+ DEFAULT_CREDENTIAL_BINDINGS,
7
+ SwarmConfigCredentialBindingStore,
5
8
  getScript,
6
9
  getScriptVersion,
10
+ listRelationalCredentialBindings,
7
11
  validateScriptImports
8
- } from "./cli-qbc6mncp.js";
12
+ } from "./cli-v1syqkcb.js";
9
13
  import {
10
14
  checkpointStep,
11
15
  checkpointStepFailure,
@@ -15,14 +19,14 @@ import {
15
19
  interpolateNodeConfig,
16
20
  runStepValidation,
17
21
  walkGraph
18
- } from "./cli-t2jk33ta.js";
22
+ } from "./cli-zghef0em.js";
19
23
  import {
20
24
  getAppUrl
21
25
  } from "./cli-dh55d5fg.js";
22
26
  import {
23
27
  withSiblingAwareness,
24
28
  workflowContextKey
25
- } from "./cli-r68m8arr.js";
29
+ } from "./cli-e7bwjntj.js";
26
30
  import {
27
31
  FollowUpConfigSchema,
28
32
  ModelTierSchema,
@@ -34,10 +38,12 @@ import {
34
38
  getDueWaitStates,
35
39
  getPendingEventWaitNames,
36
40
  getPendingWaitsByEvent,
41
+ getResolvedConfig,
37
42
  getRetryableSteps,
38
43
  getStuckApprovalRuns,
39
44
  getStuckWaitRuns,
40
45
  getStuckWorkflowRuns,
46
+ getSwarmConfigs,
41
47
  getTaskByWorkflowRunStepId,
42
48
  getWaitStateById,
43
49
  getWorkflow,
@@ -46,8 +52,6 @@ import {
46
52
  getWorkflowRunStepsByRunId,
47
53
  getWorkflowVersions,
48
54
  init_db,
49
- init_model_tiers,
50
- init_template,
51
55
  init_types,
52
56
  interpolate,
53
57
  resolveApprovalRequest,
@@ -55,7 +59,7 @@ import {
55
59
  splitLegacyModelAlias,
56
60
  updateWorkflowRun,
57
61
  updateWorkflowRunStep
58
- } from "./cli-d0t4854c.js";
62
+ } from "./cli-0jw6j755.js";
59
63
  import {
60
64
  init_zod
61
65
  } from "./cli-q21d49ac.js";
@@ -64,6 +68,7 @@ import {
64
68
  } from "./cli-anrj584m.js";
65
69
  import {
66
70
  init_secret_scrubber,
71
+ registerVolatileSecret,
67
72
  scrubObject,
68
73
  scrubSecrets
69
74
  } from "./cli-3pp1362w.js";
@@ -1014,10 +1019,6 @@ function stopRetryPoller() {
1014
1019
  pollerTimeout = null;
1015
1020
  }
1016
1021
  }
1017
-
1018
- // src/workflows/index.ts
1019
- init_template();
1020
-
1021
1022
  // src/workflows/templates.ts
1022
1023
  function validateTemplateVariables(template, provided) {
1023
1024
  const missing = [];
@@ -1141,7 +1142,6 @@ init_zod();
1141
1142
 
1142
1143
  // src/workflows/executors/agent-task.ts
1143
1144
  init_zod();
1144
- init_model_tiers();
1145
1145
  init_types();
1146
1146
  var AgentTaskConfigSchema = exports_external.object({
1147
1147
  template: exports_external.string(),
@@ -1428,7 +1428,7 @@ class HumanInTheLoopExecutor extends BaseExecutor {
1428
1428
  }
1429
1429
  if (notification.channel === "slack") {
1430
1430
  try {
1431
- const { getSlackApp } = await import("./app-tnq1pz27.js");
1431
+ const { getSlackApp } = await import("./app-dr8hwx7z.js");
1432
1432
  const slackApp = getSlackApp();
1433
1433
  if (!slackApp) {
1434
1434
  console.warn("[HITL] Slack not initialized — cannot send notification");
@@ -1542,7 +1542,7 @@ class NotifyExecutor extends BaseExecutor {
1542
1542
  }
1543
1543
  }
1544
1544
  case "slack": {
1545
- const { getSlackApp } = await import("./app-tnq1pz27.js");
1545
+ const { getSlackApp } = await import("./app-dr8hwx7z.js");
1546
1546
  const app = getSlackApp();
1547
1547
  if (!app) {
1548
1548
  return {
@@ -1836,6 +1836,28 @@ class ScriptExecutor extends BaseExecutor {
1836
1836
  // src/workflows/executors/swarm-script.ts
1837
1837
  init_zod();
1838
1838
 
1839
+ // src/be/script-credential-broker.ts
1840
+ init_secret_scrubber();
1841
+ init_db();
1842
+ class RelationalCredentialBindingStore extends SwarmConfigCredentialBindingStore {
1843
+ listActiveBindings(context) {
1844
+ const relational = listRelationalCredentialBindings(context);
1845
+ if (relational.length > 0)
1846
+ return relational;
1847
+ return super.listActiveBindings(context);
1848
+ }
1849
+ }
1850
+ function buildScriptCredentialBindings(input) {
1851
+ const resolvedConfigs = getResolvedConfig(input.agentId, input.repoId);
1852
+ const configMap = new Map(resolvedConfigs.map((config) => [config.key, config.value]));
1853
+ const broker = new CredentialBroker(new RelationalCredentialBindingStore((filters) => getSwarmConfigs(filters)), (configKey) => configMap.get(configKey) ?? process.env[configKey], DEFAULT_CREDENTIAL_BINDINGS);
1854
+ const bindings = broker.resolveBindings({ agentId: input.agentId, repoId: input.repoId });
1855
+ for (const binding of bindings) {
1856
+ registerVolatileSecret(binding.value, binding.configKey);
1857
+ }
1858
+ return bindings;
1859
+ }
1860
+
1839
1861
  // src/scripts-runtime/executors/types.ts
1840
1862
  var DEFAULT_SCRIPT_RESOURCES = {
1841
1863
  memoryMb: 512,
@@ -1851,22 +1873,9 @@ var DEFAULT_SCRIPT_RESOURCES = {
1851
1873
  init_secret_scrubber();
1852
1874
 
1853
1875
  // src/scripts-runtime/egress-secrets.ts
1854
- var EGRESS_ALLOWLIST = {
1855
- GITHUB_TOKEN: ["api.github.com"]
1856
- };
1857
1876
  function buildEgressSecrets() {
1858
- const entries = [];
1859
- for (const [envKey, hosts] of Object.entries(EGRESS_ALLOWLIST)) {
1860
- const value = process.env[envKey];
1861
- if (!value)
1862
- continue;
1863
- entries.push({
1864
- placeholder: `[REDACTED:${envKey}]`,
1865
- hosts,
1866
- value
1867
- });
1868
- }
1869
- return entries;
1877
+ const broker = new CredentialBroker({ listActiveBindings: () => [] }, (configKey) => process.env[configKey], DEFAULT_CREDENTIAL_BINDINGS);
1878
+ return broker.resolveBindings({});
1870
1879
  }
1871
1880
 
1872
1881
  // src/scripts-runtime/executors/native.ts
@@ -2114,7 +2123,8 @@ function buildConfigPayload(input) {
2114
2123
  }
2115
2124
  },
2116
2125
  user: input.userConfig ?? {},
2117
- egressSecrets: buildEgressSecrets()
2126
+ egressSecrets: input.egressSecrets ?? buildEgressSecrets(),
2127
+ apiConnections: input.apiConnections ?? []
2118
2128
  };
2119
2129
  }
2120
2130
  async function runScript(input) {
@@ -2210,6 +2220,7 @@ class SwarmScriptExecutor extends BaseExecutor {
2210
2220
  args: config.args,
2211
2221
  fsMode: "none",
2212
2222
  agentId: agentId ?? "workflow",
2223
+ egressSecrets: buildScriptCredentialBindings({ agentId: agentId ?? undefined }),
2213
2224
  timeoutMs: config.timeoutMs
2214
2225
  });
2215
2226
  const workflowOutput = {
@@ -2545,7 +2556,6 @@ function createExecutorRegistry(deps) {
2545
2556
  }
2546
2557
 
2547
2558
  // src/workflows/index.ts
2548
- init_template();
2549
2559
  var _registry = null;
2550
2560
  function getExecutorRegistry() {
2551
2561
  if (!_registry) {
@@ -2568,4 +2578,4 @@ function initWorkflows() {
2568
2578
  initWaitBusSubscriptions(_registry);
2569
2579
  }
2570
2580
 
2571
- export { setupWorkflowResumeListener, retryFailedRun, cancelWorkflowRun, resumeWaitState, initWaitBusSubscriptions, subscribeWaitToBus, recoverIncompleteRuns, startRetryPoller, stopRetryPoller, validateTemplateVariables, instantiateTemplate, snapshotWorkflow, startWaitPoller, stopWaitPoller, RawLlmConfigSchema, executeRawLlm, runScript, getExecutorRegistry, initWorkflows };
2581
+ export { setupWorkflowResumeListener, retryFailedRun, cancelWorkflowRun, resumeWaitState, initWaitBusSubscriptions, subscribeWaitToBus, recoverIncompleteRuns, startRetryPoller, stopRetryPoller, validateTemplateVariables, instantiateTemplate, snapshotWorkflow, startWaitPoller, stopWaitPoller, RawLlmConfigSchema, executeRawLlm, buildScriptCredentialBindings, runScript, getExecutorRegistry, initWorkflows };
@@ -4,11 +4,11 @@ import {
4
4
  getEmbeddingProvider,
5
5
  init_embedding,
6
6
  serializeEmbedding
7
- } from "./cli-k81y1cjb.js";
7
+ } from "./cli-p4cj4vhc.js";
8
8
  import {
9
9
  getDb,
10
10
  init_db
11
- } from "./cli-d0t4854c.js";
11
+ } from "./cli-0jw6j755.js";
12
12
  import {
13
13
  init_secret_scrubber,
14
14
  scrubSecrets
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getDb,
3
3
  init_db
4
- } from "./cli-d0t4854c.js";
4
+ } from "./cli-0jw6j755.js";
5
5
 
6
6
  // src/be/seed-pricing.ts
7
7
  init_db();
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  checkToolLoop
3
- } from "./cli-g5px3d7x.js";
3
+ } from "./cli-2957pqpj.js";
4
4
 
5
5
  // src/providers/swarm-events-shared.ts
6
6
  var CANCELLATION_THROTTLE_MS = 500;
@@ -4,11 +4,11 @@ import {
4
4
  getNextResumeGeneration,
5
5
  getResumeGeneration,
6
6
  repointTrackerSyncBySwarmId
7
- } from "./cli-k1ghyj8b.js";
7
+ } from "./cli-s42f54ja.js";
8
8
  import {
9
9
  getExecutorRegistry,
10
10
  recoverIncompleteRuns
11
- } from "./cli-zk4gn40w.js";
11
+ } from "./cli-54h5daha.js";
12
12
  import {
13
13
  assignUnassignedTaskPending,
14
14
  backfillSupersedeTaskResumeTaskId,
@@ -43,7 +43,7 @@ import {
43
43
  resolveTemplate,
44
44
  supersedeTask,
45
45
  updateAgentStatus
46
- } from "./cli-d0t4854c.js";
46
+ } from "./cli-0jw6j755.js";
47
47
 
48
48
  // src/heartbeat/heartbeat.ts
49
49
  init_db();
@@ -347,6 +347,18 @@ function remediateCrashedWorkerTask(findings, task, opts) {
347
347
  if (remaining === 0)
348
348
  updateAgentStatus(task.agentId, "idle");
349
349
  }
350
+ function getBootEpochMs() {
351
+ const gs = globalThis;
352
+ const runId = gs.__runId;
353
+ if (!runId || typeof runId !== "string")
354
+ return null;
355
+ const match = runId.match(/^run_(\d+)$/);
356
+ if (!match)
357
+ return null;
358
+ const epoch = Number(match[1]);
359
+ return Number.isFinite(epoch) ? epoch : null;
360
+ }
361
+ var BOOT_EPOCH_SKEW_MS = 5000;
350
362
  async function runRebootSweep() {
351
363
  if (isSweeping) {
352
364
  console.log("[Heartbeat] Reboot sweep skipped — another sweep is running");
@@ -361,14 +373,27 @@ async function runRebootSweep() {
361
373
  return;
362
374
  }
363
375
  const reason = "Auto-failed by reboot sweep: worker session not found after server restart";
376
+ const bootEpoch = getBootEpochMs();
377
+ if (bootEpoch === null) {
378
+ console.warn("[Heartbeat] Reboot sweep: could not parse boot epoch from __runId — falling back to legacy session-exists check");
379
+ }
364
380
  for (const task of allInProgress) {
365
381
  if (!task.agentId) {
366
382
  console.warn(`[Heartbeat] Reboot sweep: skipping task ${task.id} — in_progress with no agentId`);
367
383
  continue;
368
384
  }
369
385
  const session = getActiveSessionForTask(task.id);
386
+ if (session) {
387
+ if (bootEpoch === null) {
388
+ continue;
389
+ }
390
+ const sessionLastSeen = new Date(session.lastHeartbeatAt).getTime();
391
+ if (sessionLastSeen >= bootEpoch - BOOT_EPOCH_SKEW_MS) {
392
+ continue;
393
+ }
394
+ }
370
395
  if (session)
371
- continue;
396
+ deleteActiveSession(task.id);
372
397
  const failed = failTask(task.id, reason);
373
398
  if (!failed)
374
399
  continue;
@@ -850,4 +875,4 @@ function stopHeartbeatChecklist() {
850
875
  console.log("[Heartbeat] Checklist stopped");
851
876
  }
852
877
  }
853
- export { runRebootSweep, getRebootAffectedTasks, checkHeartbeatChecklist, runHeartbeatSweep, startHeartbeat, stopHeartbeat };
878
+ export { getBootEpochMs, runRebootSweep, getRebootAffectedTasks, checkHeartbeatChecklist, runHeartbeatSweep, startHeartbeat, stopHeartbeat };
@@ -3,7 +3,7 @@ import {
3
3
  getAgentById,
4
4
  getInProgressTasksByContextKey,
5
5
  init_db
6
- } from "./cli-d0t4854c.js";
6
+ } from "./cli-0jw6j755.js";
7
7
 
8
8
  // src/tasks/context-key.ts
9
9
  var SEPARATOR = ":";
@@ -1,20 +1,18 @@
1
1
  import {
2
- createAdditiveBuffer
3
- } from "./cli-zctkpdmd.js";
4
- import {
2
+ createAdditiveBuffer,
5
3
  extractSlackMessageText
6
- } from "./cli-2deg0cen.js";
4
+ } from "./cli-nzc0h54v.js";
7
5
  import {
8
6
  getSlackApp,
9
7
  registerTreeMessage
10
- } from "./cli-sygq3fhn.js";
8
+ } from "./cli-zaxksbgj.js";
11
9
  import {
12
10
  buildBufferFlushBlocks
13
11
  } from "./cli-z92pkwzn.js";
14
12
  import {
15
13
  createTaskWithSiblingAwareness,
16
14
  slackContextKey
17
- } from "./cli-r68m8arr.js";
15
+ } from "./cli-e7bwjntj.js";
18
16
  import {
19
17
  getLatestActiveTaskInThread,
20
18
  getLeadAgent,
@@ -22,7 +20,7 @@ import {
22
20
  init_db,
23
21
  init_registry,
24
22
  registerTemplate
25
- } from "./cli-d0t4854c.js";
23
+ } from "./cli-0jw6j755.js";
26
24
 
27
25
  // src/slack/event-dedup.ts
28
26
  var DEFAULT_TTL_MS = 300000;
@@ -3,7 +3,7 @@ import {
3
3
  incrKv,
4
4
  init_db,
5
5
  upsertKv
6
- } from "./cli-d0t4854c.js";
6
+ } from "./cli-0jw6j755.js";
7
7
 
8
8
  // src/be/unmapped-identities.ts
9
9
  init_db();
@@ -7,7 +7,7 @@ import {
7
7
  } from "./cli-4wmnp8q3.js";
8
8
  import {
9
9
  createSwarmEventHandler
10
- } from "./cli-7xdq3jg3.js";
10
+ } from "./cli-92fqyjcv.js";
11
11
  import {
12
12
  resolveCodexPrompt
13
13
  } from "./cli-r94z9p1z.js";
@@ -3,7 +3,7 @@ import {
3
3
  getAgentWorkingOnThread,
4
4
  getAllAgents,
5
5
  init_db
6
- } from "./cli-d0t4854c.js";
6
+ } from "./cli-0jw6j755.js";
7
7
 
8
8
  // src/slack/router.ts
9
9
  init_db();
@@ -63,6 +63,125 @@ function extractTaskFromMessage(text, botUserId) {
63
63
  return text.replace(new RegExp(`<@${botUserId}>`, "g"), "").replace(/swarm#[a-f0-9-]{36}/gi, "").replace(/swarm#all/gi, "").trim();
64
64
  }
65
65
 
66
+ // src/slack/message-text.ts
67
+ function collectRichTextParts(node, parts) {
68
+ if (node == null || typeof node !== "object")
69
+ return;
70
+ const n = node;
71
+ if (n.type === "text" && n.text) {
72
+ parts.push(n.text);
73
+ }
74
+ if (Array.isArray(n.elements)) {
75
+ for (const child of n.elements) {
76
+ collectRichTextParts(child, parts);
77
+ }
78
+ }
79
+ }
80
+ function extractSlackMessageText(msg) {
81
+ const topText = msg.text?.trim() ?? "";
82
+ const attachmentParts = [];
83
+ if (Array.isArray(msg.attachments) && msg.attachments.length > 0) {
84
+ for (const raw of msg.attachments) {
85
+ if (raw == null || typeof raw !== "object")
86
+ continue;
87
+ const a = raw;
88
+ const attParts = [];
89
+ const titleText = a.title_link && a.title ? `<${a.title_link}|${a.title}>` : a.title;
90
+ const seenPrimary = new Set;
91
+ for (const part of [a.pretext, titleText, a.text, a.fallback]) {
92
+ const s = part?.trim();
93
+ if (s && !seenPrimary.has(s)) {
94
+ seenPrimary.add(s);
95
+ attParts.push(s);
96
+ }
97
+ }
98
+ if (Array.isArray(a.fields)) {
99
+ for (const field of a.fields) {
100
+ if (field == null || typeof field !== "object")
101
+ continue;
102
+ const f = field;
103
+ if (f.title && f.value)
104
+ attParts.push(`${f.title}: ${f.value}`);
105
+ else if (f.title)
106
+ attParts.push(f.title);
107
+ else if (f.value)
108
+ attParts.push(f.value);
109
+ }
110
+ }
111
+ if (Array.isArray(a.actions)) {
112
+ for (const action of a.actions) {
113
+ if (action == null || typeof action !== "object")
114
+ continue;
115
+ const act = action;
116
+ if (act.url) {
117
+ attParts.push(act.text ? `<${act.url}|${act.text}>` : act.url);
118
+ }
119
+ }
120
+ }
121
+ if (attParts.length > 0)
122
+ attachmentParts.push(attParts.join(`
123
+ `));
124
+ }
125
+ }
126
+ const blockParts = [];
127
+ if (Array.isArray(msg.blocks) && msg.blocks.length > 0) {
128
+ for (const rawBlock of msg.blocks) {
129
+ if (rawBlock == null || typeof rawBlock !== "object")
130
+ continue;
131
+ const block = rawBlock;
132
+ if (block.type === "section") {
133
+ if (block.text?.text)
134
+ blockParts.push(block.text.text);
135
+ if (Array.isArray(block.fields)) {
136
+ for (const field of block.fields) {
137
+ if (field != null && typeof field === "object" && field.text) {
138
+ blockParts.push(field.text);
139
+ }
140
+ }
141
+ }
142
+ } else if (block.type === "rich_text" && Array.isArray(block.elements)) {
143
+ for (const el of block.elements) {
144
+ collectRichTextParts(el, blockParts);
145
+ }
146
+ } else if (block.type === "header") {
147
+ if (block.text?.text)
148
+ blockParts.push(block.text.text);
149
+ } else if (block.type === "context" && Array.isArray(block.elements)) {
150
+ for (const el of block.elements) {
151
+ if (el == null || typeof el !== "object")
152
+ continue;
153
+ const e = el;
154
+ if (e.text)
155
+ blockParts.push(e.text);
156
+ }
157
+ } else if (block.type === "actions" && Array.isArray(block.elements)) {
158
+ for (const el of block.elements) {
159
+ if (el == null || typeof el !== "object")
160
+ continue;
161
+ const e = el;
162
+ const label = e.text?.text;
163
+ const url = e.url;
164
+ if (label && url)
165
+ blockParts.push(`<${url}|${label}>`);
166
+ else if (label)
167
+ blockParts.push(label);
168
+ else if (url)
169
+ blockParts.push(url);
170
+ }
171
+ }
172
+ }
173
+ }
174
+ const bodyText = [...attachmentParts, ...blockParts].filter(Boolean).join(`
175
+ `);
176
+ const bodyLines = new Set(bodyText.split(`
177
+ `).map((l) => l.trim()).filter(Boolean));
178
+ if (topText && !bodyLines.has(topText)) {
179
+ return bodyText ? `${topText}
180
+ ${bodyText}` : topText;
181
+ }
182
+ return bodyText || topText;
183
+ }
184
+
66
185
  // src/tasks/additive-buffer.ts
67
186
  function createAdditiveBuffer(options) {
68
187
  const { timeoutMs, onFlush, label } = options;
@@ -133,4 +252,4 @@ function createAdditiveBuffer(options) {
133
252
  };
134
253
  }
135
254
 
136
- export { hasOtherUserMention, routeMessage, extractTaskFromMessage, createAdditiveBuffer };
255
+ export { hasOtherUserMention, routeMessage, extractTaskFromMessage, extractSlackMessageText, createAdditiveBuffer };