@cursor/bdk 0.2.9 → 0.2.10

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 (570) hide show
  1. package/dist/artifacts.js +3 -5
  2. package/dist/bin/agent-serve.js +803 -812
  3. package/dist/channels/bitbucket/api.js +305 -321
  4. package/dist/channels/bitbucket/binding.js +97 -61
  5. package/dist/channels/bitbucket/bitbucket-channel.d.ts +15 -1
  6. package/dist/channels/bitbucket/bitbucket-channel.d.ts.map +1 -1
  7. package/dist/channels/bitbucket/bitbucket-channel.js +95 -42
  8. package/dist/channels/bitbucket/bitbucket-webhook.d.ts +11 -0
  9. package/dist/channels/bitbucket/bitbucket-webhook.d.ts.map +1 -1
  10. package/dist/channels/bitbucket/bitbucket-webhook.js +214 -204
  11. package/dist/channels/bitbucket/checks.js +9 -21
  12. package/dist/channels/bitbucket/cursor-account.js +1 -1
  13. package/dist/channels/bitbucket/defaults.js +14 -4
  14. package/dist/channels/bitbucket/events.js +1 -2
  15. package/dist/channels/bitbucket/index.d.ts +6 -2
  16. package/dist/channels/bitbucket/index.d.ts.map +1 -1
  17. package/dist/channels/bitbucket/index.js +6 -2
  18. package/dist/channels/bitbucket/replay.js +80 -56
  19. package/dist/channels/bitbucket/state.js +16 -7
  20. package/dist/channels/bitbucket/types.d.ts +11 -2
  21. package/dist/channels/bitbucket/types.d.ts.map +1 -1
  22. package/dist/channels/checks.js +18 -28
  23. package/dist/channels/deployments/deployments-channel.js +26 -34
  24. package/dist/channels/github/api.js +216 -210
  25. package/dist/channels/github/auth.d.ts +5 -1
  26. package/dist/channels/github/auth.d.ts.map +1 -1
  27. package/dist/channels/github/auth.js +157 -174
  28. package/dist/channels/github/binding.js +48 -39
  29. package/dist/channels/github/checks.js +9 -14
  30. package/dist/channels/github/cursor-account.js +6 -11
  31. package/dist/channels/github/defaults.js +105 -130
  32. package/dist/channels/github/forward.js +13 -17
  33. package/dist/channels/github/github-channel.d.ts +43 -2
  34. package/dist/channels/github/github-channel.d.ts.map +1 -1
  35. package/dist/channels/github/github-channel.js +1228 -958
  36. package/dist/channels/github/progress.js +145 -146
  37. package/dist/channels/github/replay.js +30 -39
  38. package/dist/channels/github/state.js +40 -16
  39. package/dist/channels/github/types.d.ts +30 -6
  40. package/dist/channels/github/types.d.ts.map +1 -1
  41. package/dist/channels/gitlab/api.js +100 -114
  42. package/dist/channels/gitlab/binding.js +52 -33
  43. package/dist/channels/gitlab/checks.js +28 -29
  44. package/dist/channels/gitlab/cursor-account.js +1 -1
  45. package/dist/channels/gitlab/defaults.js +9 -3
  46. package/dist/channels/gitlab/gitlab-channel.d.ts +16 -1
  47. package/dist/channels/gitlab/gitlab-channel.d.ts.map +1 -1
  48. package/dist/channels/gitlab/gitlab-channel.js +95 -42
  49. package/dist/channels/gitlab/gitlab-webhook.d.ts +10 -1
  50. package/dist/channels/gitlab/gitlab-webhook.d.ts.map +1 -1
  51. package/dist/channels/gitlab/gitlab-webhook.js +282 -249
  52. package/dist/channels/gitlab/index.d.ts +6 -2
  53. package/dist/channels/gitlab/index.d.ts.map +1 -1
  54. package/dist/channels/gitlab/index.js +6 -2
  55. package/dist/channels/gitlab/replay.js +50 -27
  56. package/dist/channels/gitlab/state.js +14 -6
  57. package/dist/channels/gitlab/types.d.ts +13 -2
  58. package/dist/channels/gitlab/types.d.ts.map +1 -1
  59. package/dist/channels/origin/api.js +100 -116
  60. package/dist/channels/origin/binding.js +15 -16
  61. package/dist/channels/origin/checks.js +30 -28
  62. package/dist/channels/origin/defaults.js +50 -65
  63. package/dist/channels/origin/origin-channel.js +266 -272
  64. package/dist/channels/origin/origin-webhook.js +70 -88
  65. package/dist/channels/origin/reactions.js +9 -21
  66. package/dist/channels/origin/state.js +13 -5
  67. package/dist/channels/slack/agentic-delivery.js +426 -478
  68. package/dist/channels/slack/agentic-posted.js +9 -10
  69. package/dist/channels/slack/agentic-signals.js +2 -3
  70. package/dist/channels/slack/api.js +417 -427
  71. package/dist/channels/slack/approvals.js +1 -1
  72. package/dist/channels/slack/assistant.js +37 -47
  73. package/dist/channels/slack/attachments.js +188 -206
  74. package/dist/channels/slack/auth.js +8 -6
  75. package/dist/channels/slack/bot-mentions.js +31 -45
  76. package/dist/channels/slack/channel-watch.js +42 -48
  77. package/dist/channels/slack/cli-project.js +112 -137
  78. package/dist/channels/slack/code-fences.js +3 -5
  79. package/dist/channels/slack/constants.js +2 -2
  80. package/dist/channels/slack/credentials.js +23 -38
  81. package/dist/channels/slack/defaults.js +292 -331
  82. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  83. package/dist/channels/slack/dispatch.js +533 -460
  84. package/dist/channels/slack/doctor.js +200 -214
  85. package/dist/channels/slack/eval-directive.js +79 -96
  86. package/dist/channels/slack/event-id-dedupe.js +1 -1
  87. package/dist/channels/slack/external-policy.js +26 -39
  88. package/dist/channels/slack/footer.js +28 -41
  89. package/dist/channels/slack/inbound.d.ts +1 -0
  90. package/dist/channels/slack/inbound.d.ts.map +1 -1
  91. package/dist/channels/slack/inbound.js +50 -31
  92. package/dist/channels/slack/init.d.ts +1 -5
  93. package/dist/channels/slack/init.d.ts.map +1 -1
  94. package/dist/channels/slack/init.js +42 -59
  95. package/dist/channels/slack/interactive.d.ts +9 -3
  96. package/dist/channels/slack/interactive.d.ts.map +1 -1
  97. package/dist/channels/slack/interactive.js +160 -162
  98. package/dist/channels/slack/links.js +1 -2
  99. package/dist/channels/slack/live-delivery.js +172 -190
  100. package/dist/channels/slack/manifest.d.ts.map +1 -1
  101. package/dist/channels/slack/manifest.js +44 -23
  102. package/dist/channels/slack/message-body.js +2 -2
  103. package/dist/channels/slack/nudge-carrier.js +30 -42
  104. package/dist/channels/slack/nudge-store.js +164 -191
  105. package/dist/channels/slack/paint-start.js +66 -81
  106. package/dist/channels/slack/placeholder.js +123 -152
  107. package/dist/channels/slack/pr-ref.js +1 -1
  108. package/dist/channels/slack/progress-delivery.js +65 -78
  109. package/dist/channels/slack/reasoning-card.js +36 -49
  110. package/dist/channels/slack/recording-sink.js +12 -24
  111. package/dist/channels/slack/reply-options.js +7 -12
  112. package/dist/channels/slack/self-identity.js +27 -35
  113. package/dist/channels/slack/sender-name.d.ts +12 -3
  114. package/dist/channels/slack/sender-name.d.ts.map +1 -1
  115. package/dist/channels/slack/sender-name.js +57 -61
  116. package/dist/channels/slack/setup.js +2 -4
  117. package/dist/channels/slack/slack-channel.d.ts +6 -4
  118. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  119. package/dist/channels/slack/slack-channel.js +441 -308
  120. package/dist/channels/slack/socket-mode.js +38 -52
  121. package/dist/channels/slack/thread-context.js +143 -160
  122. package/dist/channels/slack/tool-approval-events.js +149 -166
  123. package/dist/channels/slack/tool-cards.js +6 -11
  124. package/dist/channels/slack/tool-chip.js +1 -2
  125. package/dist/channels/slack/types.d.ts +15 -17
  126. package/dist/channels/slack/types.d.ts.map +1 -1
  127. package/dist/channels/slack/upload.js +84 -97
  128. package/dist/channels/slack/user-info.js +27 -41
  129. package/dist/channels.js +9 -20
  130. package/dist/dashboard-session-url.js +3 -4
  131. package/dist/docs/404.html +2 -2
  132. package/dist/docs/assets/{app.BNhEdGa8.js → app.DXI7bwox.js} +4 -4
  133. package/dist/docs/assets/{building-with-agents.md.BPjPFxFg.js → building-with-agents.md.Df87rAe1.js} +1 -1
  134. package/dist/docs/assets/chunks/@localSearchIndexroot.CtLtpWcx.js +1 -0
  135. package/dist/docs/assets/chunks/{VPLocalSearchBox.DIdUV1Ph.js → VPLocalSearchBox.BrbO5mEe.js} +1 -1
  136. package/dist/docs/assets/chunks/{arc.lELI4_SR.js → arc.BOG1yms8.js} +1 -1
  137. package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.iCMdvuoM.js → architectureDiagram-Q4EWVU46.C0hsMZnZ.js} +1 -1
  138. package/dist/docs/assets/chunks/{baseUniq.C1-nDJBf.js → baseUniq.H044KjKs.js} +1 -1
  139. package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.ClemzBox.js → blockDiagram-DXYQGD6D.BsRW6GoB.js} +1 -1
  140. package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.BqTak6cR.js → c4Diagram-AHTNJAMY.B9HV5PFR.js} +1 -1
  141. package/dist/docs/assets/chunks/channel.CBwrU9rP.js +1 -0
  142. package/dist/docs/assets/chunks/{chunk-4BX2VUAB.CUS3qs_R.js → chunk-4BX2VUAB.CPoT_ajl.js} +1 -1
  143. package/dist/docs/assets/chunks/{chunk-4TB4RGXK.dz5fdHcl.js → chunk-4TB4RGXK.DZBwWuCL.js} +1 -1
  144. package/dist/docs/assets/chunks/{chunk-55IACEB6.D6BEBmve.js → chunk-55IACEB6.CZ3yTiyq.js} +1 -1
  145. package/dist/docs/assets/chunks/{chunk-EDXVE4YY.B5uK4ID9.js → chunk-EDXVE4YY.6DfvHSd8.js} +1 -1
  146. package/dist/docs/assets/chunks/{chunk-FMBD7UC4.PgOJgNQs.js → chunk-FMBD7UC4.CpBj8HfK.js} +1 -1
  147. package/dist/docs/assets/chunks/{chunk-OYMX7WX6.CvkTrCii.js → chunk-OYMX7WX6.BdKo8YqS.js} +1 -1
  148. package/dist/docs/assets/chunks/{chunk-QZHKN3VN.BnSfKYsB.js → chunk-QZHKN3VN.BnXNyxJx.js} +1 -1
  149. package/dist/docs/assets/chunks/{chunk-YZCP3GAM.MZH6v5UC.js → chunk-YZCP3GAM.Cg1OcF8G.js} +1 -1
  150. package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.CbC_mrvB.js +1 -0
  151. package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.CbC_mrvB.js +1 -0
  152. package/dist/docs/assets/chunks/clone.BTvFyY1a.js +1 -0
  153. package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.BBbw_YZi.js → cose-bilkent-S5V4N54A.1SP8al9c.js} +1 -1
  154. package/dist/docs/assets/chunks/{dagre-KV5264BT.CNJB2l7E.js → dagre-KV5264BT.DS1L6hJt.js} +1 -1
  155. package/dist/docs/assets/chunks/{diagram-5BDNPKRD.BQzlnFfq.js → diagram-5BDNPKRD.ChsausbG.js} +1 -1
  156. package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.DkgqqZMz.js → diagram-G4DWMVQ6.3XsptNWj.js} +1 -1
  157. package/dist/docs/assets/chunks/{diagram-MMDJMWI5.DIT8L7H_.js → diagram-MMDJMWI5.DPA9Dk_P.js} +1 -1
  158. package/dist/docs/assets/chunks/{diagram-TYMM5635.3xLPZWGJ.js → diagram-TYMM5635.BVswXWrB.js} +1 -1
  159. package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.5_IHz8jF.js → erDiagram-SMLLAGMA.BSak5OSP.js} +1 -1
  160. package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.BGUCXz8A.js → flowDiagram-DWJPFMVM.CQgN4TTz.js} +1 -1
  161. package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.DbfFavS1.js → ganttDiagram-T4ZO3ILL.GrT0kA4a.js} +1 -1
  162. package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.D2yKdeNW.js → gitGraphDiagram-UUTBAWPF.CdS7Ucll.js} +1 -1
  163. package/dist/docs/assets/chunks/{graph.CSCxwHba.js → graph.BVqKRmRo.js} +1 -1
  164. package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.FDeb6xHY.js → infoDiagram-42DDH7IO.C3C9FRto.js} +1 -1
  165. package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.DbeYs9VL.js → ishikawaDiagram-UXIWVN3A.2FuAh_Zj.js} +1 -1
  166. package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.CWjKINpx.js → journeyDiagram-VCZTEJTY.CaHMfK4b.js} +1 -1
  167. package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.B4FrAlwz.js → kanban-definition-6JOO6SKY.CjhIUwcA.js} +1 -1
  168. package/dist/docs/assets/chunks/{layout.DFGxQ9ab.js → layout.CGU3gfSf.js} +1 -1
  169. package/dist/docs/assets/chunks/{linear.BmjZ-G59.js → linear.DaihpW_n.js} +1 -1
  170. package/dist/docs/assets/chunks/{min.DZSxulMW.js → min.BS-j8kHQ.js} +1 -1
  171. package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.CHLi3-aN.js → mindmap-definition-QFDTVHPH.BVJ1Bbnk.js} +1 -1
  172. package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.DteG-CkU.js → pieDiagram-DEJITSTG.Cz1WIv9r.js} +1 -1
  173. package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.D458ipN3.js → quadrantDiagram-34T5L4WZ.DKLFxcjy.js} +1 -1
  174. package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.DcFgUxst.js → requirementDiagram-MS252O5E.BHegiK7x.js} +1 -1
  175. package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.BwQAMmSA.js → sankeyDiagram-XADWPNL6.DYkY6yPc.js} +1 -1
  176. package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.B_Xdsrh9.js → sequenceDiagram-FGHM5R23.DYQ1QUrI.js} +1 -1
  177. package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.CdfDW6-C.js → stateDiagram-FHFEXIEX.Iru8BsFo.js} +1 -1
  178. package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.BYXl4LW6.js +1 -0
  179. package/dist/docs/assets/chunks/{theme.sfdL3srp.js → theme.DaplWQhQ.js} +2 -2
  180. package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.56-4hXaC.js → timeline-definition-GMOUNBTQ.BwFA8hiX.js} +1 -1
  181. package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.CvZSQBO7.js → vennDiagram-DHZGUBPP.CZ60W1C_.js} +1 -1
  182. package/dist/docs/assets/chunks/{wardley-RL74JXVD.C9qc8k39.js → wardley-RL74JXVD.iXazD3Z7.js} +1 -1
  183. package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.D9s0nihi.js → wardleyDiagram-NUSXRM2D.B69D2r8-.js} +1 -1
  184. package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.BVJSpYrC.js → xychartDiagram-5P7HB3ND.CLPZEIU9.js} +1 -1
  185. package/dist/docs/assets/{deployment.md.BdqTiGdc.js → deployment.md.BYuEcDBv.js} +2 -2
  186. package/dist/docs/assets/{guides_bitbucket.md.BB6fqD-M.js → guides_bitbucket.md.CKUayYtD.js} +3 -3
  187. package/dist/docs/assets/{guides_bitbucket.md.BB6fqD-M.lean.js → guides_bitbucket.md.CKUayYtD.lean.js} +1 -1
  188. package/dist/docs/assets/{guides_github.md.Cr1Xlf-m.js → guides_github.md.TuNiZAOQ.js} +4 -4
  189. package/dist/docs/assets/{guides_github.md.Cr1Xlf-m.lean.js → guides_github.md.TuNiZAOQ.lean.js} +1 -1
  190. package/dist/docs/assets/{guides_gitlab.md.CMpmFi4M.js → guides_gitlab.md.CtNI4fSH.js} +4 -4
  191. package/dist/docs/assets/{guides_gitlab.md.CMpmFi4M.lean.js → guides_gitlab.md.CtNI4fSH.lean.js} +1 -1
  192. package/dist/docs/assets/guides_migrate.md.sCAvvlC6.js +7 -0
  193. package/dist/docs/assets/guides_migrate.md.sCAvvlC6.lean.js +1 -0
  194. package/dist/docs/assets/{reference_cli.md.GwugN3n-.js → reference_cli.md.dYCAL2lB.js} +4 -3
  195. package/dist/docs/assets/reference_cli.md.dYCAL2lB.lean.js +1 -0
  196. package/dist/docs/assets/{reference_skills.md.ClkMoQsV.js → reference_skills.md.C0guGcH0.js} +3 -3
  197. package/dist/docs/assets/troubleshooting.md.x-GBa7wN.js +1 -0
  198. package/dist/docs/assets/{troubleshooting.md.Bscj6ODe.lean.js → troubleshooting.md.x-GBa7wN.lean.js} +1 -1
  199. package/dist/docs/building-with-agents.html +37 -37
  200. package/dist/docs/building-with-agents.md +2 -0
  201. package/dist/docs/deployment.html +38 -38
  202. package/dist/docs/deployment.md +7 -0
  203. package/dist/docs/evals.html +36 -36
  204. package/dist/docs/guides/agent-to-agent.html +35 -35
  205. package/dist/docs/guides/bitbucket.html +38 -38
  206. package/dist/docs/guides/bitbucket.md +9 -1
  207. package/dist/docs/guides/cloud-agents.html +35 -35
  208. package/dist/docs/guides/convert-automation.html +35 -35
  209. package/dist/docs/guides/github.html +39 -39
  210. package/dist/docs/guides/github.md +20 -4
  211. package/dist/docs/guides/gitlab.html +38 -38
  212. package/dist/docs/guides/gitlab.md +9 -1
  213. package/dist/docs/guides/grokbot-agents.html +35 -35
  214. package/dist/docs/guides/hooks.html +35 -35
  215. package/dist/docs/guides/improve.html +35 -35
  216. package/dist/docs/guides/jev.html +35 -35
  217. package/dist/docs/guides/mcp-oauth.html +35 -35
  218. package/dist/docs/guides/migrate.html +66 -0
  219. package/dist/docs/guides/migrate.md +122 -0
  220. package/dist/docs/guides/opentelemetry.html +35 -35
  221. package/dist/docs/guides/slack.html +35 -35
  222. package/dist/docs/guides/webhooks.html +35 -35
  223. package/dist/docs/hashmap.json +1 -1
  224. package/dist/docs/hillclimbing.html +35 -35
  225. package/dist/docs/index.html +35 -35
  226. package/dist/docs/llms-full.txt +214 -6
  227. package/dist/docs/llms.txt +1 -0
  228. package/dist/docs/quickstart.html +35 -35
  229. package/dist/docs/reference/agent-config.html +35 -35
  230. package/dist/docs/reference/artifacts.html +35 -35
  231. package/dist/docs/reference/channels.html +35 -35
  232. package/dist/docs/reference/cli.html +39 -38
  233. package/dist/docs/reference/cli.md +39 -0
  234. package/dist/docs/reference/connections.html +35 -35
  235. package/dist/docs/reference/evals.html +35 -35
  236. package/dist/docs/reference/extensions.html +35 -35
  237. package/dist/docs/reference/hooks.html +35 -35
  238. package/dist/docs/reference/http-api.html +35 -35
  239. package/dist/docs/reference/instructions.html +35 -35
  240. package/dist/docs/reference/playground.html +35 -35
  241. package/dist/docs/reference/project-layout.html +35 -35
  242. package/dist/docs/reference/prompt.html +35 -35
  243. package/dist/docs/reference/schedules.html +35 -35
  244. package/dist/docs/reference/sessions.html +35 -35
  245. package/dist/docs/reference/skills.html +38 -38
  246. package/dist/docs/reference/subagents.html +35 -35
  247. package/dist/docs/reference/tools.html +35 -35
  248. package/dist/docs/templates/agentic-owners.html +35 -35
  249. package/dist/docs/templates/grokbot-agents.html +35 -35
  250. package/dist/docs/templates/security-reviewer.html +35 -35
  251. package/dist/docs/templates/thermo-quality-review.html +35 -35
  252. package/dist/docs/templates/thermo-review.html +35 -35
  253. package/dist/docs/templates/triage.html +35 -35
  254. package/dist/docs/troubleshooting.html +36 -36
  255. package/dist/docs/troubleshooting.md +1 -0
  256. package/dist/evals/assertions.js +20 -34
  257. package/dist/evals/expect.js +3 -6
  258. package/dist/evals/judge.js +5 -8
  259. package/dist/evals/loaders.js +45 -62
  260. package/dist/evals/matchers.js +2 -3
  261. package/dist/evals/reporters.js +43 -67
  262. package/dist/evals/results.js +1 -1
  263. package/dist/evals/run-facts.js +5 -6
  264. package/dist/evals.js +27 -15
  265. package/dist/extensions/cursor-cloud-agents/extension.js +4 -1
  266. package/dist/extensions/cursor-cloud-agents/lib/backend.js +100 -126
  267. package/dist/extensions/cursor-cloud-agents/lib/fleet.js +22 -38
  268. package/dist/extensions/cursor-cloud-agents/lib/repos.js +8 -10
  269. package/dist/extensions/cursor-cloud-agents/lib/transcript.js +2 -3
  270. package/dist/extensions/cursor-cloud-agents/lib/watch.js +52 -66
  271. package/dist/extensions/cursor-cloud-agents/reminders/cloud-agent-stop-watch.js +29 -40
  272. package/dist/extensions/cursor-cloud-agents/tools/cancel.js +6 -17
  273. package/dist/extensions/cursor-cloud-agents/tools/dump.js +25 -36
  274. package/dist/extensions/cursor-cloud-agents/tools/get.js +3 -14
  275. package/dist/extensions/cursor-cloud-agents/tools/launch.js +13 -21
  276. package/dist/extensions/cursor-cloud-agents/tools/list.js +8 -19
  277. package/dist/extensions/cursor-cloud-agents/tools/reply.js +5 -16
  278. package/dist/extensions/cursor-grokbot-agents/extension.js +4 -1
  279. package/dist/extensions/cursor-grokbot-agents/lib/agents.js +3 -3
  280. package/dist/extensions/cursor-grokbot-agents/lib/backend.js +53 -73
  281. package/dist/extensions/cursor-grokbot-agents/lib/contacts.js +10 -23
  282. package/dist/extensions/cursor-grokbot-agents/lib/conversation.js +112 -132
  283. package/dist/extensions/cursor-grokbot-agents/lib/lock.js +1 -2
  284. package/dist/extensions/cursor-grokbot-agents/tools/ask.js +5 -16
  285. package/dist/extensions/cursor-grokbot-agents/tools/check.js +4 -15
  286. package/dist/extensions/cursor-grokbot-agents/tools/interrupt.js +2 -13
  287. package/dist/extensions/cursor-grokbot-agents/tools/list.js +11 -23
  288. package/dist/extensions/jev/extension.js +3 -3
  289. package/dist/extensions/jev/lib/evaluate.js +43 -60
  290. package/dist/extensions/jev/tools/evaluate.js +6 -17
  291. package/dist/extensions/slack-communication/tools/post-file.js +1 -1
  292. package/dist/extensions.js +3 -5
  293. package/dist/files-backends/cursor-hosted.js +504 -523
  294. package/dist/files-backends/local-fs.js +72 -134
  295. package/dist/files.js +3 -3
  296. package/dist/filesystem.js +562 -861
  297. package/dist/index.js +16 -35
  298. package/dist/internal/advertise-tools.js +74 -86
  299. package/dist/internal/artifacts-store.js +298 -361
  300. package/dist/internal/as-of.js +2 -4
  301. package/dist/internal/authored-alias-hooks.js +6 -4
  302. package/dist/internal/authored-loaders.js +37 -52
  303. package/dist/internal/bounded-int.js +1 -2
  304. package/dist/internal/bounded.js +13 -24
  305. package/dist/internal/brand.js +1 -1
  306. package/dist/internal/browser-origin-guard.js +4 -4
  307. package/dist/internal/builtin-tools/artifacts.js +15 -27
  308. package/dist/internal/builtin-tools/index.js +2 -3
  309. package/dist/internal/builtin-tools/reminders.js +33 -52
  310. package/dist/internal/channel-architecture.d.ts +21 -0
  311. package/dist/internal/channel-architecture.d.ts.map +1 -0
  312. package/dist/internal/channel-architecture.js +41 -0
  313. package/dist/internal/channel-dispatch.js +3 -4
  314. package/dist/internal/channel-route-dispatch.js +40 -51
  315. package/dist/internal/channel-state.js +1 -1
  316. package/dist/internal/chat-client.js +319 -340
  317. package/dist/internal/cli-ax.js +1262 -1294
  318. package/dist/internal/cli-bitbucket.js +244 -272
  319. package/dist/internal/cli-convert-automation.js +137 -151
  320. package/dist/internal/cli-cursor.js +126 -147
  321. package/dist/internal/cli-deploy.d.ts.map +1 -1
  322. package/dist/internal/cli-deploy.js +1457 -1507
  323. package/dist/internal/cli-docs.js +130 -147
  324. package/dist/internal/cli-github.js +437 -476
  325. package/dist/internal/cli-gitlab.js +259 -288
  326. package/dist/internal/cli-images.js +266 -334
  327. package/dist/internal/cli-manifest.js +25 -37
  328. package/dist/internal/cli-mcp-oauth.js +228 -247
  329. package/dist/internal/cli-mcp.js +358 -383
  330. package/dist/internal/cli-migrate.js +73 -90
  331. package/dist/internal/cli-skills.js +35 -47
  332. package/dist/internal/cli-slack-manual.d.ts +0 -1
  333. package/dist/internal/cli-slack-manual.d.ts.map +1 -1
  334. package/dist/internal/cli-slack-manual.js +175 -204
  335. package/dist/internal/cli-slack.d.ts +1 -1
  336. package/dist/internal/cli-slack.d.ts.map +1 -1
  337. package/dist/internal/cli-slack.js +416 -456
  338. package/dist/internal/cloud-merge.js +7 -3
  339. package/dist/internal/cloud-turn-cost.js +8 -1
  340. package/dist/internal/connection-env.js +5 -6
  341. package/dist/internal/continuation-channel.js +10 -7
  342. package/dist/internal/continuation-identity.js +85 -67
  343. package/dist/internal/conversation-mirror.js +112 -131
  344. package/dist/internal/convert-automation/convert-workflow.js +21 -31
  345. package/dist/internal/cron.js +3 -3
  346. package/dist/internal/cursor/account-mcp.js +147 -146
  347. package/dist/internal/cursor/backend-client.js +290 -320
  348. package/dist/internal/cursor/bound-secret-file.js +3 -3
  349. package/dist/internal/cursor/credentials.js +127 -142
  350. package/dist/internal/cursor/cursor-api-transport.js +4 -8
  351. package/dist/internal/cursor/github-credentials.js +91 -108
  352. package/dist/internal/cursor/hosted-bound-secrets.js +3 -4
  353. package/dist/internal/cursor/hosted-deployment-secrets.js +1 -1
  354. package/dist/internal/cursor/hosted-store-secrets.js +5 -9
  355. package/dist/internal/cursor/session-token.js +36 -48
  356. package/dist/internal/cursor/store-api-client.js +77 -92
  357. package/dist/internal/cursor-account-mcp-auth.js +132 -149
  358. package/dist/internal/cursor-agent-template.js +1 -1
  359. package/dist/internal/cursor-deployment-relay.js +33 -54
  360. package/dist/internal/cursor-event-relay.js +65 -59
  361. package/dist/internal/cursor-relay-core.js +258 -286
  362. package/dist/internal/deferred-channel-session.js +3 -12
  363. package/dist/internal/deploy-client.js +410 -475
  364. package/dist/internal/deploy-manifest.d.ts +17 -0
  365. package/dist/internal/deploy-manifest.d.ts.map +1 -1
  366. package/dist/internal/deploy-manifest.js +71 -21
  367. package/dist/internal/deploy-source.js +31 -43
  368. package/dist/internal/discovery/agent-config.js +45 -59
  369. package/dist/internal/discovery/agent.js +276 -280
  370. package/dist/internal/discovery/channels.js +67 -80
  371. package/dist/internal/discovery/connections.js +286 -296
  372. package/dist/internal/discovery/context.js +2 -13
  373. package/dist/internal/discovery/cursor-plugin.js +223 -259
  374. package/dist/internal/discovery/extension-overlay.js +104 -131
  375. package/dist/internal/discovery/extensions.js +276 -281
  376. package/dist/internal/discovery/fs.js +56 -79
  377. package/dist/internal/discovery/hooks.js +39 -50
  378. package/dist/internal/discovery/info.js +17 -19
  379. package/dist/internal/discovery/instructions.js +58 -71
  380. package/dist/internal/discovery/modules.js +45 -58
  381. package/dist/internal/discovery/project.d.ts.map +1 -1
  382. package/dist/internal/discovery/project.js +192 -215
  383. package/dist/internal/discovery/reminders.js +41 -52
  384. package/dist/internal/discovery/runtime.js +1 -1
  385. package/dist/internal/discovery/schedules.js +71 -82
  386. package/dist/internal/discovery/seed-files.js +21 -32
  387. package/dist/internal/discovery/services.js +74 -96
  388. package/dist/internal/discovery/skills.js +77 -94
  389. package/dist/internal/discovery/subagent.js +79 -95
  390. package/dist/internal/discovery/tools.js +12 -23
  391. package/dist/internal/distribution.js +2 -2
  392. package/dist/internal/docs-site.js +30 -45
  393. package/dist/internal/duration.js +1 -1
  394. package/dist/internal/env-file.js +48 -64
  395. package/dist/internal/eval-judge-model.js +17 -28
  396. package/dist/internal/eval-run-store.js +265 -254
  397. package/dist/internal/eval-runner.d.ts +8 -0
  398. package/dist/internal/eval-runner.d.ts.map +1 -1
  399. package/dist/internal/eval-runner.js +406 -408
  400. package/dist/internal/eval-transport.d.ts +24 -0
  401. package/dist/internal/eval-transport.d.ts.map +1 -0
  402. package/dist/internal/eval-transport.js +22 -0
  403. package/dist/internal/evals-client.js +242 -246
  404. package/dist/internal/event-log.js +72 -120
  405. package/dist/internal/event-mapper.js +30 -31
  406. package/dist/internal/factory-resource-channel.js +16 -30
  407. package/dist/internal/filesystem/errors.js +6 -6
  408. package/dist/internal/filesystem/format.js +10 -13
  409. package/dist/internal/filesystem/merge.js +52 -94
  410. package/dist/internal/filesystem/nearest.js +15 -27
  411. package/dist/internal/filesystem/scratch.js +65 -85
  412. package/dist/internal/filesystem/tools.js +221 -241
  413. package/dist/internal/filesystem/walk.js +76 -143
  414. package/dist/internal/framework-file-storage.js +118 -139
  415. package/dist/internal/framework-storage-selection.js +21 -13
  416. package/dist/internal/frontmatter.js +4 -6
  417. package/dist/internal/github-fanout.js +50 -64
  418. package/dist/internal/guest-network.js +96 -109
  419. package/dist/internal/handleAgentServeTrigger.js +121 -126
  420. package/dist/internal/host-files.js +73 -88
  421. package/dist/internal/host-kv.js +21 -36
  422. package/dist/internal/host-otel.js +22 -19
  423. package/dist/internal/host-platforms.js +49 -63
  424. package/dist/internal/hosted-catch-protocol.d.ts +1 -0
  425. package/dist/internal/hosted-catch-protocol.d.ts.map +1 -1
  426. package/dist/internal/hosted-catch-protocol.js +1 -0
  427. package/dist/internal/hosted-catch.d.ts +5 -3
  428. package/dist/internal/hosted-catch.d.ts.map +1 -1
  429. package/dist/internal/hosted-catch.js +84 -93
  430. package/dist/internal/hosted-delivery-protocol.js +32 -8
  431. package/dist/internal/hosted-delivery.d.ts +13 -1
  432. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  433. package/dist/internal/hosted-delivery.js +614 -584
  434. package/dist/internal/hosted-eval-cases.d.ts +21 -0
  435. package/dist/internal/hosted-eval-cases.d.ts.map +1 -0
  436. package/dist/internal/hosted-eval-cases.js +162 -0
  437. package/dist/internal/hosted-execution-diag.js +38 -30
  438. package/dist/internal/hosted-execution-flush.js +75 -66
  439. package/dist/internal/hosted-execution-latency.js +16 -8
  440. package/dist/internal/hosted-managed-automation.js +2 -2
  441. package/dist/internal/hosting.js +2 -3
  442. package/dist/internal/http-channel-define.js +4 -1
  443. package/dist/internal/http-channel.js +101 -112
  444. package/dist/internal/http-control-plane-session.d.ts +18 -1
  445. package/dist/internal/http-control-plane-session.d.ts.map +1 -1
  446. package/dist/internal/http-control-plane-session.js +66 -32
  447. package/dist/internal/incoming-headers-to-fetch.js +1 -2
  448. package/dist/internal/init-interview.js +73 -93
  449. package/dist/internal/init-project.js +182 -214
  450. package/dist/internal/init-scaffold.js +10 -21
  451. package/dist/internal/inline-stdio-mcp.js +80 -86
  452. package/dist/internal/install-cursor-skills.js +231 -273
  453. package/dist/internal/legacy-command-guard.js +18 -31
  454. package/dist/internal/listen-port.js +34 -45
  455. package/dist/internal/local-control-plane.js +293 -307
  456. package/dist/internal/local-env.js +1 -1
  457. package/dist/internal/local-ingress.js +15 -9
  458. package/dist/internal/log-ring.js +1 -2
  459. package/dist/internal/logs-client.js +207 -227
  460. package/dist/internal/map-pool.js +24 -38
  461. package/dist/internal/mcp-endpoint.js +204 -180
  462. package/dist/internal/mcp-host.js +165 -168
  463. package/dist/internal/mcp-oauth-on-demand.js +170 -207
  464. package/dist/internal/mcp-oauth-persist.js +15 -29
  465. package/dist/internal/mcp-oauth.js +209 -266
  466. package/dist/internal/named-webhook-secret.d.ts +39 -0
  467. package/dist/internal/named-webhook-secret.d.ts.map +1 -0
  468. package/dist/internal/named-webhook-secret.js +47 -0
  469. package/dist/internal/open-browser.js +2 -3
  470. package/dist/internal/otel/collector.js +104 -68
  471. package/dist/internal/otel/config.js +24 -37
  472. package/dist/internal/otel/http.js +5 -7
  473. package/dist/internal/otel/mcp.js +3 -12
  474. package/dist/internal/otel/runtime.js +69 -83
  475. package/dist/internal/package-inline-stdio.js +57 -65
  476. package/dist/internal/peer-connections.js +9 -5
  477. package/dist/internal/platform-schedule-sync.js +39 -54
  478. package/dist/internal/platform-timers.js +176 -210
  479. package/dist/internal/playground/static.js +1 -2
  480. package/dist/internal/playground/toolchain.js +37 -53
  481. package/dist/internal/playground-proxy.js +230 -270
  482. package/dist/internal/process-memory-telemetry.js +33 -51
  483. package/dist/internal/prompt-context.js +3 -6
  484. package/dist/internal/reminder-control-plane-protocol.js +46 -13
  485. package/dist/internal/reminder-runner.js +770 -785
  486. package/dist/internal/reminder-schedule.js +1 -1
  487. package/dist/internal/reminder-store.js +57 -78
  488. package/dist/internal/request-error-status.js +1 -3
  489. package/dist/internal/request-headers.js +2 -2
  490. package/dist/internal/resolve-prod-target.js +119 -135
  491. package/dist/internal/resolved-connections.js +16 -6
  492. package/dist/internal/run-client.js +221 -229
  493. package/dist/internal/runtime-dispatch-runner.js +18 -43
  494. package/dist/internal/schedule-runner.js +49 -58
  495. package/dist/internal/scm/pr-url.js +7 -6
  496. package/dist/internal/sdk-runner.js +388 -363
  497. package/dist/internal/serve-restart.js +26 -39
  498. package/dist/internal/server.d.ts.map +1 -1
  499. package/dist/internal/server.js +1283 -1244
  500. package/dist/internal/session-cost.js +7 -9
  501. package/dist/internal/session-engine.d.ts +3 -1
  502. package/dist/internal/session-engine.d.ts.map +1 -1
  503. package/dist/internal/session-engine.js +2801 -2777
  504. package/dist/internal/session-links.js +12 -16
  505. package/dist/internal/session-run-log.js +134 -82
  506. package/dist/internal/session-store.js +133 -164
  507. package/dist/internal/sessions-client.js +97 -118
  508. package/dist/internal/skill-catalog.js +18 -23
  509. package/dist/internal/skills-sync.js +16 -30
  510. package/dist/internal/slack-provision-client.js +90 -116
  511. package/dist/internal/start-log-store.js +48 -67
  512. package/dist/internal/steering.js +1 -2
  513. package/dist/internal/storage-coordinator.js +160 -196
  514. package/dist/internal/store-mirror.js +16 -30
  515. package/dist/internal/stream-progress.js +6 -8
  516. package/dist/internal/terminal-style.js +3 -4
  517. package/dist/internal/testing/scm-continuation-fixtures.js +6 -2
  518. package/dist/internal/testing/slack-continuation-fixtures.d.ts +26 -0
  519. package/dist/internal/testing/slack-continuation-fixtures.d.ts.map +1 -0
  520. package/dist/internal/testing/slack-continuation-fixtures.js +136 -0
  521. package/dist/internal/tool-catalog.js +11 -5
  522. package/dist/internal/tool-result.js +1 -1
  523. package/dist/internal/trajectory.js +19 -22
  524. package/dist/internal/turn-cost.js +52 -62
  525. package/dist/internal/turn-governor.js +5 -8
  526. package/dist/internal/turn-lease-store.js +85 -105
  527. package/dist/internal/turn-outbox.js +28 -43
  528. package/dist/internal/update-check.js +231 -259
  529. package/dist/internal/v2-hosting.js +1 -2
  530. package/dist/internal/workspace-sync.js +25 -41
  531. package/dist/internal/workspace.js +111 -139
  532. package/dist/kv/memory-kv.js +27 -51
  533. package/dist/memory.js +106 -148
  534. package/dist/otel.js +5 -8
  535. package/dist/playground/assets/index-DXm_VXAQ.css +1 -0
  536. package/dist/playground/assets/{index-Co4CUVTQ.js → index-JekUQERK.js} +45 -45
  537. package/dist/playground/index.html +2 -2
  538. package/dist/prompt.js +2 -4
  539. package/dist/storage-backends/cursor-hosted-v2.js +53 -83
  540. package/dist/storage-backends/cursor-hosted.js +105 -145
  541. package/dist/storage-backends/file-kv.js +100 -128
  542. package/dist/storage-protocol.js +3 -5
  543. package/dist/storage.js +17 -26
  544. package/dist/types.d.ts +68 -0
  545. package/dist/types.d.ts.map +1 -1
  546. package/dist/types.js +20 -18
  547. package/docs/building-with-agents.md +2 -0
  548. package/docs/deployment.md +7 -0
  549. package/docs/guides/bitbucket.md +9 -1
  550. package/docs/guides/github.md +20 -4
  551. package/docs/guides/gitlab.md +9 -1
  552. package/docs/guides/migrate.md +127 -0
  553. package/docs/reference/cli.md +39 -0
  554. package/docs/troubleshooting.md +1 -0
  555. package/package.json +1 -1
  556. package/skills/debug/SKILL.md +1 -0
  557. package/skills/github/SKILL.md +23 -0
  558. package/skills/migrate-v2/SKILL.md +51 -10
  559. package/dist/docs/assets/chunks/@localSearchIndexroot.BJ8UZggu.js +0 -1
  560. package/dist/docs/assets/chunks/channel.BTJ5J9FI.js +0 -1
  561. package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.D4BZ3cVV.js +0 -1
  562. package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.D4BZ3cVV.js +0 -1
  563. package/dist/docs/assets/chunks/clone.62tX-O-1.js +0 -1
  564. package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.DkTs1aEU.js +0 -1
  565. package/dist/docs/assets/reference_cli.md.GwugN3n-.lean.js +0 -1
  566. package/dist/docs/assets/troubleshooting.md.Bscj6ODe.js +0 -1
  567. package/dist/playground/assets/index-C1g_PTTZ.css +0 -1
  568. /package/dist/docs/assets/{building-with-agents.md.BPjPFxFg.lean.js → building-with-agents.md.Df87rAe1.lean.js} +0 -0
  569. /package/dist/docs/assets/{deployment.md.BdqTiGdc.lean.js → deployment.md.BYuEcDBv.lean.js} +0 -0
  570. /package/dist/docs/assets/{reference_skills.md.ClkMoQsV.lean.js → reference_skills.md.C0guGcH0.lean.js} +0 -0
@@ -1,12 +1,3 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
1
  import { randomBytes } from "node:crypto";
11
2
  import { packageVersion } from "./distribution.js";
12
3
  import { dispatchOutcome } from "./channel-dispatch.js";
@@ -27,19 +18,16 @@ import { endActiveHttpSpan } from "./otel/http.js";
27
18
  import { ReminderValidationError, UnknownReminderError } from "./reminder-runner.js";
28
19
  import { mapThrownRequestError, statusForThrownRequestError } from "./request-error-status.js";
29
20
  import { HostedEnqueueNotActiveError } from "./session-engine.js";
30
- function responseToReply(response) {
31
- return __awaiter(this, void 0, void 0, function* () {
32
- var _a;
33
- const value = (yield response.json());
34
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
35
- throw new Error("Hosted delivery produced a non-object JSON response.");
36
- }
37
- return {
38
- status: response.status,
39
- body: value,
40
- serverTiming: (_a = response.headers.get("server-timing")) !== null && _a !== void 0 ? _a : undefined,
41
- };
42
- });
21
+ async function responseToReply(response) {
22
+ const value = (await response.json());
23
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
24
+ throw new Error("Hosted delivery produced a non-object JSON response.");
25
+ }
26
+ return {
27
+ status: response.status,
28
+ body: value,
29
+ serverTiming: response.headers.get("server-timing") ?? undefined,
30
+ };
43
31
  }
44
32
  function responseFromReply(reply) {
45
33
  return Response.json(reply.body, {
@@ -79,16 +67,14 @@ function boundedMessage(text) {
79
67
  * Carry it, bounded, into the terminal channel_dispatch_failed so the
80
68
  * control plane's failure log is diagnosable.
81
69
  */
82
- function channelDispatchDetail(response) {
83
- return __awaiter(this, void 0, void 0, function* () {
84
- try {
85
- const text = (yield response.text()).trim();
86
- return text === "" ? undefined : boundedMessage(text);
87
- }
88
- catch (_a) {
89
- return undefined;
90
- }
91
- });
70
+ async function channelDispatchDetail(response) {
71
+ try {
72
+ const text = (await response.text()).trim();
73
+ return text === "" ? undefined : boundedMessage(text);
74
+ }
75
+ catch {
76
+ return undefined;
77
+ }
92
78
  }
93
79
  function terminalHostedError(status, error, message) {
94
80
  return hostedGuestErrorResponse({
@@ -160,18 +146,16 @@ function mappedAdmissionFailure(error) {
160
146
  * Dispatch is the adapter the mounted channel attached. Hosted delivery
161
147
  * does not switch on `channelKind`.
162
148
  */
163
- export function dispatchHostedAdmission(input) {
164
- return __awaiter(this, void 0, void 0, function* () {
165
- const adapter = getHostedAdmissionAdapter(input.definition);
166
- if (adapter === undefined || adapter.kind !== input.delivery.channelKind) {
167
- return {
168
- response: terminalHostedError(422, "channel_kind_mismatch"),
169
- };
170
- }
171
- // The admission window marker follows the async graph into task bodies so
172
- // the engine can refuse local sends that would bypass the capture stub.
173
- return runDuringHostedAdmission(() => runAdmission(input, adapter));
174
- });
149
+ export async function dispatchHostedAdmission(input) {
150
+ const adapter = getHostedAdmissionAdapter(input.definition);
151
+ if (adapter === undefined || adapter.kind !== input.delivery.channelKind) {
152
+ return {
153
+ response: terminalHostedError(422, "channel_kind_mismatch"),
154
+ };
155
+ }
156
+ // The admission window marker follows the async graph into task bodies so
157
+ // the engine can refuse local sends that would bypass the capture stub.
158
+ return runDuringHostedAdmission(() => runAdmission(input, adapter));
175
159
  }
176
160
  /**
177
161
  * Reserved reminder admission: parse the compact payload and invoke
@@ -179,42 +163,14 @@ export function dispatchHostedAdmission(input) {
179
163
  * `skip`) and never opens the send-capture / model-session path here —
180
164
  * prompt-form fires still follow up inside the runner.
181
165
  */
182
- function dispatchHostedReminderAdmission(input, delivery) {
183
- return __awaiter(this, void 0, void 0, function* () {
184
- const descriptor = parseHostedReminderFireDescriptorPayload(delivery.payload);
185
- if (descriptor !== undefined) {
186
- if (input.executeReminderDescriptor === undefined) {
187
- return transientHostedError(503, "reminder_dispatch_unavailable", "This guest has no reminder CP executor wired for hosted admission.");
188
- }
189
- try {
190
- const result = yield input.executeReminderDescriptor(descriptor);
191
- const outcome = result.outcome === "noop" ? "skip" : "task";
192
- return Response.json({
193
- ok: true,
194
- v: HOSTED_DELIVERY_PROTOCOL_VERSION,
195
- outcome,
196
- });
197
- }
198
- catch (error) {
199
- if (error instanceof UnknownReminderError) {
200
- return terminalHostedError(404, "unknown_reminder", boundedMessage(error.message));
201
- }
202
- if (error instanceof ReminderValidationError) {
203
- return terminalHostedError(400, "invalid_reminder", boundedMessage(error.message));
204
- }
205
- // Transient CP apply/fetch failures must remain retryable.
206
- throw error;
207
- }
208
- }
209
- if (input.fireReminder === undefined) {
210
- return transientHostedError(503, "reminder_dispatch_unavailable", "This guest has no reminder runner wired for hosted admission.");
211
- }
212
- const payload = parseHostedReminderFirePayload(delivery.payload);
213
- if (payload === undefined) {
214
- return terminalHostedError(400, "invalid_reminder_payload", "Expected reminder descriptor or legacy payload { reminderId, fireCount }.");
166
+ async function dispatchHostedReminderAdmission(input, delivery) {
167
+ const descriptor = parseHostedReminderFireDescriptorPayload(delivery.payload);
168
+ if (descriptor !== undefined) {
169
+ if (input.executeReminderDescriptor === undefined) {
170
+ return transientHostedError(503, "reminder_dispatch_unavailable", "This guest has no reminder CP executor wired for hosted admission.");
215
171
  }
216
172
  try {
217
- const result = yield input.fireReminder(payload.reminderId, payload.fireCount);
173
+ const result = await input.executeReminderDescriptor(descriptor);
218
174
  const outcome = result.outcome === "noop" ? "skip" : "task";
219
175
  return Response.json({
220
176
  ok: true,
@@ -229,114 +185,143 @@ function dispatchHostedReminderAdmission(input, delivery) {
229
185
  if (error instanceof ReminderValidationError) {
230
186
  return terminalHostedError(400, "invalid_reminder", boundedMessage(error.message));
231
187
  }
188
+ // Transient CP apply/fetch failures must remain retryable.
232
189
  throw error;
233
190
  }
234
- });
235
- }
236
- function runAdmission(input, adapter) {
237
- return __awaiter(this, void 0, void 0, function* () {
238
- var _a;
239
- var _b;
240
- const background = [];
241
- let captured;
242
- const capturingArgs = Object.assign(Object.assign({}, input.args), { send: (message_1, ...args_1) => __awaiter(this, [message_1, ...args_1], void 0, function* (message, options = {}) {
243
- if (captured !== undefined) {
244
- throw new HostedSendLimitExceeded();
245
- }
246
- captured = { message, options };
247
- return createDeferredChannelSession();
248
- }), waitUntil: promise => {
249
- background.push(promise);
250
- } });
251
- const args = (_b = (_a = adapter.prepareArgs) === null || _a === void 0 ? void 0 : _a.call(adapter, capturingArgs)) !== null && _b !== void 0 ? _b : capturingArgs;
252
- let dispatched;
253
- try {
254
- dispatched = yield adapter.dispatch({
255
- channelId: input.delivery.channelId,
256
- eventType: input.delivery.eventType,
257
- payload: input.delivery.payload,
258
- deliveryId: input.delivery.deliveryId,
259
- args,
260
- mailboxContinuationKey: input.delivery.mailboxContinuationKey,
261
- platformHandoff: input.delivery.platformHandoff,
262
- });
263
- }
264
- catch (error) {
265
- const mapped = mappedAdmissionFailure(error);
266
- if (mapped !== undefined) {
267
- return mapped;
268
- }
269
- return {
270
- response: terminalHostedError(500, "agent_admission_threw", boundedMessage(error instanceof Error ? error.message : String(error))),
271
- };
272
- }
273
- if (!dispatched.ok) {
274
- return {
275
- response: terminalHostedError(dispatched.status >= 400 ? dispatched.status : 502, "channel_dispatch_failed", yield channelDispatchDetail(dispatched)),
276
- };
191
+ }
192
+ if (input.fireReminder === undefined) {
193
+ return transientHostedError(503, "reminder_dispatch_unavailable", "This guest has no reminder runner wired for hosted admission.");
194
+ }
195
+ const payload = parseHostedReminderFirePayload(delivery.payload);
196
+ if (payload === undefined) {
197
+ return terminalHostedError(400, "invalid_reminder_payload", "Expected reminder descriptor or legacy payload { reminderId, fireCount }.");
198
+ }
199
+ try {
200
+ const result = await input.fireReminder(payload.reminderId, payload.fireCount);
201
+ const outcome = result.outcome === "noop" ? "skip" : "task";
202
+ return Response.json({
203
+ ok: true,
204
+ v: HOSTED_DELIVERY_PROTOCOL_VERSION,
205
+ outcome,
206
+ });
207
+ }
208
+ catch (error) {
209
+ if (error instanceof UnknownReminderError) {
210
+ return terminalHostedError(404, "unknown_reminder", boundedMessage(error.message));
277
211
  }
278
- try {
279
- yield Promise.all(background);
212
+ if (error instanceof ReminderValidationError) {
213
+ return terminalHostedError(400, "invalid_reminder", boundedMessage(error.message));
280
214
  }
281
- catch (error) {
282
- const mapped = mappedAdmissionFailure(error);
283
- if (mapped !== undefined) {
284
- return mapped;
215
+ throw error;
216
+ }
217
+ }
218
+ async function runAdmission(input, adapter) {
219
+ const background = [];
220
+ let captured;
221
+ const capturingArgs = {
222
+ ...input.args,
223
+ send: async (message, options = {}) => {
224
+ if (captured !== undefined) {
225
+ throw new HostedSendLimitExceeded();
285
226
  }
286
- return {
287
- response: terminalHostedError(503, "background_dispatch_failed", boundedMessage(error instanceof Error ? error.message : String(error))),
288
- };
289
- }
290
- if (captured !== undefined) {
291
- return {
292
- response: Response.json({
293
- ok: true,
294
- v: HOSTED_DELIVERY_PROTOCOL_VERSION,
295
- outcome: "send",
296
- }),
297
- pendingSend: {
298
- channelId: input.delivery.channelId,
299
- message: captured.message,
300
- options: captured.options,
301
- mailboxContinuationKey: input.delivery.mailboxContinuationKey,
302
- },
303
- };
227
+ captured = { message, options };
228
+ return createDeferredChannelSession();
229
+ },
230
+ waitUntil: promise => {
231
+ background.push(promise);
232
+ },
233
+ };
234
+ const args = adapter.prepareArgs?.(capturingArgs) ?? capturingArgs;
235
+ let dispatched;
236
+ try {
237
+ dispatched = await adapter.dispatch({
238
+ channelId: input.delivery.channelId,
239
+ eventType: input.delivery.eventType,
240
+ payload: input.delivery.payload,
241
+ deliveryId: input.delivery.deliveryId,
242
+ args,
243
+ mailboxContinuationKey: input.delivery.mailboxContinuationKey,
244
+ platformHandoff: input.delivery.platformHandoff,
245
+ });
246
+ }
247
+ catch (error) {
248
+ const mapped = mappedAdmissionFailure(error);
249
+ if (mapped !== undefined) {
250
+ return mapped;
304
251
  }
305
- // A "send" tag with nothing captured means the channel's send bypassed the
306
- // capture stub, so there is nothing for the control plane to execute.
307
- const outcome = dispatchOutcome(dispatched);
308
- if (outcome === undefined || outcome === "send") {
309
- return {
310
- response: terminalHostedError(502, "channel_outcome_missing"),
311
- };
252
+ return {
253
+ response: terminalHostedError(500, "agent_admission_threw", boundedMessage(error instanceof Error ? error.message : String(error))),
254
+ };
255
+ }
256
+ if (!dispatched.ok) {
257
+ return {
258
+ response: terminalHostedError(dispatched.status >= 400 ? dispatched.status : 502, "channel_dispatch_failed", await channelDispatchDetail(dispatched)),
259
+ };
260
+ }
261
+ try {
262
+ await Promise.all(background);
263
+ }
264
+ catch (error) {
265
+ const mapped = mappedAdmissionFailure(error);
266
+ if (mapped !== undefined) {
267
+ return mapped;
312
268
  }
313
- const rejection = outcome === "skip" ? yield handlerRejection(dispatched) : undefined;
314
269
  return {
315
- response: Response.json(Object.assign({ ok: true, v: HOSTED_DELIVERY_PROTOCOL_VERSION, outcome }, (rejection === undefined ? {} : { rejection, engineVersion: packageVersion() }))),
270
+ response: terminalHostedError(503, "background_dispatch_failed", boundedMessage(error instanceof Error ? error.message : String(error))),
316
271
  };
317
- });
272
+ }
273
+ if (captured !== undefined) {
274
+ return {
275
+ response: Response.json({
276
+ ok: true,
277
+ v: HOSTED_DELIVERY_PROTOCOL_VERSION,
278
+ outcome: "send",
279
+ }),
280
+ pendingSend: {
281
+ channelId: input.delivery.channelId,
282
+ message: captured.message,
283
+ options: captured.options,
284
+ mailboxContinuationKey: input.delivery.mailboxContinuationKey,
285
+ },
286
+ };
287
+ }
288
+ // A "send" tag with nothing captured means the channel's send bypassed the
289
+ // capture stub, so there is nothing for the control plane to execute.
290
+ const outcome = dispatchOutcome(dispatched);
291
+ if (outcome === undefined || outcome === "send") {
292
+ return {
293
+ response: terminalHostedError(502, "channel_outcome_missing"),
294
+ };
295
+ }
296
+ const rejection = outcome === "skip" ? await handlerRejection(dispatched) : undefined;
297
+ return {
298
+ response: Response.json({
299
+ ok: true,
300
+ v: HOSTED_DELIVERY_PROTOCOL_VERSION,
301
+ outcome,
302
+ ...(rejection === undefined ? {} : { rejection, engineVersion: packageVersion() }),
303
+ }),
304
+ };
318
305
  }
319
306
  /** Handler 4xx on a skip. Benign skips (nothing to do) have no status. */
320
- function handlerRejection(response) {
321
- return __awaiter(this, void 0, void 0, function* () {
322
- try {
323
- const body = (yield response.clone().json());
324
- if (typeof body !== "object" || body === null || Array.isArray(body)) {
325
- return undefined;
326
- }
327
- const record = body;
328
- if (record.skipped !== true) {
329
- return undefined;
330
- }
331
- return parseHostedAdmissionHandlerRejection({
332
- reason: record.reason,
333
- status: record.status,
334
- });
307
+ async function handlerRejection(response) {
308
+ try {
309
+ const body = (await response.clone().json());
310
+ if (typeof body !== "object" || body === null || Array.isArray(body)) {
311
+ return undefined;
335
312
  }
336
- catch (_a) {
313
+ const record = body;
314
+ if (record.skipped !== true) {
337
315
  return undefined;
338
316
  }
339
- });
317
+ return parseHostedAdmissionHandlerRejection({
318
+ reason: record.reason,
319
+ status: record.status,
320
+ });
321
+ }
322
+ catch {
323
+ return undefined;
324
+ }
340
325
  }
341
326
  function withServerTiming(response, durationMs, guestNetwork, latency) {
342
327
  const parts = [`agent_sdk;desc="hosted";dur=${Math.max(0, durationMs).toFixed(1)}`];
@@ -391,15 +376,14 @@ function logGuestNetworkWait(phase, stats) {
391
376
  console.info(`[bdk] guest network ${stats.outcome} phase=${phase} waitMs=${String(stats.waitMs)} probes=${String(stats.probeAttempts)}`);
392
377
  }
393
378
  export function registerHostedDeliveryRoute(input) {
394
- var _a, _b;
395
379
  const pending = new Map();
396
380
  const admissions = new Map();
397
381
  const activeOwners = new Map();
398
- const pendingTtlMs = 10 * 60000;
382
+ const pendingTtlMs = 10 * 60_000;
399
383
  /** Keep an in-flight owner turn addressable for status polls. */
400
- const ownerTurnPendingTtlMs = 12 * 60 * 60000;
401
- const waitForNetwork = (_a = input.waitForGuestNetwork) !== null && _a !== void 0 ? _a : (() => waitForGuestNetworkReady());
402
- const consumeBoundSecrets = (_b = input.consumeBoundSecrets) !== null && _b !== void 0 ? _b : (() => consumeHostedBoundSecrets());
384
+ const ownerTurnPendingTtlMs = 12 * 60 * 60_000;
385
+ const waitForNetwork = input.waitForGuestNetwork ?? (() => waitForGuestNetworkReady());
386
+ const consumeBoundSecrets = input.consumeBoundSecrets ?? (() => consumeHostedBoundSecrets());
403
387
  /**
404
388
  * Close the bind-file handoff before anything else touches the request.
405
389
  * A surviving secret is retryable: the control plane re-binds and the next
@@ -411,9 +395,9 @@ export function registerHostedDeliveryRoute(input) {
411
395
  ? undefined
412
396
  : transientHostedError(503, consumed.code, boundedMessage(consumed.message));
413
397
  };
414
- const finishNetworkWait = (phase) => __awaiter(this, void 0, void 0, function* () {
398
+ const finishNetworkWait = async (phase) => {
415
399
  try {
416
- const timing = guestNetworkStatsFromWait(yield waitForNetwork());
400
+ const timing = guestNetworkStatsFromWait(await waitForNetwork());
417
401
  logGuestNetworkWait(phase, timing);
418
402
  return { timing };
419
403
  }
@@ -430,7 +414,7 @@ export function registerHostedDeliveryRoute(input) {
430
414
  response: transientHostedError(503, GUEST_NETWORK_UNAVAILABLE, boundedMessage(message)),
431
415
  };
432
416
  }
433
- });
417
+ };
434
418
  const pruneExpired = () => {
435
419
  const now = Date.now();
436
420
  for (const [token, item] of pending) {
@@ -444,50 +428,48 @@ export function registerHostedDeliveryRoute(input) {
444
428
  }
445
429
  }
446
430
  };
447
- const runAdmissionOperation = (delivery, definition) => __awaiter(this, void 0, void 0, function* () {
448
- return afterHostedWork(input.flushOtel, () => __awaiter(this, void 0, void 0, function* () {
449
- const startedAt = performance.now();
450
- let guestNetwork;
451
- const finish = (response) => withServerTiming(response, performance.now() - startedAt, guestNetwork);
452
- try {
453
- const network = yield finishNetworkWait("admission");
454
- guestNetwork = network.timing;
455
- if (network.response !== undefined) {
456
- return yield responseToReply(finish(network.response));
457
- }
458
- if (isHostedReminderAdmission(delivery)) {
459
- return yield responseToReply(finish(yield dispatchHostedReminderAdmission(input, delivery)));
460
- }
461
- if (definition === undefined) {
462
- return yield responseToReply(finish(terminalHostedError(404, "channel_not_found", `No channel named "${delivery.channelId}" is mounted.`)));
463
- }
464
- const admitted = yield dispatchHostedAdmission({
465
- delivery,
466
- definition,
467
- args: input.buildHandlerArgs(delivery.channelId),
468
- });
469
- if (admitted.pendingSend === undefined) {
470
- return yield responseToReply(finish(admitted.response));
471
- }
472
- pruneExpired();
473
- const admissionToken = randomBytes(24).toString("hex");
474
- pending.set(admissionToken, {
475
- send: admitted.pendingSend,
476
- channelKind: delivery.channelKind,
477
- expiresAt: Date.now() + pendingTtlMs,
478
- deliveryId: delivery.deliveryId,
479
- });
480
- return yield responseToReply(finish(Response.json({
481
- ok: true,
482
- v: HOSTED_DELIVERY_PROTOCOL_VERSION,
483
- outcome: "send",
484
- admissionToken,
485
- })));
431
+ const runAdmissionOperation = async (delivery, definition) => afterHostedWork(input.flushOtel, async () => {
432
+ const startedAt = performance.now();
433
+ let guestNetwork;
434
+ const finish = (response) => withServerTiming(response, performance.now() - startedAt, guestNetwork);
435
+ try {
436
+ const network = await finishNetworkWait("admission");
437
+ guestNetwork = network.timing;
438
+ if (network.response !== undefined) {
439
+ return await responseToReply(finish(network.response));
440
+ }
441
+ if (isHostedReminderAdmission(delivery)) {
442
+ return await responseToReply(finish(await dispatchHostedReminderAdmission(input, delivery)));
443
+ }
444
+ if (definition === undefined) {
445
+ return await responseToReply(finish(terminalHostedError(404, "channel_not_found", `No channel named "${delivery.channelId}" is mounted.`)));
486
446
  }
487
- catch (error) {
488
- return yield responseToReply(finish(terminalHostedError(503, "internal_error", boundedMessage(error instanceof Error ? error.message : String(error)))));
447
+ const admitted = await dispatchHostedAdmission({
448
+ delivery,
449
+ definition,
450
+ args: input.buildHandlerArgs(delivery.channelId),
451
+ });
452
+ if (admitted.pendingSend === undefined) {
453
+ return await responseToReply(finish(admitted.response));
489
454
  }
490
- }));
455
+ pruneExpired();
456
+ const admissionToken = randomBytes(24).toString("hex");
457
+ pending.set(admissionToken, {
458
+ send: admitted.pendingSend,
459
+ channelKind: delivery.channelKind,
460
+ expiresAt: Date.now() + pendingTtlMs,
461
+ deliveryId: delivery.deliveryId,
462
+ });
463
+ return await responseToReply(finish(Response.json({
464
+ ok: true,
465
+ v: HOSTED_DELIVERY_PROTOCOL_VERSION,
466
+ outcome: "send",
467
+ admissionToken,
468
+ })));
469
+ }
470
+ catch (error) {
471
+ return await responseToReply(finish(terminalHostedError(503, "internal_error", boundedMessage(error instanceof Error ? error.message : String(error)))));
472
+ }
491
473
  });
492
474
  // Hosted callers reach this only through Anyrun's signed pod-port URL.
493
475
  // The marker is a second, route-specific fence distinct from channel auth.
@@ -505,86 +487,83 @@ export function registerHostedDeliveryRoute(input) {
505
487
  method: "POST",
506
488
  pattern: `${input.base}${HOSTED_ADMISSION_PATH}`,
507
489
  auth: [auth],
508
- handler: (request) => __awaiter(this, void 0, void 0, function* () {
509
- return afterHostedWork(input.flushOtel, () => __awaiter(this, void 0, void 0, function* () {
510
- var _a;
511
- const startedAt = performance.now();
512
- const finish = (response) => withServerTiming(response, performance.now() - startedAt);
513
- const unconsumed = finishBoundSecrets();
514
- if (unconsumed !== undefined) {
515
- return finish(unconsumed);
490
+ handler: async (request) => afterHostedWork(input.flushOtel, async () => {
491
+ const startedAt = performance.now();
492
+ const finish = (response) => withServerTiming(response, performance.now() - startedAt);
493
+ const unconsumed = finishBoundSecrets();
494
+ if (unconsumed !== undefined) {
495
+ return finish(unconsumed);
496
+ }
497
+ const rawAdmission = await readJsonObject(request);
498
+ const delivery = parseHostedAdmission(rawAdmission);
499
+ if (delivery === undefined) {
500
+ const rawKeys = typeof rawAdmission === "object" &&
501
+ rawAdmission !== null &&
502
+ !Array.isArray(rawAdmission)
503
+ ? Object.keys(rawAdmission)
504
+ : [];
505
+ console.info(`[bdk] hosted admission rejected: envelope failed to parse keys=${JSON.stringify(rawKeys)} hasManagedAutomation=${String(rawKeys.includes("managedAutomation"))}`);
506
+ return finish(terminalHostedError(400, "invalid_hosted_admission", "Expected a supported Agent SDK hosted-admission envelope."));
507
+ }
508
+ pruneExpired();
509
+ const existing = admissions.get(delivery.deliveryId);
510
+ if (delivery.mode === "status") {
511
+ if (existing === undefined) {
512
+ return finish(transientHostedError(409, "hosted_admission_unavailable", "No hosted admission is in flight for this delivery."));
516
513
  }
517
- const rawAdmission = yield readJsonObject(request);
518
- const delivery = parseHostedAdmission(rawAdmission);
519
- if (delivery === undefined) {
520
- const rawKeys = typeof rawAdmission === "object" &&
521
- rawAdmission !== null &&
522
- !Array.isArray(rawAdmission)
523
- ? Object.keys(rawAdmission)
524
- : [];
525
- console.info(`[bdk] hosted admission rejected: envelope failed to parse keys=${JSON.stringify(rawKeys)} hasManagedAutomation=${String(rawKeys.includes("managedAutomation"))}`);
526
- return finish(terminalHostedError(400, "invalid_hosted_admission", "Expected a supported Agent SDK hosted-admission envelope."));
514
+ return existing.settledReply === undefined
515
+ ? finish(Response.json({
516
+ ok: true,
517
+ v: HOSTED_DELIVERY_PROTOCOL_VERSION,
518
+ outcome: "running",
519
+ }))
520
+ : responseFromReply(existing.settledReply);
521
+ }
522
+ if (existing !== undefined) {
523
+ if (existing.settledReply !== undefined && isTransientRetryReply(existing.settledReply)) {
524
+ admissions.delete(delivery.deliveryId);
527
525
  }
528
- pruneExpired();
529
- const existing = admissions.get(delivery.deliveryId);
530
- if (delivery.mode === "status") {
531
- if (existing === undefined) {
532
- return finish(transientHostedError(409, "hosted_admission_unavailable", "No hosted admission is in flight for this delivery."));
533
- }
526
+ else {
534
527
  return existing.settledReply === undefined
535
528
  ? finish(Response.json({
536
529
  ok: true,
537
530
  v: HOSTED_DELIVERY_PROTOCOL_VERSION,
538
- outcome: "running",
531
+ outcome: "started",
539
532
  }))
540
533
  : responseFromReply(existing.settledReply);
541
534
  }
542
- if (existing !== undefined) {
543
- if (existing.settledReply !== undefined && isTransientRetryReply(existing.settledReply)) {
544
- admissions.delete(delivery.deliveryId);
545
- }
546
- else {
547
- return existing.settledReply === undefined
548
- ? finish(Response.json({
549
- ok: true,
550
- v: HOSTED_DELIVERY_PROTOCOL_VERSION,
551
- outcome: "started",
552
- }))
553
- : responseFromReply(existing.settledReply);
554
- }
555
- }
556
- console.info(`[bdk] hosted admission received deliveryId=${delivery.deliveryId} channelId=${delivery.channelId} channelKind=${delivery.channelKind} eventType=${delivery.eventType} sessionMode=${delivery.sessionMode} managedAutomation=${delivery.managedAutomation === undefined ? "<absent>" : `automationUuid=${delivery.managedAutomation.automationUuid} mcpServerNames=${String(delivery.managedAutomation.mcpServerNames.length)} slackChannels=${delivery.managedAutomation.slackChannels === undefined ? "<absent>" : JSON.stringify(delivery.managedAutomation.slackChannels)}`}`);
557
- recordHostedManagedAutomation(delivery);
558
- const reminder = isHostedReminderAdmission(delivery);
559
- const definition = reminder
560
- ? undefined
561
- : (_a = input.channels.find(candidate => candidate.id === delivery.channelId)) === null || _a === void 0 ? void 0 : _a.definition;
562
- if (!reminder && definition === undefined) {
563
- return finish(terminalHostedError(404, "channel_not_found", `No channel named "${delivery.channelId}" is mounted.`));
564
- }
565
- let operation;
566
- const execution = runAdmissionOperation(delivery, definition).then(reply => {
567
- operation.settledReply = reply;
568
- operation.expiresAt = Date.now() + pendingTtlMs;
569
- return reply;
570
- });
571
- operation = {
572
- execution,
573
- expiresAt: Date.now() + ownerTurnPendingTtlMs,
574
- };
575
- admissions.set(delivery.deliveryId, operation);
576
- const quickReply = yield Promise.race([
577
- execution,
578
- new Promise(resolve => setImmediate(() => resolve(undefined))),
579
- ]);
580
- if (quickReply !== undefined) {
581
- return responseFromReply(quickReply);
582
- }
583
- return finish(Response.json({
584
- ok: true,
585
- v: HOSTED_DELIVERY_PROTOCOL_VERSION,
586
- outcome: "started",
587
- }));
535
+ }
536
+ console.info(`[bdk] hosted admission received deliveryId=${delivery.deliveryId} channelId=${delivery.channelId} channelKind=${delivery.channelKind} eventType=${delivery.eventType} sessionMode=${delivery.sessionMode} managedAutomation=${delivery.managedAutomation === undefined ? "<absent>" : `automationUuid=${delivery.managedAutomation.automationUuid} mcpServerNames=${String(delivery.managedAutomation.mcpServerNames.length)} slackChannels=${delivery.managedAutomation.slackChannels === undefined ? "<absent>" : JSON.stringify(delivery.managedAutomation.slackChannels)}`}`);
537
+ recordHostedManagedAutomation(delivery);
538
+ const reminder = isHostedReminderAdmission(delivery);
539
+ const definition = reminder
540
+ ? undefined
541
+ : input.channels.find(candidate => candidate.id === delivery.channelId)?.definition;
542
+ if (!reminder && definition === undefined) {
543
+ return finish(terminalHostedError(404, "channel_not_found", `No channel named "${delivery.channelId}" is mounted.`));
544
+ }
545
+ let operation;
546
+ const execution = runAdmissionOperation(delivery, definition).then(reply => {
547
+ operation.settledReply = reply;
548
+ operation.expiresAt = Date.now() + pendingTtlMs;
549
+ return reply;
550
+ });
551
+ operation = {
552
+ execution,
553
+ expiresAt: Date.now() + ownerTurnPendingTtlMs,
554
+ };
555
+ admissions.set(delivery.deliveryId, operation);
556
+ const quickReply = await Promise.race([
557
+ execution,
558
+ new Promise(resolve => setImmediate(() => resolve(undefined))),
559
+ ]);
560
+ if (quickReply !== undefined) {
561
+ return responseFromReply(quickReply);
562
+ }
563
+ return finish(Response.json({
564
+ ok: true,
565
+ v: HOSTED_DELIVERY_PROTOCOL_VERSION,
566
+ outcome: "started",
588
567
  }));
589
568
  }),
590
569
  });
@@ -592,303 +571,356 @@ export function registerHostedDeliveryRoute(input) {
592
571
  method: "POST",
593
572
  pattern: `${input.base}${HOSTED_EXECUTION_PATH}`,
594
573
  auth: [auth],
595
- handler: (request) => __awaiter(this, void 0, void 0, function* () {
596
- return afterHostedWork(input.flushOtel, () => __awaiter(this, void 0, void 0, function* () {
597
- var _a;
598
- const startedAt = performance.now();
599
- let guestNetwork;
600
- let latencySnapshot;
601
- const finish = (response) => withServerTiming(response, performance.now() - startedAt, guestNetwork, latencySnapshot);
602
- const unconsumed = finishBoundSecrets();
603
- if (unconsumed !== undefined) {
604
- return finish(unconsumed);
605
- }
606
- const execution = parseHostedExecution(yield readJsonObject(request));
607
- if (execution === undefined) {
608
- return finish(terminalHostedError(400, "invalid_hosted_execution", "Expected a supported Agent SDK hosted-execution envelope."));
609
- }
610
- pruneExpired();
611
- const admitted = pending.get(execution.admissionToken);
612
- if (admitted === undefined) {
613
- return finish(transientHostedError(409, "hosted_admission_unavailable", "The hosted admission token is missing or expired."));
614
- }
615
- if (admitted.sessionPublicId !== undefined &&
616
- admitted.sessionPublicId !== execution.sessionPublicId) {
617
- return finish(transientHostedError(409, "hosted_admission_session_mismatch", "The hosted admission token is already bound to another session."));
574
+ handler: async (request) => afterHostedWork(input.flushOtel, async () => {
575
+ const startedAt = performance.now();
576
+ let guestNetwork;
577
+ let latencySnapshot;
578
+ const finish = (response) => withServerTiming(response, performance.now() - startedAt, guestNetwork, latencySnapshot);
579
+ const unconsumed = finishBoundSecrets();
580
+ if (unconsumed !== undefined) {
581
+ return finish(unconsumed);
582
+ }
583
+ const execution = parseHostedExecution(await readJsonObject(request));
584
+ if (execution === undefined) {
585
+ return finish(terminalHostedError(400, "invalid_hosted_execution", "Expected a supported Agent SDK hosted-execution envelope."));
586
+ }
587
+ pruneExpired();
588
+ const admitted = pending.get(execution.admissionToken);
589
+ if (admitted === undefined) {
590
+ return finish(transientHostedError(409, "hosted_admission_unavailable", "The hosted admission token is missing or expired."));
591
+ }
592
+ if (admitted.sessionPublicId !== undefined &&
593
+ admitted.sessionPublicId !== execution.sessionPublicId) {
594
+ return finish(transientHostedError(409, "hosted_admission_session_mismatch", "The hosted admission token is already bound to another session."));
595
+ }
596
+ if (execution.mode === "start" &&
597
+ admitted.settledReply !== undefined &&
598
+ isTransientRetryReply(admitted.settledReply)) {
599
+ delete admitted.settledReply;
600
+ delete admitted.execution;
601
+ }
602
+ if (execution.mode === "status" ||
603
+ (execution.mode === "start" && admitted.execution !== undefined)) {
604
+ if (admitted.settledReply !== undefined) {
605
+ return responseFromReply(admitted.settledReply);
618
606
  }
619
- if (execution.mode === "start" &&
620
- admitted.settledReply !== undefined &&
621
- isTransientRetryReply(admitted.settledReply)) {
622
- delete admitted.settledReply;
623
- delete admitted.execution;
607
+ if (admitted.execution === undefined) {
608
+ return finish(transientHostedError(409, "hosted_admission_unavailable", "The hosted admission token has no owner turn in flight."));
624
609
  }
625
- if (execution.mode === "status" ||
626
- (execution.mode === "start" && admitted.execution !== undefined)) {
627
- if (admitted.settledReply !== undefined) {
628
- return responseFromReply(admitted.settledReply);
629
- }
630
- if (admitted.execution === undefined) {
631
- return finish(transientHostedError(409, "hosted_admission_unavailable", "The hosted admission token has no owner turn in flight."));
632
- }
633
- if (execution.mode === "start") {
634
- return finish(Response.json({
635
- ok: true,
636
- v: HOSTED_DELIVERY_PROTOCOL_VERSION,
637
- outcome: "started",
638
- }));
639
- }
610
+ if (execution.mode === "start") {
640
611
  return finish(Response.json({
641
612
  ok: true,
642
613
  v: HOSTED_DELIVERY_PROTOCOL_VERSION,
643
- outcome: "running",
614
+ outcome: "started",
644
615
  }));
645
616
  }
646
- admitted.sessionPublicId = execution.sessionPublicId;
647
- if (execution.mode === "enqueue") {
648
- const network = yield finishNetworkWait("execution");
649
- guestNetwork = network.timing;
650
- if (network.response !== undefined) {
651
- return finish(network.response);
652
- }
653
- const enqueueOutcome = yield enqueueIntoActiveOwner({
654
- activeOwners,
655
- sessionPublicId: execution.sessionPublicId,
656
- deliveryId: admitted.deliveryId,
657
- send: admitted.send,
658
- buildHandlerArgs: input.buildHandlerArgs,
659
- });
660
- return finish(Response.json(Object.assign({ ok: true, v: HOSTED_DELIVERY_PROTOCOL_VERSION }, enqueueOutcome)));
617
+ return finish(Response.json({
618
+ ok: true,
619
+ v: HOSTED_DELIVERY_PROTOCOL_VERSION,
620
+ outcome: "running",
621
+ }));
622
+ }
623
+ admitted.sessionPublicId = execution.sessionPublicId;
624
+ if (execution.mode === "enqueue") {
625
+ const network = await finishNetworkWait("execution");
626
+ guestNetwork = network.timing;
627
+ if (network.response !== undefined) {
628
+ return finish(network.response);
661
629
  }
662
- if (admitted.execution === undefined) {
663
- admitted.expiresAt = Date.now() + ownerTurnPendingTtlMs;
630
+ const enqueueOutcome = await enqueueIntoActiveOwner({
631
+ activeOwners,
632
+ sessionPublicId: execution.sessionPublicId,
633
+ deliveryId: admitted.deliveryId,
634
+ send: admitted.send,
635
+ buildHandlerArgs: input.buildHandlerArgs,
636
+ });
637
+ return finish(Response.json({
638
+ ok: true,
639
+ v: HOSTED_DELIVERY_PROTOCOL_VERSION,
640
+ ...enqueueOutcome,
641
+ }));
642
+ }
643
+ if (admitted.execution === undefined) {
644
+ admitted.expiresAt = Date.now() + ownerTurnPendingTtlMs;
645
+ }
646
+ admitted.execution ??= afterHostedWork(input.flushOtel, async () => {
647
+ const network = await finishNetworkWait("execution");
648
+ guestNetwork = network.timing;
649
+ if (network.response !== undefined) {
650
+ return await responseToReply(finish(network.response));
664
651
  }
665
- (_a = admitted.execution) !== null && _a !== void 0 ? _a : (admitted.execution = afterHostedWork(input.flushOtel, () => __awaiter(this, void 0, void 0, function* () {
666
- const network = yield finishNetworkWait("execution");
667
- guestNetwork = network.timing;
668
- if (network.response !== undefined) {
669
- return yield responseToReply(finish(network.response));
670
- }
671
- const startedAt = performance.now();
672
- const executionId = hostedExecutionDiagId(execution.admissionToken);
673
- const sinks = Object.assign(Object.assign(Object.assign(Object.assign({}, (input.stateRoot === undefined ? {} : { stateRoot: input.stateRoot })), (input.persistSessionRun === undefined
652
+ const startedAt = performance.now();
653
+ const executionId = hostedExecutionDiagId(execution.admissionToken);
654
+ const sinks = {
655
+ ...(input.stateRoot === undefined ? {} : { stateRoot: input.stateRoot }),
656
+ ...(input.persistSessionRun === undefined
674
657
  ? {}
675
- : { persistSessionRun: input.persistSessionRun })), (input.flushStartLog === undefined ? {} : { flushStartLog: input.flushStartLog })), (input.snapshotLogs === undefined ? {} : { snapshotLogs: input.snapshotLogs }));
676
- const writeDiag = (fields) => __awaiter(this, void 0, void 0, function* () {
677
- const classification = fields.failureCode === undefined
678
- ? undefined
679
- : hostedFailureClassification(fields.failureCode);
680
- yield flushHostedExecutionRecord(sinks, Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ executionId, sessionPublicId: execution.sessionPublicId, sessionId: fields.sessionId, turnStatus: fields.turnStatus, durationMs: Math.max(0, Math.round(performance.now() - startedAt)) }, (fields.message === undefined ? {} : { message: fields.message })), (fields.abortReason === undefined ? {} : { abortReason: fields.abortReason })), { failureCode: fields.failureCode }), (fields.errorCode === undefined ? {} : { errorCode: fields.errorCode })), { classification }), (fields.error === undefined ? {} : { error: fields.error })));
681
- });
682
- // Claim the file before the turn runs. If a later status request
683
- // fails, the host reads this record while the turn may still be
684
- // running; the marker prevents it from surfacing the previous
685
- // delivery's terminal record.
686
- yield writeDiag({
687
- sessionId: "",
688
- turnStatus: HOSTED_EXECUTION_DIAG_RUNNING_STATUS,
658
+ : { persistSessionRun: input.persistSessionRun }),
659
+ ...(input.flushStartLog === undefined ? {} : { flushStartLog: input.flushStartLog }),
660
+ ...(input.snapshotLogs === undefined ? {} : { snapshotLogs: input.snapshotLogs }),
661
+ };
662
+ const writeDiag = async (fields) => {
663
+ const classification = fields.failureCode === undefined
664
+ ? undefined
665
+ : hostedFailureClassification(fields.failureCode);
666
+ await flushHostedExecutionRecord(sinks, {
667
+ executionId,
668
+ sessionPublicId: execution.sessionPublicId,
669
+ sessionId: fields.sessionId,
670
+ turnStatus: fields.turnStatus,
671
+ durationMs: Math.max(0, Math.round(performance.now() - startedAt)),
672
+ ...(fields.message === undefined ? {} : { message: fields.message }),
673
+ ...(fields.abortReason === undefined ? {} : { abortReason: fields.abortReason }),
674
+ failureCode: fields.failureCode,
675
+ ...(fields.errorCode === undefined ? {} : { errorCode: fields.errorCode }),
676
+ classification,
677
+ ...(fields.error === undefined ? {} : { error: fields.error }),
689
678
  });
690
- let sessionId = "";
691
- const owner = {
692
- primaryDeliveryId: admitted.deliveryId,
693
- acceptedDeliveryIds: [],
694
- accepting: true,
695
- inflightInjects: new Set(),
696
- enqueueResults: new Map(),
697
- };
698
- activeOwners.set(execution.sessionPublicId, owner);
699
- return yield runWithHostedExecutionLatency({ channelKind: admitted.channelKind }, () => __awaiter(this, void 0, void 0, function* () {
700
- var _a;
701
- let completionAt;
702
- let drainAt;
703
- try {
704
- const args = input.buildHandlerArgs(admitted.send.channelId, execution.sessionPublicId);
705
- const session = yield args.send(admitted.send.message, Object.assign(Object.assign({}, admitted.send.options), { mailboxContinuation: {
706
- key: admitted.send.mailboxContinuationKey,
707
- } }));
708
- sessionId = session.id;
709
- // The pre-turn claim used an empty sessionId. Stamp the
710
- // engine id now so a dashboard / session-view poll that
711
- // only has the factory `ses_…` can follow `session-events/`.
712
- yield writeDiag({
713
- sessionId,
714
- turnStatus: HOSTED_EXECUTION_DIAG_RUNNING_STATUS,
715
- });
716
- const outcome = yield refreshStartLogWhile(sinks, execution.sessionPublicId, () => session.waitForCompletion());
717
- completionAt = hostedExecutionNow();
718
- // Status is the owner turn. waitForCompletion still waited
719
- // for any drained successor so this process is not parked
720
- // mid-follow-up; a successor failure must not 503-retry the
721
- // owner after satellites already ran.
722
- // Close acceptance at the turn boundary, before durability
723
- // work creates an idle-but-still-addressable window.
724
- owner.accepting = false;
725
- if (owner.inflightInjects.size > 0) {
726
- yield Promise.allSettled([...owner.inflightInjects]);
727
- }
728
- // Failed turns drain too: their record/continuation updates must
729
- // survive the park just like a finished turn's.
730
- yield (_a = input.drainSessionDurability) === null || _a === void 0 ? void 0 : _a.call(input, session.id);
731
- drainAt = hostedExecutionNow();
732
- const consumedDeliveryIds = [
733
- owner.primaryDeliveryId,
734
- ...owner.acceptedDeliveryIds,
735
- ];
736
- if (consumedDeliveryIds.length > HOSTED_MAX_CONSUMED_DELIVERY_IDS) {
737
- throw new Error(`hosted execute consumedDeliveryIds length ${String(consumedDeliveryIds.length)} exceeds cap ${String(HOSTED_MAX_CONSUMED_DELIVERY_IDS)}`);
738
- }
739
- // Evict before the reply: TAS parks and hibernates this process
740
- // as soon as the POST returns. A leftover SDK handle freezes a
741
- // dead Connect/HTTP2 session that the next wake then reuses.
742
- evictHostedSdkSessions(input.evictSdkSession, session.id, execution.sessionPublicId);
743
- const hostedFailure = outcome.status === "finished"
744
- ? undefined
745
- : hostedFailureForUnfinishedTurn(outcome);
746
- yield writeDiag(Object.assign({ sessionId: session.id, turnStatus: outcome.status, message: outcome.errorMessage, abortReason: abortReasonFromTurnStatus(outcome.status, outcome.cancellationReason), failureCode: hostedFailure === null || hostedFailure === void 0 ? void 0 : hostedFailure.error }, (outcome.errorCode === undefined ? {} : { errorCode: outcome.errorCode })));
747
- const reply = hostedFailure !== undefined
748
- ? {
749
- status: 503,
750
- body: Object.assign({ ok: false, error: hostedFailure.error, retry: hostedFailure.retry, classification: hostedFailureClassification(hostedFailure.error), turnStatus: outcome.status, message: outcome.errorMessage }, (outcome.errorCode === undefined
751
- ? {}
752
- : { errorCode: outcome.errorCode })),
753
- }
754
- : {
755
- status: 200,
756
- body: {
757
- ok: true,
758
- v: HOSTED_DELIVERY_PROTOCOL_VERSION,
759
- outcome: "send",
760
- consumedDeliveryIds,
761
- },
762
- };
763
- // Finalize as late as possible so `post_drain` and `total`
764
- // include eviction + diag write after durability drain.
765
- latencySnapshot = finalizeHostedExecutionLatency({
766
- completionAt,
767
- drainAt,
768
- endedAt: hostedExecutionNow(),
679
+ };
680
+ // Claim the file before the turn runs. If a later status request
681
+ // fails, the host reads this record while the turn may still be
682
+ // running; the marker prevents it from surfacing the previous
683
+ // delivery's terminal record.
684
+ await writeDiag({
685
+ sessionId: "",
686
+ turnStatus: HOSTED_EXECUTION_DIAG_RUNNING_STATUS,
687
+ });
688
+ let sessionId = "";
689
+ const owner = {
690
+ primaryDeliveryId: admitted.deliveryId,
691
+ acceptedDeliveryIds: [],
692
+ accepting: true,
693
+ inflightInjects: new Set(),
694
+ enqueueResults: new Map(),
695
+ };
696
+ activeOwners.set(execution.sessionPublicId, owner);
697
+ return await runWithHostedExecutionLatency({ channelKind: admitted.channelKind }, async () => {
698
+ let completionAt;
699
+ let drainAt;
700
+ try {
701
+ const args = input.buildHandlerArgs(admitted.send.channelId, execution.sessionPublicId);
702
+ const options = {
703
+ ...admitted.send.options,
704
+ mailboxContinuation: {
705
+ key: admitted.send.mailboxContinuationKey,
706
+ },
707
+ };
708
+ const session = input.startSend === undefined
709
+ ? await args.send(admitted.send.message, options)
710
+ : await input.startSend({
711
+ args,
712
+ message: admitted.send.message,
713
+ options,
714
+ sessionPublicId: execution.sessionPublicId,
769
715
  });
770
- return yield responseToReply(finish(Response.json(reply.body, { status: reply.status })));
716
+ sessionId = session.id;
717
+ // The pre-turn claim used an empty sessionId. Stamp the
718
+ // engine id now so a dashboard / session-view poll that
719
+ // only has the factory `ses_…` can follow `session-events/`.
720
+ await writeDiag({
721
+ sessionId,
722
+ turnStatus: HOSTED_EXECUTION_DIAG_RUNNING_STATUS,
723
+ });
724
+ const outcome = await refreshStartLogWhile(sinks, execution.sessionPublicId, () => session.waitForCompletion());
725
+ completionAt = hostedExecutionNow();
726
+ // Status is the owner turn. waitForCompletion still waited
727
+ // for any drained successor so this process is not parked
728
+ // mid-follow-up; a successor failure must not 503-retry the
729
+ // owner after satellites already ran.
730
+ // Close acceptance at the turn boundary, before durability
731
+ // work creates an idle-but-still-addressable window.
732
+ owner.accepting = false;
733
+ if (owner.inflightInjects.size > 0) {
734
+ await Promise.allSettled([...owner.inflightInjects]);
771
735
  }
772
- catch (error) {
773
- owner.accepting = false;
774
- if (owner.inflightInjects.size > 0) {
775
- yield Promise.allSettled([...owner.inflightInjects]);
776
- }
777
- evictHostedSdkSessions(input.evictSdkSession, sessionId, execution.sessionPublicId);
778
- const thrownErrorCode = describeErrorCode(error);
779
- yield writeDiag(Object.assign({ sessionId: "", turnStatus: "error", message: error instanceof Error ? error.message : String(error), abortReason: "execute_throw", failureCode: "internal_error", error }, (thrownErrorCode === undefined ? {} : { errorCode: thrownErrorCode })));
780
- const endedAt = hostedExecutionNow();
781
- // Preserve completion/drain marks when the failure happened
782
- // during post-drain work; otherwise collapse to endedAt.
783
- latencySnapshot = finalizeHostedExecutionLatency({
784
- completionAt: completionAt !== null && completionAt !== void 0 ? completionAt : endedAt,
785
- drainAt: drainAt !== null && drainAt !== void 0 ? drainAt : endedAt,
786
- endedAt,
787
- });
788
- throw error;
736
+ // Failed turns drain too: their record/continuation updates must
737
+ // survive the park just like a finished turn's.
738
+ await input.drainSessionDurability?.(session.id);
739
+ drainAt = hostedExecutionNow();
740
+ const consumedDeliveryIds = [
741
+ owner.primaryDeliveryId,
742
+ ...owner.acceptedDeliveryIds,
743
+ ];
744
+ if (consumedDeliveryIds.length > HOSTED_MAX_CONSUMED_DELIVERY_IDS) {
745
+ throw new Error(`hosted execute consumedDeliveryIds length ${String(consumedDeliveryIds.length)} exceeds cap ${String(HOSTED_MAX_CONSUMED_DELIVERY_IDS)}`);
789
746
  }
790
- finally {
791
- if (activeOwners.get(execution.sessionPublicId) === owner) {
792
- activeOwners.delete(execution.sessionPublicId);
747
+ // Evict before the reply: TAS parks and hibernates this process
748
+ // as soon as the POST returns. A leftover SDK handle freezes a
749
+ // dead Connect/HTTP2 session that the next wake then reuses.
750
+ evictHostedSdkSessions(input.evictSdkSession, session.id, execution.sessionPublicId);
751
+ const hostedFailure = outcome.status === "finished"
752
+ ? undefined
753
+ : hostedFailureForUnfinishedTurn(outcome);
754
+ await writeDiag({
755
+ sessionId: session.id,
756
+ turnStatus: outcome.status,
757
+ message: outcome.errorMessage,
758
+ abortReason: abortReasonFromTurnStatus(outcome.status, outcome.cancellationReason),
759
+ failureCode: hostedFailure?.error,
760
+ ...(outcome.errorCode === undefined ? {} : { errorCode: outcome.errorCode }),
761
+ });
762
+ const reply = hostedFailure !== undefined
763
+ ? {
764
+ status: 503,
765
+ body: {
766
+ ok: false,
767
+ error: hostedFailure.error,
768
+ retry: hostedFailure.retry,
769
+ classification: hostedFailureClassification(hostedFailure.error),
770
+ turnStatus: outcome.status,
771
+ message: outcome.errorMessage,
772
+ ...(outcome.errorCode === undefined
773
+ ? {}
774
+ : { errorCode: outcome.errorCode }),
775
+ },
793
776
  }
777
+ : {
778
+ status: 200,
779
+ body: {
780
+ ok: true,
781
+ v: HOSTED_DELIVERY_PROTOCOL_VERSION,
782
+ outcome: "send",
783
+ consumedDeliveryIds,
784
+ },
785
+ };
786
+ // Finalize as late as possible so `post_drain` and `total`
787
+ // include eviction + diag write after durability drain.
788
+ latencySnapshot = finalizeHostedExecutionLatency({
789
+ completionAt,
790
+ drainAt,
791
+ endedAt: hostedExecutionNow(),
792
+ });
793
+ return await responseToReply(finish(Response.json(reply.body, { status: reply.status })));
794
+ }
795
+ catch (error) {
796
+ owner.accepting = false;
797
+ if (owner.inflightInjects.size > 0) {
798
+ await Promise.allSettled([...owner.inflightInjects]);
794
799
  }
795
- }));
796
- })).then(reply => {
797
- admitted.settledReply = reply;
798
- admitted.expiresAt = Date.now() + pendingTtlMs;
799
- return reply;
800
- }, error => {
801
- admitted.settledReply = {
802
- status: 503,
803
- body: {
804
- ok: false,
805
- error: "internal_error",
806
- retry: HOSTED_GUEST_RETRY_TERMINAL,
807
- classification: hostedFailureClassification("internal_error"),
800
+ evictHostedSdkSessions(input.evictSdkSession, sessionId, execution.sessionPublicId);
801
+ const thrownErrorCode = describeErrorCode(error);
802
+ await writeDiag({
803
+ sessionId: "",
804
+ turnStatus: "error",
808
805
  message: error instanceof Error ? error.message : String(error),
809
- },
810
- };
811
- admitted.expiresAt = Date.now() + pendingTtlMs;
812
- return admitted.settledReply;
813
- }));
814
- if (execution.mode === "start") {
815
- const quickReply = yield Promise.race([
816
- admitted.execution,
817
- new Promise(resolve => setImmediate(() => resolve(undefined))),
818
- ]);
819
- if (quickReply !== undefined) {
820
- return responseFromReply(quickReply);
806
+ abortReason: "execute_throw",
807
+ failureCode: "internal_error",
808
+ error,
809
+ ...(thrownErrorCode === undefined ? {} : { errorCode: thrownErrorCode }),
810
+ });
811
+ const endedAt = hostedExecutionNow();
812
+ // Preserve completion/drain marks when the failure happened
813
+ // during post-drain work; otherwise collapse to endedAt.
814
+ latencySnapshot = finalizeHostedExecutionLatency({
815
+ completionAt: completionAt ?? endedAt,
816
+ drainAt: drainAt ?? endedAt,
817
+ endedAt,
818
+ });
819
+ throw error;
821
820
  }
822
- return finish(Response.json({
823
- ok: true,
824
- v: HOSTED_DELIVERY_PROTOCOL_VERSION,
825
- outcome: "started",
826
- }));
821
+ finally {
822
+ if (activeOwners.get(execution.sessionPublicId) === owner) {
823
+ activeOwners.delete(execution.sessionPublicId);
824
+ }
825
+ }
826
+ });
827
+ }).then(reply => {
828
+ admitted.settledReply = reply;
829
+ admitted.expiresAt = Date.now() + pendingTtlMs;
830
+ return reply;
831
+ }, error => {
832
+ admitted.settledReply = {
833
+ status: 503,
834
+ body: {
835
+ ok: false,
836
+ error: "internal_error",
837
+ retry: HOSTED_GUEST_RETRY_TERMINAL,
838
+ classification: hostedFailureClassification("internal_error"),
839
+ message: error instanceof Error ? error.message : String(error),
840
+ },
841
+ };
842
+ admitted.expiresAt = Date.now() + pendingTtlMs;
843
+ return admitted.settledReply;
844
+ });
845
+ if (execution.mode === "start") {
846
+ const quickReply = await Promise.race([
847
+ admitted.execution,
848
+ new Promise(resolve => setImmediate(() => resolve(undefined))),
849
+ ]);
850
+ if (quickReply !== undefined) {
851
+ return responseFromReply(quickReply);
827
852
  }
828
- return finish(terminalHostedError(400, "invalid_hosted_execution", "Owner execution requires start or status mode."));
829
- }));
853
+ return finish(Response.json({
854
+ ok: true,
855
+ v: HOSTED_DELIVERY_PROTOCOL_VERSION,
856
+ outcome: "started",
857
+ }));
858
+ }
859
+ return finish(terminalHostedError(400, "invalid_hosted_execution", "Owner execution requires start or status mode."));
830
860
  }),
831
861
  });
832
862
  }
833
- function enqueueIntoActiveOwner(input) {
834
- return __awaiter(this, void 0, void 0, function* () {
835
- const owner = input.activeOwners.get(input.sessionPublicId);
836
- if (owner === undefined || !owner.accepting) {
837
- return { outcome: "not_active" };
863
+ async function enqueueIntoActiveOwner(input) {
864
+ const owner = input.activeOwners.get(input.sessionPublicId);
865
+ if (owner === undefined || !owner.accepting) {
866
+ return { outcome: "not_active" };
867
+ }
868
+ const existing = owner.enqueueResults.get(input.deliveryId);
869
+ if (existing !== undefined) {
870
+ const shared = await existing;
871
+ if (shared.outcome === "enqueued" || shared.outcome === "not_active") {
872
+ return { outcome: shared.outcome };
838
873
  }
839
- const existing = owner.enqueueResults.get(input.deliveryId);
840
- if (existing !== undefined) {
841
- const shared = yield existing;
842
- if (shared.outcome === "enqueued" || shared.outcome === "not_active") {
843
- return { outcome: shared.outcome };
874
+ return { outcome: "not_active" };
875
+ }
876
+ let resolveResult;
877
+ const resultPromise = new Promise(resolve => {
878
+ resolveResult = resolve;
879
+ });
880
+ owner.enqueueResults.set(input.deliveryId, resultPromise);
881
+ // Capacity includes the primary delivery id.
882
+ if (1 + owner.acceptedDeliveryIds.length >= HOSTED_MAX_CONSUMED_DELIVERY_IDS) {
883
+ const outcome = { outcome: "not_active" };
884
+ resolveResult(outcome);
885
+ return outcome;
886
+ }
887
+ // Reserve before send so concurrent enqueues cannot oversubscribe.
888
+ owner.acceptedDeliveryIds.push(input.deliveryId);
889
+ const inject = (async () => {
890
+ try {
891
+ const args = input.buildHandlerArgs(input.send.channelId, input.sessionPublicId);
892
+ const enqueueOptions = {
893
+ ...input.send.options,
894
+ mailboxContinuation: {
895
+ key: input.send.mailboxContinuationKey,
896
+ },
897
+ hostedEnqueueOnly: true,
898
+ };
899
+ const session = await args.send(input.send.message, enqueueOptions);
900
+ if (session.coalesced !== true) {
901
+ throw new HostedEnqueueNotActiveError(input.sessionPublicId);
844
902
  }
845
- return { outcome: "not_active" };
903
+ resolveResult({ outcome: "enqueued" });
846
904
  }
847
- let resolveResult;
848
- const resultPromise = new Promise(resolve => {
849
- resolveResult = resolve;
850
- });
851
- owner.enqueueResults.set(input.deliveryId, resultPromise);
852
- // Capacity includes the primary delivery id.
853
- if (1 + owner.acceptedDeliveryIds.length >= HOSTED_MAX_CONSUMED_DELIVERY_IDS) {
854
- const outcome = { outcome: "not_active" };
855
- resolveResult(outcome);
856
- return outcome;
857
- }
858
- // Reserve before send so concurrent enqueues cannot oversubscribe.
859
- owner.acceptedDeliveryIds.push(input.deliveryId);
860
- const inject = (() => __awaiter(this, void 0, void 0, function* () {
861
- try {
862
- const args = input.buildHandlerArgs(input.send.channelId, input.sessionPublicId);
863
- const enqueueOptions = Object.assign(Object.assign({}, input.send.options), { mailboxContinuation: {
864
- key: input.send.mailboxContinuationKey,
865
- }, hostedEnqueueOnly: true });
866
- const session = yield args.send(input.send.message, enqueueOptions);
867
- if (session.coalesced !== true) {
868
- throw new HostedEnqueueNotActiveError(input.sessionPublicId);
869
- }
870
- resolveResult({ outcome: "enqueued" });
905
+ catch (error) {
906
+ const idx = owner.acceptedDeliveryIds.lastIndexOf(input.deliveryId);
907
+ if (idx >= 0) {
908
+ owner.acceptedDeliveryIds.splice(idx, 1);
871
909
  }
872
- catch (error) {
873
- const idx = owner.acceptedDeliveryIds.lastIndexOf(input.deliveryId);
874
- if (idx >= 0) {
875
- owner.acceptedDeliveryIds.splice(idx, 1);
876
- }
877
- resolveResult({ outcome: "not_active" });
878
- if (!(error instanceof HostedEnqueueNotActiveError)) {
879
- console.warn(`[bdk] hosted enqueue inject failed deliveryId=${input.deliveryId}: ${error instanceof Error ? error.message : String(error)}`);
880
- }
910
+ resolveResult({ outcome: "not_active" });
911
+ if (!(error instanceof HostedEnqueueNotActiveError)) {
912
+ console.warn(`[bdk] hosted enqueue inject failed deliveryId=${input.deliveryId}: ${error instanceof Error ? error.message : String(error)}`);
881
913
  }
882
- }))();
883
- owner.inflightInjects.add(inject);
884
- try {
885
- yield inject;
886
914
  }
887
- finally {
888
- owner.inflightInjects.delete(inject);
889
- }
890
- return yield resultPromise;
891
- });
915
+ })();
916
+ owner.inflightInjects.add(inject);
917
+ try {
918
+ await inject;
919
+ }
920
+ finally {
921
+ owner.inflightInjects.delete(inject);
922
+ }
923
+ return await resultPromise;
892
924
  }
893
925
  function evictHostedSdkSessions(evict, ...ids) {
894
926
  if (evict === undefined) {
@@ -940,29 +972,27 @@ function hostedFailureForUnfinishedTurn(outcome) {
940
972
  }
941
973
  return { error: "turn_failed", retry: HOSTED_GUEST_RETRY_TERMINAL };
942
974
  }
943
- function afterHostedWork(flushOtel, work) {
944
- return __awaiter(this, void 0, void 0, function* () {
945
- try {
946
- const result = yield work();
947
- if (result instanceof Response) {
948
- endActiveHttpSpan(result.status);
949
- }
950
- return result;
951
- }
952
- catch (error) {
953
- const status = statusForThrownRequestError(error);
954
- endActiveHttpSpan(status, status >= 500 ? error : undefined);
955
- throw error;
975
+ async function afterHostedWork(flushOtel, work) {
976
+ try {
977
+ const result = await work();
978
+ if (result instanceof Response) {
979
+ endActiveHttpSpan(result.status);
956
980
  }
957
- finally {
958
- if (flushOtel !== undefined) {
959
- try {
960
- yield flushOtel();
961
- }
962
- catch (_a) {
963
- // Soft-fail: exporter failure must not change hosted HTTP.
964
- }
981
+ return result;
982
+ }
983
+ catch (error) {
984
+ const status = statusForThrownRequestError(error);
985
+ endActiveHttpSpan(status, status >= 500 ? error : undefined);
986
+ throw error;
987
+ }
988
+ finally {
989
+ if (flushOtel !== undefined) {
990
+ try {
991
+ await flushOtel();
992
+ }
993
+ catch {
994
+ // Soft-fail: exporter failure must not change hosted HTTP.
965
995
  }
966
996
  }
967
- });
997
+ }
968
998
  }