@desplega.ai/agent-swarm 1.152.2 → 1.154.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 (284) hide show
  1. package/README.md +2 -2
  2. package/dist/{acp-adapter-pfeje2v5.js → acp-adapter-eb2aj8xy.js} +4 -4
  3. package/dist/{actions-0sttc7f5.js → actions-kpnwp1kz.js} +31 -27
  4. package/dist/{anthropic-messages-2y8nktar.js → anthropic-messages-9vqsbznt.js} +112 -84
  5. package/dist/{app-p8teva95.js → app-zk1apkf6.js} +10 -7
  6. package/dist/{assistant-r45jnsrt.js → assistant-kwq4y50q.js} +32 -28
  7. package/dist/{azure-openai-responses-f38x2avq.js → azure-openai-responses-04qwdwfq.js} +27 -13
  8. package/dist/{boot-reembed-je26h5y7.js → boot-reembed-22hd3jjn.js} +9 -7
  9. package/dist/{boot-reembed-1qmybsd4.js → boot-reembed-qe168424.js} +10 -8
  10. package/dist/{boot-scrub-logs-gte3h1mm.js → boot-scrub-logs-pkdpsrjd.js} +7 -5
  11. package/dist/{claude-adapter-csc1mzka.js → claude-adapter-3fx90nww.js} +18 -16
  12. package/dist/{claude-managed-adapter-dsmkcrjy.js → claude-managed-adapter-ea2aga6w.js} +3 -3
  13. package/dist/{claude-sdk-session-fcd6f078.js → claude-sdk-session-z7fahf1k.js} +18 -16
  14. package/dist/{cli-r2fpe7cx.js → cli-00w2c66p.js} +61 -55
  15. package/dist/{cli-wbyk465z.js → cli-09y3tjxz.js} +1 -1
  16. package/dist/{cli-ht5rs63n.js → cli-0e31nm4n.js} +16 -7
  17. package/dist/cli-0x5qzvkg.js +4279 -0
  18. package/dist/{cli-d3p82erb.js → cli-18amys3y.js} +9 -9
  19. package/dist/{cli-4ahpr4sw.js → cli-1jpjafw4.js} +5 -5
  20. package/dist/{cli-jbmc0r7r.js → cli-243tzws8.js} +1 -1
  21. package/dist/{cli-ch38q5z4.js → cli-24k806sc.js} +6789 -2542
  22. package/dist/cli-3bkz2p7j.js +2828 -0
  23. package/dist/cli-3er6gcsn.js +1849 -0
  24. package/dist/cli-4k7jazkq.js +3339 -0
  25. package/dist/{cli-c4eeb5q2.js → cli-5b6b62tz.js} +1 -1
  26. package/dist/{cli-qd65dvr6.js → cli-5vs0nh43.js} +65 -44
  27. package/dist/{cli-z3wkng35.js → cli-6r3cgpk2.js} +224 -156
  28. package/dist/{cli-pgj4a5fb.js → cli-71cj99hx.js} +4 -3
  29. package/dist/cli-8sea27q4.js +14075 -0
  30. package/dist/{cli-jvy9qgjs.js → cli-913yakhv.js} +22 -7
  31. package/dist/{cli-pf9q3696.js → cli-927erqqt.js} +5 -2
  32. package/dist/cli-95jnpnqg.js +230 -0
  33. package/dist/{cli-wpv5rgg2.js → cli-abp3g4ax.js} +15 -2
  34. package/dist/{cli-ckz5t2hb.js → cli-acy6bfhr.js} +10 -7
  35. package/dist/{cli-4yc5d8fk.js → cli-avkd6mqv.js} +50 -0
  36. package/dist/{cli-8wrympd7.js → cli-bzr0ftht.js} +26 -7
  37. package/dist/{cli-qn042eh7.js → cli-c1v10xb2.js} +194 -1913
  38. package/dist/cli-cgj4hc12.js +18902 -0
  39. package/dist/{cli-2nnd56zt.js → cli-e0pg4zeh.js} +3 -2
  40. package/dist/{cli-r84ctdxn.js → cli-e31ehqwy.js} +2 -2
  41. package/dist/{cli-gphgnvpf.js → cli-e3229na9.js} +3 -3
  42. package/dist/{cli-gpqcs935.js → cli-e3cyf59d.js} +2 -2
  43. package/dist/{cli-s25avqg9.js → cli-e781c6f9.js} +1 -0
  44. package/dist/{cli-s2qjdd6z.js → cli-eetrvv91.js} +1 -1
  45. package/dist/{cli-j4nv2wqy.js → cli-fdzg6jhf.js} +10 -4
  46. package/dist/{cli-fm4ytsdk.js → cli-g2h29qar.js} +2 -2
  47. package/dist/{cli-zvgj5zg8.js → cli-ge67p080.js} +302 -3497
  48. package/dist/cli-h38x0qhg.js +6912 -0
  49. package/dist/{cli-9xvdm3bx.js → cli-h60qfasa.js} +742 -278
  50. package/dist/{cli-jew3jda5.js → cli-hws0vn86.js} +2 -2
  51. package/dist/{cli-j8dggbcr.js → cli-k0g1sjzm.js} +23 -31
  52. package/dist/{cli-xw7vak96.js → cli-kp3qs53m.js} +5 -5
  53. package/dist/{cli-rgvp6r2x.js → cli-mcnhgnn1.js} +193 -4
  54. package/dist/{cli-zvkq5csn.js → cli-myaxtgh8.js} +7 -6
  55. package/dist/{cli-56h18ng2.js → cli-n62atwh9.js} +1 -1
  56. package/dist/cli-n7h1kqpf.js +29 -0
  57. package/dist/{cli-fmy65jdn.js → cli-pf1v8xhb.js} +7 -5
  58. package/dist/{cli-xy1cchaf.js → cli-q85qhckh.js} +238 -11
  59. package/dist/{cli-3bpzj8me.js → cli-r1d3dzt6.js} +2 -2
  60. package/dist/{pi-mono-adapter-jcqt71cg.js → cli-rxkqvngf.js} +67343 -101083
  61. package/dist/{cli-kj76p1ez.js → cli-scwq51gn.js} +13 -7
  62. package/dist/{cli-b9dd0h3k.js → cli-stwsmd6k.js} +3 -2
  63. package/dist/{cli-c2mk1kgf.js → cli-v4en75c5.js} +8 -1
  64. package/dist/{cli-z61ykvam.js → cli-wg04s9kr.js} +4 -3
  65. package/dist/cli-yn0a417a.js +4069 -0
  66. package/dist/{cli-zfzznn7c.js → cli-ytxs7mn1.js} +26 -2
  67. package/dist/{cli-4j8k1m4w.js → cli-zt1227k1.js} +1162 -192
  68. package/dist/cli.js +28 -35
  69. package/dist/{codex-adapter-fxmpsabw.js → codex-adapter-ttdm995v.js} +12 -11
  70. package/dist/{codex-hook-8jexc34x.js → codex-hook-8gx7bcz0.js} +3 -3
  71. package/dist/{codex-session-runner-rr1e47ea.js → codex-session-runner-3v8nh4c8.js} +12 -11
  72. package/dist/{commands-0f5rxz51.js → commands-1cxwbhhq.js} +7 -5
  73. package/dist/{db-r3jxf3wy.js → db-y9zwsr79.js} +25 -5
  74. package/dist/{dispatcher-06vph6q4.js → dispatcher-9m9zss36.js} +30 -26
  75. package/dist/dsh-adapter-gsb2qqf9.js +19 -0
  76. package/dist/{e2b-413b8t4v.js → e2b-93x1k0j5.js} +6 -7
  77. package/dist/{google-generative-ai-ndjmj5fa.js → google-generative-ai-gwwrnzqn.js} +33 -73
  78. package/dist/{google-vertex-fr665tqs.js → google-vertex-5wfawpwz.js} +38 -68
  79. package/dist/{handlers-0hgtc910.js → handlers-36fm1bwn.js} +33 -29
  80. package/dist/{hook-9kvrv1er.js → hook-pntw4r8h.js} +12 -10
  81. package/dist/{hook-fbfhkat3.js → hook-vwq8y26p.js} +13 -11
  82. package/dist/{http-xbyx8k5j.js → http-20jesakk.js} +357 -261
  83. package/dist/{index-jsw3aynb.js → index-6artrehg.js} +30 -26
  84. package/dist/{cli-pdz9qde4.js → index-9ch1n761.js} +10 -11
  85. package/dist/{index-rnyahfn5.js → index-9n5z2492.js} +30 -26
  86. package/dist/{index-66xz5e9j.js → index-h5gs261z.js} +521 -9
  87. package/dist/{index-tfsdxyv6.js → index-j5wrf1yw.js} +40 -25
  88. package/dist/{index-2sp0384z.js → index-kkeftv5h.js} +738 -21
  89. package/dist/{index-sgk50mbg.js → index-m2xqpz5r.js} +31 -27
  90. package/dist/{index-gpfn1741.js → index-m9ks8a7t.js} +9 -7
  91. package/dist/index-w097eg0x.js +5 -0
  92. package/dist/jiti-loader-b4837mtm.js +34 -0
  93. package/dist/jiti-static-loader-q2g5ds0y.js +31267 -0
  94. package/dist/{keepalive-s3xpr7sw.js → keepalive-pwxvxd2c.js} +9 -7
  95. package/dist/{lead-rq4n5r16.js → lead-m789wqa3.js} +46 -41
  96. package/dist/{maintenance-f0atj1ab.js → maintenance-bvg6w7e2.js} +10 -8
  97. package/dist/{mistral-conversations-qhr84ph3.js → mistral-conversations-zx0kn554.js} +24 -18
  98. package/dist/{node-x1g4v0pq.js → node-5qtycf6a.js} +16 -11
  99. package/dist/{oauth-refresh-sweep-q0t3bxre.js → oauth-refresh-sweep-6v4bd737.js} +8 -6
  100. package/dist/{onboard-br5j1kch.js → onboard-snckpcj1.js} +115 -35
  101. package/dist/{openai-codex-responses-wy6a43wd.js → openai-codex-responses-4vjqzvjp.js} +33 -27
  102. package/dist/{openai-completions-32rdwmze.js → openai-completions-pxsmym7g.js} +52 -64
  103. package/dist/{openai-responses-6xwf7bzg.js → openai-responses-tmn0rqp0.js} +23 -24
  104. package/dist/{opencode-adapter-28axqa09.js → opencode-adapter-qbmv4tpy.js} +6 -6
  105. package/dist/{otel-impl-vdqge2nt.js → otel-impl-e0ytens5.js} +4 -4
  106. package/dist/{pi-messages-b1mbr6gp.js → pi-messages-txpjj39q.js} +3 -3
  107. package/dist/pi-mono-adapter-c4ggemhz.js +1316 -0
  108. package/dist/{pricing-refresh-hb3691fd.js → pricing-refresh-52g2ywrw.js} +9 -7
  109. package/dist/{rbac-roles-t78xt39b.js → rbac-roles-5455kfdn.js} +8 -6
  110. package/dist/{rbac-roles-jh280k9g.js → rbac-roles-hbf0xa52.js} +9 -7
  111. package/dist/{render-v2-7p8r2ymg.js → render-v2-npm8xdzh.js} +16 -9
  112. package/dist/{seed-pricing-hf889enh.js → seed-pricing-650wbr1n.js} +8 -6
  113. package/dist/{setup-w6mb03jv.js → setup-k1mew5rf.js} +4 -5
  114. package/dist/virtual-modules-2q5b2pk4.js +54 -0
  115. package/dist/{work-objects-nt8gy1kj.js → work-objects-2ea3kvwg.js} +33 -29
  116. package/dist/{worker-dwy617t0.js → worker-ec6hvc4m.js} +46 -41
  117. package/openapi.json +109 -16
  118. package/package.json +7 -6
  119. package/plugin/opencode-plugins/lib/memory-raters.ts +7 -0
  120. package/src/be/automation-preflight.ts +6 -4
  121. package/src/be/db/agents.ts +75 -2
  122. package/src/be/db/tasks/read.ts +2 -0
  123. package/src/be/db/tasks/write.ts +7 -1
  124. package/src/be/db.ts +140 -18
  125. package/src/be/extensions/db.ts +35 -4
  126. package/src/be/memory/raters/llm.ts +2 -6
  127. package/src/be/memory/raters/noop.ts +2 -3
  128. package/src/be/memory/raters/registry.ts +4 -10
  129. package/src/be/migrations/157_defer_provenance_and_marker.sql +27 -0
  130. package/src/be/models-catalog.ts +2 -0
  131. package/src/be/modelsdev-cache.json +213 -0
  132. package/src/be/rbac-audit.ts +2 -0
  133. package/src/be/seed/agent-fs-provision.ts +23 -0
  134. package/src/be/seed-pricing.ts +3 -1
  135. package/src/be/swarm-config-guard.ts +1 -0
  136. package/src/commands/onboard/compose-generator.ts +16 -1
  137. package/src/commands/onboard/env-generator.ts +14 -1
  138. package/src/commands/onboard/manifest.ts +1 -0
  139. package/src/commands/onboard/steps/integration-slack.tsx +56 -16
  140. package/src/commands/onboard/steps/review.tsx +5 -0
  141. package/src/commands/onboard/types.ts +6 -0
  142. package/src/commands/onboard.tsx +5 -1
  143. package/src/commands/provider-credentials.ts +14 -2
  144. package/src/commands/runner.ts +18 -2
  145. package/src/extensions/identity.ts +15 -7
  146. package/src/extensions/lifecycle.ts +15 -21
  147. package/src/hooks/codex-hook.ts +7 -1
  148. package/src/http/agents.ts +12 -4
  149. package/src/http/config.ts +1 -1
  150. package/src/http/core.ts +5 -3
  151. package/src/http/extensions.ts +108 -34
  152. package/src/http/poll.ts +7 -0
  153. package/src/http/schedules.ts +10 -0
  154. package/src/http/script-runs.ts +35 -26
  155. package/src/http/status.ts +24 -11
  156. package/src/http/tasks.ts +6 -1
  157. package/src/prompts/base-prompt.ts +15 -7
  158. package/src/prompts/memories.ts +5 -7
  159. package/src/prompts/session-templates.ts +3 -2
  160. package/src/prompts/steering-delivery.ts +2 -0
  161. package/src/providers/claude-managed-models.ts +8 -0
  162. package/src/providers/codex-adapter.ts +3 -6
  163. package/src/providers/codex-models.ts +15 -1
  164. package/src/providers/dsh-adapter.ts +248 -0
  165. package/src/providers/index.ts +5 -1
  166. package/src/providers/modelsdev-reasoning.json +50 -0
  167. package/src/providers/pi-mono-extension.ts +2 -5
  168. package/src/rbac/legacy-policy.ts +15 -1
  169. package/src/rbac/types.ts +2 -0
  170. package/src/server.ts +7 -1
  171. package/src/slack/ack.ts +43 -8
  172. package/src/slack/app.ts +32 -10
  173. package/src/slack/config.ts +29 -0
  174. package/src/slack/handlers.ts +7 -1
  175. package/src/slack/render-v2.ts +186 -17
  176. package/src/slack/responses.ts +1 -3
  177. package/src/slack/task-output.ts +66 -8
  178. package/src/slack/thread-buffer.ts +27 -3
  179. package/src/telemetry.ts +2 -3
  180. package/src/tests/agent-fs-provision-seeder.test.ts +56 -2
  181. package/src/tests/agents-harness-provider.test.ts +19 -0
  182. package/src/tests/agents-list-model-display.test.ts +60 -1
  183. package/src/tests/base-prompt.test.ts +25 -0
  184. package/src/tests/claude-managed-adapter.test.ts +6 -0
  185. package/src/tests/codex-gpt6-release.test.ts +97 -0
  186. package/src/tests/codex-steering-hook.test.ts +2 -2
  187. package/src/tests/config-api-only-keys.test.ts +9 -0
  188. package/src/tests/context-window.test.ts +1 -0
  189. package/src/tests/db-task-read-contract.test.ts +9 -0
  190. package/src/tests/db-task-write-contract.test.ts +9 -0
  191. package/src/tests/defer-task.test.ts +115 -16
  192. package/src/tests/dsh-adapter.test.ts +276 -0
  193. package/src/tests/e2e-nightly-report.test.ts +3 -3
  194. package/src/tests/e2e-redact.test.ts +2 -0
  195. package/src/tests/env-flag.test.ts +6 -0
  196. package/src/tests/extension-agent-visibility.test.ts +474 -0
  197. package/src/tests/extensions-db.test.ts +41 -0
  198. package/src/tests/extensions-http.test.ts +148 -4
  199. package/src/tests/extensions-lifecycle.test.ts +21 -1
  200. package/src/tests/extensions-mcp-tools.test.ts +9 -5
  201. package/src/tests/fetch-resolved-env.test.ts +43 -0
  202. package/src/tests/internal-ai/complete-structured.test.ts +32 -9
  203. package/src/tests/internal-ai/credentials.test.ts +4 -4
  204. package/src/tests/internal-ai/models.test.ts +20 -0
  205. package/src/tests/memory-rate-tool.test.ts +7 -10
  206. package/src/tests/memory-rater-defaults.test.ts +23 -0
  207. package/src/tests/memory-rater-e2e.test.ts +2 -3
  208. package/src/tests/migration-046-budgets.test.ts +2 -0
  209. package/src/tests/model-control.test.ts +2 -2
  210. package/src/tests/onboard-compose.test.ts +14 -0
  211. package/src/tests/onboard-env.test.ts +17 -0
  212. package/src/tests/onboard-manifest.test.ts +12 -0
  213. package/src/tests/opus-5-5-registry.test.ts +48 -0
  214. package/src/tests/pricing-refresh.test.ts +1 -1
  215. package/src/tests/pricing-routes.test.ts +15 -3
  216. package/src/tests/provider-registration.test.ts +5 -2
  217. package/src/tests/rbac-admission-e2e.test.ts +54 -0
  218. package/src/tests/rbac-e2e-helpers.ts +2 -0
  219. package/src/tests/rbac-engine.test.ts +32 -0
  220. package/src/tests/rbac-wire-e2e.test.ts +33 -0
  221. package/src/tests/reasoning-effort.test.ts +8 -0
  222. package/src/tests/reload-config.test.ts +33 -0
  223. package/src/tests/script-connections.test.ts +3 -0
  224. package/src/tests/session-costs-model-key-normalize.test.ts +1 -0
  225. package/src/tests/slack-config.test.ts +136 -0
  226. package/src/tests/slack-mode-lifecycle.test.ts +69 -0
  227. package/src/tests/slack-render-v2.test.ts +446 -16
  228. package/src/tests/slack-steering.test.ts +69 -1
  229. package/src/tests/slack-task-output.test.ts +33 -12
  230. package/src/tests/status.test.ts +22 -2
  231. package/src/tests/steering-core.test.ts +35 -0
  232. package/src/tests/steering-delivery.test.ts +39 -0
  233. package/src/tests/steering-transport.test.ts +2 -2
  234. package/src/tests/task-tool-preload-mcp.test.ts +3 -1
  235. package/src/tests/telemetry-init.test.ts +18 -0
  236. package/src/tests/workflow-live-recovery.test.ts +126 -0
  237. package/src/tests/workflow-llm.test.ts +3 -3
  238. package/src/tools/defer-task.ts +64 -26
  239. package/src/tools/extension-common.ts +4 -0
  240. package/src/tools/extension-install.ts +1 -1
  241. package/src/tools/extension-list.ts +4 -3
  242. package/src/tools/join-swarm.ts +1 -1
  243. package/src/tools/schedules/create-schedule.ts +11 -1
  244. package/src/tools/schedules/patch-schedule.ts +5 -0
  245. package/src/tools/schedules/update-schedule.ts +5 -0
  246. package/src/tools/send-task.ts +6 -0
  247. package/src/tools/utils.ts +1 -1
  248. package/src/types.ts +30 -8
  249. package/src/utils/context-window.ts +1 -0
  250. package/src/utils/credentials.ts +8 -0
  251. package/src/utils/internal-ai/complete-structured.ts +8 -0
  252. package/src/utils/internal-ai/models.ts +5 -5
  253. package/src/utils/memory-raters.ts +3 -0
  254. package/src/workflows/engine.ts +28 -0
  255. package/src/workflows/recovery.ts +7 -4
  256. package/templates/schedules/daily-status-report/content.md +25 -12
  257. package/templates/schedules/daily-workflow-health-audit/content.md +1 -1
  258. package/templates/skills/swarm-extensions/content.md +9 -5
  259. package/dist/cli-4wppfkcm.js +0 -16384
  260. package/dist/cli-55qrx3q8.js +0 -6041
  261. package/dist/cli-cg4vnyh4.js +0 -305
  262. package/dist/cli-jyetr64j.js +0 -52
  263. package/dist/cli-pp9ax9pa.js +0 -520
  264. package/dist/cli-qa66qaf0.js +0 -6076
  265. package/dist/cli-qghpvca2.js +0 -590
  266. package/dist/cli-rembwgt8.js +0 -861
  267. package/dist/cli-tcvj7j2r.js +0 -1971
  268. package/dist/cli-vfcth11k.js +0 -36
  269. package/dist/cli-w1d1bgkk.js +0 -1422
  270. package/dist/cli-y6x0gqtg.js +0 -5977
  271. package/dist/es5-tj3tn4jj.js +0 -844
  272. package/dist/index-1kq5hw2p.js +0 -467
  273. package/dist/index-1p8wdstt.js +0 -7
  274. package/dist/index-8fdjzb2f.js +0 -100
  275. package/dist/index-bxmwzbgw.js +0 -365
  276. package/dist/index-nzerxd5z.js +0 -7
  277. package/dist/index-pyymnzat.js +0 -1168
  278. package/dist/index-qv6atbab.js +0 -619
  279. package/dist/index-rja32qa7.js +0 -801
  280. package/dist/index-tzg5srfp.js +0 -211
  281. package/dist/index-vhncw983.js +0 -90
  282. package/dist/index-xk036zsk.js +0 -859
  283. package/dist/index-zyazbzcb.js +0 -6
  284. package/dist/{claude-managed-setup-48dwg9bv.js → claude-managed-setup-f5pmsyrp.js} +3 -3
@@ -31,9 +31,11 @@ import {
31
31
  getLiveAgentCounts,
32
32
  hasFirstCompletedTask,
33
33
  listAgentsWithCredStatusByProvider,
34
+ NOT_EXTENSION_AGENT_SQL,
34
35
  } from "../be/db";
35
36
  import { getEmbeddingProvider } from "../be/memory";
36
37
  import { getFileStorageProvider } from "../fs/registry";
38
+ import { getSlackConfiguration } from "../slack/config";
37
39
  import { type AgentCredStatus, AutomationIntegrationIdSchema, ProviderNameSchema } from "../types";
38
40
  import { route } from "./route-def";
39
41
  import { json, jsonError } from "./utils";
@@ -407,26 +409,37 @@ function embeddingsMilestone(): SetupMilestone {
407
409
  }
408
410
 
409
411
  function slackMilestone(state: AutomationSetupStates["slack"]): SetupMilestone {
410
- const disable = process.env.SLACK_DISABLE;
411
- const disabled = disable === "true" || disable === "1";
412
+ const config = getSlackConfiguration();
412
413
 
413
414
  if (state === "unverified") {
415
+ let hint: string;
416
+ if (config.disabled) {
417
+ hint = "Slack is explicitly disabled (SLACK_DISABLE=true).";
418
+ } else if (!config.mode) {
419
+ hint = "Invalid SLACK_MODE. Use socket or http.";
420
+ } else if (config.mode === "http" && config.missingCredentials.length === 0) {
421
+ hint =
422
+ "HTTP credentials are configured, but HTTP ingress is unavailable until the receiver is installed.";
423
+ } else {
424
+ hint = `Set ${config.missingCredentials.join(" + ")} for Slack ${config.mode} mode.`;
425
+ }
414
426
  return {
415
427
  id: "slack",
416
- label: "Slack connected",
428
+ label: "Slack configured",
417
429
  state: "unverified",
418
- hint: disabled
419
- ? "Slack is explicitly disabled (SLACK_DISABLE=true)."
420
- : "Set SLACK_BOT_TOKEN + SLACK_APP_TOKEN to connect Slack.",
430
+ hint,
421
431
  action_url: automationIntegrationFixUrl("slack"),
422
432
  };
423
433
  }
424
- // Socket Mode connection state isn't surfaced today — Phase 2+ enhancement.
425
- // For now treat env-present as `verified` so the UX matches the brainstorm.
434
+
426
435
  return {
427
436
  id: "slack",
428
- label: "Slack connected",
429
- state: "verified",
437
+ label: "Slack configured",
438
+ state: "configured",
439
+ hint:
440
+ config.mode === "http"
441
+ ? "HTTP credentials are configured, but HTTP ingress is unavailable until the receiver is installed."
442
+ : "Socket Mode credentials are configured; a live connection has not been verified.",
430
443
  action_url: automationIntegrationFixUrl("slack"),
431
444
  };
432
445
  }
@@ -527,7 +540,7 @@ async function workersMilestone(): Promise<SetupMilestone> {
527
540
  // `configured` if ≥1 row in agents; `verified` if both lead+worker alive
528
541
  // within the last 5 minutes.
529
542
  const totalRow = await getDbClient().get<{ count: number }>(
530
- `SELECT COUNT(*) AS count FROM agents`,
543
+ `SELECT COUNT(*) AS count FROM agents WHERE ${NOT_EXTENSION_AGENT_SQL}`,
531
544
  );
532
545
  const totalAgents = totalRow?.count ?? 0;
533
546
 
package/src/http/tasks.ts CHANGED
@@ -7,6 +7,7 @@ import {
7
7
  backfillSupersedeTaskResumeTaskId,
8
8
  cancelTask,
9
9
  completeTask,
10
+ ExtensionAgentAssignmentError,
10
11
  failTask,
11
12
  getAgentById,
12
13
  getAllTasks,
@@ -259,7 +260,7 @@ const createTask = route({
259
260
  }),
260
261
  responses: {
261
262
  201: { description: "Task created", schema: AgentTaskSchema },
262
- 400: { description: "Validation error" },
263
+ 400: { description: "Validation error, or agentId/offeredTo targets an extension identity" },
263
264
  422: {
264
265
  description: "Task creation blocked by an extension",
265
266
  schema: z.object({
@@ -906,6 +907,10 @@ export async function handleTasks(
906
907
  createTask.respond(res, 422, { error: error.reason, extension: error.extension });
907
908
  return true;
908
909
  }
910
+ if (error instanceof ExtensionAgentAssignmentError) {
911
+ jsonError(res, error.message, 400);
912
+ return true;
913
+ }
909
914
  console.error("[HTTP] Failed to create task:", error);
910
915
  jsonError(res, "Failed to create task", 500);
911
916
  }
@@ -16,6 +16,7 @@
16
16
  */
17
17
 
18
18
  import type { ProviderTraits } from "../providers/types";
19
+ import { getSlackConfiguration } from "../slack/config";
19
20
  import type { ProviderName } from "../types";
20
21
  import { isSteeringEnabled } from "../utils/steering-enabled";
21
22
  import { matchesDefaultClaudeMd, matchesDefaultIdentityMd } from "./defaults";
@@ -54,11 +55,18 @@ const CLAUDE_MD_INJECT_PROVIDERS: ReadonlySet<string> = new Set(["codex", "openc
54
55
  /** Providers that get the repo CLAUDE.md inlined until native loading is verified. */
55
56
  const REPO_CLAUDE_MD_INLINE_PROVIDERS: ReadonlySet<string> = new Set(["opencode"]);
56
57
 
57
- export function areSlackPromptToolsEnabled(env: NodeJS.ProcessEnv = process.env): boolean {
58
- const slackDisable = env.SLACK_DISABLE;
59
- if (slackDisable === "true" || slackDisable === "1") return false;
60
-
61
- return Boolean(env.SLACK_BOT_TOKEN && env.SLACK_APP_TOKEN);
58
+ export function areSlackPromptToolsEnabled(
59
+ env: NodeJS.ProcessEnv = process.env,
60
+ serverCapabilities?: string[],
61
+ ): boolean {
62
+ const config = getSlackConfiguration(env);
63
+ if (config.disabled || !config.mode) return false;
64
+
65
+ // Preserve the socket credential gate. For the HTTP contract, workers use
66
+ // the server tool capability without needing the API-owned signing secret.
67
+ if (serverCapabilities && !serverCapabilities.includes("slack")) return false;
68
+ if (config.mode === "http" && serverCapabilities) return true;
69
+ return config.missingCredentials.length === 0;
62
70
  }
63
71
 
64
72
  export type BasePromptArgs = {
@@ -185,8 +193,8 @@ export const getBasePrompt = async (args: BasePromptArgs): Promise<string> => {
185
193
 
186
194
  // H. Slack. One block for both roles; the scripts-only variant covers Slack
187
195
  // via ctx.swarm.slack_* for Slack-originated tasks.
188
- const slackPromptToolsEnabled = areSlackPromptToolsEnabled();
189
- if (hasMcp && slackPromptToolsEnabled && !scriptsOnlyMode && serverHasCapability("slack", true)) {
196
+ const slackPromptToolsEnabled = areSlackPromptToolsEnabled(process.env, args.serverCapabilities);
197
+ if (hasMcp && slackPromptToolsEnabled && !scriptsOnlyMode) {
190
198
  const slackResult = await resolveTemplateAsync("system.agent.slack", {});
191
199
  prompt += slackResult.text;
192
200
  }
@@ -7,10 +7,12 @@
7
7
  * scripts/check-db-boundary.sh.
8
8
  *
9
9
  * The conditional hint at the end is gated on `MEMORY_RATERS` containing
10
- * `explicit-self`. When the gate is closed (the default), the rendered
11
- * prompt is byte-identical to pre-rater builds — strict backward compat.
10
+ * `explicit-self` (part of the default when unset). An explicitly empty value
11
+ * closes the gate and preserves the prompt without rating hints.
12
12
  */
13
13
 
14
+ import { getMemoryRaterNames } from "../utils/memory-raters";
15
+
14
16
  export type RelevantMemory = {
15
17
  id: string;
16
18
  name: string;
@@ -54,9 +56,5 @@ export function renderMemoriesPrompt(memories: RelevantMemory[]): string | null
54
56
  * env var between renders without re-importing the module.
55
57
  */
56
58
  export function isExplicitSelfRaterEnabled(): boolean {
57
- const ratersEnabled = (process.env.MEMORY_RATERS ?? "")
58
- .split(",")
59
- .map((s) => s.trim())
60
- .filter(Boolean);
61
- return ratersEnabled.includes("explicit-self");
59
+ return getMemoryRaterNames().includes("explicit-self");
62
60
  }
@@ -295,7 +295,7 @@ registerTemplate({
295
295
  defaultBody: `
296
296
  ## Live task steering
297
297
 
298
- You may receive steering messages while this task is running. Each one arrives wrapped in a \`[steering <id>]\` marker that carries its steering message ID. Incorporate the message into your current work, then call \`accept-steer\` with that ID. Act on a message before you acknowledge it.
298
+ You may receive steering messages while this task is running. Each one arrives wrapped in a \`[steering <id>]\` marker that carries its steering message ID, followed by the sender name and kind. Incorporate the message into your current work, then call \`accept-steer\` with that ID. Act on a message before you acknowledge it.
299
299
  `,
300
300
  variables: [],
301
301
  category: "system",
@@ -310,12 +310,13 @@ You may receive steering messages while this task is running. Each one arrives w
310
310
  registerTemplate({
311
311
  eventType: "system.agent.steering.delivery",
312
312
  header: "",
313
- defaultBody: `[steering {{steeringMessageId}}] {{body}}
313
+ defaultBody: `[steering {{steeringMessageId}}] From {{sender}}: {{body}}
314
314
 
315
315
  (Once you have acted on this, call \`accept-steer\` with steeringMessageId "{{steeringMessageId}}".)`,
316
316
  variables: [
317
317
  { name: "steeringMessageId", description: "ID of the steering message being delivered" },
318
318
  { name: "body", description: "The steering message text as the sender wrote it" },
319
+ { name: "sender", description: "Sender name and kind (user, agent, or system)" },
319
320
  ],
320
321
  category: "system",
321
322
  });
@@ -19,11 +19,13 @@ import { resolveTemplateAsync } from "./resolver.ts";
19
19
  export async function renderSteeringDelivery(
20
20
  steeringMessageId: string,
21
21
  body: string,
22
+ sender = "Unknown sender",
22
23
  ): Promise<string> {
23
24
  try {
24
25
  const result = await resolveTemplateAsync("system.agent.steering.delivery", {
25
26
  steeringMessageId,
26
27
  body,
28
+ sender: sender.replace(/\s+/g, " ").trim(),
27
29
  });
28
30
  return result.skipped || !result.text.trim() ? body : result.text;
29
31
  } catch {
@@ -27,6 +27,7 @@
27
27
  export const CLAUDE_MANAGED_MODELS = [
28
28
  "claude-fable-5-1",
29
29
  "claude-mythos-5-1",
30
+ "claude-opus-5-5",
30
31
  "claude-opus-5",
31
32
  "claude-fable-5",
32
33
  "claude-mythos-5",
@@ -69,6 +70,7 @@ export interface ClaudeManagedModelPricing extends ClaudeManagedTokenPricing {
69
70
  * - claude-mythos-5-1: $10 / $50 / $0.25 / $12.50 (invite only, verified 2026-09-02)
70
71
  * - claude-fable-5: $10 / $50 / $1.00 / $12.50 (verified 2026-06-10)
71
72
  * - claude-mythos-5: $10 / $50 / $1.00 / $12.50 (limited availability, verified 2026-06-10)
73
+ * - claude-opus-5-5: $4 / $20 / $0.20 / $5.00 (verified 2026-09-22)
72
74
  * - claude-opus-5: $5 / $25 / $0.50 / $6.25 (verified 2026-07-25)
73
75
  * - claude-sonnet-5: $2 / $10 / $0.20 / $2.50 (standard rate, verified 2026-08-29)
74
76
  * - claude-sonnet-4-6: $3 / $15 / $0.30 / $3.75 (in / out / cache-read / cache-write)
@@ -90,6 +92,12 @@ export const CLAUDE_MANAGED_MODEL_PRICING: Record<ClaudeManagedModel, ClaudeMana
90
92
  cacheReadPerMillion: 0.25,
91
93
  cacheWritePerMillion: 12.5,
92
94
  },
95
+ "claude-opus-5-5": {
96
+ inputPerMillion: 4.0,
97
+ outputPerMillion: 20.0,
98
+ cacheReadPerMillion: 0.2,
99
+ cacheWritePerMillion: 5.0,
100
+ },
93
101
  "claude-opus-5": {
94
102
  inputPerMillion: 5.0,
95
103
  outputPerMillion: 25.0,
@@ -39,6 +39,7 @@ import {
39
39
  } from "../utils/context-window";
40
40
  import { SessionErrorTracker } from "../utils/error-tracker";
41
41
  import { summarizeSession as runSummarize } from "../utils/internal-ai";
42
+ import { getMemoryRaterNames } from "../utils/memory-raters";
42
43
  import { swarmRuntimeInstanceId } from "../utils/multi-runtime";
43
44
  import {
44
45
  detachedProcessGroup,
@@ -1797,11 +1798,7 @@ export class CodexSession implements ProviderSession {
1797
1798
  const _postRatings = this.summarizeDeps.postRatings ?? postRatings;
1798
1799
  const _buildRatings = this.summarizeDeps.buildRatingsFromLlm ?? buildRatingsFromLlm;
1799
1800
 
1800
- const memoryRaters = (process.env.MEMORY_RATERS ?? "")
1801
- .split(",")
1802
- .map((s) => s.trim())
1803
- .filter(Boolean);
1804
- const wantRatings = memoryRaters.includes("llm");
1801
+ const wantRatings = getMemoryRaterNames().includes("llm");
1805
1802
  const retrievals = wantRatings
1806
1803
  ? await _fetchRetrievals({ apiUrl, apiKey, agentId, taskId }).catch(() => [])
1807
1804
  : [];
@@ -2145,7 +2142,7 @@ class CodexSubprocessSession implements ProviderSession {
2145
2142
  ...(process.env.SKIP_SESSION_SUMMARY
2146
2143
  ? { SKIP_SESSION_SUMMARY: process.env.SKIP_SESSION_SUMMARY }
2147
2144
  : {}),
2148
- ...(process.env.MEMORY_RATERS ? { MEMORY_RATERS: process.env.MEMORY_RATERS } : {}),
2145
+ MEMORY_RATERS: getMemoryRaterNames().join(","),
2149
2146
  },
2150
2147
  stdin: "pipe",
2151
2148
  stdout: "pipe",
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Codex API-addressable models, verified from https://developers.openai.com/api/docs/models
3
- * and https://developers.openai.com/api/docs/deprecations as of 2026-09-05.
3
+ * and https://developers.openai.com/api/docs/deprecations as of 2026-09-23.
4
4
  *
5
5
  * NOTE: `gpt-5.3-codex-spark` is intentionally excluded. It is a ChatGPT Pro
6
6
  * research preview and is NOT API-addressable via the Codex SDK at launch.
@@ -20,6 +20,8 @@ import modelsDevCache from "../be/modelsdev-cache.json";
20
20
  */
21
21
  export const CODEX_MODELS = [
22
22
  "gpt-6-astra", // most capable model for complex reasoning, coding, and agentic work
23
+ "gpt-6-sol", // complex coding and agentic workflows
24
+ "gpt-6-luna", // focused, high-volume tasks
23
25
  "gpt-5.6-sol", // frontier GPT-5.6 tier for complex reasoning/coding
24
26
  "gpt-5.6-terra", // balanced GPT-5.6 tier
25
27
  "gpt-5.6-luna", // fast/cheap GPT-5.6 tier for high-volume workloads
@@ -83,6 +85,8 @@ const MODELSDEV_OPENAI_MODELS =
83
85
 
84
86
  const FALLBACK_CODEX_MODEL_CONTEXT_WINDOWS: Record<CodexModel, number> = {
85
87
  "gpt-6-astra": 1_050_000,
88
+ "gpt-6-sol": 1_050_000,
89
+ "gpt-6-luna": 1_050_000,
86
90
  "gpt-5.6-sol": 1_050_000,
87
91
  "gpt-5.6-terra": 1_050_000,
88
92
  "gpt-5.6-luna": 1_050_000,
@@ -153,6 +157,16 @@ export const FALLBACK_CODEX_MODEL_PRICING: Record<CodexModel, CodexModelPricing>
153
157
  cachedInputPerMillion: 1.0,
154
158
  outputPerMillion: 50.0,
155
159
  },
160
+ "gpt-6-sol": {
161
+ inputPerMillion: 2.0,
162
+ cachedInputPerMillion: 0.2,
163
+ outputPerMillion: 10.0,
164
+ },
165
+ "gpt-6-luna": {
166
+ inputPerMillion: 0.1,
167
+ cachedInputPerMillion: 0.01,
168
+ outputPerMillion: 0.5,
169
+ },
156
170
  "gpt-5.6-sol": {
157
171
  inputPerMillion: 4.0,
158
172
  cachedInputPerMillion: 0.4,
@@ -0,0 +1,248 @@
1
+ import { mkdtemp, rm, writeFile } from "node:fs/promises";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { DEFAULT_MODEL_TIER_MAP } from "../types";
5
+ import { getOpenRouterBaseUrl } from "../utils/openrouter-base-url";
6
+ import {
7
+ detachedProcessGroup,
8
+ registerProcessGroup,
9
+ terminateProcessGroup,
10
+ } from "../utils/process-group";
11
+ import { registerVolatileSecret, scrubSecrets } from "../utils/secret-scrubber";
12
+ import { resolveSlashSkillPrompt } from "./codex-skill-resolver";
13
+ import type {
14
+ CredStatus,
15
+ ProviderAdapter,
16
+ ProviderEvent,
17
+ ProviderResult,
18
+ ProviderSession,
19
+ ProviderSessionConfig,
20
+ ProviderTraits,
21
+ } from "./types";
22
+
23
+ // npm's `latest` is older and lacks the JSON/stdin contract used here.
24
+ export const DSH_PACKAGE = "@deepseek-ai/dsh@0.1.7-alpha.2";
25
+
26
+ export function checkDshCredentials(env: Record<string, string | undefined>): CredStatus {
27
+ return env.DEEPSEEK_API_KEY?.trim() || env.OPENROUTER_API_KEY?.trim()
28
+ ? { ready: true, missing: [], satisfiedBy: "env" }
29
+ : {
30
+ ready: false,
31
+ missing: ["DEEPSEEK_API_KEY", "OPENROUTER_API_KEY"],
32
+ hint: "Set DEEPSEEK_API_KEY or OPENROUTER_API_KEY for dsh.",
33
+ };
34
+ }
35
+
36
+ class DshSession implements ProviderSession {
37
+ sessionId: string | undefined;
38
+ private listeners: ((event: ProviderEvent) => void)[] = [];
39
+ private pending: ProviderEvent[] = [];
40
+ private output: string | undefined;
41
+ private failure: string | undefined;
42
+ private stderr = "";
43
+ private aborted = false;
44
+ private completion: Promise<ProviderResult>;
45
+
46
+ constructor(
47
+ private proc: Bun.Subprocess<"pipe", "pipe", "pipe">,
48
+ private directory: string,
49
+ prompt: string,
50
+ ) {
51
+ this.completion = this.run(prompt);
52
+ }
53
+
54
+ onEvent(listener: (event: ProviderEvent) => void): void {
55
+ this.listeners.push(listener);
56
+ for (const event of this.pending.splice(0)) listener(event);
57
+ }
58
+
59
+ private emit(event: ProviderEvent): void {
60
+ if (this.listeners.length === 0) this.pending.push(event);
61
+ else for (const listener of this.listeners) listener(event);
62
+ }
63
+
64
+ private consumeLine(line: string): void {
65
+ if (!line.trim()) return;
66
+ const clean = scrubSecrets(line);
67
+ this.emit({ type: "raw_log", content: clean });
68
+ try {
69
+ const event = JSON.parse(clean);
70
+ if (event.type === "session" && typeof event.sessionId === "string") {
71
+ this.sessionId = event.sessionId;
72
+ this.emit({ type: "session_init", sessionId: event.sessionId, provider: "dsh" });
73
+ } else if (event.type === "text" && typeof event.text === "string") {
74
+ this.emit({ type: "message", role: "assistant", content: event.text });
75
+ } else if (event.type === "final" && typeof event.text === "string") {
76
+ this.output = event.text;
77
+ } else if (event.type === "error" && typeof event.message === "string") {
78
+ this.failure = event.message;
79
+ } else if (event.type === "status" && typeof event.phase === "string") {
80
+ this.emit({ type: "progress", message: event.phase });
81
+ if (event.phase === "turn_end" && event.reason?.kind !== "completed") {
82
+ this.failure =
83
+ typeof event.reason?.error?.message === "string"
84
+ ? event.reason.error.message
85
+ : `dsh turn ended: ${event.reason?.kind ?? "unknown"}`;
86
+ }
87
+ }
88
+ } catch {
89
+ this.failure = "dsh emitted invalid JSON output";
90
+ }
91
+ }
92
+
93
+ private async readStdout(): Promise<void> {
94
+ const decoder = new TextDecoder();
95
+ let buffer = "";
96
+ for await (const chunk of this.proc.stdout) {
97
+ buffer += decoder.decode(chunk, { stream: true });
98
+ let newline = buffer.indexOf("\n");
99
+ while (newline >= 0) {
100
+ this.consumeLine(buffer.slice(0, newline));
101
+ buffer = buffer.slice(newline + 1);
102
+ newline = buffer.indexOf("\n");
103
+ }
104
+ }
105
+ this.consumeLine(buffer + decoder.decode());
106
+ }
107
+
108
+ private async readStderr(): Promise<void> {
109
+ const decoder = new TextDecoder();
110
+ for await (const chunk of this.proc.stderr) {
111
+ const content = scrubSecrets(decoder.decode(chunk, { stream: true }));
112
+ this.stderr = (this.stderr + content).slice(-8000);
113
+ this.emit({ type: "raw_stderr", content });
114
+ }
115
+ }
116
+
117
+ private async run(prompt: string): Promise<ProviderResult> {
118
+ try {
119
+ const [exitCode] = await Promise.all([
120
+ this.proc.exited,
121
+ this.readStdout(),
122
+ this.readStderr(),
123
+ (async () => {
124
+ this.proc.stdin.write(prompt);
125
+ await this.proc.stdin.end();
126
+ })(),
127
+ ]);
128
+ const isError = this.aborted || exitCode !== 0 || !!this.failure || this.output === undefined;
129
+ const failureReason = isError
130
+ ? this.aborted
131
+ ? "dsh session aborted"
132
+ : this.failure || this.stderr.trim() || `dsh exited ${exitCode} without a final result`
133
+ : undefined;
134
+ if (failureReason) this.emit({ type: "error", message: failureReason });
135
+ return {
136
+ exitCode: isError ? exitCode || 1 : 0,
137
+ sessionId: this.sessionId,
138
+ output: this.output,
139
+ isError,
140
+ failureReason,
141
+ };
142
+ } catch (error) {
143
+ await terminateProcessGroup(this.proc.pid);
144
+ const failureReason = scrubSecrets(String(error));
145
+ this.emit({ type: "error", message: failureReason });
146
+ return { exitCode: 1, sessionId: this.sessionId, isError: true, failureReason };
147
+ } finally {
148
+ await rm(this.directory, { recursive: true, force: true });
149
+ }
150
+ }
151
+
152
+ waitForCompletion(): Promise<ProviderResult> {
153
+ return this.completion;
154
+ }
155
+
156
+ async abort(): Promise<void> {
157
+ this.aborted = true;
158
+ await terminateProcessGroup(this.proc.pid);
159
+ }
160
+ }
161
+
162
+ export class DshAdapter implements ProviderAdapter {
163
+ readonly name = "dsh";
164
+ readonly traits: ProviderTraits = {
165
+ hasMcp: false,
166
+ nativeSkillDiscovery: false,
167
+ hasLocalEnvironment: true,
168
+ steerModes: [],
169
+ };
170
+
171
+ async createSession(config: ProviderSessionConfig): Promise<ProviderSession> {
172
+ const env = { ...process.env, ...config.env };
173
+ if (!checkDshCredentials(env).ready) {
174
+ throw new Error("dsh requires DEEPSEEK_API_KEY or OPENROUTER_API_KEY");
175
+ }
176
+ const model = config.model || DEFAULT_MODEL_TIER_MAP.dsh.regular;
177
+ const openrouter = model.startsWith("openrouter/");
178
+ const modelId = openrouter ? model.slice("openrouter/".length) : model;
179
+ const keyEnv = openrouter ? "OPENROUTER_API_KEY" : "DEEPSEEK_API_KEY";
180
+ if (!modelId.trim()) throw new Error("dsh requires a model ID after openrouter/");
181
+ if (!env[keyEnv]?.trim()) throw new Error(`dsh model ${model} requires ${keyEnv}`);
182
+ const binary = env.DSH_BINARY || Bun.which("dsh", { PATH: env.PATH });
183
+ if (!binary) {
184
+ throw new Error(
185
+ `dsh CLI not found. Install ${DSH_PACKAGE} during image provisioning or set DSH_BINARY to a trusted executable.`,
186
+ );
187
+ }
188
+ registerVolatileSecret(env[keyEnv]!, keyEnv);
189
+ const prompt = await resolveSlashSkillPrompt(config.prompt, {
190
+ providerLabel: "dsh",
191
+ skillsDir: join(env.HOME ?? "/home/worker", ".agents", "skills"),
192
+ });
193
+ const directory = await mkdtemp(join(tmpdir(), "swarm-dsh-"));
194
+ try {
195
+ const patchPath = join(directory, "patch.json");
196
+ // JSON is valid YAML. Values stay data, including arbitrary system prompts.
197
+ await writeFile(
198
+ patchPath,
199
+ JSON.stringify([
200
+ {
201
+ id: "agent-default-model",
202
+ config: { provider: openrouter ? "openrouter" : "deepseek-official", model: modelId },
203
+ },
204
+ { id: "system-prompt", config: { personaPrefix: config.systemPrompt } },
205
+ openrouter
206
+ ? {
207
+ id: "llm-pi-ai",
208
+ config: {
209
+ providers: {
210
+ openrouter: {
211
+ apiKeyEnv: keyEnv,
212
+ baseURL: getOpenRouterBaseUrl(env),
213
+ api: "openai-completions",
214
+ // Declare the selected ID even if the bundled catalog predates it.
215
+ models: [{ id: modelId }],
216
+ },
217
+ },
218
+ },
219
+ }
220
+ : { id: "llm-deepseek", config: { apiKeyEnv: keyEnv } },
221
+ ]),
222
+ { mode: 0o600 },
223
+ );
224
+ const proc = registerProcessGroup(
225
+ Bun.spawn([binary, "--profile", "headless", "--patch", patchPath, "--json", "-"], {
226
+ cwd: config.cwd,
227
+ env,
228
+ stdin: "pipe",
229
+ stdout: "pipe",
230
+ stderr: "pipe",
231
+ detached: detachedProcessGroup,
232
+ }),
233
+ );
234
+ return new DshSession(proc, directory, prompt);
235
+ } catch (error) {
236
+ await rm(directory, { recursive: true, force: true });
237
+ throw error;
238
+ }
239
+ }
240
+
241
+ async canResume(_sessionId: string): Promise<boolean> {
242
+ return false;
243
+ }
244
+
245
+ formatCommand(commandName: string): string {
246
+ return `/${commandName}`;
247
+ }
248
+ }
@@ -47,13 +47,17 @@ export async function createProviderAdapter(provider: string): Promise<ProviderA
47
47
  const { OpencodeAdapter } = await import("./opencode-adapter");
48
48
  return new OpencodeAdapter();
49
49
  }
50
+ case "dsh": {
51
+ const { DshAdapter } = await import("./dsh-adapter");
52
+ return new DshAdapter();
53
+ }
50
54
  case "acp": {
51
55
  const { ACPAdapter } = await import("./acp-adapter");
52
56
  return new ACPAdapter();
53
57
  }
54
58
  default:
55
59
  throw new Error(
56
- `Unknown HARNESS_PROVIDER: "${provider}". Supported: claude, pi, codex, devin, claude-managed, opencode, acp`,
60
+ `Unknown HARNESS_PROVIDER: "${provider}". Supported: claude, pi, codex, devin, claude-managed, opencode, acp, dsh`,
57
61
  );
58
62
  }
59
63
  }
@@ -1,5 +1,21 @@
1
1
  {
2
2
  "anthropic": {
3
+ "claude-opus-5-5": {
4
+ "id": "claude-opus-5-5",
5
+ "reasoning": true,
6
+ "reasoningOptions": [
7
+ {
8
+ "type": "effort",
9
+ "values": [
10
+ "low",
11
+ "medium",
12
+ "high",
13
+ "xhigh",
14
+ "max"
15
+ ]
16
+ }
17
+ ]
18
+ },
3
19
  "claude-sonnet-4-6": {
4
20
  "id": "claude-sonnet-4-6",
5
21
  "reasoning": true,
@@ -919,6 +935,40 @@
919
935
  ]
920
936
  }
921
937
  ]
938
+ },
939
+ "gpt-6-sol": {
940
+ "id": "gpt-6-sol",
941
+ "reasoning": true,
942
+ "reasoningOptions": [
943
+ {
944
+ "type": "effort",
945
+ "values": [
946
+ "none",
947
+ "low",
948
+ "medium",
949
+ "high",
950
+ "xhigh",
951
+ "max"
952
+ ]
953
+ }
954
+ ]
955
+ },
956
+ "gpt-6-luna": {
957
+ "id": "gpt-6-luna",
958
+ "reasoning": true,
959
+ "reasoningOptions": [
960
+ {
961
+ "type": "effort",
962
+ "values": [
963
+ "none",
964
+ "low",
965
+ "medium",
966
+ "high",
967
+ "xhigh",
968
+ "max"
969
+ ]
970
+ }
971
+ ]
922
972
  }
923
973
  },
924
974
  "openrouter": {
@@ -10,6 +10,7 @@ import type { ExtensionFactory } from "@earendil-works/pi-coding-agent";
10
10
  import { buildRatingsFromLlm, fetchRetrievalsForTask, postRatings } from "../be/memory/raters/llm";
11
11
  import { checkToolLoop, clearToolHistory } from "../hooks/tool-loop-detection";
12
12
  import { summarizeSession as runSummarize } from "../utils/internal-ai";
13
+ import { getMemoryRaterNames } from "../utils/memory-raters";
13
14
  import { scrubSecrets } from "../utils/secret-scrubber";
14
15
 
15
16
  export interface SwarmHooksConfig {
@@ -341,11 +342,7 @@ export async function summarizeSessionForPi(
341
342
 
342
343
  const taskDetails = await fetchTaskDetails(config).catch(() => null);
343
344
 
344
- const memoryRaters = (process.env.MEMORY_RATERS ?? "")
345
- .split(",")
346
- .map((s) => s.trim())
347
- .filter(Boolean);
348
- const wantRatings = memoryRaters.includes("llm");
345
+ const wantRatings = getMemoryRaterNames().includes("llm");
349
346
  const retrievals = wantRatings
350
347
  ? await _fetchRetrievals({
351
348
  apiUrl: config.apiUrl,