@cursor/bdk 0.2.13 → 0.2.15

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 (322) hide show
  1. package/AGENTS.md +51 -52
  2. package/README.md +1 -1
  3. package/dist/bin/agent-sdk.js +0 -0
  4. package/dist/bin/agent-serve.js +0 -0
  5. package/dist/channels/slack/attachments.d.ts +2 -0
  6. package/dist/channels/slack/attachments.d.ts.map +1 -1
  7. package/dist/channels/slack/attachments.js +17 -5
  8. package/dist/channels/slack/channel-watch.d.ts +4 -2
  9. package/dist/channels/slack/channel-watch.d.ts.map +1 -1
  10. package/dist/channels/slack/channel-watch.js +4 -2
  11. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  12. package/dist/channels/slack/slack-channel.js +4 -2
  13. package/dist/channels/slack/types.d.ts +6 -4
  14. package/dist/channels/slack/types.d.ts.map +1 -1
  15. package/dist/connections.d.ts +29 -0
  16. package/dist/connections.d.ts.map +1 -1
  17. package/dist/connections.js +54 -0
  18. package/dist/docs/404.html +2 -2
  19. package/dist/docs/assets/{app.CaLG1pPt.js → app.CRMxF0qX.js} +4 -4
  20. package/dist/docs/assets/{building-with-agents.md.Df87rAe1.js → building-with-agents.md.Bi9CQ-bR.js} +3 -3
  21. package/dist/docs/assets/{building-with-agents.md.Df87rAe1.lean.js → building-with-agents.md.Bi9CQ-bR.lean.js} +1 -1
  22. package/dist/docs/assets/chunks/@localSearchIndexroot.BZwvb2LN.js +1 -0
  23. package/dist/docs/assets/chunks/{VPLocalSearchBox.YsP_2wqD.js → VPLocalSearchBox.C4BiQe53.js} +1 -1
  24. package/dist/docs/assets/chunks/{arc.C2j9hR7c.js → arc.D1TA2Mxn.js} +1 -1
  25. package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.C5qkGp7y.js → architectureDiagram-Q4EWVU46.CA-hBJCN.js} +1 -1
  26. package/dist/docs/assets/chunks/{baseUniq.U6GgTHOD.js → baseUniq.CzsSgiab.js} +1 -1
  27. package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.D51mJop2.js → blockDiagram-DXYQGD6D.sxrH_f0l.js} +1 -1
  28. package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.w1d6QxV7.js → c4Diagram-AHTNJAMY.D_Z3mqAl.js} +1 -1
  29. package/dist/docs/assets/chunks/channel.D7DtboxW.js +1 -0
  30. package/dist/docs/assets/chunks/{chunk-4BX2VUAB.B_A815un.js → chunk-4BX2VUAB.BS6_uTUf.js} +1 -1
  31. package/dist/docs/assets/chunks/{chunk-4TB4RGXK.DMrm-ZCb.js → chunk-4TB4RGXK.D-URAeTU.js} +1 -1
  32. package/dist/docs/assets/chunks/{chunk-55IACEB6.8qw6Xdal.js → chunk-55IACEB6.b4SZc5kO.js} +1 -1
  33. package/dist/docs/assets/chunks/{chunk-EDXVE4YY.Cq_nHODn.js → chunk-EDXVE4YY.DLKEEDkN.js} +1 -1
  34. package/dist/docs/assets/chunks/{chunk-FMBD7UC4.B67ohCYn.js → chunk-FMBD7UC4.3SyQHgpY.js} +1 -1
  35. package/dist/docs/assets/chunks/{chunk-OYMX7WX6.Bo8rQI8F.js → chunk-OYMX7WX6.DBKKaFeS.js} +1 -1
  36. package/dist/docs/assets/chunks/{chunk-QZHKN3VN.BERUMfE9.js → chunk-QZHKN3VN.BhCYeR7H.js} +1 -1
  37. package/dist/docs/assets/chunks/{chunk-YZCP3GAM.DWG2tXIX.js → chunk-YZCP3GAM.Cpg0VgI7.js} +1 -1
  38. package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.irslOV8B.js +1 -0
  39. package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.irslOV8B.js +1 -0
  40. package/dist/docs/assets/chunks/clone.DosLeDYL.js +1 -0
  41. package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.tezXBs9b.js → cose-bilkent-S5V4N54A.4q0YNZN6.js} +1 -1
  42. package/dist/docs/assets/chunks/{dagre-KV5264BT.aSbEUwT7.js → dagre-KV5264BT.Bk_CcQPr.js} +1 -1
  43. package/dist/docs/assets/chunks/{diagram-5BDNPKRD.vnT6aJ57.js → diagram-5BDNPKRD.CgreoM_Z.js} +1 -1
  44. package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.hGYdrDa2.js → diagram-G4DWMVQ6.DlZGpm6W.js} +1 -1
  45. package/dist/docs/assets/chunks/{diagram-MMDJMWI5.CmdSUP6L.js → diagram-MMDJMWI5.BxtXxgIR.js} +1 -1
  46. package/dist/docs/assets/chunks/{diagram-TYMM5635.BbAnLEBB.js → diagram-TYMM5635.DSzlJp2D.js} +1 -1
  47. package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.H40W4HWE.js → erDiagram-SMLLAGMA.BN1YUmEV.js} +1 -1
  48. package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.BFMtUSv-.js → flowDiagram-DWJPFMVM.B61NGNYu.js} +1 -1
  49. package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.CbYiu7Dt.js → ganttDiagram-T4ZO3ILL.DR-tto3M.js} +1 -1
  50. package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.Cyc5mzZD.js → gitGraphDiagram-UUTBAWPF.CBPs2W_2.js} +1 -1
  51. package/dist/docs/assets/chunks/{graph.BRptDG1H.js → graph.DmlaqzCE.js} +1 -1
  52. package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.Bz6KCA3a.js → infoDiagram-42DDH7IO.obPv-fFg.js} +1 -1
  53. package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.DDJ_7_Fq.js → ishikawaDiagram-UXIWVN3A.CXHTUcM3.js} +1 -1
  54. package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.D0t_ltlb.js → journeyDiagram-VCZTEJTY.BoVHerYZ.js} +1 -1
  55. package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.DyyNsMfi.js → kanban-definition-6JOO6SKY.CfYmPHZg.js} +1 -1
  56. package/dist/docs/assets/chunks/{layout.Cbxq-Rhp.js → layout.621UdAhB.js} +1 -1
  57. package/dist/docs/assets/chunks/{linear.DxGYL0MP.js → linear.Cz_zRKjr.js} +1 -1
  58. package/dist/docs/assets/chunks/{min.DA5KL8wu.js → min.ON4GjCH7.js} +1 -1
  59. package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.Bc72Utls.js → mindmap-definition-QFDTVHPH.DLPMLJlv.js} +1 -1
  60. package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.BtpHnIB_.js → pieDiagram-DEJITSTG.BFp11AYt.js} +1 -1
  61. package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.Cx4oCSRR.js → quadrantDiagram-34T5L4WZ.ChX7xo6B.js} +1 -1
  62. package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.BC0hXWlW.js → requirementDiagram-MS252O5E.DbKtHG_Q.js} +1 -1
  63. package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.Dg8T1SEp.js → sankeyDiagram-XADWPNL6.Spw8tv-7.js} +1 -1
  64. package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.CWSdHYAF.js → sequenceDiagram-FGHM5R23.BYso9LlE.js} +1 -1
  65. package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.0MVPRI28.js → stateDiagram-FHFEXIEX.D8l54jqW.js} +1 -1
  66. package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.CAYMmzGj.js +1 -0
  67. package/dist/docs/assets/chunks/{theme.DO1avLBn.js → theme.m_Ethbkv.js} +2 -2
  68. package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.BuRinAVi.js → timeline-definition-GMOUNBTQ.BLdhhyy9.js} +1 -1
  69. package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.DXf0PCoJ.js → vennDiagram-DHZGUBPP.CyGT2F_P.js} +1 -1
  70. package/dist/docs/assets/chunks/wardley-RL74JXVD.C5JJS3bh.js +162 -0
  71. package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.T4ThngYV.js → wardleyDiagram-NUSXRM2D.p_Sz9p1i.js} +1 -1
  72. package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.b4pZF3D5.js → xychartDiagram-5P7HB3ND.DtXsNUaf.js} +1 -1
  73. package/dist/docs/assets/deployment.md.hKKN9I4c.js +31 -0
  74. package/dist/docs/assets/{deployment.md.BYuEcDBv.lean.js → deployment.md.hKKN9I4c.lean.js} +1 -1
  75. package/dist/docs/assets/{evals.md.C851kViu.js → evals.md.CHR34K1Y.js} +3 -7
  76. package/dist/docs/assets/{evals.md.C851kViu.lean.js → evals.md.CHR34K1Y.lean.js} +1 -1
  77. package/dist/docs/assets/guides_cloud-agents.md.CBK7W0-O.js +9 -0
  78. package/dist/docs/assets/guides_cloud-agents.md.CBK7W0-O.lean.js +1 -0
  79. package/dist/docs/assets/guides_grokbot-agents.md.BwAykJ7U.js +15 -0
  80. package/dist/docs/assets/{guides_grokbot-agents.md.tD1smFhU.lean.js → guides_grokbot-agents.md.BwAykJ7U.lean.js} +1 -1
  81. package/dist/docs/assets/{guides_hooks.md.5Ce3NXxZ.js → guides_hooks.md.B_bKG1oA.js} +1 -1
  82. package/dist/docs/assets/{guides_improve.md.CRrYq22s.js → guides_improve.md.CZKVt1cT.js} +2 -3
  83. package/dist/docs/assets/{guides_improve.md.CRrYq22s.lean.js → guides_improve.md.CZKVt1cT.lean.js} +1 -1
  84. package/dist/docs/assets/{guides_mcp-oauth.md.DR3zhC9r.js → guides_mcp-oauth.md.BM_eFC0L.js} +3 -15
  85. package/dist/docs/assets/guides_mcp-oauth.md.BM_eFC0L.lean.js +1 -0
  86. package/dist/docs/assets/{guides_webhooks.md.BBvAm_VF.js → guides_webhooks.md.Cpdc3BDX.js} +13 -12
  87. package/dist/docs/assets/{guides_webhooks.md.BBvAm_VF.lean.js → guides_webhooks.md.Cpdc3BDX.lean.js} +1 -1
  88. package/dist/docs/assets/{index.md.Dxxr7pFa.js → index.md.BIBHIQtU.js} +1 -1
  89. package/dist/docs/assets/{quickstart.md.BK5gjHM2.js → quickstart.md.CduLGBAB.js} +1 -1
  90. package/dist/docs/assets/reference_channels.md.DYg0CLud.js +22 -0
  91. package/dist/docs/assets/{reference_channels.md.LbNIJBwd.lean.js → reference_channels.md.DYg0CLud.lean.js} +1 -1
  92. package/dist/docs/assets/{reference_cli.md.dYCAL2lB.js → reference_cli.md.BYNIHwbi.js} +15 -12
  93. package/dist/docs/assets/{reference_cli.md.dYCAL2lB.lean.js → reference_cli.md.BYNIHwbi.lean.js} +1 -1
  94. package/dist/docs/assets/{reference_connections.md.DLrgAd5f.js → reference_connections.md.CxbLpaaP.js} +4 -5
  95. package/dist/docs/assets/{reference_connections.md.DLrgAd5f.lean.js → reference_connections.md.CxbLpaaP.lean.js} +1 -1
  96. package/dist/docs/assets/{reference_evals.md.D5i8PuXJ.js → reference_evals.md.if--BLd0.js} +1 -1
  97. package/dist/docs/assets/{reference_hooks.md.B-eGa2km.js → reference_hooks.md.DbJC8mcZ.js} +1 -1
  98. package/dist/docs/assets/reference_http-api.md.CrqhTv6S.js +11 -0
  99. package/dist/docs/assets/{reference_http-api.md.DbFNOubV.lean.js → reference_http-api.md.CrqhTv6S.lean.js} +1 -1
  100. package/dist/docs/assets/reference_playground.md.q4MI-0td.js +1 -0
  101. package/dist/docs/assets/reference_playground.md.q4MI-0td.lean.js +1 -0
  102. package/dist/docs/assets/{reference_schedules.md.BuJ8fgMa.js → reference_schedules.md.03Ryy9ca.js} +5 -5
  103. package/dist/docs/assets/{reference_schedules.md.BuJ8fgMa.lean.js → reference_schedules.md.03Ryy9ca.lean.js} +1 -1
  104. package/dist/docs/assets/reference_sessions.md.C_uzIWuy.js +1 -0
  105. package/dist/docs/assets/{reference_skills.md.C0guGcH0.js → reference_skills.md.Ckddg6KX.js} +4 -4
  106. package/dist/docs/assets/{reference_tools.md.DzIY9JzY.js → reference_tools.md.08XR7lIl.js} +3 -14
  107. package/dist/docs/assets/reference_tools.md.08XR7lIl.lean.js +1 -0
  108. package/dist/docs/assets/{templates_grokbot-agents.md.2sydjFiO.js → templates_grokbot-agents.md.DgpPEs7B.js} +1 -1
  109. package/dist/docs/assets/troubleshooting.md.PCafNCb5.js +1 -0
  110. package/dist/docs/assets/{troubleshooting.md.x-GBa7wN.lean.js → troubleshooting.md.PCafNCb5.lean.js} +1 -1
  111. package/dist/docs/building-with-agents.html +37 -37
  112. package/dist/docs/building-with-agents.md +5 -5
  113. package/dist/docs/deployment.html +43 -41
  114. package/dist/docs/deployment.md +70 -33
  115. package/dist/docs/evals.html +38 -42
  116. package/dist/docs/evals.md +1 -16
  117. package/dist/docs/guides/agent-to-agent.html +35 -35
  118. package/dist/docs/guides/bitbucket.html +35 -35
  119. package/dist/docs/guides/cloud-agents.html +38 -39
  120. package/dist/docs/guides/cloud-agents.md +2 -8
  121. package/dist/docs/guides/convert-automation.html +35 -35
  122. package/dist/docs/guides/github.html +35 -35
  123. package/dist/docs/guides/gitlab.html +35 -35
  124. package/dist/docs/guides/grokbot-agents.html +37 -38
  125. package/dist/docs/guides/grokbot-agents.md +9 -13
  126. package/dist/docs/guides/hooks.html +37 -37
  127. package/dist/docs/guides/hooks.md +0 -1
  128. package/dist/docs/guides/improve.html +37 -38
  129. package/dist/docs/guides/improve.md +4 -6
  130. package/dist/docs/guides/jev.html +35 -35
  131. package/dist/docs/guides/mcp-oauth.html +39 -51
  132. package/dist/docs/guides/mcp-oauth.md +17 -40
  133. package/dist/docs/guides/migrate.html +35 -35
  134. package/dist/docs/guides/opentelemetry.html +35 -35
  135. package/dist/docs/guides/slack.html +35 -35
  136. package/dist/docs/guides/webhooks.html +47 -46
  137. package/dist/docs/guides/webhooks.md +35 -18
  138. package/dist/docs/hashmap.json +1 -1
  139. package/dist/docs/hillclimbing.html +35 -35
  140. package/dist/docs/index.html +36 -36
  141. package/dist/docs/index.md +1 -1
  142. package/dist/docs/llms-full.txt +347 -269
  143. package/dist/docs/llms.txt +4 -4
  144. package/dist/docs/quickstart.html +37 -37
  145. package/dist/docs/quickstart.md +2 -2
  146. package/dist/docs/reference/agent-config.html +35 -35
  147. package/dist/docs/reference/artifacts.html +35 -35
  148. package/dist/docs/reference/channels.html +42 -43
  149. package/dist/docs/reference/channels.md +29 -13
  150. package/dist/docs/reference/cli.html +49 -46
  151. package/dist/docs/reference/cli.md +113 -40
  152. package/dist/docs/reference/connections.html +39 -40
  153. package/dist/docs/reference/connections.md +6 -5
  154. package/dist/docs/reference/evals.html +37 -37
  155. package/dist/docs/reference/evals.md +2 -4
  156. package/dist/docs/reference/extensions.html +35 -35
  157. package/dist/docs/reference/hooks.html +37 -37
  158. package/dist/docs/reference/hooks.md +0 -1
  159. package/dist/docs/reference/http-api.html +38 -38
  160. package/dist/docs/reference/http-api.md +7 -17
  161. package/dist/docs/reference/instructions.html +35 -35
  162. package/dist/docs/reference/playground.html +37 -37
  163. package/dist/docs/reference/playground.md +1 -4
  164. package/dist/docs/reference/project-layout.html +35 -35
  165. package/dist/docs/reference/prompt.html +35 -35
  166. package/dist/docs/reference/schedules.html +39 -39
  167. package/dist/docs/reference/schedules.md +26 -3
  168. package/dist/docs/reference/sessions.html +36 -36
  169. package/dist/docs/reference/sessions.md +1 -2
  170. package/dist/docs/reference/skills.html +39 -39
  171. package/dist/docs/reference/skills.md +1 -1
  172. package/dist/docs/reference/subagents.html +35 -35
  173. package/dist/docs/reference/tools.html +39 -50
  174. package/dist/docs/reference/tools.md +2 -28
  175. package/dist/docs/templates/agentic-owners.html +35 -35
  176. package/dist/docs/templates/grokbot-agents.html +37 -37
  177. package/dist/docs/templates/grokbot-agents.md +1 -1
  178. package/dist/docs/templates/security-reviewer.html +35 -35
  179. package/dist/docs/templates/thermo-quality-review.html +35 -35
  180. package/dist/docs/templates/thermo-review.html +35 -35
  181. package/dist/docs/templates/triage.html +35 -35
  182. package/dist/docs/troubleshooting.html +36 -36
  183. package/dist/docs/troubleshooting.md +12 -7
  184. package/dist/executors.d.ts +11 -0
  185. package/dist/executors.d.ts.map +1 -0
  186. package/dist/executors.js +21 -0
  187. package/dist/extensions/cursor-cloud-agents/extension.d.ts +6 -2
  188. package/dist/extensions/cursor-cloud-agents/extension.d.ts.map +1 -1
  189. package/dist/extensions/cursor-cloud-agents/extension.js +5 -1
  190. package/dist/extensions/cursor-cloud-agents/lib/channels.d.ts.map +1 -1
  191. package/dist/extensions/cursor-cloud-agents/lib/channels.js +5 -1
  192. package/dist/extensions/cursor-cloud-agents/lib/launch-agent.d.ts +21 -4
  193. package/dist/extensions/cursor-cloud-agents/lib/launch-agent.d.ts.map +1 -1
  194. package/dist/extensions/cursor-cloud-agents/lib/launch-agent.js +26 -5
  195. package/dist/files.d.ts +1 -0
  196. package/dist/files.d.ts.map +1 -1
  197. package/dist/files.js +3 -1
  198. package/dist/filesystem.d.ts +10 -0
  199. package/dist/filesystem.d.ts.map +1 -1
  200. package/dist/filesystem.js +128 -0
  201. package/dist/index.d.ts +1 -1
  202. package/dist/index.d.ts.map +1 -1
  203. package/dist/index.js +1 -1
  204. package/dist/internal/cli-deploy.d.ts.map +1 -1
  205. package/dist/internal/cli-deploy.js +17 -0
  206. package/dist/internal/continuation-identity.js +1 -1
  207. package/dist/internal/conversation-mirror.d.ts +11 -0
  208. package/dist/internal/conversation-mirror.d.ts.map +1 -1
  209. package/dist/internal/conversation-mirror.js +198 -125
  210. package/dist/internal/conversation-pack.d.ts +29 -0
  211. package/dist/internal/conversation-pack.d.ts.map +1 -0
  212. package/dist/internal/conversation-pack.js +96 -0
  213. package/dist/internal/deploy-client.d.ts +2 -0
  214. package/dist/internal/deploy-client.d.ts.map +1 -1
  215. package/dist/internal/deploy-client.js +4 -0
  216. package/dist/internal/discovery/agent-config.d.ts +6 -0
  217. package/dist/internal/discovery/agent-config.d.ts.map +1 -1
  218. package/dist/internal/discovery/agent-config.js +19 -0
  219. package/dist/internal/discovery/agent.d.ts.map +1 -1
  220. package/dist/internal/discovery/agent.js +2 -1
  221. package/dist/internal/hosted-catch-protocol.d.ts +2 -0
  222. package/dist/internal/hosted-catch-protocol.d.ts.map +1 -1
  223. package/dist/internal/hosted-catch-protocol.js +2 -0
  224. package/dist/internal/hosted-catch.d.ts +2 -3
  225. package/dist/internal/hosted-catch.d.ts.map +1 -1
  226. package/dist/internal/hosted-catch.js +2 -3
  227. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  228. package/dist/internal/hosted-delivery.js +22 -12
  229. package/dist/internal/hosted-execution-flush.d.ts +6 -3
  230. package/dist/internal/hosted-execution-flush.d.ts.map +1 -1
  231. package/dist/internal/hosted-execution-flush.js +28 -31
  232. package/dist/internal/peer-connections.d.ts +6 -2
  233. package/dist/internal/peer-connections.d.ts.map +1 -1
  234. package/dist/internal/peer-connections.js +23 -19
  235. package/dist/internal/sdk-runner.d.ts.map +1 -1
  236. package/dist/internal/sdk-runner.js +13 -2
  237. package/dist/internal/server.d.ts.map +1 -1
  238. package/dist/internal/server.js +6 -5
  239. package/dist/internal/session-engine.d.ts.map +1 -1
  240. package/dist/internal/session-engine.js +4 -0
  241. package/dist/internal/session-run-log.d.ts.map +1 -1
  242. package/dist/internal/session-run-log.js +26 -11
  243. package/dist/internal/turn-cost.d.ts +2 -2
  244. package/dist/internal/turn-cost.d.ts.map +1 -1
  245. package/dist/internal/turn-cost.js +17 -3
  246. package/dist/playground/assets/index-BVYWBxLU.css +1 -0
  247. package/dist/playground/assets/{index-DIiKbZ25.js → index-DCsq6f_I.js} +45 -45
  248. package/dist/playground/index.html +2 -2
  249. package/dist/types.d.ts +18 -0
  250. package/dist/types.d.ts.map +1 -1
  251. package/docs/README.md +1 -1
  252. package/docs/building-with-agents.md +5 -5
  253. package/docs/deployment.md +70 -33
  254. package/docs/evals.md +1 -16
  255. package/docs/guides/cloud-agents.md +3 -9
  256. package/docs/guides/grokbot-agents.md +10 -14
  257. package/docs/guides/hooks.md +0 -1
  258. package/docs/guides/improve.md +4 -6
  259. package/docs/guides/mcp-oauth.md +18 -41
  260. package/docs/guides/webhooks.md +35 -18
  261. package/docs/quickstart.md +2 -2
  262. package/docs/reference/channels.md +29 -13
  263. package/docs/reference/cli.md +113 -40
  264. package/docs/reference/connections.md +6 -5
  265. package/docs/reference/evals.md +2 -4
  266. package/docs/reference/hooks.md +0 -1
  267. package/docs/reference/http-api.md +7 -17
  268. package/docs/reference/playground.md +2 -5
  269. package/docs/reference/schedules.md +26 -3
  270. package/docs/reference/sessions.md +1 -2
  271. package/docs/reference/skills.md +1 -1
  272. package/docs/reference/tools.md +3 -29
  273. package/docs/templates/grokbot-agents.md +1 -1
  274. package/docs/troubleshooting.md +12 -7
  275. package/package.json +43 -32
  276. package/skills/create-agent/SKILL.md +9 -6
  277. package/skills/debug/SKILL.md +3 -4
  278. package/skills/evals/SKILL.md +2 -2
  279. package/skills/framework-map/SKILL.md +10 -10
  280. package/skills/mcp-auth/SKILL.md +10 -34
  281. package/skills/migrate-v2/SKILL.md +13 -9
  282. package/skills/setup-slack/SKILL.md +0 -13
  283. package/templates/agents-md/README.md +3 -3
  284. package/templates/agents-md/bot/channels/queue.ts +3 -8
  285. package/templates/agents-md/bot/instructions.md +1 -2
  286. package/templates/agents-md/bot/tools/apply_agents.ts +0 -1
  287. package/templates/agents-md/evals/agents.eval.ts +2 -2
  288. package/templates/demo/bot/channels/queue.ts +5 -15
  289. package/templates/grokbot-agents/.gitignore +4 -0
  290. package/templates/pr-autofixer/bot/channels/drive.ts +3 -16
  291. package/templates/security-help/.gitignore +4 -0
  292. package/templates/triage/bot/channels/queue.ts +11 -22
  293. package/templates/triage/bot/channels/webhook.ts +3 -6
  294. package/templates/triage/bot/lib/parse-queue-event.ts +0 -6
  295. package/dist/docs/assets/chunks/@localSearchIndexroot.DvlKuIO-.js +0 -1
  296. package/dist/docs/assets/chunks/channel.BRSFxCcD.js +0 -1
  297. package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.Cmtm6WkN.js +0 -1
  298. package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.Cmtm6WkN.js +0 -1
  299. package/dist/docs/assets/chunks/clone.JMC96Eo6.js +0 -1
  300. package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.N4Am6sXd.js +0 -1
  301. package/dist/docs/assets/chunks/wardley-RL74JXVD._eATmGtu.js +0 -162
  302. package/dist/docs/assets/deployment.md.BYuEcDBv.js +0 -29
  303. package/dist/docs/assets/guides_cloud-agents.md.CWJjS9No.js +0 -10
  304. package/dist/docs/assets/guides_cloud-agents.md.CWJjS9No.lean.js +0 -1
  305. package/dist/docs/assets/guides_grokbot-agents.md.tD1smFhU.js +0 -16
  306. package/dist/docs/assets/guides_mcp-oauth.md.DR3zhC9r.lean.js +0 -1
  307. package/dist/docs/assets/reference_channels.md.LbNIJBwd.js +0 -23
  308. package/dist/docs/assets/reference_http-api.md.DbFNOubV.js +0 -11
  309. package/dist/docs/assets/reference_playground.md.1hx0gcIu.js +0 -1
  310. package/dist/docs/assets/reference_playground.md.1hx0gcIu.lean.js +0 -1
  311. package/dist/docs/assets/reference_sessions.md.CyM7ARz1.js +0 -1
  312. package/dist/docs/assets/reference_tools.md.DzIY9JzY.lean.js +0 -1
  313. package/dist/docs/assets/troubleshooting.md.x-GBa7wN.js +0 -1
  314. package/dist/playground/assets/index-CzttDc-d.css +0 -1
  315. /package/dist/docs/assets/{guides_hooks.md.5Ce3NXxZ.lean.js → guides_hooks.md.B_bKG1oA.lean.js} +0 -0
  316. /package/dist/docs/assets/{index.md.Dxxr7pFa.lean.js → index.md.BIBHIQtU.lean.js} +0 -0
  317. /package/dist/docs/assets/{quickstart.md.BK5gjHM2.lean.js → quickstart.md.CduLGBAB.lean.js} +0 -0
  318. /package/dist/docs/assets/{reference_evals.md.D5i8PuXJ.lean.js → reference_evals.md.if--BLd0.lean.js} +0 -0
  319. /package/dist/docs/assets/{reference_hooks.md.B-eGa2km.lean.js → reference_hooks.md.DbJC8mcZ.lean.js} +0 -0
  320. /package/dist/docs/assets/{reference_sessions.md.CyM7ARz1.lean.js → reference_sessions.md.C_uzIWuy.lean.js} +0 -0
  321. /package/dist/docs/assets/{reference_skills.md.C0guGcH0.lean.js → reference_skills.md.Ckddg6KX.lean.js} +0 -0
  322. /package/dist/docs/assets/{templates_grokbot-agents.md.2sydjFiO.lean.js → templates_grokbot-agents.md.DgpPEs7B.lean.js} +0 -0
@@ -5,6 +5,13 @@
5
5
  * persists it after each local turn. Conversation data uses framework-owned
6
6
  * storage, isolated from author-facing files and KV.
7
7
  *
8
+ * Checkpoint blobs are written in content-addressed packs
9
+ * (`conversation-pack.ts`): a turn's new blobs are one store write, not one
10
+ * per blob. The manifest (v2) lists the packs and is written last. Manifests
11
+ * from engines that wrote one object per blob (v1) still restore; the first
12
+ * persist after such a restore re-packs the whole conversation from the
13
+ * local store.
14
+ *
8
15
  * Restore failures propagate so a temporary storage outage cannot fork an
9
16
  * existing thread into a fresh conversation. Run bookkeeping remains local;
10
17
  * the durable session event stream already records user-visible history.
@@ -12,6 +19,7 @@
12
19
  import { agentSdkAgentStoreKeys } from "../files.js";
13
20
  import { cursorHostedFiles } from "../files-backends/cursor-hosted.js";
14
21
  import { mapBounded } from "./bounded.js";
22
+ import { conversationPackEntrySize, decodeConversationPack, encodeConversationPack, } from "./conversation-pack.js";
15
23
  import { resolveApiKeySync } from "./cursor/credentials.js";
16
24
  import { describeError } from "./describe-error.js";
17
25
  import { resolveAgentV2Hosting } from "./v2-hosting.js";
@@ -19,41 +27,27 @@ import { resolveAgentV2Hosting } from "./v2-hosting.js";
19
27
  export function createConversationMirror(options) {
20
28
  const { sink, agentName } = options;
21
29
  const logger = options.logger ?? (() => { });
30
+ const packTargetBytes = options.packTargetBytes ?? PACK_TARGET_BYTES;
31
+ const maxPacks = options.maxPacks ?? MAX_PACKS;
22
32
  /**
23
- * Blob ids known to be in the sink, per SDK agent id (upload dedupe).
24
- * Bounded oldest-out like the files backend's etag cache: a resident
25
- * engine touches an unbounded number of conversations over its lifetime,
26
- * and a miss costs one manifest read, never correctness.
33
+ * Packs each conversation's last successful manifest listed. Bounded
34
+ * oldest-out like the files backend's etag cache: a resident engine
35
+ * touches an unbounded number of conversations over its lifetime, and a
36
+ * miss costs one manifest read, never correctness.
27
37
  */
28
- const mirrored = new Map();
29
- const rememberMirrored = (sdkAgentId, blobIds) => {
30
- if (!mirrored.has(sdkAgentId) && mirrored.size >= MAX_TRACKED_CONVERSATIONS) {
31
- const oldest = mirrored.keys().next();
32
- if (!oldest.done) {
33
- mirrored.delete(oldest.value);
34
- }
35
- }
36
- mirrored.set(sdkAgentId, blobIds);
38
+ const packStates = new Map();
39
+ const rememberPacks = (sdkAgentId, packs) => {
40
+ rememberBounded(packStates, sdkAgentId, packs);
37
41
  };
38
42
  /**
39
43
  * Content of the last manifest each conversation **successfully** wrote
40
44
  * (minus `persistedAtMs`, which changes on every call by construction).
41
- * A persist whose agent document and blob list are unchanged skips the
45
+ * A persist whose agent document and pack list are unchanged skips the
42
46
  * manifest rewrite — `persist` runs on every turn boundary, but most
43
47
  * boundaries between checkpoints change nothing durable. Same bound and
44
- * eviction as `mirrored`; a miss only costs a redundant rewrite.
48
+ * eviction as `packStates`; a miss only costs a redundant rewrite.
45
49
  */
46
50
  const lastManifestContent = new Map();
47
- const rememberManifest = (sdkAgentId, content) => {
48
- if (!lastManifestContent.has(sdkAgentId) &&
49
- lastManifestContent.size >= MAX_TRACKED_CONVERSATIONS) {
50
- const oldest = lastManifestContent.keys().next();
51
- if (!oldest.done) {
52
- lastManifestContent.delete(oldest.value);
53
- }
54
- }
55
- lastManifestContent.set(sdkAgentId, content);
56
- };
57
51
  /**
58
52
  * Per-conversation serialization so a persist cannot interleave with a
59
53
  * hydrate (or another persist) for the same conversation. Entries are
@@ -74,67 +68,61 @@ export function createConversationMirror(options) {
74
68
  chains.set(sdkAgentId, stored);
75
69
  return next;
76
70
  }
77
- async function mirroredBlobIds(sdkAgentId) {
78
- const cached = mirrored.get(sdkAgentId);
71
+ async function persistedPacks(sdkAgentId) {
72
+ const cached = packStates.get(sdkAgentId);
79
73
  if (cached !== undefined) {
80
74
  return cached;
81
75
  }
82
- // Seed from the previous manifest so a new process does not re-upload the
83
- // whole history on its first persist. A miss, an unusable manifest, or
84
- // a failed read seeds empty — re-uploading is wasteful, never wrong.
85
- const seeded = new Set();
76
+ // Seed from the previous manifest so a new process appends to it instead
77
+ // of re-packing the whole history. Anything but a usable v2 manifest
78
+ // seeds empty — re-packing from the local store is wasteful, never wrong.
79
+ let seeded = [];
86
80
  try {
87
81
  const read = await readManifest(sink, agentName, sdkAgentId);
88
- if (read.outcome === "found") {
89
- for (const blobId of read.manifest.blobIds) {
90
- seeded.add(blobId);
91
- }
82
+ if (read.outcome === "found" && read.manifest.v === 2) {
83
+ seeded = read.manifest.packs;
92
84
  }
93
85
  }
94
86
  catch (error) {
95
- logger(`[bdk] conversation mirror: could not read the prior manifest for ${sdkAgentId} (${describeError(error)}); re-uploading blobs`);
87
+ logger(`[bdk] conversation mirror: could not read the prior manifest for ${sdkAgentId} (${describeError(error)}); re-packing the conversation`);
96
88
  }
97
- rememberMirrored(sdkAgentId, seeded);
89
+ rememberPacks(sdkAgentId, seeded);
98
90
  return seeded;
99
91
  }
100
- async function uploadBlobs(store, sdkAgentId, blobIds, uploaded) {
101
- const entries = [];
102
- for (const blobId of blobIds) {
103
- const body = await store.checkpoints.get({ agentId: sdkAgentId, blobId });
104
- if (body !== null) {
105
- entries.push({
106
- blobId,
107
- key: agentSdkAgentStoreKeys.conversationBlob(agentName, sdkAgentId, blobId),
108
- body,
109
- });
110
- }
111
- }
112
- if (entries.length === 0) {
113
- return;
114
- }
115
- if (sink.putMany === undefined) {
116
- for (const entry of entries) {
117
- await sink.put(entry.key, entry.body);
118
- uploaded.add(entry.blobId);
92
+ /**
93
+ * Read `blobIds` from the local store and upload them as packs of at most
94
+ * `packTargetBytes` (a larger blob gets a pack of its own). Packs upload
95
+ * one at a time so a re-pack never holds more than one pack in memory.
96
+ */
97
+ async function writePacks(store, sdkAgentId, blobIds) {
98
+ const written = [];
99
+ let entries = [];
100
+ let bytes = 0;
101
+ const flush = async () => {
102
+ if (entries.length === 0) {
103
+ return;
119
104
  }
120
- return;
121
- }
122
- const settled = await sink.putMany(entries.map(({ key, body }) => ({ key, body })));
123
- let failure;
124
- for (const [index, entry] of entries.entries()) {
125
- const outcome = settled[index];
126
- if (outcome?.status === "fulfilled") {
127
- uploaded.add(entry.blobId);
105
+ const { packId, body } = encodeConversationPack(entries);
106
+ await sink.put(agentSdkAgentStoreKeys.conversationPack(agentName, sdkAgentId, packId), body);
107
+ written.push({ id: packId, blobIds: entries.map((entry) => entry.blobId) });
108
+ entries = [];
109
+ bytes = 0;
110
+ };
111
+ for (const blobId of blobIds) {
112
+ const data = await store.checkpoints.get({ agentId: sdkAgentId, blobId });
113
+ if (data === null) {
114
+ continue;
128
115
  }
129
- else if (failure === undefined) {
130
- failure =
131
- outcome?.reason ??
132
- new Error(`conversation mirror: batched upload of "${entry.key}" returned no outcome`);
116
+ const entry = { blobId, data };
117
+ const size = conversationPackEntrySize(entry);
118
+ if (entries.length > 0 && bytes + size > packTargetBytes) {
119
+ await flush();
133
120
  }
121
+ entries.push(entry);
122
+ bytes += size;
134
123
  }
135
- if (failure !== undefined) {
136
- throw failure;
137
- }
124
+ await flush();
125
+ return written;
138
126
  }
139
127
  return {
140
128
  persist(store, sdkAgentId) {
@@ -144,34 +132,53 @@ export function createConversationMirror(options) {
144
132
  // Nothing restorable yet (no conversation, or no checkpoint).
145
133
  return;
146
134
  }
147
- const uploaded = await mirroredBlobIds(sdkAgentId);
148
- const blobIds = await listCheckpointBlobIds(store, sdkAgentId);
149
- const pending = blobIds.filter((blobId) => !uploaded.has(blobId));
150
- for (let start = 0; start < pending.length; start += PERSIST_UPLOAD_BATCH_SIZE) {
151
- await uploadBlobs(store, sdkAgentId, pending.slice(start, start + PERSIST_UPLOAD_BATCH_SIZE), uploaded);
135
+ const previous = await persistedPacks(sdkAgentId);
136
+ const packed = new Set(previous.flatMap((pack) => pack.blobIds));
137
+ const local = await listCheckpointBlobIds(store, sdkAgentId);
138
+ const pending = local.filter((blobId) => !packed.has(blobId));
139
+ let packs = previous;
140
+ if (pending.length > 0) {
141
+ const localSet = new Set(local);
142
+ const canRepack = [...packed].every((blobId) => localSet.has(blobId));
143
+ if (previous.length + 1 > maxPacks && canRepack) {
144
+ // The packs this replaces stay in the store: another process
145
+ // holding an outdated pack list may still write a manifest that
146
+ // references them, and that manifest must remain restorable.
147
+ packs = await writePacks(store, sdkAgentId, local);
148
+ }
149
+ else {
150
+ packs = [...previous, ...(await writePacks(store, sdkAgentId, pending))];
151
+ }
152
152
  }
153
153
  const manifest = {
154
- v: 1,
154
+ v: 2,
155
155
  // The referenced run is process-local bookkeeping and is not mirrored;
156
156
  // a hydrated store must not point at a run row it does not hold.
157
157
  agent: { ...document, activeRunId: null },
158
- blobIds: blobIds.filter((blobId) => uploaded.has(blobId)),
158
+ packs,
159
159
  persistedAtMs: Date.now(),
160
160
  };
161
161
  // Skip the rewrite when nothing durable changed. `persistedAtMs`
162
162
  // is excluded from the comparison — it differs on every call by
163
163
  // construction and carries no restore semantics.
164
- const content = JSON.stringify({
165
- agent: manifest.agent,
166
- blobIds: manifest.blobIds,
167
- });
164
+ const content = JSON.stringify({ agent: manifest.agent, packs: manifest.packs });
168
165
  if (lastManifestContent.get(sdkAgentId) === content) {
169
166
  return;
170
167
  }
171
168
  lastManifestContent.delete(sdkAgentId);
172
- // Manifest last: it only ever references blobs already uploaded.
173
- await sink.put(agentSdkAgentStoreKeys.conversationManifest(agentName, sdkAgentId), new TextEncoder().encode(JSON.stringify(manifest)));
174
- rememberManifest(sdkAgentId, content);
169
+ // Manifest last: it only ever references packs already uploaded.
170
+ try {
171
+ await sink.put(agentSdkAgentStoreKeys.conversationManifest(agentName, sdkAgentId), new TextEncoder().encode(JSON.stringify(manifest)));
172
+ }
173
+ catch (error) {
174
+ // A conflict means another process wrote the manifest. Re-read it
175
+ // on the next persist and append to its packs rather than
176
+ // overwriting them from this process's outdated list.
177
+ packStates.delete(sdkAgentId);
178
+ throw error;
179
+ }
180
+ rememberPacks(sdkAgentId, packs);
181
+ rememberBounded(lastManifestContent, sdkAgentId, content);
175
182
  });
176
183
  },
177
184
  hydrate(store, sdkAgentId) {
@@ -193,62 +200,114 @@ export function createConversationMirror(options) {
193
200
  return false;
194
201
  }
195
202
  const manifest = read.manifest;
203
+ const listed = new Set(manifest.v === 2 ? manifest.packs.flatMap((pack) => pack.blobIds) : manifest.blobIds);
196
204
  const rootBlobId = manifest.agent.latestCheckpoint?.rootBlobId;
197
- if (rootBlobId === undefined || !manifest.blobIds.includes(rootBlobId)) {
205
+ if (rootBlobId === undefined || !listed.has(rootBlobId)) {
198
206
  logger(`[bdk] conversation mirror: the manifest for ${sdkAgentId} does not list its root checkpoint blob; treating the conversation as unrestorable`);
199
207
  return false;
200
208
  }
201
- // This sits on the resume critical path. Prefer a batched read and
202
- // fall back to bounded parallel reads when the sink has no batch API.
203
- const blobKeys = manifest.blobIds.map((blobId) => agentSdkAgentStoreKeys.conversationBlob(agentName, sdkAgentId, blobId));
204
- const blobBodies = sink.getMany !== undefined
205
- ? await sink.getMany(blobKeys)
206
- : await mapBounded(blobKeys, HYDRATE_DOWNLOAD_CONCURRENCY, (key) => sink.get(key));
207
- const bodies = manifest.blobIds.map((blobId, index) => ({
208
- blobId,
209
- body: blobBodies[index],
210
- }));
211
- const missing = bodies.filter((entry) => entry.body === undefined);
209
+ const blobs = manifest.v === 2
210
+ ? await readPackedBlobs(sdkAgentId, manifest.packs)
211
+ : await readLooseBlobs(sdkAgentId, manifest.blobIds);
212
+ if (blobs === undefined) {
213
+ return false;
214
+ }
215
+ // The manifest lists exactly what a previous persist uploaded, so
216
+ // any definitive absence is store loss — and the checkpoint graph
217
+ // may reach any listed blob, not just the root. Restoring a partial
218
+ // graph would create an agent row whose resume succeeds and whose
219
+ // checkpoint walk then fails unrecoverably.
220
+ const missing = [...listed].filter((blobId) => !blobs.has(blobId));
212
221
  if (missing.length > 0) {
213
- // The manifest lists exactly what a previous persist uploaded, so
214
- // any definitive absence is store loss — and the checkpoint graph
215
- // may reach any listed blob, not just the root. Restoring a
216
- // partial graph would create an agent row whose resume succeeds
217
- // and whose checkpoint walk then fails unrecoverably.
218
222
  logger(`[bdk] conversation mirror: ${missing.length} checkpoint blob(s) for ${sdkAgentId} are missing from the sink; treating the conversation as unrestorable`);
219
223
  return false;
220
224
  }
221
- const restored = new Set();
222
- for (const entry of bodies) {
223
- const body = entry.body;
224
- const bytes = body instanceof Uint8Array ? body : body.body;
225
- if ((await store.checkpoints.get({
226
- agentId: sdkAgentId,
227
- blobId: entry.blobId,
228
- })) === null) {
229
- await store.checkpoints.create({
230
- agentId: sdkAgentId,
231
- blobId: entry.blobId,
232
- data: bytes,
233
- });
225
+ for (const [blobId, data] of blobs) {
226
+ if ((await store.checkpoints.get({ agentId: sdkAgentId, blobId })) === null) {
227
+ await store.checkpoints.create({ agentId: sdkAgentId, blobId, data });
234
228
  }
235
- restored.add(entry.blobId);
236
229
  }
237
230
  await store.agents.create({
238
231
  agent: { ...manifest.agent, activeRunId: null },
239
232
  });
240
- rememberMirrored(sdkAgentId, restored);
241
- logger(`[bdk] conversation mirror: restored the conversation for ${sdkAgentId} (${restored.size} checkpoint blob(s))`);
233
+ if (manifest.v === 2) {
234
+ rememberPacks(sdkAgentId, manifest.packs);
235
+ }
236
+ logger(`[bdk] conversation mirror: restored the conversation for ${sdkAgentId} (${blobs.size} checkpoint blob(s))`);
242
237
  return true;
243
238
  });
244
239
  },
245
240
  };
241
+ /** This sits on the resume critical path: one batched read when the sink has one. */
242
+ async function readMany(keys) {
243
+ return sink.getMany !== undefined
244
+ ? await sink.getMany(keys)
245
+ : await mapBounded(keys, HYDRATE_DOWNLOAD_CONCURRENCY, (key) => sink.get(key));
246
+ }
247
+ /**
248
+ * Every blob in `packs`, or `undefined` when a pack is absent or damaged
249
+ * (definitive store loss: the conversation is unrestorable).
250
+ */
251
+ async function readPackedBlobs(sdkAgentId, packs) {
252
+ const bodies = await readMany(packs.map((pack) => agentSdkAgentStoreKeys.conversationPack(agentName, sdkAgentId, pack.id)));
253
+ const blobs = new Map();
254
+ for (const [index, pack] of packs.entries()) {
255
+ const body = bodies[index];
256
+ if (body === undefined) {
257
+ logger(`[bdk] conversation mirror: checkpoint pack ${pack.id} for ${sdkAgentId} is missing from the sink; treating the conversation as unrestorable`);
258
+ return undefined;
259
+ }
260
+ try {
261
+ for (const entry of decodeConversationPack(pack.id, bytesOf(body))) {
262
+ blobs.set(entry.blobId, entry.data);
263
+ }
264
+ }
265
+ catch (error) {
266
+ logger(`[bdk] conversation mirror: checkpoint pack ${pack.id} for ${sdkAgentId} is unreadable (${describeError(error)}); treating the conversation as unrestorable`);
267
+ return undefined;
268
+ }
269
+ }
270
+ return blobs;
271
+ }
272
+ async function readLooseBlobs(sdkAgentId, blobIds) {
273
+ const bodies = await readMany(blobIds.map((blobId) => agentSdkAgentStoreKeys.conversationBlob(agentName, sdkAgentId, blobId)));
274
+ const blobs = new Map();
275
+ for (const [index, blobId] of blobIds.entries()) {
276
+ const body = bodies[index];
277
+ if (body !== undefined) {
278
+ blobs.set(blobId, bytesOf(body));
279
+ }
280
+ }
281
+ return blobs;
282
+ }
246
283
  }
247
- /** Oldest-out cap on the per-conversation upload-dedupe cache. */
284
+ /** Oldest-out cap on the per-conversation caches. */
248
285
  const MAX_TRACKED_CONVERSATIONS = 1_000;
249
- /** Parallel blob downloads during hydrate (resume critical path). */
286
+ function rememberBounded(map, key, value) {
287
+ if (!map.has(key) && map.size >= MAX_TRACKED_CONVERSATIONS) {
288
+ const oldest = map.keys().next();
289
+ if (!oldest.done) {
290
+ map.delete(oldest.value);
291
+ }
292
+ }
293
+ map.set(key, value);
294
+ }
295
+ /** Parallel downloads during hydrate when the sink has no batched read. */
250
296
  const HYDRATE_DOWNLOAD_CONCURRENCY = 8;
251
- const PERSIST_UPLOAD_BATCH_SIZE = 50;
297
+ /**
298
+ * Pack split size. Well under the store's single-part upload limit, and small
299
+ * enough that a re-pack holds little in memory at a time.
300
+ */
301
+ const PACK_TARGET_BYTES = 8 * 1024 * 1024;
302
+ /**
303
+ * Packs a manifest may list before the next persist re-packs the whole
304
+ * conversation. Bounds the reads a resume costs; a re-pack rewrites the
305
+ * conversation's bytes once per this many persists that add blobs.
306
+ */
307
+ const MAX_PACKS = 32;
308
+ function bytesOf(body) {
309
+ return body instanceof Uint8Array ? body : body.body;
310
+ }
252
311
  /**
253
312
  * Read the persisted manifest. Sink transport failures propagate (an
254
313
  * outage must fail the follow-up, not fork the thread); everything the
@@ -259,26 +318,40 @@ async function readManifest(sink, agentName, sdkAgentId) {
259
318
  if (body === undefined) {
260
319
  return { outcome: "miss" };
261
320
  }
262
- const bytes = body instanceof Uint8Array ? body : body.body;
263
321
  let parsed;
264
322
  try {
265
- parsed = JSON.parse(new TextDecoder().decode(bytes));
323
+ parsed = JSON.parse(new TextDecoder().decode(bytesOf(body)));
266
324
  }
267
325
  catch {
268
326
  return { outcome: "unusable", reason: "not JSON" };
269
327
  }
270
- if (parsed === null || typeof parsed !== "object" || parsed.v !== 1) {
328
+ if (parsed === null || typeof parsed !== "object") {
329
+ return { outcome: "unusable", reason: "malformed manifest" };
330
+ }
331
+ const version = parsed.v;
332
+ if (version !== 1 && version !== 2) {
271
333
  return { outcome: "unusable", reason: "unsupported manifest version" };
272
334
  }
273
335
  const manifest = parsed;
274
336
  if (manifest.agent === null ||
275
337
  typeof manifest.agent !== "object" ||
276
338
  manifest.agent.agentId !== sdkAgentId ||
277
- !Array.isArray(manifest.blobIds)) {
339
+ !(manifest.v === 1 ? isStringArray(manifest.blobIds) : isPackRefArray(manifest.packs))) {
278
340
  return { outcome: "unusable", reason: "malformed manifest" };
279
341
  }
280
342
  return { outcome: "found", manifest };
281
343
  }
344
+ function isStringArray(value) {
345
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
346
+ }
347
+ function isPackRefArray(value) {
348
+ return (Array.isArray(value) &&
349
+ value.every((item) => item !== null &&
350
+ typeof item === "object" &&
351
+ typeof item.id === "string" &&
352
+ /^[0-9a-f]{64}$/.test(item.id) &&
353
+ isStringArray(item.blobIds)));
354
+ }
282
355
  async function listCheckpointBlobIds(store, sdkAgentId) {
283
356
  const blobIds = [];
284
357
  let cursor;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Wire format for a conversation checkpoint pack: many content-addressed
3
+ * checkpoint blobs in one durable object, so a turn's new blobs cost one
4
+ * store write instead of one per blob.
5
+ *
6
+ * Layout (big-endian): the 8-byte magic, a u32 entry count, then per entry a
7
+ * u16 blob-id length, the UTF-8 blob id, a u32 data length and the data. The
8
+ * pack id is the SHA-256 of the whole encoding, so a pack is immutable and
9
+ * a re-upload after a failed persist lands on the same key.
10
+ */
11
+ export interface ConversationPackEntry {
12
+ blobId: string;
13
+ data: Uint8Array;
14
+ }
15
+ export interface EncodedConversationPack {
16
+ packId: string;
17
+ body: Uint8Array;
18
+ }
19
+ /** Bytes an entry adds to a pack; used to split packs before encoding. */
20
+ export declare function conversationPackEntrySize(entry: ConversationPackEntry): number;
21
+ export declare function conversationPackId(body: Uint8Array): string;
22
+ export declare function encodeConversationPack(entries: readonly ConversationPackEntry[]): EncodedConversationPack;
23
+ /**
24
+ * Decode a pack read back from the store. Throws on any structural damage or
25
+ * when the bytes do not hash to `packId`; the caller treats that exactly like
26
+ * a missing pack.
27
+ */
28
+ export declare function decodeConversationPack(packId: string, body: Uint8Array): ConversationPackEntry[];
29
+ //# sourceMappingURL=conversation-pack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation-pack.d.ts","sourceRoot":"","sources":["../../src/internal/conversation-pack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,UAAU,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,UAAU,CAAC;CAClB;AAMD,0EAA0E;AAC1E,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,qBAAqB,GAAG,MAAM,CAE9E;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAE3D;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,SAAS,qBAAqB,EAAE,GACxC,uBAAuB,CAgCzB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,qBAAqB,EAAE,CAoChG"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Wire format for a conversation checkpoint pack: many content-addressed
3
+ * checkpoint blobs in one durable object, so a turn's new blobs cost one
4
+ * store write instead of one per blob.
5
+ *
6
+ * Layout (big-endian): the 8-byte magic, a u32 entry count, then per entry a
7
+ * u16 blob-id length, the UTF-8 blob id, a u32 data length and the data. The
8
+ * pack id is the SHA-256 of the whole encoding, so a pack is immutable and
9
+ * a re-upload after a failed persist lands on the same key.
10
+ */
11
+ import { createHash } from "node:crypto";
12
+ const MAGIC = new TextEncoder().encode("BDKCPK1\n");
13
+ const MAX_BLOB_ID_BYTES = 0xffff;
14
+ const MAX_ENTRY_BYTES = 0xffffffff;
15
+ /** Bytes an entry adds to a pack; used to split packs before encoding. */
16
+ export function conversationPackEntrySize(entry) {
17
+ return 2 + new TextEncoder().encode(entry.blobId).length + 4 + entry.data.length;
18
+ }
19
+ export function conversationPackId(body) {
20
+ return createHash("sha256").update(body).digest("hex");
21
+ }
22
+ export function encodeConversationPack(entries) {
23
+ const encoder = new TextEncoder();
24
+ const ids = entries.map((entry) => encoder.encode(entry.blobId));
25
+ let size = MAGIC.length + 4;
26
+ for (const [index, entry] of entries.entries()) {
27
+ const id = ids[index];
28
+ if (id.length === 0 || id.length > MAX_BLOB_ID_BYTES) {
29
+ throw new Error(`conversation pack: blob id "${entry.blobId}" has an unencodable length`);
30
+ }
31
+ if (entry.data.length > MAX_ENTRY_BYTES) {
32
+ throw new Error(`conversation pack: blob "${entry.blobId}" is too large to pack`);
33
+ }
34
+ size += 2 + id.length + 4 + entry.data.length;
35
+ }
36
+ const body = new Uint8Array(size);
37
+ const view = new DataView(body.buffer);
38
+ body.set(MAGIC, 0);
39
+ let offset = MAGIC.length;
40
+ view.setUint32(offset, entries.length);
41
+ offset += 4;
42
+ for (const [index, entry] of entries.entries()) {
43
+ const id = ids[index];
44
+ view.setUint16(offset, id.length);
45
+ offset += 2;
46
+ body.set(id, offset);
47
+ offset += id.length;
48
+ view.setUint32(offset, entry.data.length);
49
+ offset += 4;
50
+ body.set(entry.data, offset);
51
+ offset += entry.data.length;
52
+ }
53
+ return { packId: conversationPackId(body), body };
54
+ }
55
+ /**
56
+ * Decode a pack read back from the store. Throws on any structural damage or
57
+ * when the bytes do not hash to `packId`; the caller treats that exactly like
58
+ * a missing pack.
59
+ */
60
+ export function decodeConversationPack(packId, body) {
61
+ if (conversationPackId(body) !== packId) {
62
+ throw new Error("conversation pack: content does not match its id");
63
+ }
64
+ if (body.length < MAGIC.length + 4 || MAGIC.some((byte, index) => body[index] !== byte)) {
65
+ throw new Error("conversation pack: unrecognized format");
66
+ }
67
+ const view = new DataView(body.buffer, body.byteOffset, body.byteLength);
68
+ const decoder = new TextDecoder("utf-8", { fatal: true });
69
+ let offset = MAGIC.length;
70
+ const count = view.getUint32(offset);
71
+ offset += 4;
72
+ const entries = [];
73
+ const need = (bytes) => {
74
+ if (offset + bytes > body.length) {
75
+ throw new Error("conversation pack: truncated");
76
+ }
77
+ };
78
+ for (let index = 0; index < count; index++) {
79
+ need(2);
80
+ const idLength = view.getUint16(offset);
81
+ offset += 2;
82
+ need(idLength);
83
+ const blobId = decoder.decode(body.subarray(offset, offset + idLength));
84
+ offset += idLength;
85
+ need(4);
86
+ const dataLength = view.getUint32(offset);
87
+ offset += 4;
88
+ need(dataLength);
89
+ entries.push({ blobId, data: body.slice(offset, offset + dataLength) });
90
+ offset += dataLength;
91
+ }
92
+ if (offset !== body.length) {
93
+ throw new Error("conversation pack: trailing bytes");
94
+ }
95
+ return entries;
96
+ }
@@ -355,6 +355,8 @@ export declare class AgentServeDeployClient {
355
355
  persistent?: boolean;
356
356
  /** Single-agent `hosting.image`; components carry their own. */
357
357
  image?: string;
358
+ /** `init --template` scaffold name, reported for deploy analytics. */
359
+ template?: string;
358
360
  }): Promise<AgentkitDeployAccepted>;
359
361
  getAgentkitDeploy(args: {
360
362
  teamId: number;