@cursor/bdk 0.2.16 → 0.2.18

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 (221) hide show
  1. package/README.md +2 -2
  2. package/dist/bin/agent-serve.js +7 -0
  3. package/dist/channels/runs/index.d.ts +4 -0
  4. package/dist/channels/runs/index.d.ts.map +1 -0
  5. package/dist/channels/runs/index.js +2 -0
  6. package/dist/channels/runs/runs-channel.d.ts +5 -0
  7. package/dist/channels/runs/runs-channel.d.ts.map +1 -0
  8. package/dist/channels/runs/runs-channel.js +34 -0
  9. package/dist/channels/runs/types.d.ts +34 -0
  10. package/dist/channels/runs/types.d.ts.map +1 -0
  11. package/dist/channels/runs/types.js +1 -0
  12. package/dist/channels/slack/agentic-delivery.js +4 -4
  13. package/dist/channels/slack/api.d.ts.map +1 -1
  14. package/dist/channels/slack/api.js +7 -4
  15. package/dist/channels/slack/channel-watch.d.ts +2 -0
  16. package/dist/channels/slack/channel-watch.d.ts.map +1 -1
  17. package/dist/channels/slack/channel-watch.js +7 -3
  18. package/dist/channels/slack/dispatch.d.ts +3 -0
  19. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  20. package/dist/channels/slack/dispatch.js +6 -2
  21. package/dist/channels/slack/thread-context.d.ts.map +1 -1
  22. package/dist/channels/slack/thread-context.js +58 -26
  23. package/dist/channels/slack/types.d.ts +19 -0
  24. package/dist/channels/slack/types.d.ts.map +1 -1
  25. package/dist/docs/404.html +3 -3
  26. package/dist/docs/assets/{app.BSrZkTHD.js → app.CJ-XZTK5.js} +4 -4
  27. package/dist/docs/assets/{building-with-agents.md.Bi9CQ-bR.js → building-with-agents.md.FZXrY8Nk.js} +1 -1
  28. package/dist/docs/assets/chunks/@localSearchIndexroot.ylB4B_Ud.js +1 -0
  29. package/dist/docs/assets/chunks/{VPLocalSearchBox.BxmgcwIX.js → VPLocalSearchBox.CpbYgURZ.js} +1 -1
  30. package/dist/docs/assets/chunks/{arc.CAid9y9R.js → arc.B081PemO.js} +1 -1
  31. package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.kLxg-1A5.js → architectureDiagram-Q4EWVU46.DPaT_hi-.js} +1 -1
  32. package/dist/docs/assets/chunks/{baseUniq.BWvpjFlO.js → baseUniq.Buu61NLg.js} +1 -1
  33. package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.DyjX8R7M.js → blockDiagram-DXYQGD6D.C6t63owh.js} +1 -1
  34. package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.DBdWlnqr.js → c4Diagram-AHTNJAMY.BtKabdXR.js} +1 -1
  35. package/dist/docs/assets/chunks/channel.BgjgeSqp.js +1 -0
  36. package/dist/docs/assets/chunks/{chunk-4BX2VUAB.T5enPS2D.js → chunk-4BX2VUAB.DQpNaR8N.js} +1 -1
  37. package/dist/docs/assets/chunks/{chunk-4TB4RGXK.D6zswRAS.js → chunk-4TB4RGXK.DrhL-6Rv.js} +1 -1
  38. package/dist/docs/assets/chunks/{chunk-55IACEB6.Bh05N-a3.js → chunk-55IACEB6.DRLIBfNR.js} +1 -1
  39. package/dist/docs/assets/chunks/{chunk-EDXVE4YY.DZv_O-d9.js → chunk-EDXVE4YY.kuUuFkIg.js} +1 -1
  40. package/dist/docs/assets/chunks/{chunk-FMBD7UC4.BY53CZaL.js → chunk-FMBD7UC4.BlrVxprw.js} +1 -1
  41. package/dist/docs/assets/chunks/{chunk-OYMX7WX6.CO5lI2PE.js → chunk-OYMX7WX6.CZCfYeQA.js} +1 -1
  42. package/dist/docs/assets/chunks/{chunk-QZHKN3VN.DMfpW0s4.js → chunk-QZHKN3VN.C7rwVEMV.js} +1 -1
  43. package/dist/docs/assets/chunks/{chunk-YZCP3GAM.COPT56Nr.js → chunk-YZCP3GAM.CGseJtT_.js} +1 -1
  44. package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.CIVv63wE.js +1 -0
  45. package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.CIVv63wE.js +1 -0
  46. package/dist/docs/assets/chunks/clone.HcW7h-70.js +1 -0
  47. package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.BJSj7zzd.js → cose-bilkent-S5V4N54A.BWlczAK4.js} +1 -1
  48. package/dist/docs/assets/chunks/{dagre-KV5264BT.DDv7IQZT.js → dagre-KV5264BT.Cw0tT0bB.js} +1 -1
  49. package/dist/docs/assets/chunks/{diagram-5BDNPKRD.BUoE9HFH.js → diagram-5BDNPKRD.Cm96ah9V.js} +1 -1
  50. package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.BF3JtrnJ.js → diagram-G4DWMVQ6.Cl0AoWYM.js} +1 -1
  51. package/dist/docs/assets/chunks/{diagram-MMDJMWI5.BvuCWc4e.js → diagram-MMDJMWI5.Bp7mlzKs.js} +1 -1
  52. package/dist/docs/assets/chunks/{diagram-TYMM5635._EqUGqFN.js → diagram-TYMM5635.ClVeqpcW.js} +1 -1
  53. package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.DxNvSdzj.js → erDiagram-SMLLAGMA.Bi8dojF9.js} +1 -1
  54. package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.DVtRP546.js → flowDiagram-DWJPFMVM.Bb4urpfG.js} +1 -1
  55. package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.Bn9vb7xI.js → ganttDiagram-T4ZO3ILL.whR4wFze.js} +1 -1
  56. package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.45r6n737.js → gitGraphDiagram-UUTBAWPF.6oVMi6-3.js} +1 -1
  57. package/dist/docs/assets/chunks/{graph.BOkX3Ws_.js → graph.D8AJDOFK.js} +1 -1
  58. package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.DyBCcxOm.js → infoDiagram-42DDH7IO.nTpsf5Vk.js} +1 -1
  59. package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.kg0ywDlx.js → ishikawaDiagram-UXIWVN3A.DhYDOwyB.js} +1 -1
  60. package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.BUfrLnXA.js → journeyDiagram-VCZTEJTY.Bg7Rudw3.js} +1 -1
  61. package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.Bn7X35b2.js → kanban-definition-6JOO6SKY.D80D_ZAR.js} +1 -1
  62. package/dist/docs/assets/chunks/{layout.B0QW6d8M.js → layout.e9hmuC-K.js} +1 -1
  63. package/dist/docs/assets/chunks/{linear.C59eCF0D.js → linear.D6hEyqVB.js} +1 -1
  64. package/dist/docs/assets/chunks/{min.BnDl0p08.js → min.BPAdvB9D.js} +1 -1
  65. package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.u2HYLooo.js → mindmap-definition-QFDTVHPH.tm2Sov2Q.js} +1 -1
  66. package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.CbnIrr9l.js → pieDiagram-DEJITSTG.BKHZ497m.js} +1 -1
  67. package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.D2zWIixq.js → quadrantDiagram-34T5L4WZ.CPj7gSp6.js} +1 -1
  68. package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.DvOFa3oO.js → requirementDiagram-MS252O5E._U68yVUd.js} +1 -1
  69. package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.BfKCkH3x.js → sankeyDiagram-XADWPNL6._6jrIQPb.js} +1 -1
  70. package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.CUPKdYN0.js → sequenceDiagram-FGHM5R23.D9UlmB6F.js} +1 -1
  71. package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.CimDCRiK.js → stateDiagram-FHFEXIEX.BQSaiJCe.js} +1 -1
  72. package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.B5d7jT7E.js +1 -0
  73. package/dist/docs/assets/chunks/{theme.CKht7z82.js → theme.25ZC61Iy.js} +2 -2
  74. package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.BFTd5qKs.js → timeline-definition-GMOUNBTQ.d-17NZ3L.js} +1 -1
  75. package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.N6t5MmCb.js → vennDiagram-DHZGUBPP.DE9AGEjG.js} +1 -1
  76. package/dist/docs/assets/chunks/{wardley-RL74JXVD.D2G6Zyds.js → wardley-RL74JXVD.BcY0KddE.js} +1 -1
  77. package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.BqScALbL.js → wardleyDiagram-NUSXRM2D.D9SDNipV.js} +1 -1
  78. package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.Br0WiDkT.js → xychartDiagram-5P7HB3ND.DM1sIMf8.js} +1 -1
  79. package/dist/docs/assets/{deployment.md.hKKN9I4c.js → deployment.md.ajc3VM0m.js} +1 -1
  80. package/dist/docs/assets/{guides_migrate.md.sCAvvlC6.js → guides_migrate.md.DZBL7dqT.js} +1 -1
  81. package/dist/docs/assets/index.md.CHAFTf6m.js +27 -0
  82. package/dist/docs/assets/index.md.CHAFTf6m.lean.js +1 -0
  83. package/dist/docs/assets/{quickstart.md.CduLGBAB.js → quickstart.md.D8JDfkKO.js} +1 -1
  84. package/dist/docs/assets/{reference_cli.md.2d2Y0O-d.js → reference_cli.md.Bt3sAfat.js} +1 -1
  85. package/dist/docs/assets/{reference_http-api.md.CrqhTv6S.js → reference_http-api.md.Dji-DD_Z.js} +1 -1
  86. package/dist/docs/assets/{reference_project-layout.md.C2JMRh7p.js → reference_project-layout.md.SNzIvnmC.js} +1 -1
  87. package/dist/docs/assets/{reference_skills.md.C2GWh7g8.js → reference_skills.md.Ckddg6KX.js} +3 -3
  88. package/dist/docs/building-with-agents.html +37 -37
  89. package/dist/docs/building-with-agents.md +4 -4
  90. package/dist/docs/deployment.html +37 -37
  91. package/dist/docs/deployment.md +3 -4
  92. package/dist/docs/evals.html +36 -36
  93. package/dist/docs/guides/agent-to-agent.html +36 -36
  94. package/dist/docs/guides/bitbucket.html +36 -36
  95. package/dist/docs/guides/cloud-agents.html +36 -36
  96. package/dist/docs/guides/convert-automation.html +36 -36
  97. package/dist/docs/guides/github.html +36 -36
  98. package/dist/docs/guides/gitlab.html +36 -36
  99. package/dist/docs/guides/grokbot-agents.html +36 -36
  100. package/dist/docs/guides/hooks.html +36 -36
  101. package/dist/docs/guides/improve.html +36 -36
  102. package/dist/docs/guides/jev.html +36 -36
  103. package/dist/docs/guides/mcp-oauth.html +36 -36
  104. package/dist/docs/guides/migrate.html +37 -37
  105. package/dist/docs/guides/migrate.md +3 -3
  106. package/dist/docs/guides/opentelemetry.html +36 -36
  107. package/dist/docs/guides/slack.html +36 -36
  108. package/dist/docs/guides/webhooks.html +36 -36
  109. package/dist/docs/hashmap.json +1 -1
  110. package/dist/docs/hillclimbing.html +36 -36
  111. package/dist/docs/index.html +38 -38
  112. package/dist/docs/index.md +2 -2
  113. package/dist/docs/llms-full.txt +23 -25
  114. package/dist/docs/llms.txt +2 -2
  115. package/dist/docs/quickstart.html +37 -37
  116. package/dist/docs/quickstart.md +3 -3
  117. package/dist/docs/reference/agent-config.html +36 -36
  118. package/dist/docs/reference/artifacts.html +36 -36
  119. package/dist/docs/reference/channels.html +36 -36
  120. package/dist/docs/reference/cli.html +37 -37
  121. package/dist/docs/reference/cli.md +1 -1
  122. package/dist/docs/reference/connections.html +36 -36
  123. package/dist/docs/reference/evals.html +36 -36
  124. package/dist/docs/reference/extensions.html +36 -36
  125. package/dist/docs/reference/hooks.html +36 -36
  126. package/dist/docs/reference/http-api.html +37 -37
  127. package/dist/docs/reference/http-api.md +4 -4
  128. package/dist/docs/reference/instructions.html +36 -36
  129. package/dist/docs/reference/playground.html +36 -36
  130. package/dist/docs/reference/project-layout.html +37 -37
  131. package/dist/docs/reference/project-layout.md +2 -3
  132. package/dist/docs/reference/prompt.html +36 -36
  133. package/dist/docs/reference/schedules.html +36 -36
  134. package/dist/docs/reference/sessions.html +36 -36
  135. package/dist/docs/reference/skills.html +39 -39
  136. package/dist/docs/reference/subagents.html +36 -36
  137. package/dist/docs/reference/tools.html +36 -36
  138. package/dist/docs/templates/agentic-owners.html +36 -36
  139. package/dist/docs/templates/grokbot-agents.html +36 -36
  140. package/dist/docs/templates/security-reviewer.html +36 -36
  141. package/dist/docs/templates/thermo-quality-review.html +36 -36
  142. package/dist/docs/templates/thermo-review.html +36 -36
  143. package/dist/docs/templates/triage.html +36 -36
  144. package/dist/docs/troubleshooting.html +36 -36
  145. package/dist/internal/cli-deploy.d.ts.map +1 -1
  146. package/dist/internal/cli-deploy.js +0 -14
  147. package/dist/internal/cloud-turn-cost.js +2 -2
  148. package/dist/internal/continuation-channel.d.ts.map +1 -1
  149. package/dist/internal/continuation-channel.js +6 -0
  150. package/dist/internal/continuation-identity.d.ts +6 -3
  151. package/dist/internal/continuation-identity.d.ts.map +1 -1
  152. package/dist/internal/continuation-identity.js +43 -0
  153. package/dist/internal/deploy-manifest.d.ts +6 -0
  154. package/dist/internal/deploy-manifest.d.ts.map +1 -1
  155. package/dist/internal/deploy-manifest.js +3 -0
  156. package/dist/internal/http-channel.d.ts.map +1 -1
  157. package/dist/internal/http-channel.js +20 -1
  158. package/dist/internal/http-control-plane-session.d.ts +5 -2
  159. package/dist/internal/http-control-plane-session.d.ts.map +1 -1
  160. package/dist/internal/http-control-plane-session.js +38 -2
  161. package/dist/internal/init-scaffold.js +1 -1
  162. package/dist/internal/model-config.d.ts +7 -0
  163. package/dist/internal/model-config.d.ts.map +1 -0
  164. package/dist/internal/model-config.js +67 -0
  165. package/dist/internal/peer-connections.d.ts +18 -3
  166. package/dist/internal/peer-connections.d.ts.map +1 -1
  167. package/dist/internal/peer-connections.js +46 -6
  168. package/dist/internal/request-error-status.d.ts.map +1 -1
  169. package/dist/internal/request-error-status.js +4 -1
  170. package/dist/internal/resolved-connections.d.ts +4 -1
  171. package/dist/internal/resolved-connections.d.ts.map +1 -1
  172. package/dist/internal/resolved-connections.js +9 -4
  173. package/dist/internal/sdk-runner.d.ts.map +1 -1
  174. package/dist/internal/sdk-runner.js +11 -1
  175. package/dist/internal/server.d.ts.map +1 -1
  176. package/dist/internal/server.js +2 -1
  177. package/dist/internal/session-engine.d.ts +3 -1
  178. package/dist/internal/session-engine.d.ts.map +1 -1
  179. package/dist/internal/session-engine.js +74 -19
  180. package/dist/internal/storage-coordinator.d.ts +9 -9
  181. package/dist/internal/storage-coordinator.d.ts.map +1 -1
  182. package/dist/internal/storage-coordinator.js +116 -36
  183. package/dist/internal/testing/factory-resource-fixtures.d.ts +16 -0
  184. package/dist/internal/testing/factory-resource-fixtures.d.ts.map +1 -1
  185. package/dist/internal/testing/factory-resource-fixtures.js +14 -0
  186. package/dist/internal/turn-cost.d.ts +1 -1
  187. package/dist/internal/turn-cost.d.ts.map +1 -1
  188. package/dist/internal/turn-cost.js +8 -8
  189. package/dist/playground/assets/cursor-icons-16-DBmD_cqy.woff2 +0 -0
  190. package/dist/playground/assets/index-BDPd0Sec.css +1 -0
  191. package/dist/playground/assets/{index-U3TRnwAP.js → index-BrXDwbrN.js} +1 -1
  192. package/dist/playground/index.html +2 -2
  193. package/dist/types.d.ts +44 -0
  194. package/dist/types.d.ts.map +1 -1
  195. package/docs/README.md +4 -4
  196. package/docs/building-with-agents.md +4 -4
  197. package/docs/deployment.md +3 -4
  198. package/docs/guides/migrate.md +3 -3
  199. package/docs/quickstart.md +3 -3
  200. package/docs/reference/cli.md +1 -1
  201. package/docs/reference/http-api.md +4 -4
  202. package/docs/reference/project-layout.md +2 -3
  203. package/package.json +10 -3
  204. package/dist/docs/assets/chunks/@localSearchIndexroot.JUnN1Be1.js +0 -1
  205. package/dist/docs/assets/chunks/channel.CWc3NN9g.js +0 -1
  206. package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.D5a745iS.js +0 -1
  207. package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.D5a745iS.js +0 -1
  208. package/dist/docs/assets/chunks/clone.CCGVqN_B.js +0 -1
  209. package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.ClNUVSTQ.js +0 -1
  210. package/dist/docs/assets/index.md.BIBHIQtU.js +0 -27
  211. package/dist/docs/assets/index.md.BIBHIQtU.lean.js +0 -1
  212. package/dist/playground/assets/cursor-icons-16-4RnoYH3n.woff2 +0 -0
  213. package/dist/playground/assets/index-7fVUOA5l.css +0 -1
  214. /package/dist/docs/assets/{building-with-agents.md.Bi9CQ-bR.lean.js → building-with-agents.md.FZXrY8Nk.lean.js} +0 -0
  215. /package/dist/docs/assets/{deployment.md.hKKN9I4c.lean.js → deployment.md.ajc3VM0m.lean.js} +0 -0
  216. /package/dist/docs/assets/{guides_migrate.md.sCAvvlC6.lean.js → guides_migrate.md.DZBL7dqT.lean.js} +0 -0
  217. /package/dist/docs/assets/{quickstart.md.CduLGBAB.lean.js → quickstart.md.D8JDfkKO.lean.js} +0 -0
  218. /package/dist/docs/assets/{reference_cli.md.2d2Y0O-d.lean.js → reference_cli.md.Bt3sAfat.lean.js} +0 -0
  219. /package/dist/docs/assets/{reference_http-api.md.CrqhTv6S.lean.js → reference_http-api.md.Dji-DD_Z.lean.js} +0 -0
  220. /package/dist/docs/assets/{reference_project-layout.md.C2JMRh7p.lean.js → reference_project-layout.md.SNzIvnmC.lean.js} +0 -0
  221. /package/dist/docs/assets/{reference_skills.md.C2GWh7g8.lean.js → reference_skills.md.Ckddg6KX.lean.js} +0 -0
@@ -71,6 +71,17 @@ export const MAX_VOLATILE_RECORD_SKIPS = 20;
71
71
  function resumeProjectionJson(record) {
72
72
  return JSON.stringify({ ...record, turnCount: 0, updatedAt: "" });
73
73
  }
74
+ /**
75
+ * Stamp written with a continuation pointer. Newer than the durable
76
+ * record's `updatedAt` means the record write lagged the pointer.
77
+ */
78
+ function continuationPointerUpdatedAt(pointer) {
79
+ if (typeof pointer !== "object" || pointer === null || Array.isArray(pointer)) {
80
+ return undefined;
81
+ }
82
+ const stamp = pointer.recordUpdatedAt;
83
+ return typeof stamp === "string" && stamp.length > 0 ? stamp : undefined;
84
+ }
74
85
  /** Session records out of raw sink entries; rows without a usable id are dropped. */
75
86
  function sessionRecordsOf(entries) {
76
87
  return entries
@@ -82,8 +93,9 @@ export class StorageCoordinator {
82
93
  /** Per-session pending state (events + coalesced record). */
83
94
  this.buffers = new Map();
84
95
  /**
85
- * Last continuation key written to the sink per session, so a token
86
- * change emits a delete for the stale index entry alongside the new put.
96
+ * Last continuation key this process has seen for a session. A hit
97
+ * avoids a durable read; a miss reads the stored session record so a
98
+ * fresh process still deletes the previous pointer.
87
99
  */
88
100
  this.continuationIndex = new Map();
89
101
  /**
@@ -231,11 +243,15 @@ export class StorageCoordinator {
231
243
  recordAck = { sessionId, json: recordJson, projection };
232
244
  }
233
245
  }
246
+ const continuation = record === undefined ? undefined : this.planContinuation(record);
247
+ if (continuation !== undefined) {
248
+ ops.push(...continuation.leading);
249
+ }
234
250
  if (puts.length > 0) {
235
251
  ops.push(this.putsOp(puts, recordAck));
236
252
  }
237
- if (record !== undefined) {
238
- ops.push(...this.continuationOps(record));
253
+ if (continuation !== undefined) {
254
+ ops.push(...continuation.trailing);
239
255
  }
240
256
  if (ops.length > 0) {
241
257
  this.enqueue(ops, reason);
@@ -309,39 +325,76 @@ export class StorageCoordinator {
309
325
  };
310
326
  }
311
327
  /**
312
- * Index maintenance for `continuation/{channelId}/{token}` → sessionId:
313
- * put the current token, delete the previous one when it changed.
328
+ * Index maintenance for `continuation/{channelId}/{token}` → sessionId.
329
+ * Put the current token and delete the previous one. The in-process
330
+ * index is a fast path; a fresh process reads the durable session
331
+ * record (before this flush overwrites it) and deletes that key too.
332
+ * Leading ops must run before the session-record put.
314
333
  */
315
- continuationOps(record) {
316
- const previous = this.continuationIndex.get(record.sessionId);
334
+ planContinuation(record) {
317
335
  const next = record.continuationKey;
318
- if (previous === next) {
319
- return [];
336
+ const indexKnows = this.continuationIndex.has(record.sessionId);
337
+ const known = indexKnows ? this.continuationIndex.get(record.sessionId) : undefined;
338
+ if (indexKnows && known === next) {
339
+ return undefined;
320
340
  }
321
- this.continuationIndex.set(record.sessionId, next);
322
- const ops = [];
323
- if (previous != null) {
324
- ops.push(this.deleteOp(this.keys.continuation(this.agentName, record.channelId, previous)));
341
+ const staleKeys = [];
342
+ if (indexKnows && typeof known === "string" && known !== next) {
343
+ staleKeys.push(this.keys.continuation(this.agentName, record.channelId, known));
325
344
  }
326
- if (next != null) {
327
- ops.push(this.putOp(this.keys.continuation(this.agentName, record.channelId, next), {
328
- sessionId: record.sessionId,
329
- }));
345
+ this.continuationIndex.set(record.sessionId, next);
346
+ const leading = [];
347
+ const get = this.definition.get;
348
+ if (!indexKnows && get !== undefined) {
349
+ leading.push({
350
+ label: `continuation-previous(${record.sessionId})`,
351
+ run: async (ctx) => {
352
+ const stored = (await get(this.keys.session(this.agentName, record.sessionId), ctx));
353
+ const previous = stored?.continuationKey;
354
+ if (typeof previous !== "string" || previous.length === 0 || previous === next) {
355
+ return;
356
+ }
357
+ const channelId = stored != null && typeof stored.channelId === "string" && stored.channelId.length > 0
358
+ ? stored.channelId
359
+ : record.channelId;
360
+ staleKeys.push(this.keys.continuation(this.agentName, channelId, previous));
361
+ },
362
+ });
330
363
  }
331
- return ops;
332
- }
333
- /** KV upsert op on the sink's `put`. */
334
- putOp(key, value) {
335
- return {
336
- label: `put(${key})`,
337
- run: (ctx) => this.definition.put(key, value, ctx),
338
- };
339
- }
340
- /** KV delete op on the sink's `delete` (skipped when the hook is absent). */
341
- deleteOp(key) {
342
364
  return {
343
- label: `delete(${key})`,
344
- run: (ctx) => this.definition.delete?.(key, ctx),
365
+ leading,
366
+ trailing: [
367
+ {
368
+ label: `continuation(${record.sessionId})`,
369
+ run: async (ctx) => {
370
+ // A delete failure must not skip the new pointer. These used to
371
+ // be separate queue ops, so a thrown delete still reached the put.
372
+ for (const key of staleKeys) {
373
+ try {
374
+ await this.definition.delete?.(key, ctx);
375
+ }
376
+ catch (error) {
377
+ this.logger(`[bdk] storage delete(${key}) failed: ${describeError(error)}`);
378
+ }
379
+ }
380
+ if (next == null) {
381
+ return;
382
+ }
383
+ try {
384
+ await this.definition.put(this.keys.continuation(this.agentName, record.channelId, next), {
385
+ sessionId: record.sessionId,
386
+ recordUpdatedAt: record.updatedAt,
387
+ }, ctx);
388
+ }
389
+ catch (error) {
390
+ // Plan time already advanced the in-process index. Drop it so
391
+ // a later flush retries this pointer instead of treating it as current.
392
+ this.continuationIndex.delete(record.sessionId);
393
+ throw error;
394
+ }
395
+ },
396
+ },
397
+ ],
345
398
  };
346
399
  }
347
400
  // ==========================================================================
@@ -472,11 +525,38 @@ export class StorageCoordinator {
472
525
  this.logger(`[bdk] storage continuation entry points at missing session ${sessionId}; treating as a miss`);
473
526
  return undefined;
474
527
  }
475
- // The sink must answer for the exact key it was asked about — a
476
- // mismatched row is a broken store, not a miss; treating it as a miss
477
- // would fork the continuation token onto a new session.
478
- if (record.channelId !== channelId || record.continuationKey !== continuationKey) {
479
- throw new Error(`storage returned a session that does not match the requested continuation (channel ${channelId})`);
528
+ // A different channel is a broken store. Same channel with a different
529
+ // key is a leftover pointer when the durable record is newer, and the
530
+ // live token when that record write lagged the pointer.
531
+ if (record.channelId !== channelId) {
532
+ throw new Error(`storage returned a session that does not match the requested continuation (channel ${channelId}, requestedContinuationKey=${continuationKey}, recordChannelId=${record.channelId}, recordContinuationKey=${String(record.continuationKey)})`);
533
+ }
534
+ if (record.continuationKey !== continuationKey) {
535
+ const pointerUpdatedAt = continuationPointerUpdatedAt(pointer);
536
+ const recordUpdatedAt = typeof record.updatedAt === "string" ? record.updatedAt : undefined;
537
+ // The pointer was written for a newer record than the one that landed.
538
+ // Deleting it would drop the live token; the record is the one that lagged.
539
+ if (pointerUpdatedAt !== undefined &&
540
+ recordUpdatedAt !== undefined &&
541
+ pointerUpdatedAt > recordUpdatedAt) {
542
+ this.logger(`[bdk] storage continuation record lags the pointer for channel ${channelId}; keeping the pointer`);
543
+ // The caller persists this record. Leaving the old token on it makes
544
+ // the next flush advance `updatedAt` past the pointer stamp, and the
545
+ // following lookup of the live key then deletes that pointer.
546
+ return {
547
+ ...record,
548
+ continuationKey,
549
+ updatedAt: pointerUpdatedAt,
550
+ };
551
+ }
552
+ this.logger(`[bdk] storage continuation pointer is stale for channel ${channelId}; treating as a miss`);
553
+ try {
554
+ await this.definition.delete?.(this.keys.continuation(this.agentName, channelId, continuationKey), ctx);
555
+ }
556
+ catch (error) {
557
+ this.logger(`[bdk] storage delete of stale continuation pointer failed: ${describeError(error)}`);
558
+ }
559
+ return undefined;
480
560
  }
481
561
  return record;
482
562
  }
@@ -5,6 +5,7 @@
5
5
  */
6
6
  export declare const FACTORY_CHECKPOINT_NAME: string;
7
7
  export declare const FACTORY_ISSUE_NAME: string;
8
+ export declare const FACTORY_RUN_NAME: string;
8
9
  export interface FactoryCheckpointResourceFixture {
9
10
  name: string;
10
11
  deployment: string;
@@ -27,6 +28,13 @@ export interface FactoryIssueResourceFixture {
27
28
  path: string;
28
29
  etag: string;
29
30
  }
31
+ export interface FactoryRunResourceFixture {
32
+ name: string;
33
+ environment: string;
34
+ services: string[];
35
+ deployVersion: string;
36
+ createTime: string;
37
+ }
30
38
  export interface CheckpointCreatedPayloadFixture {
31
39
  eventId: string;
32
40
  eventType: "checkpoint.created";
@@ -41,8 +49,16 @@ export interface IssueCreatedPayloadFixture {
41
49
  occurredAtMs: number;
42
50
  issue: FactoryIssueResourceFixture;
43
51
  }
52
+ export interface RunCreatedPayloadFixture {
53
+ eventId: string;
54
+ eventType: "run.created";
55
+ teamId: string;
56
+ occurredAtMs: number;
57
+ run: FactoryRunResourceFixture;
58
+ }
44
59
  export declare const FACTORY_CHECKPOINT_RESOURCE: FactoryCheckpointResourceFixture;
45
60
  export declare const FACTORY_ISSUE_RESOURCE: FactoryIssueResourceFixture;
46
61
  export declare const CHECKPOINT_CREATED_PAYLOAD: CheckpointCreatedPayloadFixture;
47
62
  export declare const ISSUE_CREATED_PAYLOAD: IssueCreatedPayloadFixture;
63
+ export declare const RUN_CREATED_PAYLOAD: RunCreatedPayloadFixture;
48
64
  //# sourceMappingURL=factory-resource-fixtures.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"factory-resource-fixtures.d.ts","sourceRoot":"","sources":["../../../src/internal/testing/factory-resource-fixtures.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,uBAAuB,EAAE,MAA+C,CAAC;AACtF,eAAO,MAAM,kBAAkB,EAAE,MAAuB,CAAC;AAEzD,MAAM,WAAW,gCAAgC;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,2BAA2B;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,YAAY,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,+BAA+B;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,oBAAoB,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,gCAAgC,CAAC;CAC9C;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,eAAe,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,2BAA2B,CAAC;CACpC;AAED,eAAO,MAAM,2BAA2B,EAAE,gCASzC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,2BASpC,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,+BAMxC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,0BAMnC,CAAC"}
1
+ {"version":3,"file":"factory-resource-fixtures.d.ts","sourceRoot":"","sources":["../../../src/internal/testing/factory-resource-fixtures.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,uBAAuB,EAAE,MAA+C,CAAC;AACtF,eAAO,MAAM,kBAAkB,EAAE,MAAuB,CAAC;AACzD,eAAO,MAAM,gBAAgB,EAAE,MAAyC,CAAC;AAEzE,MAAM,WAAW,gCAAgC;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,2BAA2B;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,YAAY,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,+BAA+B;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,oBAAoB,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,gCAAgC,CAAC;CAC9C;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,eAAe,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,2BAA2B,CAAC;CACpC;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,aAAa,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,yBAAyB,CAAC;CAChC;AAED,eAAO,MAAM,2BAA2B,EAAE,gCASzC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,2BASpC,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,+BAMxC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,0BAMnC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,wBAYjC,CAAC"}
@@ -5,6 +5,7 @@
5
5
  */
6
6
  export const FACTORY_CHECKPOINT_NAME = "changeMonitors/cm-1/checkpoints/cp-1";
7
7
  export const FACTORY_ISSUE_NAME = "issues/iss-1";
8
+ export const FACTORY_RUN_NAME = "changeMonitors/cm-1/runs/run-1";
8
9
  export const FACTORY_CHECKPOINT_RESOURCE = {
9
10
  name: FACTORY_CHECKPOINT_NAME,
10
11
  deployment: "deployments/11111111-1111-4111-8111-111111111111",
@@ -39,3 +40,16 @@ export const ISSUE_CREATED_PAYLOAD = {
39
40
  occurredAtMs: 1,
40
41
  issue: FACTORY_ISSUE_RESOURCE,
41
42
  };
43
+ export const RUN_CREATED_PAYLOAD = {
44
+ eventId: "evt-mr-1",
45
+ eventType: "run.created",
46
+ teamId: "team-1",
47
+ occurredAtMs: 1,
48
+ run: {
49
+ name: FACTORY_RUN_NAME,
50
+ environment: "environments/production",
51
+ services: ["services/portal-website"],
52
+ deployVersion: "3e165785dd2cfecb24b032176d758933a343726e",
53
+ createTime: "2026-09-08T21:00:00Z",
54
+ },
55
+ };
@@ -33,7 +33,7 @@ export declare function isOpenAiCompatGrossCacheModel(model: ModelSetting): bool
33
33
  export declare function toCatalogDisjointUsage(usage: TurnUsage, model?: ModelSetting): TurnUsage;
34
34
  export declare function roundCostUsd(usd: number): number;
35
35
  export declare function turnCostFromCents(args: {
36
- model: string | ModelSetting;
36
+ model: ModelSetting;
37
37
  cost: UsageCostCents;
38
38
  source: TurnCost["source"];
39
39
  }): TurnCost;
@@ -1 +1 @@
1
- {"version":3,"file":"turn-cost.d.ts","sourceRoot":"","sources":["../../src/internal/turn-cost.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGrE,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,qBAAqB,KAAK,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;AAEjG,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAE1D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAK1E;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,YAAY,GAAG,SAAS,CAYxF;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC;IAC7B,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;CAC5B,GAAG,QAAQ,CAcX;AAeD,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAkB/B"}
1
+ {"version":3,"file":"turn-cost.d.ts","sourceRoot":"","sources":["../../src/internal/turn-cost.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGrE,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,qBAAqB,KAAK,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;AAEjG,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAE1D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAK1E;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,YAAY,GAAG,SAAS,CAYxF;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;CAC5B,GAAG,QAAQ,CAeX;AAeD,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAgB/B"}
@@ -41,14 +41,15 @@ export function roundCostUsd(usd) {
41
41
  }
42
42
  export function turnCostFromCents(args) {
43
43
  const totalUsd = roundCostUsd(args.cost.chargedCents / 100);
44
- const model = typeof args.model === "string" ? args.model : modelSettingId(args.model);
44
+ const modelParams = typeof args.model === "string" ? undefined : args.model.params;
45
45
  return {
46
46
  totalUsd,
47
47
  inputUsd: 0,
48
48
  outputUsd: 0,
49
49
  cacheReadUsd: 0,
50
50
  cacheWriteUsd: 0,
51
- model,
51
+ model: modelSettingId(args.model),
52
+ modelParams,
52
53
  source: args.source,
53
54
  rawCostCents: args.cost.rawCostCents,
54
55
  chargedCents: args.cost.chargedCents,
@@ -69,11 +70,10 @@ export async function estimateTurnCostFromApi(input) {
69
70
  if (priced !== undefined) {
70
71
  return priced;
71
72
  }
72
- // A run-scoped lookup can miss while billing catches up. Catalog-price
73
- // this turn; a retry without the run id is the agent's cumulative total.
74
- const askedForBilledRun = input.runId !== undefined &&
75
- (input.agentId !== undefined || input.conversationId !== undefined);
76
- if (!askedForBilledRun || input.usage === undefined) {
73
+ // The first lookup can time out or miss. Catalog-price this turn from
74
+ // the local usage whether or not a run id was sent. The retry omits the
75
+ // run id so it does not ask for billed events again.
76
+ if (input.usage === undefined) {
77
77
  return undefined;
78
78
  }
79
79
  return requestEstimate(resolved.apiKey, { model: input.model, usage: input.usage });
@@ -119,7 +119,7 @@ async function requestEstimate(apiKey, input) {
119
119
  return undefined;
120
120
  }
121
121
  return turnCostFromCents({
122
- model: body.model ?? model,
122
+ model: input.model,
123
123
  cost: body.cost,
124
124
  source: body.source === "usage" ? "usage" : "catalog",
125
125
  });