@desplega.ai/agent-swarm 1.173.0 → 2.1.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 (511) hide show
  1. package/README.md +1 -1
  2. package/dist/{acp-adapter-ccm9xrep.js → acp-adapter-kr4abrsk.js} +17 -16
  3. package/dist/{actions-sgeyv08k.js → actions-eh4g6w2r.js} +39 -34
  4. package/dist/{amp-adapter-gpxp3kc9.js → amp-adapter-7h7wdt8q.js} +8 -7
  5. package/dist/{app-km9qnv2f.js → app-7k8s9w5p.js} +18 -14
  6. package/dist/{assistant-5r8tcvvd.js → assistant-wswt2y7p.js} +40 -35
  7. package/dist/{boot-reembed-16rv9843.js → boot-reembed-9apm9qw6.js} +10 -9
  8. package/dist/{boot-reembed-swwzdgd7.js → boot-reembed-whzbdthj.js} +10 -9
  9. package/dist/{boot-scrub-sweep-zkr6vkqb.js → boot-scrub-sweep-ndzmvmgt.js} +11 -10
  10. package/dist/{boot-seeds-d8sp49t2.js → boot-seeds-e9sta0yt.js} +16 -13
  11. package/dist/{claude-adapter-yzzzh8jp.js → claude-adapter-4mqd3r6r.js} +19 -18
  12. package/dist/{claude-managed-adapter-xgxhqrt2.js → claude-managed-adapter-9wswb52m.js} +7 -5
  13. package/dist/{claude-managed-setup-bnmjarjc.js → claude-managed-setup-tpe1effx.js} +6 -4
  14. package/dist/{claude-sdk-session-4whxere4.js → claude-sdk-session-q49ghmh9.js} +12402 -11850
  15. package/dist/{cli-ne7smj1b.js → cli-01xvj1rq.js} +10 -10
  16. package/dist/{cli-nwrdx840.js → cli-035vekcw.js} +3 -3
  17. package/dist/{cli-9xf7fdtp.js → cli-0pd8hzhc.js} +29 -6
  18. package/dist/{cli-tmhsxhb8.js → cli-0veb92a3.js} +28 -6
  19. package/dist/{cli-c3rk1v0x.js → cli-10jesr25.js} +3 -3
  20. package/dist/{cli-6thk4jz3.js → cli-1y7yywmj.js} +6 -6
  21. package/dist/{cli-6r2f7edk.js → cli-20krdhz5.js} +47 -19
  22. package/dist/{cli-rfs4vddv.js → cli-29rja109.js} +39 -20
  23. package/dist/cli-2m1ktfzz.js +17795 -0
  24. package/dist/{cli-na2pxe4f.js → cli-2pwa0q4d.js} +15 -4
  25. package/dist/{cli-7a93cv8c.js → cli-4mengw46.js} +441 -43
  26. package/dist/{cli-94b48jhk.js → cli-5twdke5x.js} +16 -14
  27. package/dist/{cli-7a0sde2x.js → cli-6cagzc96.js} +9 -0
  28. package/dist/cli-6cvfxs8r.js +47 -0
  29. package/dist/{cli-w1apjecb.js → cli-711vwbxn.js} +2 -2
  30. package/dist/{cli-r4fqfpwf.js → cli-78vv7446.js} +50 -27
  31. package/dist/{cli-srqq3gc5.js → cli-7n6s5man.js} +5 -5
  32. package/dist/{cli-m89t9jdf.js → cli-7x0g4sn1.js} +15416 -16024
  33. package/dist/{cli-2bw3w47j.js → cli-8wwxw8a3.js} +1 -1
  34. package/dist/{cli-yatxqynm.js → cli-9ha6hs2d.js} +1 -290
  35. package/dist/{cli-ywm1azg9.js → cli-9jzdj90z.js} +8 -4
  36. package/dist/cli-9traj3dn.js +638 -0
  37. package/dist/{cli-smcrrmhy.js → cli-agzebbd5.js} +9 -9
  38. package/dist/{cli-c5km5znr.js → cli-c8r3kzzb.js} +1 -1
  39. package/dist/cli-cvv9k0hh.js +10143 -0
  40. package/dist/{cli-anzdk0z4.js → cli-d9286m9h.js} +2 -2
  41. package/dist/cli-e3g5mbkz.js +776 -0
  42. package/dist/cli-f527ce74.js +781 -0
  43. package/dist/{cli-gmdajfw5.js → cli-gxzkg1de.js} +5020 -1729
  44. package/dist/{cli-451ks6aw.js → cli-h1arqn31.js} +1 -1
  45. package/dist/cli-hjwmhcg1.js +10622 -0
  46. package/dist/{cli-jpc4r224.js → cli-hqr88ew6.js} +19 -3
  47. package/dist/{cli-h7k0xtry.js → cli-hvqbtna4.js} +4 -1256
  48. package/dist/{cli-cd0hv9nh.js → cli-j67mh2vg.js} +2 -2
  49. package/dist/cli-jta2eyzc.js +619 -0
  50. package/dist/{cli-wd0hz6ah.js → cli-kbrt8gqa.js} +9 -91
  51. package/dist/cli-kceah1eh.js +92 -0
  52. package/dist/{cli-d603qf86.js → cli-ksphgh48.js} +10 -8
  53. package/dist/{cli-3nxdmjrc.js → cli-mgz4nbgg.js} +4 -4
  54. package/dist/{cli-saqyage0.js → cli-mz5as5ha.js} +179 -27
  55. package/dist/cli-n2wq4j7m.js +6985 -0
  56. package/dist/{cli-ppy4nnnh.js → cli-n8ndw8j7.js} +2 -2
  57. package/dist/{cli-1w0vj3gw.js → cli-naqzr17j.js} +7 -7
  58. package/dist/{cli-0a7mm3zp.js → cli-nm1p8jfr.js} +25 -21
  59. package/dist/{cli-wrh08zjd.js → cli-p3zbc1rw.js} +5 -18
  60. package/dist/{cli-hsem16hb.js → cli-pe05f8yk.js} +29 -6
  61. package/dist/{cli-5wpw4rab.js → cli-qmzsbkvy.js} +5 -5
  62. package/dist/{cli-bv2etw2y.js → cli-qnm4e9e4.js} +99 -590
  63. package/dist/{cli-1x7da0de.js → cli-qqy4q48b.js} +8 -8
  64. package/dist/{cli-r44t9wqc.js → cli-r106725k.js} +2 -2
  65. package/dist/{cli-5er5gjbm.js → cli-r35rw5de.js} +15 -15
  66. package/dist/{cli-v3zhnxsb.js → cli-r610p9bs.js} +2 -2
  67. package/dist/{cli-7jykv7ef.js → cli-rc6pf5kv.js} +1 -1
  68. package/dist/{cli-x119kdba.js → cli-rdxm77k3.js} +1 -1
  69. package/dist/cli-rhs9pz33.js +294 -0
  70. package/dist/{cli-0p3enk35.js → cli-s69nfyeh.js} +9 -1
  71. package/dist/{cli-0kxf81jj.js → cli-sawv63e8.js} +2 -2
  72. package/dist/{cli-e3pmyt39.js → cli-sg19gbf0.js} +1 -1
  73. package/dist/{cli-d161g69q.js → cli-shk7r5cs.js} +57 -6
  74. package/dist/{cli-7pz3b7x5.js → cli-sksetb2q.js} +36 -1
  75. package/dist/{cli-014vns2y.js → cli-stfs0k5s.js} +208 -525
  76. package/dist/{cli-db3m6zdt.js → cli-t02z59f2.js} +1 -1
  77. package/dist/{cli-b07hr3bt.js → cli-txqb9s38.js} +2 -2
  78. package/dist/{cli-s8z6x4b4.js → cli-v7g551te.js} +225 -113
  79. package/dist/{cli-rfz2ve55.js → cli-vgqzp4em.js} +3341 -955
  80. package/dist/{cli-7avy4v8w.js → cli-w1q7h2r2.js} +5 -3
  81. package/dist/{cli-rcp5aqdw.js → cli-w7m81tb7.js} +1 -1
  82. package/dist/cli-wfnemr1t.js +86 -0
  83. package/dist/cli-wmgrkscj.js +23254 -0
  84. package/dist/{cli-qm1448f9.js → cli-wms6x9db.js} +8 -8
  85. package/dist/{cli-tadfgd0t.js → cli-x1r545x8.js} +33 -4
  86. package/dist/{cli-xc7p7s3g.js → cli-xczsgshn.js} +6 -6
  87. package/dist/{cli-fmhj1ehj.js → cli-y3167wt1.js} +882 -271
  88. package/dist/{cli-r0byd61h.js → cli-yjmqpxt3.js} +17 -16
  89. package/dist/{cli-81r1wjyv.js → cli-z780ec7c.js} +1 -1
  90. package/dist/{cli-phcqp1b9.js → cli-zm9t2vde.js} +2 -2
  91. package/dist/cli.js +34 -49
  92. package/dist/{codex-adapter-r3dn4fp5.js → codex-adapter-4z16v9n0.js} +15 -14
  93. package/dist/{codex-login-841kv5fk.js → codex-login-pkepy2j1.js} +3 -2
  94. package/dist/{codex-session-runner-fwt793h4.js → codex-session-runner-rvms9y2x.js} +15 -14
  95. package/dist/{commands-z8fq9qna.js → commands-2a9rtyat.js} +11 -10
  96. package/dist/{controller-hq5ggpcp.js → controller-3k3madbn.js} +5 -4
  97. package/dist/{controllers-connect-3mf2btyj.js → controllers-connect-v9yn8zb9.js} +42 -37
  98. package/dist/{cursor-adapter-q8pgv5qa.js → cursor-adapter-98gbhyzn.js} +7 -6
  99. package/dist/{db-qfpq4bt7.js → db-eywwsnjw.js} +30 -9
  100. package/dist/{db-yyhqqrbf.js → db-ncypk9np.js} +12 -11
  101. package/dist/{devin-adapter-xgtj680j.js → devin-adapter-zeq8b9gz.js} +3 -2
  102. package/dist/{dispatcher-x0x7qfcq.js → dispatcher-w94kc575.js} +38 -33
  103. package/dist/{docker-f503k9p0.js → docker-b1e4cqab.js} +3 -2
  104. package/dist/{dsh-adapter-34etvb5m.js → dsh-adapter-47ztej36.js} +7 -6
  105. package/dist/{e2b-66xra4az.js → e2b-bbt8ey45.js} +4 -3
  106. package/dist/{e2b-xwhyj8cw.js → e2b-dp804sen.js} +4 -3
  107. package/dist/{event-bus-vjtv82gm.js → event-bus-j2jdg3qb.js} +3 -2
  108. package/dist/{external-channel-h1fjecwe.js → external-channel-zrkg8ar9.js} +11 -10
  109. package/dist/{google-generative-ai-szdxbpqg.js → google-generative-ai-g8db7x0f.js} +4 -2
  110. package/dist/{google-vertex-qzw3p36d.js → google-vertex-r2692q0r.js} +4 -2
  111. package/dist/{grok-adapter-e7mr287e.js → grok-adapter-s9ncp9vy.js} +18 -17
  112. package/dist/{handlers-znb9n7d4.js → handlers-kqftvjgw.js} +41 -36
  113. package/dist/{heartbeat-bm4qkn8d.js → heartbeat-9q96p8v9.js} +43 -38
  114. package/dist/{hook-254r4mza.js → hook-56qe10dp.js} +11 -23
  115. package/dist/{hook-xaa3q80s.js → hook-yy6rw42k.js} +12 -11
  116. package/dist/{http-3dgrgp8y.js → http-r2dnb8f8.js} +2411 -275
  117. package/dist/{index-fx3jqq1e.js → index-3gtmkhc6.js} +38 -33
  118. package/dist/{index-bdsqa799.js → index-3k5hkz7r.js} +43 -38
  119. package/dist/index-52j1aja4.js +3465 -0
  120. package/dist/{index-g2byveez.js → index-5e101240.js} +38 -33
  121. package/dist/{index-2ybk7khy.js → index-5wyfjc2c.js} +845 -683
  122. package/dist/index-9gw58n4k.js +193 -0
  123. package/dist/index-9j87mcm8.js +56305 -0
  124. package/dist/index-bsmcresk.js +79424 -0
  125. package/dist/index-mh85qhec.js +475 -0
  126. package/dist/{index-jd7sejm2.js → index-vxvhxxbn.js} +10 -9
  127. package/dist/index-we27kd31.js +12810 -0
  128. package/dist/{keepalive-6ywhpja1.js → keepalive-psj6j54c.js} +12 -11
  129. package/dist/{lead-cw45n21s.js → lead-hajz4688.js} +61 -56
  130. package/dist/{maintenance-ss1a1ge9.js → maintenance-ps02sb5m.js} +10 -9
  131. package/dist/{node-fkajaq96.js → node-mwb5r697.js} +2 -1
  132. package/dist/{oauth-refresh-sweep-3c6f8vyy.js → oauth-refresh-sweep-0284h93b.js} +11 -10
  133. package/dist/{onboard-8hzdhc1k.js → onboard-rbf6bg01.js} +11 -3
  134. package/dist/{opencode-adapter-qbchbcfz.js → opencode-adapter-13dcatgq.js} +18 -13
  135. package/dist/{otel-impl-e6mnvc4v.js → otel-impl-zvqcbhp7.js} +242 -868
  136. package/dist/{pi-mono-adapter-3c9g9snh.js → pi-mono-adapter-xxy47q4v.js} +244 -106
  137. package/dist/{pricing-refresh-gedkjdw0.js → pricing-refresh-kefx9v3t.js} +12 -11
  138. package/dist/{rbac-roles-dt4vh1yy.js → rbac-roles-3m36rxm2.js} +11 -10
  139. package/dist/{rbac-roles-eszdg6pm.js → rbac-roles-z76xv0hq.js} +12 -11
  140. package/dist/{render-v2-907cy6sa.js → render-v2-wz73bs25.js} +18 -14
  141. package/dist/{resume-42stcaz0.js → resume-k4wzge8w.js} +25 -21
  142. package/dist/{runtime-qfry88v2.js → runtime-sa2vr16g.js} +2 -2
  143. package/dist/{setup-adbc1c10.js → setup-2fp2pypp.js} +2 -2
  144. package/dist/{virtual-modules-rtmt494q.js → virtual-modules-9gkxqrap.js} +6 -5
  145. package/dist/{work-objects-wpj8ck95.js → work-objects-6k0ywz3m.js} +41 -36
  146. package/dist/{worker-bzdra9rf.js → worker-5v3rxsdh.js} +61 -56
  147. package/dist/{x-qfmygqqv.js → x-4mtdeym1.js} +3 -2
  148. package/openapi.json +1279 -329
  149. package/package.json +15 -15
  150. package/src/agentmail/handlers.ts +21 -11
  151. package/src/apps/definition.ts +16 -0
  152. package/src/azure-devops/api.ts +52 -2
  153. package/src/azure-devops/boards-sync.ts +50 -20
  154. package/src/azure-devops/index.ts +1 -0
  155. package/src/azure-devops/outbound.ts +95 -0
  156. package/src/be/boot-seeds.ts +11 -0
  157. package/src/be/config-refs.ts +60 -0
  158. package/src/be/db/model-profiles.ts +315 -0
  159. package/src/be/db/page-versions.ts +15 -0
  160. package/src/be/db/runtime.ts +35 -8
  161. package/src/be/db/skill-name-resolution.ts +36 -0
  162. package/src/be/db/tasks/read.ts +237 -0
  163. package/src/be/db/tasks/write.ts +7 -0
  164. package/src/be/db.ts +87 -36
  165. package/src/be/migrations/215_swarm_config_export_to_env.sql +34 -0
  166. package/src/be/migrations/216_task_resolved_effort.sql +5 -0
  167. package/src/be/migrations/217_chat_sdk_state.sql +104 -0
  168. package/src/be/migrations/219_relabel_pi_context_compactions.sql +22 -0
  169. package/src/be/migrations/220_model_profiles.sql +137 -0
  170. package/src/be/model-catalog-store.ts +5 -1
  171. package/src/be/model-tier-resolution.ts +155 -10
  172. package/src/be/model-validation.ts +12 -2
  173. package/src/be/models-catalog.ts +26 -1
  174. package/src/be/modelsdev-cache.json +198 -63
  175. package/src/be/modelsdev-cache.ts +9 -1
  176. package/src/be/script-credential-broker.ts +39 -2
  177. package/src/be/scripts/run-saved.ts +1 -0
  178. package/src/be/scripts/typecheck.ts +22 -8
  179. package/src/be/secret-registry.ts +6 -2
  180. package/src/be/seed/runner.ts +13 -1
  181. package/src/be/seed/state-db.ts +5 -0
  182. package/src/be/seed/types.ts +6 -0
  183. package/src/be/seed-model-profiles.ts +41 -0
  184. package/src/be/seed-pricing.ts +19 -2
  185. package/src/be/seed-scripts/catalog/heartbeat-jev-gate.ts +368 -0
  186. package/src/be/seed-scripts/catalog/ops-catalog-audit.inline.ts +1 -1
  187. package/src/be/seed-scripts/catalog/ops-catalog-audit.ts +1 -1
  188. package/src/be/seed-scripts/index.ts +9 -0
  189. package/src/be/seed-skills/bundled-files.generated.json +0 -18
  190. package/src/be/seed-skills/index.ts +104 -3
  191. package/src/be/swarm-config-guard.ts +53 -0
  192. package/src/cli.tsx +0 -16
  193. package/src/commands/onboard/non-interactive.ts +4 -2
  194. package/src/commands/provider-credentials.ts +52 -6
  195. package/src/commands/runner.ts +193 -71
  196. package/src/e2b/env.ts +5 -0
  197. package/src/extensions/catalog.generated.json +17 -0
  198. package/src/extensions/contract-types.generated.ts +1 -1
  199. package/src/extensions/contract.ts +45 -0
  200. package/src/extensions/dispatcher.ts +7 -0
  201. package/src/extensions/loader.ts +10 -5
  202. package/src/extensions/post-bridge.ts +40 -0
  203. package/src/github/handlers.ts +11 -4
  204. package/src/heartbeat/heartbeat.ts +2 -1
  205. package/src/heartbeat/templates.ts +8 -5
  206. package/src/hooks/hook.ts +0 -26
  207. package/src/http/agents.ts +49 -2
  208. package/src/http/all-routes.ts +1 -1
  209. package/src/http/apps.ts +30 -3
  210. package/src/http/config.ts +62 -19
  211. package/src/http/core.ts +8 -0
  212. package/src/http/index.ts +25 -3
  213. package/src/http/integrations.ts +88 -1
  214. package/src/http/mcp.ts +15 -5
  215. package/src/http/model-profiles.ts +303 -0
  216. package/src/http/page-proxy.ts +2 -4
  217. package/src/http/pages-public.ts +13 -7
  218. package/src/http/pages.ts +3 -13
  219. package/src/http/poll.ts +42 -71
  220. package/src/http/requested-by.ts +54 -0
  221. package/src/http/script-runs.ts +1 -1
  222. package/src/http/scripts.ts +26 -2
  223. package/src/http/stats.ts +1 -30
  224. package/src/http/tasks.ts +79 -5
  225. package/src/http/utils.ts +14 -0
  226. package/src/http/webhooks.ts +160 -3
  227. package/src/http/x.ts +1 -0
  228. package/src/integrations/chat-sdk/adapters.ts +129 -0
  229. package/src/integrations/chat-sdk/attachments.ts +232 -0
  230. package/src/integrations/chat-sdk/background.ts +36 -0
  231. package/src/integrations/chat-sdk/commands.ts +194 -0
  232. package/src/integrations/chat-sdk/config.ts +198 -0
  233. package/src/integrations/chat-sdk/discord-api.ts +63 -0
  234. package/src/integrations/chat-sdk/discord-gateway.ts +185 -0
  235. package/src/integrations/chat-sdk/handlers.ts +28 -0
  236. package/src/integrations/chat-sdk/inbound.ts +426 -0
  237. package/src/integrations/chat-sdk/limits.ts +48 -0
  238. package/src/integrations/chat-sdk/logger.ts +81 -0
  239. package/src/integrations/chat-sdk/outbound.ts +123 -0
  240. package/src/integrations/chat-sdk/relay.ts +172 -0
  241. package/src/integrations/chat-sdk/router.ts +169 -0
  242. package/src/integrations/chat-sdk/runtime.ts +351 -0
  243. package/src/integrations/chat-sdk/schema.ts +245 -0
  244. package/src/integrations/chat-sdk/state.ts +243 -0
  245. package/src/integrations/chat-sdk/status.ts +244 -0
  246. package/src/integrations/chat-sdk/steering.ts +58 -0
  247. package/src/integrations/chat-sdk/teams-origin.ts +77 -0
  248. package/src/integrations/chat-sdk/telegram-api.ts +56 -0
  249. package/src/integrations/chat-sdk/templates.ts +16 -0
  250. package/src/integrations/chat-sdk/test-hooks.ts +37 -0
  251. package/src/integrations/chat-sdk/thread-buffer.ts +100 -0
  252. package/src/integrations/chat-sdk/typing.ts +65 -0
  253. package/src/{artifact-sdk → pages}/feedback-overlay.ts +65 -6
  254. package/src/pages/version.ts +4 -5
  255. package/src/prompts/base-prompt.ts +111 -45
  256. package/src/providers/acp-target-catalog.ts +6 -0
  257. package/src/providers/acp-targets.ts +56 -3
  258. package/src/providers/amp-adapter.ts +1 -1
  259. package/src/providers/claude-adapter.ts +1 -1
  260. package/src/providers/claude-flag-settings.ts +17 -5
  261. package/src/providers/claude-managed-adapter.ts +1 -1
  262. package/src/providers/claude-session-events.ts +6 -1
  263. package/src/providers/dsh-adapter.ts +1 -1
  264. package/src/providers/opencode-adapter.ts +243 -26
  265. package/src/providers/opencode-swarm-plugin.ts +31 -0
  266. package/src/providers/pi-mono-adapter.ts +398 -153
  267. package/src/providers/pi-mono-extension.ts +17 -3
  268. package/src/providers/pricing-sources.md +33 -2
  269. package/src/providers/reasoning-effort.ts +37 -0
  270. package/src/providers/types.ts +6 -2
  271. package/src/rbac/legacy-policy.ts +16 -2
  272. package/src/rbac/permissions.ts +26 -0
  273. package/src/scheduler/deferred-task-waits.ts +18 -5
  274. package/src/scheduler/scheduler.ts +11 -3
  275. package/src/scripts-runtime/executors/quickjs-prelude.ts +75 -6
  276. package/src/scripts-runtime/executors/quickjs-runner.ts +85 -8
  277. package/src/scripts-runtime/executors/quickjs-web-shims.ts +1041 -0
  278. package/src/scripts-runtime/extract-args-schema.ts +9 -8
  279. package/src/scripts-runtime/loader.ts +19 -7
  280. package/src/scripts-runtime/quickjs-compat.ts +464 -0
  281. package/src/scripts-runtime/sdk-allowlist.ts +12 -6
  282. package/src/scripts-runtime/swarm-sdk.ts +0 -11
  283. package/src/scripts-runtime/types/stdlib.d.ts +39 -15
  284. package/src/scripts-runtime/types/swarm-extension.d.ts +66 -1
  285. package/src/scripts-runtime/types/swarm-sdk.d.ts +39 -15
  286. package/src/server.ts +62 -19
  287. package/src/slack/blocks.ts +4 -2
  288. package/src/slack/event-dedup.ts +1 -1
  289. package/src/slack/reaction-shortcode.ts +14 -0
  290. package/src/slack/render-v2.ts +12 -7
  291. package/src/slack/responses.ts +5 -4
  292. package/src/slack/thread-buffer.ts +41 -22
  293. package/src/tasks/additive-buffer.ts +4 -2
  294. package/src/tasks/context-key.ts +60 -1
  295. package/src/tasks/model-pin.ts +67 -0
  296. package/src/tasks/worker-follow-up.ts +15 -33
  297. package/src/tests/acp-adapter.test.ts +42 -0
  298. package/src/tests/agentmail-filters.test.ts +47 -0
  299. package/src/tests/api-drain-worker-e2e.test.ts +1 -6
  300. package/src/tests/apps-spike2.test.ts +35 -0
  301. package/src/tests/azure-devops-outbound.test.ts +420 -0
  302. package/src/tests/base-prompt.test.ts +58 -54
  303. package/src/tests/chat-sdk-commands.test.ts +191 -0
  304. package/src/tests/chat-sdk-config.test.ts +334 -0
  305. package/src/tests/chat-sdk-discord-api.test.ts +68 -0
  306. package/src/tests/chat-sdk-discord-gateway.test.ts +252 -0
  307. package/src/tests/chat-sdk-discord-webhook.test.ts +126 -0
  308. package/src/tests/chat-sdk-fields-sync.test.ts +50 -0
  309. package/src/tests/chat-sdk-harness.ts +146 -0
  310. package/src/tests/chat-sdk-inbound.test.ts +363 -0
  311. package/src/tests/chat-sdk-relay.test.ts +470 -0
  312. package/src/tests/chat-sdk-reload.test.ts +128 -0
  313. package/src/tests/chat-sdk-shutdown.test.ts +220 -0
  314. package/src/tests/chat-sdk-slack.test.ts +268 -0
  315. package/src/tests/chat-sdk-state.test.ts +163 -0
  316. package/src/tests/chat-sdk-status-route.test.ts +382 -0
  317. package/src/tests/chat-sdk-teams.test.ts +277 -0
  318. package/src/tests/chat-sdk-tools.test.ts +520 -0
  319. package/src/tests/chat-sdk-typing.test.ts +120 -0
  320. package/src/tests/chat-sdk-webhook-telegram.test.ts +200 -0
  321. package/src/tests/claude-adapter-binary.test.ts +9 -4
  322. package/src/tests/claude-flag-settings.test.ts +11 -3
  323. package/src/tests/claude-managed-adapter.test.ts +1 -1
  324. package/src/tests/claude-sdk-lifecycle.test.ts +9 -3
  325. package/src/tests/claude-thinking-tokens.test.ts +57 -0
  326. package/src/tests/claude-worker-parity.test.ts +2 -7
  327. package/src/tests/config-env-export-chat-sdk.test.ts +11 -0
  328. package/src/tests/config-refs.test.ts +66 -0
  329. package/src/tests/context-key.test.ts +19 -0
  330. package/src/tests/cors-allowlist.test.ts +25 -0
  331. package/src/tests/create-page-tool.test.ts +18 -0
  332. package/src/tests/credential-check.test.ts +139 -0
  333. package/src/tests/credentials.test.ts +21 -0
  334. package/src/tests/db-runtime.test.ts +61 -0
  335. package/src/tests/db-task-read-contract.test.ts +22 -0
  336. package/src/tests/db-task-write-contract.test.ts +11 -0
  337. package/src/tests/deferred-task-wake.test.ts +78 -1
  338. package/src/tests/docs-index-footprint.test.js +3 -3
  339. package/src/tests/dsh-adapter.test.ts +1 -1
  340. package/src/tests/enabled-capabilities.test.ts +20 -0
  341. package/src/tests/entrypoint-api-readiness.test.ts +14 -8
  342. package/src/tests/entrypoint-config-env-export.test.ts +5 -2
  343. package/src/tests/entrypoint-export-to-env.test.ts +78 -0
  344. package/src/tests/env-flag.test.ts +1 -0
  345. package/src/tests/explicit-model-validation.test.ts +105 -1
  346. package/src/tests/extensions-catalog.test.ts +1 -0
  347. package/src/tests/extensions-example-comms-adherence-gate.test.ts +413 -0
  348. package/src/tests/extensions-example-route-chat-channel.test.ts +154 -0
  349. package/src/tests/extensions-loader.test.ts +15 -0
  350. package/src/tests/extensions-post-bridge.test.ts +51 -0
  351. package/src/tests/fetch-resolved-env.test.ts +128 -0
  352. package/src/tests/fixtures/chat-sdk/telegram-private-text.json +10 -0
  353. package/src/tests/fixtures/extensions/route-chat-channel-to-agent/hooks.ts +27 -0
  354. package/src/tests/fixtures/extensions/route-chat-channel-to-agent/manifest.json +9 -0
  355. package/src/tests/fixtures/openai-compatible-registry-extension.child.ts +146 -0
  356. package/src/tests/fixtures/runner-legacy-resume-prompt.ts +122 -0
  357. package/src/tests/github-handlers.test.ts +35 -0
  358. package/src/tests/harness-provider-resolution.test.ts +12 -0
  359. package/src/tests/heartbeat-checklist.test.ts +3 -2
  360. package/src/tests/heartbeat-jev-gate-credentials.test.ts +168 -0
  361. package/src/tests/heartbeat-jev-gate.test.ts +385 -0
  362. package/src/tests/hook-runtime-close.test.ts +0 -2
  363. package/src/tests/http-api-integration.test.ts +0 -25
  364. package/src/tests/migration-046-budgets.test.ts +17 -16
  365. package/src/tests/migration-217-chat-sdk-state.test.ts +113 -0
  366. package/src/tests/model-profile-backcompat.test.ts +327 -0
  367. package/src/tests/model-profile-providers.test.ts +302 -0
  368. package/src/tests/model-profile-runtime-secrets.test.ts +223 -0
  369. package/src/tests/model-profiles-api.test.ts +614 -0
  370. package/src/tests/model-tier-resolution.test.ts +93 -0
  371. package/src/tests/models-catalog.test.ts +42 -1
  372. package/src/tests/openai-compatible-providers.test.ts +134 -0
  373. package/src/tests/openai-compatible-registry-extension.test.ts +42 -0
  374. package/src/tests/opencode-adapter.test.ts +216 -2
  375. package/src/tests/opencode-helmcode-sdk.test.ts +201 -0
  376. package/src/tests/opencode-shell-env.test.ts +145 -0
  377. package/src/tests/openrouter-base-url.test.ts +101 -151
  378. package/src/tests/page-proxy.test.ts +1 -1
  379. package/src/tests/pages-browser-sdk.test.ts +76 -0
  380. package/src/tests/pages-feedback-keys.test.ts +121 -0
  381. package/src/tests/pages-feedback.test.ts +4 -1
  382. package/src/tests/paused-tasks-requested-by.test.ts +102 -0
  383. package/src/tests/pi-context-compaction.test.ts +193 -0
  384. package/src/tests/pi-custom-provider-fake-server.test.ts +442 -0
  385. package/src/tests/pi-mono-adapter.test.ts +385 -5
  386. package/src/tests/pi-shell-env.test.ts +170 -0
  387. package/src/tests/profile-claim.test.ts +269 -0
  388. package/src/tests/prompt-template-remaining.test.ts +35 -0
  389. package/src/tests/quickjs-compat.test.ts +213 -0
  390. package/src/tests/rbac-engine.test.ts +32 -3
  391. package/src/tests/runner-exit-after-tasks.test.ts +0 -4
  392. package/src/tests/runner-legacy-resume-prompt.test.ts +64 -0
  393. package/src/tests/script-connections.test.ts +6 -0
  394. package/src/tests/script-executor-conformance.test.ts +252 -1
  395. package/src/tests/script-executor-quickjs.test.ts +96 -0
  396. package/src/tests/script-runs-http.test.ts +89 -0
  397. package/src/tests/scripts-http.test.ts +217 -1
  398. package/src/tests/scripts-only-gating.test.ts +2 -3
  399. package/src/tests/scripts-runtime.test.ts +58 -40
  400. package/src/tests/secret-scrubber.test.ts +96 -0
  401. package/src/tests/seed-model-profiles.test.ts +174 -0
  402. package/src/tests/seed-scripts.test.ts +2 -2
  403. package/src/tests/seed-skills-bundled-files.test.ts +45 -53
  404. package/src/tests/seed-skills-retire.test.ts +182 -0
  405. package/src/tests/send-task-requester-gate.test.ts +58 -0
  406. package/src/tests/session-cost-recompute-unit.test.ts +46 -0
  407. package/src/tests/skill-get-name-resolution.test.ts +137 -0
  408. package/src/tests/skill-invocations.test.ts +4 -2
  409. package/src/tests/slack-blocks.test.ts +36 -0
  410. package/src/tests/slack-inline-output.test.ts +14 -0
  411. package/src/tests/slack-reaction-config.test.ts +20 -0
  412. package/src/tests/slack-render-v2.test.ts +37 -0
  413. package/src/tests/slack-thread-buffer.test.ts +98 -1
  414. package/src/tests/sonnet-5-5-registry.test.ts +9 -1
  415. package/src/tests/swarm-config-export-to-env.test.ts +267 -0
  416. package/src/tests/swarm-config-reserved-keys.test.ts +16 -0
  417. package/src/tests/swarm-diff.test.ts +1 -1
  418. package/src/tests/task-model-effort-rerun.test.ts +164 -0
  419. package/src/tests/task-session-prompts.test.ts +132 -0
  420. package/src/tests/task-tool-manifest.test.ts +14 -0
  421. package/src/tests/task-tools-ctx.test.ts +2 -0
  422. package/src/tests/tool-annotations.test.ts +6 -6
  423. package/src/tests/ui-logs-parser.test.ts +43 -0
  424. package/src/tests/used-by-route.test.ts +6 -0
  425. package/src/tests/vercel-ai-gateway.test.ts +149 -0
  426. package/src/tests/workflow-llm.test.ts +61 -0
  427. package/src/tests/workflow-swarm-script.test.ts +38 -0
  428. package/src/tests/workflow-wait-filter.test.ts +5 -3
  429. package/src/tools/chat-access.ts +41 -0
  430. package/src/tools/chat-open-dm.ts +59 -0
  431. package/src/tools/chat-post.ts +74 -0
  432. package/src/tools/chat-read-thread.ts +100 -0
  433. package/src/tools/chat-reply.ts +75 -0
  434. package/src/tools/create-page.ts +3 -13
  435. package/src/tools/model-catalog/index.ts +2 -1
  436. package/src/tools/model-profiles/list-model-profiles.ts +54 -0
  437. package/src/tools/register-chat-channel.ts +139 -0
  438. package/src/tools/request-human-input.ts +11 -3
  439. package/src/tools/script-apis.ts +5 -1
  440. package/src/tools/script-upsert.ts +4 -1
  441. package/src/tools/send-task.ts +48 -1
  442. package/src/tools/skills/skill-get.ts +17 -9
  443. package/src/tools/swarm-config/get-config.ts +2 -1
  444. package/src/tools/swarm-config/list-config.ts +2 -1
  445. package/src/tools/swarm-config/set-config.ts +16 -3
  446. package/src/tools/system-one-decide.ts +104 -0
  447. package/src/tools/task-action.ts +22 -1
  448. package/src/tools/tool-config.ts +14 -6
  449. package/src/types.ts +48 -3
  450. package/src/utils/config-env-export.ts +74 -0
  451. package/src/utils/credentials.test.ts +92 -0
  452. package/src/utils/credentials.ts +52 -4
  453. package/src/utils/harness-provider.ts +15 -6
  454. package/src/utils/runtime-model-catalog.ts +11 -1
  455. package/src/utils/secret-scrubber.ts +86 -10
  456. package/src/utils/task-tool-manifest.ts +19 -2
  457. package/src/utils/vcs-repo-match.ts +29 -0
  458. package/src/workflows/executors/raw-llm.ts +8 -3
  459. package/src/workflows/executors/swarm-script.ts +1 -0
  460. package/src/workflows/executors/system-one-decision.ts +21 -11
  461. package/src/workflows/executors/workflow-llm.ts +22 -0
  462. package/src/workflows/index.ts +21 -12
  463. package/templates/extensions/README.md +1 -0
  464. package/templates/extensions/comms-adherence-gate/README.md +88 -0
  465. package/templates/extensions/comms-adherence-gate/hooks.ts +489 -0
  466. package/templates/extensions/comms-adherence-gate/manifest.json +8 -0
  467. package/templates/skills/agent-browser/SKILL.md +1 -1
  468. package/templates/skills/agent-browser/content.md +1 -1
  469. package/templates/skills/apps/SKILL.md +8 -1
  470. package/templates/skills/apps/content.md +8 -1
  471. package/templates/skills/chat-sdk/config.json +14 -0
  472. package/templates/skills/chat-sdk/content.md +84 -0
  473. package/templates/skills/composio-gmail/content.md +7 -0
  474. package/templates/skills/composio-google-docs/content.md +1 -1
  475. package/templates/skills/email-domain-health/config.json +14 -0
  476. package/templates/skills/email-domain-health/content.md +131 -0
  477. package/templates/skills/kv-storage/content.md +2 -2
  478. package/templates/skills/pages/content.md +8 -10
  479. package/templates/skills/swarm-extensions/content.md +2 -0
  480. package/templates/skills/swarm-scripts/SKILL.md +4 -2
  481. package/templates/skills/swarm-scripts/config.json +1 -1
  482. package/templates/skills/swarm-scripts/content.md +4 -2
  483. package/templates/skills/workflow-iterate/content.md +38 -0
  484. package/dist/artifact-eczsknc3.js +0 -3843
  485. package/dist/cli-42qhyvwx.js +0 -33
  486. package/dist/cli-bd957dgb.js +0 -153
  487. package/dist/cli-q51yprfq.js +0 -1104
  488. package/dist/cli-t1ze64h3.js +0 -811
  489. package/dist/cli-tcc4wd5d.js +0 -56471
  490. package/dist/index-9ch1n761.js +0 -1102
  491. package/src/artifact-sdk/index.ts +0 -2
  492. package/src/artifact-sdk/localtunnel.d.ts +0 -20
  493. package/src/artifact-sdk/port.ts +0 -12
  494. package/src/artifact-sdk/server.ts +0 -183
  495. package/src/artifact-sdk/tunnel.ts +0 -19
  496. package/src/commands/artifact.ts +0 -249
  497. package/src/http/ecosystem.ts +0 -77
  498. package/src/tests/artifact-commands.test.ts +0 -92
  499. package/src/tests/artifact-sdk.test.ts +0 -793
  500. package/src/tests/register-service-security.test.ts +0 -194
  501. package/src/tools/list-services.ts +0 -107
  502. package/src/tools/register-service.ts +0 -177
  503. package/src/tools/unregister-service.ts +0 -73
  504. package/src/tools/update-service-status.ts +0 -96
  505. package/templates/skills/artifacts/config.json +0 -14
  506. package/templates/skills/artifacts/content.md +0 -344
  507. package/templates/skills/artifacts/files/examples/approval-flow.ts +0 -34
  508. package/templates/skills/artifacts/files/examples/hono-dashboard.ts +0 -31
  509. package/templates/skills/artifacts/files/examples/multi-artifact.ts +0 -20
  510. package/templates/skills/artifacts/files/examples/static-report.sh +0 -17
  511. /package/src/{artifact-sdk → pages}/browser-sdk.ts +0 -0
@@ -41,6 +41,7 @@ import {
41
41
  import { can } from "../rbac";
42
42
  import { extractScriptSignature, type ScriptSignature } from "../scripts-runtime/extract-signature";
43
43
  import { runScript } from "../scripts-runtime/loader";
44
+ import { checkQuickJSCompat, quickJSCompatWarnings } from "../scripts-runtime/quickjs-compat";
44
45
  import {
45
46
  ScriptApiAuthModeSchema,
46
47
  ScriptApiRecordSchema,
@@ -236,6 +237,10 @@ const upsertRoute = route({
236
237
  name: z.string(),
237
238
  version: z.number(),
238
239
  contentDeduped: z.boolean(),
240
+ warnings: z
241
+ .array(z.string())
242
+ .optional()
243
+ .describe("Advisory quickjs-executor compatibility findings. Never blocks the save."),
239
244
  }),
240
245
  },
241
246
  400: { description: "Validation or typecheck failure" },
@@ -424,7 +429,15 @@ const createScriptApiRoute = route({
424
429
  params: idParamsSchema,
425
430
  body: createScriptApiBodySchema,
426
431
  responses: {
427
- 201: { description: "Endpoint created", schema: scriptApiWithSecretSchema },
432
+ 201: {
433
+ description: "Endpoint created",
434
+ schema: scriptApiWithSecretSchema.extend({
435
+ warnings: z
436
+ .array(z.string())
437
+ .optional()
438
+ .describe("Advisory quickjs-executor compatibility findings for the script."),
439
+ }),
440
+ },
428
441
  400: { description: "Validation error or script has no owning agent" },
429
442
  404: { description: "Script not found" },
430
443
  },
@@ -702,10 +715,14 @@ export async function handleScripts(
702
715
  });
703
716
  }
704
717
 
718
+ const warnings = quickJSCompatWarnings(
719
+ checkQuickJSCompat(parsed.body.source, { fsMode: parsed.body.fsMode }),
720
+ );
705
721
  upsertRoute.respond(res, 200, {
706
722
  name: result.script.name,
707
723
  version: result.script.version,
708
724
  contentDeduped: result.contentDeduped,
725
+ ...(warnings.length > 0 ? { warnings } : {}),
709
726
  });
710
727
  return true;
711
728
  }
@@ -765,6 +782,7 @@ export async function handleScripts(
765
782
  runtimeInstanceId,
766
783
  egressSecrets: credentials.egressSecrets,
767
784
  failedBindings: credentials.failedBindings,
785
+ userConfig: credentials.userConfig,
768
786
  apiConnections: getScriptApiConnectionDescriptors({ agentId: agent.id }),
769
787
  mcpConnections: getScriptMcpConnectionDescriptors({ agentId: agent.id }),
770
788
  });
@@ -1091,7 +1109,13 @@ export async function handleScripts(
1091
1109
  label: parsed.body.label ?? null,
1092
1110
  createdBy: await resolveHttpAuditUserId(req, agentId),
1093
1111
  });
1094
- createScriptApiRoute.respond(res, 201, endpoint);
1112
+ const warnings = quickJSCompatWarnings(
1113
+ checkQuickJSCompat(script.source, { fsMode: script.fsMode }),
1114
+ );
1115
+ createScriptApiRoute.respond(res, 201, {
1116
+ ...endpoint,
1117
+ ...(warnings.length > 0 ? { warnings } : {}),
1118
+ });
1095
1119
  return true;
1096
1120
  }
1097
1121
 
package/src/http/stats.ts CHANGED
@@ -3,7 +3,6 @@ import { z } from "zod";
3
3
  import {
4
4
  getAgentStatusCounts,
5
5
  getAllLogs,
6
- getAllServices,
7
6
  getConcurrentContext,
8
7
  getLogsByAgentId,
9
8
  getScheduledTasks,
@@ -14,7 +13,7 @@ import {
14
13
  import { getDbRetentionStats } from "../be/db-retention";
15
14
  import { isSteeringEnabled } from "../be/steering";
16
15
  import type { AgentLog } from "../types";
17
- import { AgentLogSchema, ScheduledTaskSchema, ServiceSchema } from "../types";
16
+ import { AgentLogSchema, ScheduledTaskSchema } from "../types";
18
17
  import { isEnvFlagEnabled } from "../utils/env-flag";
19
18
  import { isMultiRuntimeEnabled } from "../utils/multi-runtime";
20
19
  import { resolveHttpFavoriteOwner } from "./favorite-owner";
@@ -166,22 +165,6 @@ const getMetrics = route({
166
165
  },
167
166
  });
168
167
 
169
- const listServices = route({
170
- method: "get",
171
- path: "/api/services",
172
- pattern: ["api", "services"],
173
- summary: "List all registered services",
174
- tags: ["Stats"],
175
- query: z.object({
176
- status: z.string().optional(),
177
- agentId: z.string().optional(),
178
- name: z.string().optional(),
179
- }),
180
- responses: {
181
- 200: { description: "Service list", schema: z.object({ services: z.array(ServiceSchema) }) },
182
- },
183
- });
184
-
185
168
  const listScheduledTasks = route({
186
169
  method: "get",
187
170
  path: "/api/scheduled-tasks",
@@ -295,18 +278,6 @@ export async function handleStats(
295
278
  return true;
296
279
  }
297
280
 
298
- if (listServices.match(req.method, pathSegments)) {
299
- const parsed = await listServices.parse(req, res, pathSegments, queryParams);
300
- if (!parsed) return true;
301
- const services = await getAllServices({
302
- status: (parsed.query.status as import("../types").ServiceStatus) || undefined,
303
- agentId: parsed.query.agentId || undefined,
304
- name: parsed.query.name || undefined,
305
- });
306
- listServices.respond(res, 200, { services });
307
- return true;
308
- }
309
-
310
281
  if (listScheduledTasks.match(req.method, pathSegments)) {
311
282
  const parsed = await listScheduledTasks.parse(req, res, pathSegments, queryParams);
312
283
  if (!parsed) return true;
package/src/http/tasks.ts CHANGED
@@ -35,6 +35,7 @@ import {
35
35
  updateTaskTitle,
36
36
  updateTaskVcs,
37
37
  } from "../be/db";
38
+ import { modelProfileRefError, taskProfileError } from "../be/db/model-profiles";
38
39
  import { explicitModelErrorForAgent } from "../be/model-validation";
39
40
  import {
40
41
  getTaskSteeringFields,
@@ -45,6 +46,7 @@ import {
45
46
  import { getTaskCitations, TaskCitationSchema } from "../be/task-citations";
46
47
  import { findUserById } from "../be/users";
47
48
  import { can, type RbacPrincipal, type RbacResource } from "../rbac";
49
+ import { chatThreadOfContextKey } from "../tasks/context-key";
48
50
  import { TaskCreationBlockedError } from "../tasks/errors";
49
51
  import { createTaskWithSiblingAwareness } from "../tasks/sibling-awareness";
50
52
  import { guardTerminalTaskResultWrite } from "../tasks/terminal-result-guard";
@@ -76,6 +78,7 @@ import { ensure } from "../utils/business-use";
76
78
  import { getRequestAuth } from "../utils/request-auth-context";
77
79
  import { scrubSecrets } from "../utils/secret-scrubber";
78
80
  import { rejectGuest } from "./request-principal";
81
+ import { buildTaskRequestedBy, TaskRequestedBySchema } from "./requested-by";
79
82
  import { route } from "./route-def";
80
83
  import { jsonError, parseBody } from "./utils";
81
84
 
@@ -110,6 +113,7 @@ const AgentTaskSummarySchema = AgentTaskSchema.pick({
110
113
  modelSource: true,
111
114
  modelAlias: true,
112
115
  effort: true,
116
+ resolvedEffort: true,
113
117
  provider: true,
114
118
  requestedByUserId: true,
115
119
  progress: true,
@@ -284,6 +288,8 @@ const createTask = route({
284
288
  */
285
289
  allowCustomModel: z.boolean().optional(),
286
290
  effort: ReasoningEffortSchema.optional(),
291
+ /** Model profile name, applied at claim. Exclusive with `model` and `modelTier`. */
292
+ profile: z.string().trim().min(1).optional(),
287
293
  /**
288
294
  * Create in `draft` status instead of the normal pending/unassigned/offered
289
295
  * status (#1240) — the task exists and is visible to its owner, but is not
@@ -308,6 +314,10 @@ const createTask = route({
308
314
  description:
309
315
  "Validation error, an unknown `model` (set `allowCustomModel` to store a custom id), or agentId/offeredTo targets an extension identity",
310
316
  },
317
+ 403: {
318
+ description:
319
+ "An agent caller names a parentTaskId it neither owns nor created, or a non-lead agent binds the task to a chat thread",
320
+ },
311
321
  422: {
312
322
  description: "Task creation blocked by an extension",
313
323
  schema: z.object({
@@ -357,6 +367,8 @@ const updateSession = route({
357
367
  claudeSessionId: z.string().min(1),
358
368
  provider: ProviderNameSchema.exclude(["devin"]).optional(),
359
369
  model: z.string().optional(),
370
+ // Effort the session runs at; null when the harness default applies.
371
+ effort: ReasoningEffortSchema.nullable().optional(),
360
372
  providerMeta: z.object({ transport: z.enum(["cli", "sdk"]).optional() }).optional(),
361
373
  harnessVariant: z.string().optional(),
362
374
  harnessVariantMeta: z.record(z.string(), z.unknown()).optional(),
@@ -592,7 +604,14 @@ const listPausedTasks = route({
592
604
  200: {
593
605
  description: "Paused task list",
594
606
  schema: z.object({
595
- tasks: z.array(AgentTaskSchema.extend({ attachments: z.array(TaskAttachmentSchema) })),
607
+ tasks: z.array(
608
+ AgentTaskSchema.extend({
609
+ attachments: z.array(TaskAttachmentSchema),
610
+ // Same requester projection a fresh task_assigned trigger carries,
611
+ // so a resumed session gets the same requester-profile prompt.
612
+ requestedBy: TaskRequestedBySchema.optional(),
613
+ }),
614
+ ),
596
615
  }),
597
616
  },
598
617
  },
@@ -950,10 +969,54 @@ export async function handleTasks(
950
969
  jsonError(res, modelError, 400);
951
970
  return true;
952
971
  }
972
+ const profileError = await taskProfileError({
973
+ profile: parsed.body.profile,
974
+ ...splitLegacyModelAlias({ model: parsed.body.model, modelTier: parsed.body.modelTier }),
975
+ agentId: defaultAgentId,
976
+ });
977
+ if (profileError) {
978
+ jsonError(res, profileError, 400);
979
+ return true;
980
+ }
953
981
 
954
982
  const parentTask = parsed.body.parentTaskId
955
983
  ? await getTaskById(parsed.body.parentTaskId)
956
984
  : null;
985
+ // The child inherits the parent's thread context, so an agent caller must own or
986
+ // have created the parent. Operator and user callers keep their access.
987
+ const principal = await resolveTaskWritePrincipal(req, myAgentId);
988
+ if (
989
+ parentTask &&
990
+ !can({
991
+ principal,
992
+ verb: "task.parent.attach",
993
+ resource: {
994
+ kind: "task",
995
+ taskId: parentTask.id,
996
+ requestedByUserId: parentTask.requestedByUserId,
997
+ creatorAgentId: parentTask.creatorAgentId,
998
+ agentId: parentTask.agentId,
999
+ },
1000
+ source: "http",
1001
+ }).allow
1002
+ ) {
1003
+ jsonError(res, `You don't have context for parent task ${parentTask.id}.`, 403);
1004
+ return true;
1005
+ }
1006
+ // A chat-sdk contextKey binds the task to a chat thread that its assignee and creator
1007
+ // may then read and post to. An agent may only name a thread other than the parent's
1008
+ // with the lead's chat post permission.
1009
+ if (
1010
+ principal.kind === "agent" &&
1011
+ parsed.body.contextKey &&
1012
+ parsed.body.contextKey !== parentTask?.contextKey &&
1013
+ chatThreadOfContextKey(parsed.body.contextKey) &&
1014
+ !can({ principal, verb: "integration.chat.post", resource: { kind: "none" }, source: "http" })
1015
+ .allow
1016
+ ) {
1017
+ jsonError(res, "Permission denied: only a lead can bind a task to a chat thread.", 403);
1018
+ return true;
1019
+ }
957
1020
  let assetKey: string | undefined;
958
1021
  try {
959
1022
  const inheritedKey = parentTask?.key;
@@ -1006,6 +1069,7 @@ export async function handleTasks(
1006
1069
  modelTier: parsed.body.modelTier,
1007
1070
  }),
1008
1071
  effort: parsed.body.effort,
1072
+ profile: parsed.body.profile,
1009
1073
  },
1010
1074
  { origin: "rest", allowCustomModel: parsed.body.allowCustomModel },
1011
1075
  );
@@ -1036,6 +1100,11 @@ export async function handleTasks(
1036
1100
  jsonError(res, error.message, 400);
1037
1101
  return true;
1038
1102
  }
1103
+ // The profile was deleted between taskProfileError and the insert.
1104
+ if (modelProfileRefError(error) === "missing") {
1105
+ jsonError(res, `Unknown model profile "${parsed.body.profile}"`, 400);
1106
+ return true;
1107
+ }
1039
1108
  console.error("[HTTP] Failed to create task:", error);
1040
1109
  jsonError(res, "Failed to create task", 500);
1041
1110
  }
@@ -1083,6 +1152,7 @@ export async function handleTasks(
1083
1152
  parsed.body.model,
1084
1153
  "harnessVariant" in parsed.body ? parsed.body.harnessVariant : undefined,
1085
1154
  "harnessVariantMeta" in parsed.body ? parsed.body.harnessVariantMeta : undefined,
1155
+ "effort" in parsed.body ? parsed.body.effort : undefined,
1086
1156
  );
1087
1157
  if (!task) {
1088
1158
  jsonError(res, "Task not found", 404);
@@ -1667,10 +1737,14 @@ export async function handleTasks(
1667
1737
  }
1668
1738
  const pausedTasks = await getPausedTasksForAgent(myAgentId);
1669
1739
  const tasks = await Promise.all(
1670
- pausedTasks.map(async (task) => ({
1671
- ...task,
1672
- attachments: await getTaskAttachments(task.id),
1673
- })),
1740
+ pausedTasks.map(async (task) => {
1741
+ const requestedBy = await buildTaskRequestedBy(task);
1742
+ return {
1743
+ ...task,
1744
+ attachments: await getTaskAttachments(task.id),
1745
+ ...(requestedBy && { requestedBy }),
1746
+ };
1747
+ }),
1674
1748
  );
1675
1749
  listPausedTasks.respond(res, 200, { tasks });
1676
1750
  return true;
package/src/http/utils.ts CHANGED
@@ -2,6 +2,7 @@ import type { IncomingMessage, ServerResponse } from "node:http";
2
2
  import { getActiveTaskCount } from "../be/db";
3
3
  import type { SwarmSpan } from "../otel";
4
4
  import { isEnvFlagEnabled } from "../utils/env-flag";
5
+ import { getNodeEnv } from "../utils/node-env";
5
6
  import { scrubSecrets } from "../utils/secret-scrubber";
6
7
 
7
8
  export function duplicateGuardedQueryKey(query: URLSearchParams): string | undefined {
@@ -41,6 +42,18 @@ function getAllowedOrigins(): string[] {
41
42
  .filter(Boolean);
42
43
  }
43
44
 
45
+ /**
46
+ * Loopback origins on any port are trusted in local development
47
+ * (`NODE_ENV=development`, set by `start:http` and `dev:http`). The dashboard
48
+ * dev server, Playwright, or a second worktree pick arbitrary ports, and every
49
+ * loopback page already runs on the developer's machine. The production binary
50
+ * and the Docker image run without NODE_ENV, so this never applies there.
51
+ */
52
+ function isDevLoopbackOrigin(origin: string): boolean {
53
+ if (getNodeEnv() !== "development") return false;
54
+ return /^https?:\/\/(localhost|127\.0\.0\.1|\[::1\])(:\d{1,5})?$/.test(origin);
55
+ }
56
+
44
57
  /**
45
58
  * Decide whether `origin` may receive credentialed CORS headers.
46
59
  * Unset or blank uses the built-in hosted/dev allowlist. Exact entries retain
@@ -50,6 +63,7 @@ function getAllowedOrigins(): string[] {
50
63
  * Bare `*`, `https://*`, other wildcard positions, and non-origin URLs are ignored.
51
64
  */
52
65
  function originAllowedForCredentials(origin: string): boolean {
66
+ if (isDevLoopbackOrigin(origin)) return true;
53
67
  return getAllowedOrigins().some((entry) => {
54
68
  if (!entry.includes("*")) return entry === origin;
55
69
 
@@ -66,6 +66,14 @@ import {
66
66
  verifyGitLabWebhook,
67
67
  } from "../gitlab";
68
68
  import { gitlabWorkflowActionName } from "../gitlab/workflow-action-name";
69
+ import { trackBackground } from "../integrations/chat-sdk/background";
70
+ import { isChatSdkEnabled } from "../integrations/chat-sdk/config";
71
+ import {
72
+ getChatInstance,
73
+ isChatAdapterConfigured,
74
+ isChatSdkStopping,
75
+ } from "../integrations/chat-sdk/runtime";
76
+ import { isTrustedTeamsServiceUrl } from "../integrations/chat-sdk/teams-origin";
69
77
  import {
70
78
  type KapsoMessageActionResult,
71
79
  markKapsoMessageRead,
@@ -76,11 +84,14 @@ import { getKapsoConfig } from "../integrations/kapso/config";
76
84
  import type { KapsoWebhookPayload } from "../integrations/kapso/inbound";
77
85
  import { resolveKapsoRequestedByUserId, routeKapsoInbound } from "../integrations/kapso/inbound";
78
86
  import { TaskCreationBlockedError } from "../tasks/errors";
87
+ import { getPublicMcpBaseUrl } from "../utils/constants";
88
+ import { scrubSecrets } from "../utils/secret-scrubber";
79
89
  import { canonicalAzureDevOpsRepoUrl } from "../vcs/azure-devops";
80
90
  import { getExecutorRegistry } from "../workflows";
81
91
  import { workflowEventBus } from "../workflows/event-bus";
82
92
  import { handleWebhookTrigger, verifyHmacSignature, WebhookError } from "../workflows/triggers";
83
93
  import { route } from "./route-def";
94
+ import { BODY_TOO_LARGE, enforceContentLengthCap, jsonError } from "./utils";
84
95
 
85
96
  // ─── Route Definitions (documentation only — webhooks handle their own body parsing) ─
86
97
 
@@ -203,8 +214,75 @@ const kapsoWebhook = route({
203
214
  },
204
215
  });
205
216
 
217
+ const chatSdkWebhook = route({
218
+ method: "post",
219
+ path: "/api/integrations/chat/{adapter}/webhook",
220
+ pattern: ["api", "integrations", "chat", null, "webhook"],
221
+ summary: "Handle Chat SDK platform webhooks (Telegram, Slack, Discord, Teams)",
222
+ tags: ["Webhooks"],
223
+ params: z.object({ adapter: z.string().describe("Chat SDK adapter name, e.g. telegram") }),
224
+ auth: { apiKey: false },
225
+ rbac: {
226
+ ungated:
227
+ "provider webhook: the Chat SDK adapter verifies the platform signature (Telegram secret token, Slack signing secret, Discord Ed25519, Teams JWT)",
228
+ },
229
+ responses: {
230
+ 200: { description: "Adapter response", unstructured: "adapter response proxied as-is" },
231
+ 401: { description: "Invalid platform signature or secret token" },
232
+ 403: { description: "Teams activity whose serviceUrl is not a Bot Framework host" },
233
+ 404: { description: "Chat SDK disabled or adapter not configured" },
234
+ 413: { description: "Body exceeds 1 MiB" },
235
+ 503: { description: "Adapter configured but failed to start" },
236
+ },
237
+ });
238
+
239
+ /**
240
+ * Upper bound for a Chat SDK webhook body. Platform payloads are a few KB and
241
+ * files travel by URL, so anything larger is not a platform delivery.
242
+ */
243
+ const CHAT_SDK_WEBHOOK_MAX_BODY_BYTES = 1024 * 1024;
244
+
206
245
  // ─── Handler ─────────────────────────────────────────────────────────────────
207
246
 
247
+ /** False when a Teams activity body carries a `serviceUrl` that is not a Bot Framework host. */
248
+ function hasTrustedTeamsServiceUrl(body: Buffer): boolean {
249
+ let serviceUrl: unknown;
250
+ try {
251
+ serviceUrl = (JSON.parse(body.toString("utf-8")) as { serviceUrl?: unknown } | null)
252
+ ?.serviceUrl;
253
+ } catch {
254
+ // Not JSON: the adapter rejects it.
255
+ return true;
256
+ }
257
+ if (serviceUrl === undefined || serviceUrl === null || serviceUrl === "") return true;
258
+ return typeof serviceUrl === "string" && isTrustedTeamsServiceUrl(serviceUrl);
259
+ }
260
+
261
+ /**
262
+ * Rebuild a Fetch `Request` from the raw Node request. Headers come from
263
+ * `rawHeaders` pairs: building `Headers` from `IncomingMessage.headers`
264
+ * comma-joins repeated values, which breaks signature checks.
265
+ */
266
+ function toFetchRequest(req: IncomingMessage, rawBody: Buffer, fallbackPath: string): Request {
267
+ const headers = new Headers();
268
+ if (Array.isArray(req.rawHeaders) && req.rawHeaders.length > 0) {
269
+ for (let i = 0; i + 1 < req.rawHeaders.length; i += 2) {
270
+ headers.append(req.rawHeaders[i] as string, req.rawHeaders[i + 1] as string);
271
+ }
272
+ } else {
273
+ for (const [name, value] of Object.entries(req.headers)) {
274
+ for (const item of Array.isArray(value) ? value : value === undefined ? [] : [value]) {
275
+ headers.append(name, item);
276
+ }
277
+ }
278
+ }
279
+ return new Request(`${getPublicMcpBaseUrl()}${req.url ?? fallbackPath}`, {
280
+ method: req.method ?? "POST",
281
+ headers,
282
+ body: rawBody.length > 0 ? new Uint8Array(rawBody) : undefined,
283
+ });
284
+ }
285
+
208
286
  function logKapsoAckResult(action: string, result: KapsoMessageActionResult): void {
209
287
  if (result.ok) return;
210
288
  console.warn(
@@ -316,7 +394,8 @@ export async function handleWebhooks(
316
394
  return true;
317
395
  }
318
396
 
319
- console.log(`[GitHub] Received ${eventType} event`);
397
+ const deliveryId = req.headers["x-github-delivery"] as string | undefined;
398
+ console.log(`[GitHub] Received ${eventType} event (delivery ${deliveryId ?? "unknown"})`);
320
399
 
321
400
  let result: WebhookDispatchResult = { created: false };
322
401
 
@@ -678,9 +757,8 @@ export async function handleWebhooks(
678
757
  payload.message &&
679
758
  !isInboxAllowed(payload.message.inbox_id, process.env.AGENTMAIL_INBOX_DOMAIN_FILTER)
680
759
  ) {
681
- const domain = payload.message.inbox_id.split("@")[1] ?? "unknown";
682
760
  console.log(
683
- `[AgentMail] Ignoring event for inbox domain "${domain}" (not in AGENTMAIL_INBOX_DOMAIN_FILTER)`,
761
+ `[AgentMail] Ignoring event for inbox "${payload.message.inbox_id}" (not in AGENTMAIL_INBOX_DOMAIN_FILTER)`,
684
762
  );
685
763
  return true;
686
764
  }
@@ -818,5 +896,84 @@ export async function handleWebhooks(
818
896
  return true;
819
897
  }
820
898
 
899
+ // Chat SDK webhook: the adapter verifies the platform signature over the raw
900
+ // body, so the request is proxied as-is and the adapter's response returned.
901
+ if (chatSdkWebhook.match(req.method, pathSegments)) {
902
+ const adapterName = pathSegments[3] ?? "";
903
+ if (!isChatSdkEnabled() || !isChatAdapterConfigured(adapterName)) {
904
+ res.writeHead(404, { "Content-Type": "application/json" });
905
+ res.end(JSON.stringify({ error: "Chat SDK adapter not configured" }));
906
+ return true;
907
+ }
908
+ if (isChatSdkStopping()) {
909
+ res.writeHead(503, { "Content-Type": "application/json" });
910
+ res.end(JSON.stringify({ error: "Chat SDK is shutting down" }));
911
+ return true;
912
+ }
913
+ const chat = getChatInstance(adapterName);
914
+ const handler = chat?.webhooks[adapterName];
915
+ if (!handler) {
916
+ res.writeHead(503, { "Content-Type": "application/json" });
917
+ res.end(JSON.stringify({ error: "Chat SDK adapter failed to start" }));
918
+ return true;
919
+ }
920
+
921
+ // The route is unauthenticated and the adapter verifies the signature over
922
+ // the buffered body, so the body is bounded before it is buffered. An
923
+ // oversized stream is answered at once and drained without buffering, the
924
+ // same way `parseBody` keeps the connection usable.
925
+ if (enforceContentLengthCap(req, res, CHAT_SDK_WEBHOOK_MAX_BODY_BYTES) === BODY_TOO_LARGE) {
926
+ return true;
927
+ }
928
+ const chunks: Buffer[] = [];
929
+ let receivedBytes = 0;
930
+ let tooLarge = false;
931
+ for await (const chunk of req) {
932
+ if (tooLarge) continue;
933
+ receivedBytes += (chunk as Buffer).byteLength;
934
+ if (receivedBytes > CHAT_SDK_WEBHOOK_MAX_BODY_BYTES) {
935
+ tooLarge = true;
936
+ chunks.length = 0;
937
+ jsonError(res, `Payload too large (max ${CHAT_SDK_WEBHOOK_MAX_BODY_BYTES} bytes)`, 413);
938
+ continue;
939
+ }
940
+ chunks.push(chunk as Buffer);
941
+ }
942
+ if (tooLarge) return true;
943
+ const rawBody = Buffer.concat(chunks);
944
+ // The Teams adapter replies, reads history and downloads files with the
945
+ // bot token at the activity's serviceUrl, and caches it for DMs. Refuse an
946
+ // untrusted one before the adapter sees the activity.
947
+ if (adapterName === "teams" && !hasTrustedTeamsServiceUrl(rawBody)) {
948
+ console.warn("[chat-sdk] teams webhook refused: serviceUrl is not a Bot Framework host");
949
+ res.writeHead(403, { "Content-Type": "application/json" });
950
+ res.end(JSON.stringify({ error: "Untrusted Teams serviceUrl" }));
951
+ return true;
952
+ }
953
+ const request = toFetchRequest(req, rawBody, `/api/integrations/chat/${adapterName}/webhook`);
954
+
955
+ try {
956
+ const response = await handler(request, {
957
+ // Handler errors are logged by `trackBackground` in `handlers.ts`.
958
+ waitUntil: trackBackground,
959
+ });
960
+ const responseHeaders: Record<string, string> = {};
961
+ response.headers.forEach((value, name) => {
962
+ responseHeaders[name] = value;
963
+ });
964
+ const body = Buffer.from(await response.arrayBuffer());
965
+ res.writeHead(response.status, responseHeaders);
966
+ res.end(body);
967
+ } catch (err) {
968
+ const message = err instanceof Error ? err.message : String(err);
969
+ console.error(`[chat-sdk] ${adapterName} webhook failed: ${scrubSecrets(message)}`);
970
+ if (!res.headersSent) {
971
+ res.writeHead(500, { "Content-Type": "application/json" });
972
+ }
973
+ res.end(JSON.stringify({ error: "Chat SDK webhook failed" }));
974
+ }
975
+ return true;
976
+ }
977
+
821
978
  return false;
822
979
  }
package/src/http/x.ts CHANGED
@@ -255,6 +255,7 @@ export async function handleX(
255
255
  timeoutMs,
256
256
  egressSecrets: credentials.egressSecrets,
257
257
  failedBindings: credentials.failedBindings,
258
+ userConfig: credentials.userConfig,
258
259
  apiConnections: getScriptApiConnectionDescriptors({ agentId: endpoint.agentId }),
259
260
  mcpConnections: getScriptMcpConnectionDescriptors({ agentId: endpoint.agentId }),
260
261
  });