@desplega.ai/agent-swarm 1.122.0 → 1.123.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 (229) hide show
  1. package/README.md +2 -0
  2. package/dist/{actions-k3bwtmgy.js → actions-e4c9f0xy.js} +6 -6
  3. package/dist/{app-knevny0f.js → app-vmvmj2v3.js} +4 -4
  4. package/dist/{assistant-as8087ft.js → assistant-yn7a792a.js} +14 -11
  5. package/dist/{boot-reembed-j305cpdr.js → boot-reembed-chxty50a.js} +4 -4
  6. package/dist/{boot-reembed-1dcc1yyk.js → boot-reembed-xg1r86h2.js} +3 -3
  7. package/dist/{boot-scrub-logs-w9qkjzkm.js → boot-scrub-logs-exwddvp5.js} +2 -2
  8. package/dist/{claude-adapter-vxvcym3r.js → claude-adapter-zvzp4x76.js} +1 -1
  9. package/dist/{claude-managed-adapter-g807894s.js → claude-managed-adapter-g92bcm1a.js} +1 -1
  10. package/dist/{cli-3ptjc655.js → cli-1592nfd6.js} +1 -1
  11. package/dist/{cli-x4apc9t3.js → cli-36dctyg8.js} +139 -23
  12. package/dist/{cli-fc1gvt9c.js → cli-3tv9z4wx.js} +6 -3
  13. package/dist/{cli-wmx631p8.js → cli-4509mwm5.js} +159 -21
  14. package/dist/{cli-ma04faw5.js → cli-5arfywtm.js} +2 -0
  15. package/dist/{cli-m7dmk462.js → cli-822d4bjk.js} +18 -14
  16. package/dist/{cli-mjxnr12j.js → cli-8cq4z4x7.js} +510 -30
  17. package/dist/{cli-zpa6gjwq.js → cli-8ef5ky75.js} +1 -1
  18. package/dist/{cli-hjq6c6vz.js → cli-9eka6jwv.js} +2 -2
  19. package/dist/{cli-z3hcrghs.js → cli-9hj1adgp.js} +1 -1
  20. package/dist/{cli-60q15ncp.js → cli-byv3720g.js} +2 -2
  21. package/dist/{cli-tc8xk5zh.js → cli-c9m59f83.js} +1 -1
  22. package/dist/{cli-zweca3q3.js → cli-exfs8aym.js} +1 -1
  23. package/dist/{cli-9fhxk91h.js → cli-fjf04hpa.js} +11 -6
  24. package/dist/{cli-w48hgc2y.js → cli-h2say6xk.js} +3 -3
  25. package/dist/{cli-586x669g.js → cli-hbbxmhec.js} +4 -4
  26. package/dist/{cli-5c4327dx.js → cli-jj1arm18.js} +15 -1
  27. package/dist/{cli-00yr0kxv.js → cli-kmm1rwmp.js} +1 -1
  28. package/dist/{cli-7jb8mk4n.js → cli-mepk1j0t.js} +1 -1
  29. package/dist/{cli-y3an9mk7.js → cli-mkpf4ndf.js} +1052 -254
  30. package/dist/{cli-haeq79yf.js → cli-mngsj9fx.js} +8 -3
  31. package/dist/{cli-bxdb36d2.js → cli-n8mf7x4b.js} +2 -2
  32. package/dist/{cli-wwsaj97q.js → cli-ngbsk4yx.js} +16 -1
  33. package/dist/{cli-8sv69q06.js → cli-np0yhmmk.js} +60 -22
  34. package/dist/{cli-8x745f40.js → cli-p11rf59d.js} +7 -4
  35. package/dist/{cli-16dv125e.js → cli-peaqed7c.js} +20 -3
  36. package/dist/{cli-qnmj37m5.js → cli-vz9drmce.js} +3 -2
  37. package/dist/{cli-tyfxrrdd.js → cli-w5r4wfm5.js} +11 -1
  38. package/dist/{cli-kpfsabp2.js → cli-we91ywvy.js} +85 -7
  39. package/dist/{cli-qf0qxzw5.js → cli-zdp11t8m.js} +22 -17
  40. package/dist/{cli-j89ph4c4.js → cli-zkj6f2sk.js} +2 -2
  41. package/dist/cli.js +12 -12
  42. package/dist/{codex-adapter-0kv2meed.js → codex-adapter-vcseqpwf.js} +1 -1
  43. package/dist/{codex-session-runner-m1e1v4r0.js → codex-session-runner-jec9e9t1.js} +1 -1
  44. package/dist/{commands-6j54dz62.js → commands-sjk3zfyr.js} +7 -4
  45. package/dist/{db-gcnz2tqx.js → db-2je5agjb.js} +24 -2
  46. package/dist/{devin-adapter-pe1cgpd4.js → devin-adapter-8nmsgff3.js} +1 -1
  47. package/dist/{handlers-c43sm2h1.js → handlers-yzv369hf.js} +41 -12
  48. package/dist/{hook-y1p25vm5.js → hook-rfsj2r8x.js} +1 -1
  49. package/dist/{http-bsz1rze1.js → http-v9rr144m.js} +484 -640
  50. package/dist/{index-03zn2rz7.js → index-3xtk777g.js} +9 -9
  51. package/dist/{index-qyzfh62q.js → index-c3tan44f.js} +10 -10
  52. package/dist/{index-8m5gd1vs.js → index-nr2199m6.js} +11 -11
  53. package/dist/{index-7swcv6rv.js → index-smjdc3h9.js} +7 -7
  54. package/dist/{keepalive-69v93p45.js → keepalive-5ds53bjd.js} +5 -5
  55. package/dist/{lead-xn8kfchy.js → lead-5xhez25b.js} +26 -26
  56. package/dist/{maintenance-g2x7q13q.js → maintenance-b43d24q6.js} +4 -4
  57. package/dist/{oauth-refresh-sweep-j80szsyr.js → oauth-refresh-sweep-qe286vn2.js} +4 -4
  58. package/dist/{onboard-e3xcjt8b.js → onboard-c4r3ds3z.js} +2 -2
  59. package/dist/{opencode-adapter-s3nhtp9m.js → opencode-adapter-44z93505.js} +1 -1
  60. package/dist/{otel-impl-24egvjaa.js → otel-impl-nv3rjw61.js} +1 -1
  61. package/dist/{pi-mono-adapter-k3z6e5fn.js → pi-mono-adapter-2syx1x4d.js} +21 -1
  62. package/dist/{pricing-refresh-01kg9gky.js → pricing-refresh-5ct2wp4k.js} +4 -4
  63. package/dist/{rbac-roles-jqfp0zza.js → rbac-roles-b82cxpxn.js} +4 -4
  64. package/dist/{rbac-roles-f9bdj93y.js → rbac-roles-m502w0qv.js} +3 -3
  65. package/dist/{seed-pricing-z2t7rank.js → seed-pricing-jhjphbf0.js} +3 -3
  66. package/dist/{setup-kw2ps002.js → setup-zbaspydq.js} +2 -2
  67. package/dist/{worker-336w8930.js → worker-snvhpax5.js} +26 -26
  68. package/openapi.json +311 -16
  69. package/package.json +3 -3
  70. package/src/be/budget-admission.ts +2 -1
  71. package/src/be/db.ts +288 -2
  72. package/src/be/memory/constants.ts +29 -25
  73. package/src/be/memory/providers/sqlite-store.ts +3 -3
  74. package/src/be/memory/reranker.ts +4 -5
  75. package/src/be/migrations/121_task_steering_messages.sql +24 -0
  76. package/src/be/migrations/122_steering_handled_note.sql +4 -0
  77. package/src/be/rbac-audit.ts +2 -1
  78. package/src/be/scripts/typecheck.ts +1 -0
  79. package/src/be/steering.ts +251 -0
  80. package/src/be/swarm-config-guard.ts +117 -1
  81. package/src/commands/context-preamble.ts +68 -8
  82. package/src/commands/provider-credentials.ts +2 -2
  83. package/src/commands/runner.ts +168 -1
  84. package/src/gitlab/auth.ts +3 -1
  85. package/src/heartbeat/heartbeat.ts +79 -20
  86. package/src/http/active-sessions.ts +1 -1
  87. package/src/http/core.ts +69 -1
  88. package/src/http/index.ts +6 -2
  89. package/src/http/mcp-oauth.ts +2 -1
  90. package/src/http/memory.ts +2 -2
  91. package/src/http/schedules.ts +2 -2
  92. package/src/http/script-runs.ts +1 -1
  93. package/src/http/sessions.ts +5 -1
  94. package/src/http/stats.ts +5 -1
  95. package/src/http/tasks.ts +407 -13
  96. package/src/oauth/mcp-wrapper.ts +2 -1
  97. package/src/otel.ts +23 -10
  98. package/src/prompts/base-prompt.ts +15 -0
  99. package/src/prompts/session-templates.ts +31 -0
  100. package/src/providers/claude-adapter.ts +208 -26
  101. package/src/providers/claude-managed-adapter.ts +20 -1
  102. package/src/providers/codex-adapter.ts +2 -1
  103. package/src/providers/devin-adapter.ts +18 -1
  104. package/src/providers/opencode-adapter.ts +32 -0
  105. package/src/providers/pi-mono-adapter.ts +33 -1
  106. package/src/providers/types.ts +11 -1
  107. package/src/rbac/admission.ts +2 -1
  108. package/src/rbac/legacy-policy.ts +2 -0
  109. package/src/rbac/permissions.ts +8 -0
  110. package/src/scripts-runtime/sdk-allowlist.ts +1 -0
  111. package/src/scripts-runtime/types/stdlib.d.ts +6 -0
  112. package/src/scripts-runtime/types/swarm-sdk.d.ts +6 -0
  113. package/src/server-user.ts +22 -0
  114. package/src/server.ts +11 -0
  115. package/src/slack/HEURISTICS.md +7 -0
  116. package/src/slack/assistant.ts +3 -2
  117. package/src/slack/blocks.ts +2 -0
  118. package/src/slack/commands.ts +2 -1
  119. package/src/slack/handlers.ts +39 -4
  120. package/src/slack/router.ts +5 -2
  121. package/src/slack/steering.ts +67 -0
  122. package/src/slack/thread-buffer.ts +39 -0
  123. package/src/slack/watcher.ts +5 -0
  124. package/src/tasks/worker-follow-up.ts +9 -2
  125. package/src/telemetry.ts +2 -1
  126. package/src/tests/claude-adapter-binary.test.ts +5 -0
  127. package/src/tests/claude-managed-adapter.test.ts +61 -0
  128. package/src/tests/devin-adapter.test.ts +41 -0
  129. package/src/tests/env-flag.test.ts +93 -0
  130. package/src/tests/heartbeat-reroute-decision.test.ts +10 -10
  131. package/src/tests/heartbeat-supersede-resume.test.ts +2 -2
  132. package/src/tests/mcp-user-route.test.ts +14 -2
  133. package/src/tests/opencode-adapter.test.ts +176 -1
  134. package/src/tests/pi-mono-adapter.test.ts +80 -0
  135. package/src/tests/prompt-template-session.test.ts +5 -4
  136. package/src/tests/provider-steering-capabilities.test.ts +44 -0
  137. package/src/tests/rbac-engine.test.ts +2 -1
  138. package/src/tests/reload-config.test.ts +81 -6
  139. package/src/tests/sdk-allowlist.test.ts +7 -0
  140. package/src/tests/slack-steering.test.ts +227 -0
  141. package/src/tests/status.test.ts +20 -0
  142. package/src/tests/steer-task-tool.test.ts +200 -0
  143. package/src/tests/steering-core.test.ts +601 -0
  144. package/src/tests/steering-enabled.test.ts +343 -0
  145. package/src/tests/steering-promotion.test.ts +205 -0
  146. package/src/tests/steering-transport.test.ts +338 -0
  147. package/src/tests/tool-output-agent-id.test.ts +182 -0
  148. package/src/tests/user-token-rest-auth.test.ts +31 -30
  149. package/src/tools/accept-steer.ts +148 -0
  150. package/src/tools/cancel-task.ts +1 -1
  151. package/src/tools/context-diff.ts +1 -1
  152. package/src/tools/context-history.ts +2 -3
  153. package/src/tools/create-channel.ts +2 -2
  154. package/src/tools/credential-bindings/tool.ts +1 -1
  155. package/src/tools/delete-channel.ts +1 -1
  156. package/src/tools/get-swarm.ts +1 -1
  157. package/src/tools/get-task-details.ts +4 -1
  158. package/src/tools/get-tasks.ts +4 -1
  159. package/src/tools/inject-learning.ts +1 -1
  160. package/src/tools/join-swarm.ts +1 -1
  161. package/src/tools/kv/kv-delete.ts +1 -1
  162. package/src/tools/kv/kv-get.ts +1 -1
  163. package/src/tools/kv/kv-incr.ts +1 -1
  164. package/src/tools/kv/kv-list.ts +1 -1
  165. package/src/tools/kv/kv-set.ts +1 -1
  166. package/src/tools/list-channels.ts +1 -1
  167. package/src/tools/list-services.ts +2 -2
  168. package/src/tools/mcp-servers/mcp-server-create.ts +1 -1
  169. package/src/tools/mcp-servers/mcp-server-delete.ts +1 -1
  170. package/src/tools/mcp-servers/mcp-server-get.ts +1 -1
  171. package/src/tools/mcp-servers/mcp-server-install.ts +1 -1
  172. package/src/tools/mcp-servers/mcp-server-list.ts +1 -1
  173. package/src/tools/mcp-servers/mcp-server-uninstall.ts +1 -1
  174. package/src/tools/mcp-servers/mcp-server-update.ts +1 -1
  175. package/src/tools/memory-delete.ts +1 -1
  176. package/src/tools/memory-edit.ts +1 -1
  177. package/src/tools/memory-get.ts +1 -1
  178. package/src/tools/memory-search.ts +27 -22
  179. package/src/tools/my-agent-info.ts +1 -1
  180. package/src/tools/poll-task.ts +1 -1
  181. package/src/tools/post-message.ts +2 -2
  182. package/src/tools/prompt-templates/delete.ts +1 -1
  183. package/src/tools/prompt-templates/get.ts +1 -1
  184. package/src/tools/prompt-templates/list.ts +1 -1
  185. package/src/tools/prompt-templates/preview.ts +1 -1
  186. package/src/tools/prompt-templates/set.ts +1 -1
  187. package/src/tools/read-messages.ts +1 -1
  188. package/src/tools/register-agentmail-inbox.ts +1 -1
  189. package/src/tools/register-kapso-number.ts +2 -3
  190. package/src/tools/register-service.ts +1 -1
  191. package/src/tools/request-human-input.ts +1 -1
  192. package/src/tools/schedules/create-schedule.ts +2 -6
  193. package/src/tools/schedules/delete-schedule.ts +1 -1
  194. package/src/tools/schedules/list-schedules.ts +1 -1
  195. package/src/tools/schedules/patch-schedule.ts +2 -2
  196. package/src/tools/schedules/run-schedule-now.ts +1 -1
  197. package/src/tools/schedules/update-schedule.ts +2 -2
  198. package/src/tools/script-connections/tool.ts +1 -1
  199. package/src/tools/send-task.ts +4 -2
  200. package/src/tools/skills/skill-create.ts +1 -1
  201. package/src/tools/skills/skill-delete.ts +1 -1
  202. package/src/tools/skills/skill-get-file.ts +1 -1
  203. package/src/tools/skills/skill-get.ts +1 -1
  204. package/src/tools/skills/skill-install-remote.ts +1 -1
  205. package/src/tools/skills/skill-install.ts +1 -1
  206. package/src/tools/skills/skill-list.ts +1 -1
  207. package/src/tools/skills/skill-publish.ts +1 -1
  208. package/src/tools/skills/skill-search.ts +1 -1
  209. package/src/tools/skills/skill-sync-remote.ts +1 -1
  210. package/src/tools/skills/skill-uninstall.ts +1 -1
  211. package/src/tools/skills/skill-update.ts +1 -1
  212. package/src/tools/steer-task.ts +149 -0
  213. package/src/tools/store-progress.ts +17 -12
  214. package/src/tools/swarm-config/delete-config.ts +1 -1
  215. package/src/tools/swarm-config/get-config.ts +1 -2
  216. package/src/tools/swarm-config/list-config.ts +2 -2
  217. package/src/tools/swarm-config/set-config.ts +1 -2
  218. package/src/tools/task-action.ts +1 -1
  219. package/src/tools/tool-config.ts +3 -1
  220. package/src/tools/unregister-service.ts +1 -1
  221. package/src/tools/update-profile.ts +1 -2
  222. package/src/tools/update-service-status.ts +1 -1
  223. package/src/tools/whatsapp-message.ts +1 -1
  224. package/src/types.ts +106 -22
  225. package/src/utils/env-flag.ts +55 -0
  226. package/src/utils/scripts-only-mode.ts +12 -2
  227. package/src/utils/steering-enabled.ts +12 -0
  228. package/src/workflows/engine.ts +14 -6
  229. package/src/workflows/executors/agent-task.ts +3 -1
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  checkCodexCredentials
3
- } from "./cli-zweca3q3.js";
3
+ } from "./cli-exfs8aym.js";
4
4
  import {
5
5
  checkClaudeManagedCredentials
6
- } from "./cli-5c4327dx.js";
6
+ } from "./cli-jj1arm18.js";
7
7
  import {
8
8
  checkDevinCredentials
9
- } from "./cli-tyfxrrdd.js";
9
+ } from "./cli-w5r4wfm5.js";
10
10
  import {
11
11
  checkOpencodeCredentials
12
- } from "./cli-16dv125e.js";
12
+ } from "./cli-peaqed7c.js";
13
13
  import {
14
14
  initOtel,
15
15
  injectTraceContext,
@@ -19,7 +19,7 @@ import {
19
19
  withSpan,
20
20
  withSpanContext,
21
21
  writeSkillsToFilesystem
22
- } from "./cli-y3an9mk7.js";
22
+ } from "./cli-mkpf4ndf.js";
23
23
  import {
24
24
  authJsonToCredentialSelection,
25
25
  credentialsToAuthJson,
@@ -27,7 +27,7 @@ import {
27
27
  } from "./cli-tk9vyqzh.js";
28
28
  import {
29
29
  checkClaudeCredentials
30
- } from "./cli-x4apc9t3.js";
30
+ } from "./cli-36dctyg8.js";
31
31
  import {
32
32
  MAX_RATE_LIMIT_RESET_MS,
33
33
  isCodexCreditsExhaustedMessage,
@@ -41,10 +41,10 @@ import {
41
41
  import {
42
42
  ensure,
43
43
  initialize
44
- } from "./cli-586x669g.js";
44
+ } from "./cli-hbbxmhec.js";
45
45
  import {
46
46
  validateJsonSchema
47
- } from "./cli-m7dmk462.js";
47
+ } from "./cli-822d4bjk.js";
48
48
  import {
49
49
  getApiKey
50
50
  } from "./cli-f14fvzag.js";
@@ -75,15 +75,17 @@ import {
75
75
  init_defaults,
76
76
  init_resolver,
77
77
  init_session_templates,
78
+ init_steering_enabled,
78
79
  init_telemetry,
79
80
  init_template,
80
81
  init_templates,
81
82
  init_types,
82
83
  interpolate,
84
+ isSteeringEnabled,
83
85
  resolveTaskModelSelection,
84
86
  resolveTemplateAsync,
85
87
  telemetry
86
- } from "./cli-mjxnr12j.js";
88
+ } from "./cli-8cq4z4x7.js";
87
89
  import {
88
90
  init_credentials,
89
91
  resolveCredentialPools
@@ -101,6 +103,7 @@ import { existsSync, statSync } from "node:fs";
101
103
  import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
102
104
 
103
105
  // src/prompts/base-prompt.ts
106
+ init_steering_enabled();
104
107
  init_resolver();
105
108
  init_session_templates();
106
109
  var BOOTSTRAP_MAX_CHARS = 20000;
@@ -119,6 +122,7 @@ function areSlackPromptToolsEnabled(env = process.env) {
119
122
  var getBasePrompt = async (args) => {
120
123
  const { role, agentId, swarmUrl, traits } = args;
121
124
  const { hasMcp = true, hasLocalEnvironment: hasLocalEnv = true } = traits ?? {};
125
+ const steerModes = traits?.steerModes ?? [];
122
126
  const vars = { role, agentId, swarmUrl };
123
127
  let compositeEventType;
124
128
  if (!hasMcp) {
@@ -156,6 +160,10 @@ ${scriptsOnlyResult.text}`;
156
160
  const messagingResult = await resolveTemplateAsync("system.agent.messaging", {});
157
161
  prompt += messagingResult.text;
158
162
  }
163
+ if (hasMcp && isSteeringEnabled() && steerModes.length > 0 && !scriptsOnlyMode && serverHasCapability("core", true)) {
164
+ const steeringResult = await resolveTemplateAsync("system.agent.steering", {});
165
+ prompt += steeringResult.text;
166
+ }
159
167
  if (!hasLocalEnv) {
160
168
  prompt += `
161
169
 
@@ -457,27 +465,27 @@ async function materializeCodexAuthJson(_slot, creds, deps = {}) {
457
465
  async function createProviderAdapter(provider) {
458
466
  switch (provider) {
459
467
  case "claude": {
460
- const { ClaudeAdapter } = await import("./claude-adapter-vxvcym3r.js");
468
+ const { ClaudeAdapter } = await import("./claude-adapter-zvzp4x76.js");
461
469
  return new ClaudeAdapter;
462
470
  }
463
471
  case "pi": {
464
- const { PiMonoAdapter } = await import("./pi-mono-adapter-k3z6e5fn.js");
472
+ const { PiMonoAdapter } = await import("./pi-mono-adapter-2syx1x4d.js");
465
473
  return new PiMonoAdapter;
466
474
  }
467
475
  case "codex": {
468
- const { CodexAdapter } = await import("./codex-adapter-0kv2meed.js");
476
+ const { CodexAdapter } = await import("./codex-adapter-vcseqpwf.js");
469
477
  return new CodexAdapter;
470
478
  }
471
479
  case "claude-managed": {
472
- const { ClaudeManagedAdapter } = await import("./claude-managed-adapter-g807894s.js");
480
+ const { ClaudeManagedAdapter } = await import("./claude-managed-adapter-g92bcm1a.js");
473
481
  return new ClaudeManagedAdapter;
474
482
  }
475
483
  case "devin": {
476
- const { DevinAdapter } = await import("./devin-adapter-pe1cgpd4.js");
484
+ const { DevinAdapter } = await import("./devin-adapter-8nmsgff3.js");
477
485
  return new DevinAdapter;
478
486
  }
479
487
  case "opencode": {
480
- const { OpencodeAdapter } = await import("./opencode-adapter-s3nhtp9m.js");
488
+ const { OpencodeAdapter } = await import("./opencode-adapter-44z93505.js");
481
489
  return new OpencodeAdapter;
482
490
  }
483
491
  default:
@@ -832,6 +840,7 @@ async function refreshSkillsIfChanged(ctx, lastHashRef, homeOverride) {
832
840
  }
833
841
 
834
842
  // src/commands/runner.ts
843
+ init_steering_enabled();
835
844
  init_template();
836
845
 
837
846
  // src/vcs/index.ts
@@ -845,6 +854,7 @@ function detectVcsProvider(url) {
845
854
 
846
855
  // src/commands/context-preamble.ts
847
856
  init_secret_scrubber();
857
+ init_steering_enabled();
848
858
  var CONTEXT_PREAMBLE_MAX_TOKENS = Number(process.env.CONTEXT_PREAMBLE_MAX_TOKENS || "2000");
849
859
  var CONTEXT_PREAMBLE_MAX_CHARS = CONTEXT_PREAMBLE_MAX_TOKENS * 4;
850
860
  var CONTEXT_PREAMBLE_MAX_ANCESTORS = 5;
@@ -965,6 +975,20 @@ async function fetchSessionLogsForResume(apiUrl, apiKey, taskId) {
965
975
  return [];
966
976
  }
967
977
  }
978
+ async function fetchSteeringMessagesForResume(apiUrl, apiKey, taskId) {
979
+ const headers = {};
980
+ if (apiKey)
981
+ headers.Authorization = `Bearer ${apiKey}`;
982
+ try {
983
+ const response = await fetch(`${apiUrl}/api/tasks/${taskId}/steering-messages?status=pending,promoted`, { headers });
984
+ if (!response.ok)
985
+ return [];
986
+ const data = await response.json();
987
+ return Array.isArray(data.messages) ? data.messages.filter((message) => (message.status === "pending" || message.status === "promoted") && typeof message.body === "string" && typeof message.createdAt === "string") : [];
988
+ } catch {
989
+ return [];
990
+ }
991
+ }
968
992
  function summarizeSessionLogLine(line) {
969
993
  const ts = line.createdAt.slice(11, 19);
970
994
  let parsed;
@@ -1024,13 +1048,20 @@ async function buildResumeContextPreamble(apiUrl, apiKey, parentTaskId) {
1024
1048
  if (!original)
1025
1049
  return null;
1026
1050
  const parent = chain[0] ?? original;
1027
- const logsBatches = await Promise.all(chain.map((c2) => fetchSessionLogsForResume(apiUrl, apiKey, c2.id)));
1051
+ const steeringEnabled = isSteeringEnabled();
1052
+ const [logsBatches, steeringBatches] = await Promise.all([
1053
+ Promise.all(chain.map((c2) => fetchSessionLogsForResume(apiUrl, apiKey, c2.id))),
1054
+ steeringEnabled ? Promise.all(chain.map((c2) => fetchSteeringMessagesForResume(apiUrl, apiKey, c2.id))) : Promise.resolve([])
1055
+ ]);
1028
1056
  const merged = logsBatches.flat();
1029
1057
  merged.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
1030
1058
  const recentLogs = merged.slice(-CONTEXT_PREAMBLE_RESUME_SESSION_LOG_LIMIT);
1059
+ const steeringMessages = steeringBatches.flat();
1060
+ steeringMessages.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
1031
1061
  const descBudget = Math.floor(CONTEXT_PREAMBLE_RESUME_MAX_CHARS * 0.4);
1032
- let logsBudget = Math.floor(CONTEXT_PREAMBLE_RESUME_MAX_CHARS * 0.35);
1033
- let artBudget = Math.floor(CONTEXT_PREAMBLE_RESUME_MAX_CHARS * 0.15);
1062
+ let logsBudget = Math.floor(CONTEXT_PREAMBLE_RESUME_MAX_CHARS * 0.3);
1063
+ let artBudget = Math.floor(CONTEXT_PREAMBLE_RESUME_MAX_CHARS * 0.1);
1064
+ const steeringBudget = Math.floor(CONTEXT_PREAMBLE_RESUME_MAX_CHARS * 0.1);
1034
1065
  const header = [
1035
1066
  `
1036
1067
  ---`,
@@ -1070,6 +1101,17 @@ async function buildResumeContextPreamble(apiUrl, apiKey, parentTaskId) {
1070
1101
  while (logsSection.length > logsBudget && scrubbedSummary.length > 0) {
1071
1102
  scrubbedSummary.shift();
1072
1103
  logsSection = scrubbedSummary.join(`
1104
+ `);
1105
+ }
1106
+ const steeringLines = steeringEnabled ? steeringMessages.map((message) => {
1107
+ const ts = message.createdAt.slice(11, 19);
1108
+ return `[${ts}] ${scrubSecrets(message.body)}`;
1109
+ }) : [];
1110
+ let steeringSection = steeringLines.join(`
1111
+ `);
1112
+ while (steeringSection.length > steeringBudget && steeringLines.length > 0) {
1113
+ steeringLines.shift();
1114
+ steeringSection = steeringLines.join(`
1073
1115
  `);
1074
1116
  }
1075
1117
  const atts = parent.attachments?.filter((a) => a.name && (a.url || a.path || a.pageId)) ?? [];
@@ -1092,6 +1134,9 @@ async function buildResumeContextPreamble(apiUrl, apiKey, parentTaskId) {
1092
1134
  if (artSection) {
1093
1135
  sections.push("### Artifacts In Flight", "", artSection, "");
1094
1136
  }
1137
+ if (steeringEnabled && steeringSection) {
1138
+ sections.push("### Undelivered Steering Messages", "", steeringSection, "");
1139
+ }
1095
1140
  sections.push("---", "", `To review the full prior session call \`get-task-details\` with taskId \`${original.id}\`.`, "", "---", "");
1096
1141
  let preamble = sections.join(`
1097
1142
  `);
@@ -1125,7 +1170,7 @@ async function checkProviderCredentials(provider, env, opts) {
1125
1170
  case "opencode":
1126
1171
  return checkOpencodeCredentials(env, opts);
1127
1172
  case "pi": {
1128
- const { checkPiMonoCredentials } = await import("./pi-mono-adapter-k3z6e5fn.js");
1173
+ const { checkPiMonoCredentials } = await import("./pi-mono-adapter-2syx1x4d.js");
1129
1174
  return checkPiMonoCredentials(env, opts);
1130
1175
  }
1131
1176
  default:
@@ -1281,7 +1326,7 @@ async function validateProviderCredentials(provider) {
1281
1326
  };
1282
1327
  }
1283
1328
  const baseUrl = env.DEVIN_API_BASE_URL ?? "https://api.devin.ai";
1284
- const r = await timedFetch(`${baseUrl.replace(/\/+$/, "")}/v1/sessions?limit=1`, {
1329
+ const r = await timedFetch(`${baseUrl.replace(/\/+$/, "")}/v3/self`, {
1285
1330
  method: "GET",
1286
1331
  headers: {
1287
1332
  Authorization: `Bearer ${apiKey}`,
@@ -1709,6 +1754,78 @@ async function ensureRepoForTask(repoConfig, role, isFirstKickoff = false) {
1709
1754
  return { clonePath: cloneExists ? clonePath : "", claudeMd: null, warning, autoStashes };
1710
1755
  }
1711
1756
  }
1757
+ function createSteeringDispatchState() {
1758
+ return {
1759
+ dispatchedIds: new Set,
1760
+ outcomes: new Map
1761
+ };
1762
+ }
1763
+ async function renderSteeringDelivery(steeringMessageId, body) {
1764
+ try {
1765
+ const result = await resolveTemplateAsync("system.agent.steering.delivery", {
1766
+ steeringMessageId,
1767
+ body
1768
+ });
1769
+ return result.skipped || !result.text.trim() ? body : result.text;
1770
+ } catch {
1771
+ return body;
1772
+ }
1773
+ }
1774
+ async function pollAndDispatchSteering(config, taskId, session, state, fetchImpl = fetch) {
1775
+ if (!isSteeringEnabled())
1776
+ return;
1777
+ const headers = {
1778
+ Authorization: `Bearer ${config.apiKey}`,
1779
+ "X-Agent-ID": config.agentId
1780
+ };
1781
+ const response = await fetchImpl(`${config.apiUrl}/api/steering-messages?taskId=${encodeURIComponent(taskId)}`, { headers });
1782
+ if (!response.ok) {
1783
+ throw new Error(`Steering poll failed (HTTP ${response.status})`);
1784
+ }
1785
+ const data = await response.json();
1786
+ for (const message of data.messages ?? []) {
1787
+ if (message.status !== "pending")
1788
+ continue;
1789
+ let outcome = state.dispatchedIds.has(message.id) ? state.outcomes.get(message.id) : undefined;
1790
+ if (!outcome) {
1791
+ try {
1792
+ outcome = session.deliverSteering ? await session.deliverSteering({
1793
+ mode: message.mode,
1794
+ text: await renderSteeringDelivery(message.id, message.body)
1795
+ }) : {
1796
+ delivered: false,
1797
+ reason: "Provider session does not support live steering"
1798
+ };
1799
+ } catch (error) {
1800
+ outcome = {
1801
+ delivered: false,
1802
+ reason: scrubSecrets(`Provider steering failed: ${error.message}`)
1803
+ };
1804
+ }
1805
+ if (!outcome.delivered) {
1806
+ outcome = {
1807
+ delivered: false,
1808
+ reason: scrubSecrets(outcome.reason).trim() || "Provider rejected steering without a reason"
1809
+ };
1810
+ }
1811
+ state.dispatchedIds.add(message.id);
1812
+ state.outcomes.set(message.id, outcome);
1813
+ }
1814
+ const endpoint = outcome.delivered ? "delivered" : "undeliverable";
1815
+ const body = outcome.delivered ? { mode: outcome.mode } : { reason: outcome.reason };
1816
+ const reportResponse = await fetchImpl(`${config.apiUrl}/api/steering-messages/${encodeURIComponent(message.id)}/${endpoint}`, {
1817
+ method: "POST",
1818
+ headers: {
1819
+ ...headers,
1820
+ "Content-Type": "application/json"
1821
+ },
1822
+ body: JSON.stringify(body)
1823
+ });
1824
+ if (!reportResponse.ok) {
1825
+ throw new Error(`Steering ${endpoint} report failed (HTTP ${reportResponse.status})`);
1826
+ }
1827
+ }
1828
+ }
1712
1829
  async function pingServer(config, _role) {
1713
1830
  const headers = {
1714
1831
  "X-Agent-ID": config.agentId
@@ -1807,7 +1924,13 @@ var RELOADABLE_ENV_KEYS = new Set([
1807
1924
  "REASONING_EFFORT_OVERRIDE",
1808
1925
  "AGENT_FS_SHARED_ORG_ID",
1809
1926
  "SWARM_USE_CLAUDE_BRIDGE",
1810
- "BEDROCK_AUTH_MODE"
1927
+ "BEDROCK_AUTH_MODE",
1928
+ "STEERING_ENABLED",
1929
+ "ANONYMIZED_TELEMETRY",
1930
+ "MEMORY_RATERS",
1931
+ "TEMPLATE_REGISTRY_URL",
1932
+ "SLACK_DISABLE",
1933
+ "SWARM_ORG_NAME"
1811
1934
  ]);
1812
1935
  function applyResolvedEnvToProcessEnv(freshEnv) {
1813
1936
  const changed = [];
@@ -4006,6 +4129,10 @@ async function runAgent(config, opts) {
4006
4129
  });
4007
4130
  bootModel = bootEnv.env.MODEL_OVERRIDE || bootModel;
4008
4131
  bootCooldownMs = resolveCodexCreditsExhaustedCooldownMs(bootEnv.env.CODEX_CREDITS_EXHAUSTED_COOLDOWN_MS);
4132
+ const bootApplied = applyResolvedEnvToProcessEnv(bootEnv.env);
4133
+ if (bootApplied.length > 0) {
4134
+ console.log(`[runner] Applied resolved swarm config at boot: ${bootApplied.join(", ")}`);
4135
+ }
4009
4136
  } catch (err) {
4010
4137
  console.warn(`[runner] fetchResolvedEnv failed at boot, falling back to env for provider and the default cooldown: ${err}`);
4011
4138
  bootProvider = resolveHarnessProvider({}, process.env);
@@ -4171,6 +4298,7 @@ ${additionalSystemPrompt}` : basePrompt;
4171
4298
  codexCreditsExhaustedCooldownMs: bootCooldownMs
4172
4299
  };
4173
4300
  const cancelledSignaled = new Set;
4301
+ const steeringDispatchState = isSteeringEnabled() ? createSteeringDispatchState() : null;
4174
4302
  let cachedCredHarnessProvider = null;
4175
4303
  let lastHarnessReconcileAt = 0;
4176
4304
  const HARNESS_RECONCILE_INTERVAL_MS = 1e4;
@@ -4754,6 +4882,16 @@ ${additionalSystemPrompt}` : basePrompt;
4754
4882
  } catch {}
4755
4883
  }
4756
4884
  }
4885
+ if (steeringDispatchState && state.activeTasks.size > 0) {
4886
+ const dispatchState = steeringDispatchState;
4887
+ for (const [taskId, task] of state.activeTasks) {
4888
+ try {
4889
+ await pollAndDispatchSteering(apiConfig, taskId, task.session, dispatchState);
4890
+ } catch (error) {
4891
+ console.warn(`[${role}] Steering dispatch failed for task ${taskId.slice(0, 8)} (non-fatal): ${scrubSecrets(error.message)}`);
4892
+ }
4893
+ }
4894
+ }
4757
4895
  if (state.activeTasks.size < state.maxConcurrent) {
4758
4896
  if (Date.now() - lastOrphanRecoveryAt > ORPHAN_RECOVERY_INTERVAL_MS) {
4759
4897
  lastOrphanRecoveryAt = Date.now();
@@ -199,6 +199,8 @@ function renderNodeLine(node) {
199
199
  let line = `${icon} *${node.agentName}* (${taskLink})`;
200
200
  if (node.duration)
201
201
  line += ` · ${node.duration}`;
202
+ if (node.steered)
203
+ line += " · _steered_";
202
204
  return line;
203
205
  }
204
206
  function renderChildDetail(node, indent) {
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  ensureAuthorizationTokenOrThrow,
9
9
  oauthAppRowToProviderConfig
10
- } from "./cli-tc8xk5zh.js";
10
+ } from "./cli-c9m59f83.js";
11
11
  import {
12
12
  getScript,
13
13
  getScriptApiConnectionDescriptors,
@@ -15,15 +15,15 @@ import {
15
15
  getScriptVersion,
16
16
  listRelationalCredentialBindings,
17
17
  validateScriptImports
18
- } from "./cli-8x745f40.js";
18
+ } from "./cli-p11rf59d.js";
19
19
  import {
20
20
  getAuthorizationById,
21
21
  getOAuthApp,
22
22
  getOAuthAppById
23
- } from "./cli-z3hcrghs.js";
23
+ } from "./cli-9hj1adgp.js";
24
24
  import {
25
25
  withSiblingAwareness
26
- } from "./cli-00yr0kxv.js";
26
+ } from "./cli-kmm1rwmp.js";
27
27
  import {
28
28
  getAppUrl
29
29
  } from "./cli-dh55d5fg.js";
@@ -77,7 +77,7 @@ import {
77
77
  updateWorkflowRun,
78
78
  updateWorkflowRunStep,
79
79
  workflowContextKey
80
- } from "./cli-mjxnr12j.js";
80
+ } from "./cli-8cq4z4x7.js";
81
81
  import {
82
82
  init_secret_scrubber,
83
83
  isSensitiveKey,
@@ -650,8 +650,12 @@ async function runStepValidation(registry, stepNode, stepOutput, context, meta)
650
650
 
651
651
  // src/workflows/engine.ts
652
652
  var DEFAULT_TIMEOUT_MS = 30000;
653
- var MAX_ITERATIONS = Number(process.env.WORKFLOW_MAX_ITERATIONS) || 100;
654
- var MAX_STEPS_PER_RUN = Number(process.env.WORKFLOW_MAX_STEPS_PER_RUN) || 500;
653
+ function maxIterations() {
654
+ return Number(process.env.WORKFLOW_MAX_ITERATIONS) || 100;
655
+ }
656
+ function maxStepsPerRun() {
657
+ return Number(process.env.WORKFLOW_MAX_STEPS_PER_RUN) || 500;
658
+ }
655
659
 
656
660
  class TriggerSchemaError extends Error {
657
661
  validationErrors;
@@ -736,10 +740,10 @@ async function walkGraph(def, runId, ctx, startNodes, registry, workflowId, secr
736
740
  }
737
741
  }
738
742
  const allSteps = getWorkflowRunStepsByRunId(runId);
739
- if (allSteps.length >= MAX_STEPS_PER_RUN) {
743
+ if (allSteps.length >= maxStepsPerRun()) {
740
744
  updateWorkflowRun(runId, {
741
745
  status: "failed",
742
- error: `Circuit breaker: run exceeded ${MAX_STEPS_PER_RUN} total steps (WORKFLOW_MAX_STEPS_PER_RUN)`,
746
+ error: `Circuit breaker: run exceeded ${maxStepsPerRun()} total steps (WORKFLOW_MAX_STEPS_PER_RUN)`,
743
747
  finishedAt: new Date().toISOString()
744
748
  });
745
749
  return;
@@ -764,10 +768,10 @@ async function walkGraph(def, runId, ctx, startNodes, registry, workflowId, secr
764
768
  const executedInThisWalk = new Set;
765
769
  while (pendingNodes.length > 0) {
766
770
  nodeExecutionCount += pendingNodes.length;
767
- if (nodeExecutionCount > MAX_ITERATIONS) {
771
+ if (nodeExecutionCount > maxIterations()) {
768
772
  updateWorkflowRun(runId, {
769
773
  status: "failed",
770
- error: `Max node executions (${MAX_ITERATIONS}) exceeded — possible infinite loop`,
774
+ error: `Max node executions (${maxIterations()}) exceeded — possible infinite loop`,
771
775
  finishedAt: new Date().toISOString()
772
776
  });
773
777
  return;
@@ -2334,7 +2338,7 @@ init_context_key();
2334
2338
  init_types();
2335
2339
  var AgentTaskConfigSchema = exports_external.object({
2336
2340
  template: exports_external.string(),
2337
- agentId: exports_external.string().uuid().optional(),
2341
+ agentId: exports_external.string().optional(),
2338
2342
  tags: exports_external.array(exports_external.string()).optional(),
2339
2343
  priority: exports_external.number().int().min(0).max(100).optional(),
2340
2344
  offerMode: exports_external.boolean().optional(),
@@ -2623,7 +2627,7 @@ class HumanInTheLoopExecutor extends BaseExecutor {
2623
2627
  }
2624
2628
  if (notification.channel === "slack") {
2625
2629
  try {
2626
- const { getSlackApp } = await import("./app-knevny0f.js");
2630
+ const { getSlackApp } = await import("./app-vmvmj2v3.js");
2627
2631
  const slackApp = getSlackApp();
2628
2632
  if (!slackApp) {
2629
2633
  console.warn("[HITL] Slack not initialized — cannot send notification");
@@ -2737,7 +2741,7 @@ class NotifyExecutor extends BaseExecutor {
2737
2741
  }
2738
2742
  }
2739
2743
  case "slack": {
2740
- const { getSlackApp } = await import("./app-knevny0f.js");
2744
+ const { getSlackApp } = await import("./app-vmvmj2v3.js");
2741
2745
  const app = getSlackApp();
2742
2746
  if (!app) {
2743
2747
  return {