agents 0.27.0 → 0.28.1

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 (216) hide show
  1. package/dist/abortable-C1SpfVoi.js +21 -0
  2. package/dist/abortable-C1SpfVoi.js.map +1 -0
  3. package/dist/{agent-routing-Bhdbvf7s.d.ts → agent-routing-BMvWTFEp.d.ts} +21 -15
  4. package/dist/agent-routing.d.ts +1 -1
  5. package/dist/agent-tool-types.d.ts +1 -1
  6. package/dist/{agent-tools-bJZwBMfq.d.ts → agent-tools-ohoewW-B.d.ts} +2 -2
  7. package/dist/agent-tools.d.ts +1 -1
  8. package/dist/ai-ahruGw7e.d.ts +239 -0
  9. package/dist/{ai-sdk-OoGkFy3s.js → ai-sdk-C2iTAwUd.js} +44 -18
  10. package/dist/ai-sdk-C2iTAwUd.js.map +1 -0
  11. package/dist/browser/ai.d.ts +8 -227
  12. package/dist/browser/ai.js +259 -1
  13. package/dist/browser/ai.js.map +1 -0
  14. package/dist/browser/index.d.ts +56 -46
  15. package/dist/browser/index.js +4 -361
  16. package/dist/browser/{ai-sdk.d.ts → tools/ai-sdk.d.ts} +7 -7
  17. package/dist/browser/{ai-sdk.js → tools/ai-sdk.js} +5 -4
  18. package/dist/browser/tools/ai-sdk.js.map +1 -0
  19. package/dist/browser/tools/pi.d.ts +111 -0
  20. package/dist/browser/tools/pi.js +119 -0
  21. package/dist/browser/tools/pi.js.map +1 -0
  22. package/dist/browser/{tanstack-ai.d.ts → tools/tanstack-ai.d.ts} +39 -37
  23. package/dist/browser/{tanstack-ai.js → tools/tanstack-ai.js} +73 -59
  24. package/dist/browser/tools/tanstack-ai.js.map +1 -0
  25. package/dist/browser-CEdNlsaD.js +481 -0
  26. package/dist/browser-CEdNlsaD.js.map +1 -0
  27. package/dist/{browser-tmkcAAI3.d.ts → browser-D30VlpcA.d.ts} +63 -37
  28. package/dist/{browser-tool-CBqs6hqa.js → browser-tool-4iomavs_.js} +145 -49
  29. package/dist/browser-tool-4iomavs_.js.map +1 -0
  30. package/dist/{browser-tool-Bn-nzJQI.d.ts → browser-tool-vtrPOV8e.d.ts} +24 -5
  31. package/dist/{capability-B4WbF81e.js → capability-DBAKc6UZ.js} +1 -3
  32. package/dist/capability-DBAKc6UZ.js.map +1 -0
  33. package/dist/{capability-runner-O5VbQzqg.d.ts → capability-runner-BiVUtjqC.d.ts} +1 -7
  34. package/dist/chat/index.d.ts +4 -4
  35. package/dist/chat/index.js +1 -1
  36. package/dist/chat-sdk/index.d.ts +1 -1
  37. package/dist/chat-sdk/index.js +1 -1
  38. package/dist/{client-1tEQ1Oqz.js → client-BnYbNT3z.js} +3 -4
  39. package/dist/client-BnYbNT3z.js.map +1 -0
  40. package/dist/{client-DS3Dz9l0.d.ts → client-Bp-JwL3p.d.ts} +2 -2
  41. package/dist/client.d.ts +1 -1
  42. package/dist/{connector-58XDGvc3.js → connector-CtZylXdk.js} +3 -603
  43. package/dist/connector-CtZylXdk.js.map +1 -0
  44. package/dist/{connector-Cl-VqPmA.d.ts → connector-DEXzVoaY.d.ts} +9 -374
  45. package/dist/{conversations-DH0ut_8n.d.ts → conversations-FjHDRZyD.d.ts} +4 -4
  46. package/dist/{current-agent-C07C5o5Y.d.ts → current-agent-CKgT5d1O.d.ts} +3 -5
  47. package/dist/current-agent-DhoDkSnH.js.map +1 -1
  48. package/dist/{durable-object-lifecycle-DRqp475_.d.ts → durable-object-lifecycle-DOI_bzCH.d.ts} +2 -2
  49. package/dist/experimental/channels/index.d.ts +2 -2
  50. package/dist/experimental/channels/index.js +2 -2
  51. package/dist/experimental/channels/web/index.d.ts +2 -2
  52. package/dist/experimental/channels/web/index.js +1 -1
  53. package/dist/{gateway-BDC07gYO.d.ts → gateway-BFO6vRDn.d.ts} +2 -2
  54. package/dist/{handler-stateless-VvrWSAVA.js → handler-stateless-Bly_nSH3.js} +12 -3
  55. package/dist/handler-stateless-Bly_nSH3.js.map +1 -0
  56. package/dist/harness/ai-sdk/index.d.ts +2 -2
  57. package/dist/harness/ai-sdk/index.js +1 -1
  58. package/dist/harness/container/index.d.ts +2 -2
  59. package/dist/harness/container/index.js +3 -3
  60. package/dist/harness/opencode/index.d.ts +183 -7
  61. package/dist/harness/opencode/index.js +355 -24
  62. package/dist/harness/opencode/index.js.map +1 -1
  63. package/dist/harness/pi/index.d.ts +2 -2
  64. package/dist/harness/pi/index.js +3 -3
  65. package/dist/harness/store/index.d.ts +1 -1
  66. package/dist/harness/store/index.js +1 -1
  67. package/dist/harness/think/index.d.ts +2 -2
  68. package/dist/harness/think/index.js +363 -171
  69. package/dist/harness/think/index.js.map +1 -1
  70. package/dist/{images-Ce9SCu3X.js → images-C4hiIexM.js} +46 -4
  71. package/dist/images-C4hiIexM.js.map +1 -0
  72. package/dist/{index-D0A5tbWu.d.ts → index-BEL3ZV-s.d.ts} +2 -6
  73. package/dist/{index-Ib_4dwOo.d.ts → index-CBt8oRJt.d.ts} +3 -5
  74. package/dist/index.d.ts +4 -4
  75. package/dist/index.js +2 -2
  76. package/dist/input-schema-BQykTEp_.js +20 -0
  77. package/dist/input-schema-BQykTEp_.js.map +1 -0
  78. package/dist/{input-schema-DNrpTu49.js → input-schema-xBofjBKC.js} +3 -3
  79. package/dist/input-schema-xBofjBKC.js.map +1 -0
  80. package/dist/internal_context.d.ts +1 -1
  81. package/dist/lifecycle/index.d.ts +3 -3
  82. package/dist/lifecycle/index.js +2 -2
  83. package/dist/{lifecycle-CFu6OV03.js → lifecycle-DGorpAmA.js} +2 -4
  84. package/dist/lifecycle-DGorpAmA.js.map +1 -0
  85. package/dist/mcp/client/index.d.ts +1 -1
  86. package/dist/mcp/client/index.js +1 -1
  87. package/dist/mcp/index.d.ts +1 -1
  88. package/dist/mcp/index.js +18 -4
  89. package/dist/mcp/index.js.map +1 -1
  90. package/dist/mcp/server/index.js +1 -1
  91. package/dist/models/ai-sdk/index.d.ts +45 -17
  92. package/dist/models/ai-sdk/index.js +1 -1
  93. package/dist/models/opencode/index.d.ts +2 -2
  94. package/dist/models/opencode/index.js +1 -1
  95. package/dist/models/pi-ai/index.d.ts +8 -3
  96. package/dist/models/pi-ai/index.js +6 -6
  97. package/dist/models/pi-ai/index.js.map +1 -1
  98. package/dist/{options-pwTNq9z6.d.ts → options-CiIsJHXR.d.ts} +2 -6
  99. package/dist/queue/index.d.ts +1 -1
  100. package/dist/queue/index.js +1 -1
  101. package/dist/{queue-BB-zfIYF.js → queue-CcIjVYTE.js} +2 -2
  102. package/dist/{queue-BB-zfIYF.js.map → queue-CcIjVYTE.js.map} +1 -1
  103. package/dist/react.d.ts +2 -2
  104. package/dist/routing/index.d.ts +2 -2
  105. package/dist/routing/index.js +1 -1
  106. package/dist/{scheduler-CrFCnv_J.d.ts → scheduler-BCLESHSC.d.ts} +2 -12
  107. package/dist/{scheduler-DZ3xQfeK.js → scheduler-FIHv2-kJ.js} +2 -4
  108. package/dist/scheduler-FIHv2-kJ.js.map +1 -0
  109. package/dist/schedules/index.d.ts +1 -1
  110. package/dist/schedules/index.js +1 -1
  111. package/dist/serializable.d.ts +1 -1
  112. package/dist/session-store-Do4xkDcf.js +606 -0
  113. package/dist/session-store-Do4xkDcf.js.map +1 -0
  114. package/dist/session-store-DoPY12xM.d.ts +383 -0
  115. package/dist/sessions/index.d.ts +1 -1
  116. package/dist/sessions/index.js +1 -1
  117. package/dist/{sessions-B9pNuxdT.js → sessions-_vN5BEZX.js} +2 -2
  118. package/dist/{sessions-B9pNuxdT.js.map → sessions-_vN5BEZX.js.map} +1 -1
  119. package/dist/{settings-C45hDliX.js → settings-BjAiPd6Z.js} +7 -4
  120. package/dist/settings-BjAiPd6Z.js.map +1 -0
  121. package/dist/{settings-NgGwF7Qt.d.ts → settings-DnD__xuE.d.ts} +22 -4
  122. package/dist/{src-DgCbZtIR.js → src-CQxJFv4l.js} +8 -8
  123. package/dist/src-CQxJFv4l.js.map +1 -0
  124. package/dist/state/index.d.ts +1 -1
  125. package/dist/state/index.js +1 -3
  126. package/dist/state/index.js.map +1 -1
  127. package/dist/{store-DLeqKuj3.d.ts → store-BKM4Xm9M.d.ts} +23 -1
  128. package/dist/{store-vgcPYo8K.js → store-CslVzfN7.js} +28 -2
  129. package/dist/store-CslVzfN7.js.map +1 -0
  130. package/dist/streams/index.d.ts +1 -1
  131. package/dist/streams/index.js +1 -1
  132. package/dist/{streams-CITClVer.js → streams-lsHMJhRW.js} +2 -2
  133. package/dist/{streams-CITClVer.js.map → streams-lsHMJhRW.js.map} +1 -1
  134. package/dist/{streams-fbG61qM8.d.ts → streams-vrCtbUIn.d.ts} +2 -2
  135. package/dist/sub-routing.d.ts +1 -1
  136. package/dist/tasks/index.d.ts +1 -1
  137. package/dist/tasks/index.js +1 -1
  138. package/dist/{tasks-CkTZNaV1.js → tasks-BN_5AWqI.js} +2 -2
  139. package/dist/{tasks-CkTZNaV1.js.map → tasks-BN_5AWqI.js.map} +1 -1
  140. package/dist/{tasks-PtlB4Uyn.d.ts → tasks-E89KdwkS.d.ts} +2 -2
  141. package/dist/{tool-BPJEbwaX.d.ts → tool-CTp72Jb_.d.ts} +4 -4
  142. package/dist/tool-CxKsvxjm.js +1126 -0
  143. package/dist/tool-CxKsvxjm.js.map +1 -0
  144. package/dist/tool-DoVberpN.d.ts +301 -0
  145. package/dist/{tool-3PA8xjB_.js → tool-VF0qiO7q.js} +7 -18
  146. package/dist/tool-VF0qiO7q.js.map +1 -0
  147. package/dist/tool-helpers-O5BDVEAY.js +58 -0
  148. package/dist/tool-helpers-O5BDVEAY.js.map +1 -0
  149. package/dist/{transport-k2mFrtL8.d.ts → transport-DCyarnwm.d.ts} +2 -2
  150. package/dist/voice/index.d.ts +2 -2
  151. package/dist/web/fetch/index.d.ts +89 -0
  152. package/dist/web/fetch/index.js +20 -0
  153. package/dist/web/fetch/index.js.map +1 -0
  154. package/dist/web/fetch/tools/ai-sdk.d.ts +80 -0
  155. package/dist/web/fetch/tools/ai-sdk.js +47 -0
  156. package/dist/web/fetch/tools/ai-sdk.js.map +1 -0
  157. package/dist/web/fetch/tools/pi.d.ts +84 -0
  158. package/dist/web/fetch/tools/pi.js +88 -0
  159. package/dist/web/fetch/tools/pi.js.map +1 -0
  160. package/dist/web/fetch/tools/tanstack-ai.d.ts +78 -0
  161. package/dist/web/fetch/tools/tanstack-ai.js +45 -0
  162. package/dist/web/fetch/tools/tanstack-ai.js.map +1 -0
  163. package/dist/{websearch → web/search}/index.d.ts +1 -1
  164. package/dist/{websearch → web/search}/index.js +1 -1
  165. package/dist/{websearch → web/search}/tools/ai-sdk.d.ts +2 -2
  166. package/dist/{websearch → web/search}/tools/ai-sdk.js +3 -3
  167. package/dist/web/search/tools/ai-sdk.js.map +1 -0
  168. package/dist/{websearch → web/search}/tools/pi.d.ts +3 -3
  169. package/dist/{websearch → web/search}/tools/pi.js +2 -2
  170. package/dist/web/search/tools/pi.js.map +1 -0
  171. package/dist/{websearch → web/search}/tools/tanstack-ai.d.ts +2 -2
  172. package/dist/{websearch → web/search}/tools/tanstack-ai.js +3 -3
  173. package/dist/web/search/tools/tanstack-ai.js.map +1 -0
  174. package/dist/websockets/index.d.ts +2 -2
  175. package/dist/websockets/index.js +1 -1
  176. package/dist/{websockets-CmENGb-Z.js → websockets-C3zy8YR0.js} +3 -5
  177. package/dist/websockets-C3zy8YR0.js.map +1 -0
  178. package/dist/workflow-types.d.ts +1 -1
  179. package/dist/workflows.d.ts +1 -1
  180. package/dist/workflows.js +1 -1
  181. package/docs/browse-the-web.md +26 -1
  182. package/docs/fetch-the-web.md +276 -0
  183. package/docs/harnesses/pi.md +25 -0
  184. package/docs/index.md +99 -76
  185. package/docs/lifecycle.md +2 -3
  186. package/docs/mcp-client.md +1 -1
  187. package/docs/mcp-servers.md +1 -1
  188. package/docs/models-pi-ai.md +11 -0
  189. package/docs/models.md +45 -3
  190. package/docs/queue.md +2 -3
  191. package/docs/scheduling.md +2 -6
  192. package/docs/search-the-web.md +2 -0
  193. package/package.json +52 -27
  194. package/dist/ai-fm7xx1BK.js +0 -312
  195. package/dist/ai-fm7xx1BK.js.map +0 -1
  196. package/dist/ai-sdk-OoGkFy3s.js.map +0 -1
  197. package/dist/browser/ai-sdk.js.map +0 -1
  198. package/dist/browser/index.js.map +0 -1
  199. package/dist/browser/tanstack-ai.js.map +0 -1
  200. package/dist/browser-tool-CBqs6hqa.js.map +0 -1
  201. package/dist/capability-B4WbF81e.js.map +0 -1
  202. package/dist/client-1tEQ1Oqz.js.map +0 -1
  203. package/dist/connector-58XDGvc3.js.map +0 -1
  204. package/dist/handler-stateless-VvrWSAVA.js.map +0 -1
  205. package/dist/images-Ce9SCu3X.js.map +0 -1
  206. package/dist/input-schema-DNrpTu49.js.map +0 -1
  207. package/dist/lifecycle-CFu6OV03.js.map +0 -1
  208. package/dist/scheduler-DZ3xQfeK.js.map +0 -1
  209. package/dist/settings-C45hDliX.js.map +0 -1
  210. package/dist/src-DgCbZtIR.js.map +0 -1
  211. package/dist/store-vgcPYo8K.js.map +0 -1
  212. package/dist/tool-3PA8xjB_.js.map +0 -1
  213. package/dist/websearch/tools/ai-sdk.js.map +0 -1
  214. package/dist/websearch/tools/pi.js.map +0 -1
  215. package/dist/websearch/tools/tanstack-ai.js.map +0 -1
  216. package/dist/websockets-CmENGb-Z.js.map +0 -1
@@ -1,3 +1,23 @@
1
+ //#region src/models/core/catalog.ts
2
+ /**
3
+ * Whether an id names an AI Gateway dynamic route: `dynamic/` and a route
4
+ * name after it.
5
+ *
6
+ * @experimental This surface is experimental and may change.
7
+ */
8
+ function isDynamicRouteId(modelId) {
9
+ return modelId.startsWith("dynamic/") && modelId.length > 8;
10
+ }
11
+ /**
12
+ * Whether a string names a language model that runs on `env.AI.run`: a
13
+ * Workers AI id or an AI Gateway dynamic route.
14
+ *
15
+ * @experimental This surface is experimental and may change.
16
+ */
17
+ function isRunPathLanguageModelId(modelId) {
18
+ return modelId.startsWith("@cf/") || isDynamicRouteId(modelId);
19
+ }
20
+ //#endregion
1
21
  //#region src/models/core/errors.ts
2
22
  /**
3
23
  * Error thrown for every failed Cloudflare AI call, whether it came back as a
@@ -239,6 +259,27 @@ function universalGatewayOptions(gateway) {
239
259
  return options;
240
260
  }
241
261
  /**
262
+ * The gateway options for the Workers AI run path, as the binding's own
263
+ * `GatewayOptions` type has them. `zdr` is left out: the binding has no field
264
+ * for it, and it applies to vendor models routed through the gateway.
265
+ */
266
+ function runGatewayOptions(gateway) {
267
+ const { zdr: _zdr, ...options } = gateway;
268
+ return options;
269
+ }
270
+ /**
271
+ * The universal call's own request headers: the caller's extra headers, plus
272
+ * `cf-aig-zdr`. The gateway reads ZDR off the request itself, not off a
273
+ * provider entry, and the binding's options have no field for it.
274
+ */
275
+ function universalRequestHeaders(request) {
276
+ const headers = {
277
+ ...request.extraHeaders,
278
+ ...request.gateway.zdr === void 0 ? {} : { "cf-aig-zdr": String(request.gateway.zdr) }
279
+ };
280
+ return Object.keys(headers).length > 0 ? headers : void 0;
281
+ }
282
+ /**
242
283
  * Whether a parsed body is the gateway's own error envelope rather than a
243
284
  * vendor payload — `{ success: false, error: [{ code, message }] }`, named
244
285
  * `AiGatewayError`. The gateway answers this for its own failures (no such
@@ -301,7 +342,7 @@ function bindingTransport(binding) {
301
342
  try {
302
343
  const response = await raw.run(request.model, request.input, {
303
344
  ...Object.keys(request.headers).length > 0 ? { extraHeaders: request.headers } : {},
304
- gateway: request.gateway,
345
+ gateway: runGatewayOptions(request.gateway),
305
346
  returnRawResponse: true,
306
347
  signal: request.signal
307
348
  });
@@ -318,13 +359,14 @@ function bindingTransport(binding) {
318
359
  },
319
360
  async universal(request) {
320
361
  try {
362
+ const extraHeaders = universalRequestHeaders(request);
321
363
  return await binding.gateway(request.gateway.id).run({
322
364
  endpoint: request.endpoint,
323
365
  headers: request.headers,
324
366
  provider: request.provider,
325
367
  query: request.query
326
368
  }, {
327
- ...request.extraHeaders === void 0 ? {} : { extraHeaders: request.extraHeaders },
369
+ ...extraHeaders === void 0 ? {} : { extraHeaders },
328
370
  gateway: universalGatewayOptions(request.gateway),
329
371
  signal: request.signal
330
372
  });
@@ -1380,6 +1422,6 @@ function imageMediaTypeOf(base64) {
1380
1422
  return "image/png";
1381
1423
  }
1382
1424
  //#endregion
1383
- export { isRetryableStatus as S, isGatewayErrorEnvelope as _, normalizeChatCompletion as a, classifyStatus as b, gatewaySlugForBaseUrl as c, resolveGatewayProvider as d, createTransport as f, headersToObject as g, errorFromResponse as h, normalizeChatCompletionsStream as i, isGatewayShapedUrl as l, errorFromGatewayEnvelope as m, imageMediaTypeOf as n, prepareChatCompletionsRequest as o, definedHeaders as p, sseDataStream as r, GATEWAY_PROVIDER_NAMES as s, buildImageInput as t, requireGatewayProvider as u, unwrapEnvelope as v, isAbortError as x, CloudflareAIError as y };
1425
+ export { isDynamicRouteId as C, isRetryableStatus as S, isGatewayErrorEnvelope as _, normalizeChatCompletion as a, classifyStatus as b, gatewaySlugForBaseUrl as c, resolveGatewayProvider as d, createTransport as f, headersToObject as g, errorFromResponse as h, normalizeChatCompletionsStream as i, isGatewayShapedUrl as l, errorFromGatewayEnvelope as m, imageMediaTypeOf as n, prepareChatCompletionsRequest as o, definedHeaders as p, sseDataStream as r, GATEWAY_PROVIDER_NAMES as s, buildImageInput as t, requireGatewayProvider as u, unwrapEnvelope as v, isRunPathLanguageModelId as w, isAbortError as x, CloudflareAIError as y };
1384
1426
 
1385
- //# sourceMappingURL=images-Ce9SCu3X.js.map
1427
+ //# sourceMappingURL=images-C4hiIexM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"images-C4hiIexM.js","names":["isRecord","isRecord","stripEchoSuffix"],"sources":["../src/models/core/catalog.ts","../src/models/core/errors.ts","../src/models/core/transport.ts","../src/models/core/gateway-providers.ts","../src/models/core/chat-completions/quirks.ts","../src/models/core/chat-completions/request.ts","../src/models/core/chat-completions/response.ts","../src/models/core/chat-completions/stream.ts","../src/models/core/sse.ts","../src/models/core/images.ts"],"sourcesContent":["/**\n * Keys of the ambient `AiModels` interface (from `@cloudflare/workers-types`)\n * whose model type extends `T`. Kept in step with the installed workers-types\n * version rather than hand-maintained here.\n */\ntype WorkersAIModelIdsExtending<T> = {\n [K in keyof AiModels]: AiModels[K] extends T ? K : never;\n}[keyof AiModels];\n\n/** The `inputs` shape a catalog entry declares. */\ntype InputsOf<K extends keyof AiModels> = AiModels[K] extends {\n inputs: infer I;\n}\n ? I\n : never;\n\n/** The `postProcessedOutputs` shape a catalog entry declares. */\ntype OutputsOf<K extends keyof AiModels> = AiModels[K] extends {\n postProcessedOutputs: infer O;\n}\n ? O\n : never;\n\n/**\n * Catalog keys whose input takes a required `messages` array — every current\n * chat model. Newer entries get their own generated class rather than\n * extending `BaseAiTextGeneration`, so the base-class arm alone misses them.\n */\ntype ChatCatalogId = {\n [K in keyof AiModels]: Extract<\n InputsOf<K>,\n { messages: unknown }\n > extends never\n ? never\n : K;\n}[keyof AiModels];\n\n/**\n * Catalog keys that take text and answer with embedding vectors. Both halves\n * matter: the input test alone also matches translation, classification and\n * speech models, which take `text` but return something else entirely.\n */\ntype EmbeddingCatalogId = {\n [K in keyof AiModels]: Extract<InputsOf<K>, { text: unknown }> extends never\n ? never\n : Extract<OutputsOf<K>, { data?: number[][] }> extends never\n ? never\n : K;\n}[keyof AiModels];\n\n/**\n * Catalog keys that take audio to transcribe. The `audio` key is required on\n * every speech-recognition input and on no other input shape, so the test is\n * exact rather than heuristic.\n */\ntype TranscriptionCatalogId = {\n [K in keyof AiModels]: Extract<InputsOf<K>, { audio: unknown }> extends never\n ? never\n : K;\n}[keyof AiModels];\n\n/**\n * Catalog keys that score a list of contexts against a query — rerankers.\n * `contexts` is required on exactly those inputs.\n */\ntype RerankingCatalogId = {\n [K in keyof AiModels]: Extract<\n InputsOf<K>,\n { contexts: unknown }\n > extends never\n ? never\n : K;\n}[keyof AiModels];\n\n/**\n * A Workers AI model id.\n *\n * Workers AI is the one catalog this package keeps up with, so this is the\n * only id shape it accepts: `@cf/<author>/<model>`. Autocomplete covers the\n * text-generation catalog from the installed `@cloudflare/workers-types`; the\n * template arm keeps every other `@cf/` slug assignable, because the catalog\n * lives server-side and moves independently of these types.\n *\n * Third-party models are not ids here — they are model objects built by their\n * own provider package and routed through AI Gateway.\n *\n * @experimental This surface is experimental and may change.\n */\nexport type WorkersAIModelId =\n // `Extract` is the runtime guard written as a type: the ambient catalog also\n // lists `@hf/...` ids, which `ai()` rejects, so they must not be suggested.\n | Extract<\n | ChatCatalogId\n | Exclude<\n WorkersAIModelIdsExtending<BaseAiTextGeneration>,\n WorkersAIModelIdsExtending<BaseAiTextToImage>\n >,\n `@cf/${string}`\n >\n // `& {}` keeps the literal arms out of the template's shadow: without it\n // TypeScript reduces every suggested id into `@cf/${string}` and stops\n // autocompleting them, exactly as `(string & {})` does elsewhere here.\n | (`@cf/${string}` & {});\n\n/**\n * An AI Gateway dynamic route, by name: `dynamic/<route>`.\n *\n * A dynamic route is configured on the gateway — which models it tries, in\n * which order, with what rate limits or budgets — and called through the\n * Workers AI run path like a model. It answers in the OpenAI chat-completions\n * shape whatever model served it, so it is a language model only.\n *\n * @experimental This surface is experimental and may change.\n */\nexport type DynamicRouteId = `dynamic/${string}`;\n\n/**\n * Whether an id names an AI Gateway dynamic route: `dynamic/` and a route\n * name after it.\n *\n * @experimental This surface is experimental and may change.\n */\nexport function isDynamicRouteId(modelId: string): modelId is DynamicRouteId {\n return modelId.startsWith(\"dynamic/\") && modelId.length > \"dynamic/\".length;\n}\n\n/**\n * Whether a string names a language model that runs on `env.AI.run`: a\n * Workers AI id or an AI Gateway dynamic route.\n *\n * @experimental This surface is experimental and may change.\n */\nexport function isRunPathLanguageModelId(modelId: string): boolean {\n return modelId.startsWith(\"@cf/\") || isDynamicRouteId(modelId);\n}\n\n/**\n * A text-embedding model id accepted by `ai.embedding()`.\n *\n * The modality methods are Workers AI only — there is no vendor route for them\n * — so, like {@link WorkersAIModelId}, they take `@cf/` ids and nothing else.\n *\n * @experimental This surface is experimental and may change.\n */\nexport type CloudflareEmbeddingModelId =\n | Extract<\n EmbeddingCatalogId | WorkersAIModelIdsExtending<BaseAiTextEmbeddings>,\n `@cf/${string}`\n >\n | (`@cf/${string}` & {});\n\n/**\n * Workers AI text-to-image ids that the generated `AiModels` entries do not\n * classify as {@link BaseAiTextToImage} — the newer partner models get their\n * own generated class instead. Curated for autocomplete only; the catalog\n * lives server-side and any slug is accepted.\n *\n * The FLUX.2 family (`flux-2-dev`, `flux-2-klein-4b`, `flux-2-klein-9b`) is\n * deliberately absent, for the reason {@link UnsupportedTranscriptionId}\n * records for the Deepgram recognisers: its generated input takes a required\n * `multipart` object body (`{ multipart: { body, contentType } }`) and no\n * `prompt`, which the JSON run path cannot carry — live, the run path answers\n * `400 Bad input: required properties at \"/\" are 'multipart'`. Suggesting an\n * id that always 400s is worse than not suggesting it.\n *\n * @experimental This surface is experimental and may change.\n */\nexport type KnownImageModelId =\n | \"@cf/black-forest-labs/flux-1-schnell\"\n | \"@cf/leonardo/lucid-origin\"\n | \"@cf/leonardo/phoenix-1.0\";\n\n/**\n * An image model id accepted by `ai.image()`.\n *\n * @experimental This surface is experimental and may change.\n */\nexport type CloudflareImageModelId =\n | Extract<\n WorkersAIModelIdsExtending<BaseAiTextToImage> | KnownImageModelId,\n `@cf/${string}`\n >\n | (`@cf/${string}` & {});\n\n/**\n * Workers AI text-to-speech ids without a {@link BaseAiTextToSpeech} entry.\n * Curated for autocomplete only.\n *\n * @experimental This surface is experimental and may change.\n */\nexport type KnownSpeechModelId =\n | \"@cf/deepgram/aura-1\"\n | \"@cf/deepgram/aura-2-en\"\n | \"@cf/deepgram/aura-2-es\";\n\n/**\n * A text-to-speech model id accepted by `ai.speech()`.\n *\n * @experimental This surface is experimental and may change.\n */\nexport type CloudflareSpeechModelId =\n | Extract<\n WorkersAIModelIdsExtending<BaseAiTextToSpeech> | KnownSpeechModelId,\n `@cf/${string}`\n >\n | (`@cf/${string}` & {});\n\n/**\n * Deepgram's recognition models want the audio as an object body\n * (`audio: { body, contentType }`) rather than as base64, which the JSON run\n * path cannot carry — every documented variant answered `400` live. They stay\n * out of the suggested arm, and the transcription model answers a clear error\n * for them.\n */\ntype UnsupportedTranscriptionId = \"@cf/deepgram/nova-3\" | \"@cf/deepgram/flux\";\n\n/**\n * A speech-recognition model id accepted by `ai.transcription()`.\n *\n * Deepgram's recognition models (`@cf/deepgram/nova-3`, `@cf/deepgram/flux`)\n * are deliberately not suggested: the run path rejects their documented input\n * shape, so this provider answers a clear error for them rather than a 400.\n *\n * @experimental This surface is experimental and may change.\n */\nexport type CloudflareTranscriptionModelId =\n | Extract<\n | Exclude<TranscriptionCatalogId, UnsupportedTranscriptionId>\n | Exclude<\n WorkersAIModelIdsExtending<BaseAiAutomaticSpeechRecognition>,\n UnsupportedTranscriptionId\n >,\n `@cf/${string}`\n >\n | (`@cf/${string}` & {});\n\n/**\n * A reranking model id accepted by `ai.reranking()`.\n *\n * @experimental This surface is experimental and may change.\n */\nexport type CloudflareRerankingModelId =\n | Extract<RerankingCatalogId, `@cf/${string}`>\n | (`@cf/${string}` & {});\n\n/** `true` when `Id` is in the literal (autocompleted) arm of `T`. */\ntype Suggests<T, Id extends string> =\n Extract<T, Id> extends never ? false : true;\n\n/**\n * Compile-time guard: the repo-standard models must stay in the literal arms,\n * so a `@cloudflare/workers-types` bump that reshapes the catalog cannot\n * silently drop them into the `(string & {})` arm and stop suggesting them.\n * `tsc` fails on this alias if any of them stops being autocompleted.\n *\n * @internal\n */\nexport type CatalogAutocompleteCheck<\n T extends [true, true, true, true, true, true, true, true, true] = [\n Suggests<WorkersAIModelId, \"@cf/zai-org/glm-4.7-flash\">,\n Suggests<WorkersAIModelId, \"@cf/meta/llama-3.3-70b-instruct-fp8-fast\">,\n Suggests<CloudflareEmbeddingModelId, \"@cf/baai/bge-base-en-v1.5\">,\n Suggests<CloudflareEmbeddingModelId, \"@cf/google/embeddinggemma-300m\">,\n Suggests<CloudflareImageModelId, \"@cf/black-forest-labs/flux-1-schnell\">,\n Suggests<\n CloudflareImageModelId,\n \"@cf/stabilityai/stable-diffusion-xl-base-1.0\"\n >,\n Suggests<CloudflareSpeechModelId, \"@cf/deepgram/aura-1\">,\n Suggests<\n CloudflareTranscriptionModelId,\n \"@cf/openai/whisper-large-v3-turbo\"\n >,\n Suggests<CloudflareRerankingModelId, \"@cf/baai/bge-reranker-base\">\n ]\n> = T;\n","/**\n * Coarse classification of a failed Cloudflare AI call.\n *\n * @experimental This surface is experimental and may change.\n */\nexport type CloudflareAIErrorCode =\n | \"auth\"\n | \"rate-limit\"\n | \"not-found\"\n | \"bad-request\"\n | \"provider-error\"\n | \"gateway-error\"\n | \"unknown\";\n\n/**\n * One leg of a {@link CloudflareAIError} fallback chain.\n *\n * @experimental This surface is experimental and may change.\n */\nexport interface CloudflareAIAttempt {\n /** The model id that was tried. */\n model: string;\n /** The error that leg failed with. */\n error: unknown;\n}\n\n/**\n * Error thrown for every failed Cloudflare AI call, whether it came back as a\n * non-2xx `Response` or as a thrown Workers AI binding error. Framework\n * modules wrap it into their own error type at their boundary (the AI SDK\n * module into an `APICallError`, so `ai`'s retry loop honours\n * {@link CloudflareAIError.isRetryable}).\n *\n * @experimental This surface is experimental and may change.\n */\nexport class CloudflareAIError extends Error {\n /** HTTP status, when the failure carried one. */\n readonly status: number | undefined;\n /** Coarse classification used for routing and fallback decisions. */\n readonly code: CloudflareAIErrorCode;\n /** `cf-aig-log-id` of the failed request, when the response carried one. */\n readonly logId: string | undefined;\n /** The model id that produced this error. */\n readonly model: string;\n /** Which binding path the request went down, for error reporting. */\n readonly url: string;\n /** The request body that failed. */\n readonly requestBodyValues: unknown;\n /** Response headers, when there was a response. */\n readonly responseHeaders: Record<string, string> | undefined;\n /** Raw response body text, when there was a response. */\n readonly responseBody: string | undefined;\n /** Whether a retry is worth attempting. */\n readonly isRetryable: boolean;\n /** Parsed error envelope, or other structured detail. */\n readonly data: unknown;\n /** Every leg tried, when this error ends a fallback chain. */\n readonly attempts: CloudflareAIAttempt[] | undefined;\n override readonly cause: unknown;\n\n constructor(options: {\n message: string;\n model: string;\n url: string;\n requestBodyValues: unknown;\n status?: number;\n code: CloudflareAIErrorCode;\n logId?: string;\n responseHeaders?: Record<string, string>;\n responseBody?: string;\n isRetryable?: boolean;\n data?: unknown;\n cause?: unknown;\n attempts?: CloudflareAIAttempt[];\n }) {\n super(options.message);\n this.name = \"CloudflareAIError\";\n this.status = options.status;\n this.code = options.code;\n this.logId = options.logId;\n this.model = options.model;\n this.url = options.url;\n this.requestBodyValues = options.requestBodyValues;\n this.responseHeaders = options.responseHeaders;\n this.responseBody = options.responseBody;\n this.isRetryable = options.isRetryable ?? isRetryableStatus(options.status);\n this.data = options.data;\n this.cause = options.cause;\n this.attempts = options.attempts;\n }\n}\n\n/**\n * Whether a status is worth retrying. Missing status means a transport-level\n * failure (connection reset, DNS, abort-adjacent), which is retryable.\n *\n * @experimental This surface is experimental and may change.\n */\nexport function isRetryableStatus(status: number | undefined): boolean {\n if (status === undefined) return true;\n return status === 408 || status === 409 || status === 429 || status >= 500;\n}\n\n/**\n * Classifies an HTTP status into a {@link CloudflareAIErrorCode}. The\n * `AiGatewayError` envelope name catches gateway-level statuses that are not\n * otherwise meaningful (notably 402 \"insufficient balance\").\n */\nexport function classifyStatus(\n status: number | undefined,\n envelopeName?: string\n): CloudflareAIErrorCode {\n if (status === 401 || status === 403) return \"auth\";\n if (status === 429) return \"rate-limit\";\n if (status === 404) return \"not-found\";\n if (status === 400 || status === 422) return \"bad-request\";\n if (status !== undefined && status >= 500) return \"provider-error\";\n if (envelopeName === \"AiGatewayError\") return \"gateway-error\";\n return \"unknown\";\n}\n\n/**\n * Workers AI binding error codes that map onto an HTTP status.\n *\n * @see https://developers.cloudflare.com/workers-ai/platform/errors/\n */\nconst BINDING_CODE_STATUS: Record<number, number> = {\n 3003: 400,\n 3006: 413,\n 3007: 408,\n 3008: 408,\n 3023: 403,\n 3036: 429,\n 3039: 400,\n 3040: 429,\n 3041: 403,\n 3042: 404,\n 5004: 400,\n 5005: 405,\n 5007: 400,\n 5016: 403,\n 5018: 403,\n 5019: 405\n};\n\n/** Abort-shaped errors must propagate untouched so callers can detect them. */\nexport function isAbortError(error: unknown): boolean {\n const name =\n error instanceof Error || error instanceof DOMException\n ? error.name\n : undefined;\n return (\n name === \"AbortError\" ||\n name === \"ResponseAborted\" ||\n name === \"TimeoutError\"\n );\n}\n\nfunction messageOf(error: unknown): string {\n if (typeof error === \"string\") return error;\n if (error instanceof Error) return error.message;\n if (error !== null && typeof error === \"object\" && \"message\" in error) {\n const message = (error as { message: unknown }).message;\n if (typeof message === \"string\") return message;\n }\n return String(error);\n}\n\n/**\n * Extracts a Workers AI internal error code from a thrown binding error. The\n * binding reports codes inside the message text (`\"3040: Capacity temporarily\n * exceeded\"`) rather than as a status, so only known codes are accepted — an\n * unrelated leading number must not be misread as a code.\n */\nfunction bindingErrorCode(error: unknown): number | undefined {\n if (error !== null && typeof error === \"object\" && \"code\" in error) {\n const code = (error as { code: unknown }).code;\n if (typeof code === \"number\" && code in BINDING_CODE_STATUS) return code;\n }\n const matches = messageOf(error).matchAll(/\\b(\\d{3,5})\\s*:/g);\n for (const match of matches) {\n const code = Number(match[1]);\n if (code in BINDING_CODE_STATUS) return code;\n }\n return undefined;\n}\n\n/**\n * Normalizes a thrown Workers AI binding error into a {@link CloudflareAIError}.\n * Abort errors and errors that are already {@link CloudflareAIError}s pass through.\n */\nexport function normalizeThrownError(\n error: unknown,\n context: {\n model: string;\n url: string;\n requestBodyValues: unknown;\n }\n): unknown {\n if (isAbortError(error)) return error;\n if (error instanceof CloudflareAIError) return error;\n\n const code = bindingErrorCode(error);\n const status = code === undefined ? undefined : BINDING_CODE_STATUS[code];\n return new CloudflareAIError({\n cause: error,\n code: classifyStatus(status),\n data: code === undefined ? undefined : { code },\n // A recognised code decides for itself. Everything else is not worth\n // retrying: the binding is the only backend, so a throw with no status is\n // a programming error rather than a transport failure, and re-running it\n // on every fallback leg helps nobody.\n isRetryable: status === undefined ? false : isRetryableStatus(status),\n message: messageOf(error),\n model: context.model,\n requestBodyValues: context.requestBodyValues,\n status,\n url: context.url\n });\n}\n","import {\n CloudflareAIError,\n classifyStatus,\n normalizeThrownError\n} from \"./errors\";\nimport type { GatewayProviderName } from \"./gateway-providers\";\nimport type { AISettings, ResolvedGateway } from \"./settings\";\n\n/** The reported `url` for a universal call made through the binding. */\nconst UNIVERSAL_BINDING_URL = \"ai-gateway-binding\";\n\n/** One request on the Cloudflare run path. */\nexport interface TransportRequest {\n /** Model id — Workers AI slug or catalog `<author>/<model>`. */\n model: string;\n /** The provider-shaped request body (`input` on the run path). */\n input: Record<string, unknown>;\n /** Gateway options for this request. */\n gateway: ResolvedGateway;\n /** Extra request headers, merged last. */\n headers: Record<string, string>;\n /** Abort signal, forwarded to the binding or to `fetch`. */\n signal?: AbortSignal;\n}\n\n/**\n * One request on the universal AI Gateway path: a vendor's own request, routed\n * by the gateway to that vendor. The body is the vendor's, untouched — nothing\n * here knows the vendor's wire format.\n *\n * @experimental This surface is experimental and may change.\n */\nexport interface UniversalRequest {\n /** The gateway provider slug the request is routed to. */\n provider: GatewayProviderName | string;\n /** The vendor path the gateway appends to that provider's base URL. */\n endpoint: string;\n /** The vendor's own request headers, minus its credential header. */\n headers: Record<string, string>;\n /** The vendor's request body, verbatim. */\n query: unknown;\n /** Gateway options for this request. */\n gateway: ResolvedGateway;\n /** Extra headers merged last, outside the vendor's own set. */\n extraHeaders?: Record<string, string>;\n /** Abort signal, forwarded to the binding or to `fetch`. */\n signal?: AbortSignal;\n}\n\n/**\n * The single code path both backends implement. Always resolves to a raw\n * `Response`, so streaming and non-streaming calls share one path and nothing\n * is buffered on the caller's behalf.\n *\n * @experimental This surface is experimental and may change.\n */\nexport interface Transport {\n /** A stable identifier for the endpoint, used in error reporting. */\n readonly url: string;\n run(request: TransportRequest): Promise<Response>;\n /**\n * Sends a vendor's own request through the gateway's universal endpoint.\n * Always resolves to the vendor's raw `Response`, error responses included:\n * only the gateway's own failures (a missing gateway, an unpaid account) are\n * lifted into a {@link CloudflareAIError}, because the vendor's provider\n * knows how to read its own errors and we do not.\n */\n universal(request: UniversalRequest): Promise<Response>;\n /**\n * A log id read off the backend itself when the response carried none. The\n * Workers AI binding exposes the last gateway log id as a mutable property,\n * so it is captured per response rather than read late.\n */\n logIdFallback(response: Response): string | undefined;\n}\n\n/**\n * Drops entries whose value is `undefined`. The AI SDK types call headers as\n * `Record<string, string | undefined>`, and an undefined value reaches the\n * binding as the string \"undefined\" rather than as an absent header.\n */\nexport function definedHeaders(\n headers: Record<string, string | undefined> | undefined\n): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers ?? {})) {\n if (value !== undefined) result[key] = value;\n }\n return result;\n}\n\n/** Copies response headers into a plain object. */\nexport function headersToObject(headers: Headers): Record<string, string> {\n const result: Record<string, string> = {};\n headers.forEach((value, key) => {\n result[key] = value;\n });\n return result;\n}\n\n/**\n * Some run-path responses arrive bare and some wrapped in the Cloudflare API\n * envelope. Unwrap only when the envelope keys are actually present, so a\n * provider payload that happens to have a `result` field is left alone.\n */\nexport function unwrapEnvelope(\n value: unknown,\n context?: { model: string; url: string; status: number }\n): unknown {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n return value;\n }\n const record = value as Record<string, unknown>;\n // A failure envelope may carry no `result` at all, only its errors.\n const failed =\n record.success === false && firstEnvelopeError(record) !== undefined;\n if (failed || (\"success\" in record && \"result\" in record)) {\n if (record.success === true) return record.result;\n // A failure envelope can arrive with a 2xx status. Parsing it as a\n // provider payload would produce an empty result and no diagnostic.\n throw new CloudflareAIError({\n code: classifyStatus(\n context?.status,\n typeof record.name === \"string\" ? record.name : undefined\n ),\n data: value,\n message: errorMessageFrom(value, context?.status),\n model: context?.model ?? \"\",\n requestBodyValues: undefined,\n status: context?.status,\n url: context?.url ?? \"\"\n });\n }\n return value;\n}\n\nfunction firstEnvelopeError(\n record: Record<string, unknown>\n): { code?: unknown; message?: unknown } | undefined {\n // Live gateway responses use `error` (an array of one); the documented\n // Cloudflare envelope uses `errors`. Accept either.\n for (const key of [\"error\", \"errors\"]) {\n const value = record[key];\n if (Array.isArray(value) && value.length > 0) {\n const first = value[0];\n if (first !== null && typeof first === \"object\") {\n return first as { code?: unknown; message?: unknown };\n }\n }\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) {\n return value as { code?: unknown; message?: unknown };\n }\n }\n return undefined;\n}\n\n/**\n * Pulls a human message out of any of the error envelopes the platform emits:\n * the gateway envelope (`error: [{ code, message }]`), the Workers AI\n * validation envelope (`message`/`description` only), a bare\n * `{ error: \"...\" }`, and the \"Model ID missing\" internal error, which carries\n * only `description`.\n */\nexport function errorMessageFrom(\n body: unknown,\n status: number | undefined\n): string {\n const record =\n body !== null && typeof body === \"object\" && !Array.isArray(body)\n ? (body as Record<string, unknown>)\n : undefined;\n if (record !== undefined) {\n const envelope = firstEnvelopeError(record);\n if (typeof envelope?.message === \"string\") return envelope.message;\n if (typeof record.error === \"string\") return record.error;\n if (typeof record.message === \"string\") return record.message;\n if (typeof record.description === \"string\") return record.description;\n }\n if (typeof body === \"string\" && body !== \"\") return body;\n return `HTTP ${status ?? \"error\"}`;\n}\n\n/** Builds a {@link CloudflareAIError} from a non-2xx run-path response. */\nexport async function errorFromResponse(\n response: Response,\n context: { model: string; url: string; requestBodyValues: unknown }\n): Promise<CloudflareAIError> {\n const text = await response.text().catch(() => \"\");\n let body: unknown = text;\n try {\n body = text === \"\" ? undefined : JSON.parse(text);\n } catch {\n // Not JSON — the raw text is the best message we have.\n }\n const record =\n body !== null && typeof body === \"object\" && !Array.isArray(body)\n ? (body as Record<string, unknown>)\n : undefined;\n const envelopeName =\n typeof record?.name === \"string\" ? record.name : undefined;\n const headers = headersToObject(response.headers);\n return new CloudflareAIError({\n code: classifyStatus(response.status, envelopeName),\n data: body,\n logId: headers[\"cf-aig-log-id\"],\n message: errorMessageFrom(body, response.status),\n model: context.model,\n requestBodyValues: context.requestBodyValues,\n responseBody: text,\n responseHeaders: headers,\n status: response.status,\n url: context.url\n });\n}\n\n/**\n * The gateway's own options for the universal call. The id is not among them:\n * it selects the gateway (`env.AI.gateway(id)`), and the binding's own `id`\n * field is deprecated.\n */\nfunction universalGatewayOptions(\n gateway: ResolvedGateway\n): UniversalGatewayOptions {\n // `id` is deprecated on this type but still required by it; the gateway is\n // already selected by `env.AI.gateway(id)`, so it repeats that id.\n const options: UniversalGatewayOptions = { id: gateway.id };\n if (gateway.skipCache !== undefined) options.skipCache = gateway.skipCache;\n if (gateway.cacheTtl !== undefined) options.cacheTtl = gateway.cacheTtl;\n if (gateway.cacheKey !== undefined) options.cacheKey = gateway.cacheKey;\n if (gateway.metadata !== undefined) options.metadata = gateway.metadata;\n if (gateway.collectLog !== undefined) options.collectLog = gateway.collectLog;\n if (gateway.eventId !== undefined) options.eventId = gateway.eventId;\n if (gateway.requestTimeoutMs !== undefined) {\n options.requestTimeoutMs = gateway.requestTimeoutMs;\n }\n if (gateway.retries !== undefined) options.retries = gateway.retries;\n return options;\n}\n\n/**\n * The gateway options for the Workers AI run path, as the binding's own\n * `GatewayOptions` type has them. `zdr` is left out: the binding has no field\n * for it, and it applies to vendor models routed through the gateway.\n */\nfunction runGatewayOptions(gateway: ResolvedGateway): GatewayOptions {\n const { zdr: _zdr, ...options } = gateway;\n return options;\n}\n\n/**\n * The universal call's own request headers: the caller's extra headers, plus\n * `cf-aig-zdr`. The gateway reads ZDR off the request itself, not off a\n * provider entry, and the binding's options have no field for it.\n */\nfunction universalRequestHeaders(\n request: UniversalRequest\n): Record<string, string> | undefined {\n const headers = {\n ...request.extraHeaders,\n ...(request.gateway.zdr === undefined\n ? {}\n : { \"cf-aig-zdr\": String(request.gateway.zdr) })\n };\n return Object.keys(headers).length > 0 ? headers : undefined;\n}\n\n/**\n * Whether a parsed body is the gateway's own error envelope rather than a\n * vendor payload — `{ success: false, error: [{ code, message }] }`, named\n * `AiGatewayError`. The gateway answers this for its own failures (no such\n * gateway, unified billing unpaid, provider not configured); everything else\n * on this path is the vendor's own error, which the vendor's provider reads.\n *\n * @experimental This surface is experimental and may change.\n */\nexport function isGatewayErrorEnvelope(json: unknown): boolean {\n if (json === null || typeof json !== \"object\" || Array.isArray(json)) {\n return false;\n }\n const record = json as Record<string, unknown>;\n if (record.name === \"AiGatewayError\") return true;\n if (record.success !== false) return false;\n const errors = record.error ?? record.errors;\n return (\n Array.isArray(errors) &&\n errors.some(\n (entry) =>\n entry !== null &&\n typeof entry === \"object\" &&\n typeof (entry as { message?: unknown }).message === \"string\"\n )\n );\n}\n\n/**\n * Builds a {@link CloudflareAIError} from the gateway's own error envelope, so\n * a gateway failure on the universal path classifies and retries exactly as\n * one on the Workers AI run path.\n *\n * @experimental This surface is experimental and may change.\n */\nexport function errorFromGatewayEnvelope(\n body: unknown,\n context: {\n model: string;\n url: string;\n requestBodyValues: unknown;\n status?: number;\n responseHeaders?: Record<string, string>;\n responseBody?: string;\n }\n): CloudflareAIError {\n const record =\n body !== null && typeof body === \"object\" && !Array.isArray(body)\n ? (body as Record<string, unknown>)\n : undefined;\n return new CloudflareAIError({\n code: classifyStatus(\n context.status,\n typeof record?.name === \"string\" ? record.name : \"AiGatewayError\"\n ),\n data: body,\n logId: context.responseHeaders?.[\"cf-aig-log-id\"],\n message: errorMessageFrom(body, context.status),\n model: context.model,\n requestBodyValues: context.requestBodyValues,\n responseBody: context.responseBody,\n responseHeaders: context.responseHeaders,\n status: context.status,\n url: context.url\n });\n}\n\n/**\n * The model id a universal request is about, for error reporting. Every vendor\n * body carries `model`; the endpoint is the fallback.\n */\nfunction universalModel(request: UniversalRequest): string {\n const query = request.query;\n if (query !== null && typeof query === \"object\" && !Array.isArray(query)) {\n const model = (query as Record<string, unknown>).model;\n if (typeof model === \"string\") return model;\n }\n return `${request.provider}/${request.endpoint}`;\n}\n\n/**\n * The `Ai` binding narrowed to the raw-response overload. The ambient\n * overloads pick their return type from the model id, and every catalog slug\n * lands on the `Record<string, unknown>` fallback, so the run-path signature\n * is stated explicitly here.\n */\ninterface RawResponseBinding {\n run(\n model: string,\n inputs: Record<string, unknown>,\n options: AiOptions & { returnRawResponse: true }\n ): Promise<Response>;\n}\n\n/** The keyless in-Worker backend: `env.AI.run(...)`. */\nfunction bindingTransport(binding: Ai): Transport {\n const raw = binding as unknown as RawResponseBinding;\n // `aiGatewayLogId` is a mutable property on the binding that every\n // concurrent `run` overwrites, so it is snapshotted against the response it\n // belongs to the moment that response arrives. A run that resolves while\n // another is mid-flight can still read the other's id; the window is one\n // microtask rather than the whole request.\n const logIds = new WeakMap<Response, string>();\n return {\n logIdFallback(response) {\n return logIds.get(response);\n },\n async run(request) {\n try {\n // Called as a method, never detached: the binding reads private\n // fields and throws on a detached reference.\n const response = await raw.run(request.model, request.input, {\n ...(Object.keys(request.headers).length > 0\n ? { extraHeaders: request.headers }\n : {}),\n gateway: runGatewayOptions(request.gateway),\n returnRawResponse: true,\n signal: request.signal\n });\n const logId = binding.aiGatewayLogId;\n if (logId !== null && logId !== undefined) {\n logIds.set(response, logId);\n }\n return response;\n } catch (error) {\n // `returnRawResponse` resolves with a `Response` for upstream errors,\n // so a throw here means the binding itself failed (e.g. code 3040,\n // out of capacity).\n throw normalizeThrownError(error, {\n model: request.model,\n requestBodyValues: request.input,\n url: \"workers-ai-binding\"\n });\n }\n },\n async universal(request) {\n try {\n const extraHeaders = universalRequestHeaders(request);\n // Called as a method on the binding, and on the `AiGateway` it\n // returns: both read private fields.\n return await binding.gateway(request.gateway.id).run(\n {\n endpoint: request.endpoint,\n headers: request.headers,\n provider: request.provider,\n query: request.query\n },\n {\n ...(extraHeaders === undefined ? {} : { extraHeaders }),\n gateway: universalGatewayOptions(request.gateway),\n signal: request.signal\n }\n );\n } catch (error) {\n throw normalizeThrownError(error, {\n model: universalModel(request),\n requestBodyValues: request.query,\n url: UNIVERSAL_BINDING_URL\n });\n }\n },\n url: \"workers-ai-binding\"\n };\n}\n\n/**\n * Builds the transport for a set of provider settings. The model id, not the\n * caller, decides the wire format; the transport only decides how the request\n * physically leaves the Worker.\n *\n * @experimental This surface is experimental and may change.\n */\nexport function createTransport(settings: AISettings): Transport {\n if (settings.binding === undefined) {\n throw new Error(\"createAI requires { binding }: the Workers AI binding.\");\n }\n return bindingTransport(settings.binding);\n}\n","/**\n * The AI Gateway provider table: which gateway provider slug a vendor's own\n * base URL belongs to, and what the universal request's `endpoint` is for a\n * given upstream URL.\n *\n * This is platform knowledge, not vendor knowledge — the gateway publishes the\n * list, and every entry here appears in `AIGatewayProviders` from\n * `@cloudflare/workers-types`. Nothing about a vendor's wire format, model ids\n * or capabilities lives here: the vendor's own provider package builds the\n * request, and this table only says where it goes.\n *\n * Adapted from `@cloudflare/ai-gateway-provider`'s `providers.ts`.\n *\n * @experimental This surface is experimental and may change.\n */\n\n/**\n * The gateway provider slugs this table maps onto. A subset of the ambient\n * `AIGatewayProviders` union; {@link GatewayProviderNameCheck} keeps it one.\n *\n * @experimental This surface is experimental and may change.\n */\nexport const GATEWAY_PROVIDER_NAMES = [\n \"workers-ai\",\n \"anthropic\",\n \"openai\",\n \"azure-openai\",\n \"google-ai-studio\",\n \"google-vertex-ai\",\n \"grok\",\n \"mistral\",\n \"perplexity-ai\",\n \"replicate\",\n \"groq\",\n \"deepseek\",\n \"openrouter\",\n \"cerebras\",\n \"cohere\",\n \"huggingface\",\n \"aws-bedrock\",\n \"elevenlabs\",\n \"cartesia\"\n] as const;\n\n/**\n * A gateway provider slug.\n *\n * @experimental This surface is experimental and may change.\n */\nexport type GatewayProviderName = (typeof GATEWAY_PROVIDER_NAMES)[number];\n\n/**\n * Compile-time guard: every slug in this table must exist in the platform's\n * own provider union, so a workers-types bump that renames one fails `tsc`\n * here rather than at runtime with a 404 from the gateway.\n *\n * @internal\n */\nexport type GatewayProviderNameCheck<\n T extends AIGatewayProviders = GatewayProviderName\n> = T;\n\n/**\n * One row of the provider table.\n *\n * @experimental This surface is experimental and may change.\n */\nexport interface GatewayProvider {\n /** The gateway provider slug. */\n readonly name: GatewayProviderName;\n /** Matches the upstream host (`URL.host`), not the whole URL. */\n readonly host: RegExp;\n /**\n * Request headers carrying the vendor's own credential. They are stripped\n * before the request is handed to the gateway, which holds the real key\n * (unified billing or BYOK). Lowercase.\n */\n readonly authHeaders: readonly string[];\n /**\n * The universal request's `endpoint` for an upstream URL: everything after\n * the host, query string included, with the provider's fixed prefix removed.\n * `undefined` when the URL does not belong to this provider.\n */\n endpoint(url: string): string | undefined;\n}\n\n/** The default credential header; providers add their own on top. */\nconst AUTHORIZATION = [\"authorization\"] as const;\n\ninterface ProviderSpec {\n name: GatewayProviderName;\n host: RegExp;\n authHeaders?: readonly string[];\n /** A fixed path prefix stripped from the endpoint. */\n pathPrefix?: RegExp;\n /** A full replacement for the default path mapping. */\n endpoint?: (url: URL) => string | undefined;\n}\n\n/** Path after the host, leading slash removed, query string kept. */\nfunction pathOf(url: URL): string {\n return `${url.pathname.replace(/^\\/+/, \"\")}${url.search}`;\n}\n\nfunction buildProvider(spec: ProviderSpec): GatewayProvider {\n const map =\n spec.endpoint ??\n ((url: URL) => {\n const path = pathOf(url);\n return spec.pathPrefix === undefined\n ? path\n : path.replace(spec.pathPrefix, \"\");\n });\n return {\n authHeaders: spec.authHeaders ?? AUTHORIZATION,\n endpoint(url) {\n const parsed = parseUrl(url);\n if (parsed === undefined || !spec.host.test(parsed.host)) {\n return undefined;\n }\n return map(parsed);\n },\n host: spec.host,\n name: spec.name\n };\n}\n\nfunction parseUrl(url: string): URL | undefined {\n try {\n return new URL(url);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Azure names the deployment in the path; the gateway names it in the\n * endpoint as `<resource>/<deployment>/<rest>`.\n */\nfunction azureEndpoint(url: URL): string | undefined {\n const resource = /^([^.]+)\\.openai\\.azure\\.com$/.exec(url.host)?.[1];\n const rest = /^\\/openai\\/deployments\\/([^/]+)\\/(.+)$/.exec(url.pathname);\n if (resource === undefined || rest === null) return undefined;\n return `${resource}/${rest[1]}/${rest[2]}${url.search}`;\n}\n\n/**\n * Bedrock's region and service live in the host; the gateway wants them as the\n * first two endpoint segments.\n */\nfunction bedrockEndpoint(url: URL): string | undefined {\n const match = /^(bedrock[a-z0-9-]*)\\.([a-z0-9-]+)\\.amazonaws\\.com$/.exec(\n url.host\n );\n if (match === null) return undefined;\n return `${match[1]}/${match[2]}/${pathOf(url)}`;\n}\n\nconst SPECS: ProviderSpec[] = [\n {\n // Workers AI's own API host. `env.AI.run` is this package's path for\n // `@cf/` models; this row exists because the gateway lists the provider,\n // so a model object pointed at that host still resolves.\n host: /^api\\.cloudflare\\.com$/,\n name: \"workers-ai\",\n pathPrefix: /^client\\/v4\\/accounts\\/[^/]+\\/ai\\//\n },\n {\n authHeaders: [\"authorization\", \"x-api-key\"],\n host: /^api\\.anthropic\\.com$/,\n name: \"anthropic\"\n },\n { host: /^api\\.openai\\.com$/, name: \"openai\" },\n {\n authHeaders: [\"authorization\", \"api-key\"],\n endpoint: azureEndpoint,\n host: /^[^.]+\\.openai\\.azure\\.com$/,\n name: \"azure-openai\"\n },\n {\n authHeaders: [\"authorization\", \"x-goog-api-key\"],\n host: /^generativelanguage\\.googleapis\\.com$/,\n name: \"google-ai-studio\"\n },\n {\n host: /^(?:[a-z0-9-]+-)?aiplatform\\.googleapis\\.com$/,\n name: \"google-vertex-ai\"\n },\n { host: /^api\\.x\\.ai$/, name: \"grok\" },\n { host: /^api\\.mistral\\.ai$/, name: \"mistral\" },\n { host: /^api\\.perplexity\\.ai$/, name: \"perplexity-ai\" },\n { host: /^api\\.replicate\\.com$/, name: \"replicate\" },\n {\n host: /^api\\.groq\\.com$/,\n name: \"groq\",\n pathPrefix: /^openai\\/v1\\//\n },\n { host: /^api\\.deepseek\\.com$/, name: \"deepseek\" },\n {\n host: /^openrouter\\.ai$/,\n name: \"openrouter\",\n pathPrefix: /^api\\//\n },\n { host: /^api\\.cerebras\\.ai$/, name: \"cerebras\" },\n { host: /^api\\.cohere\\.(?:ai|com)$/, name: \"cohere\" },\n {\n host: /^(?:api-inference|router)\\.huggingface\\.co$/,\n name: \"huggingface\",\n pathPrefix: /^models\\//\n },\n {\n endpoint: bedrockEndpoint,\n host: /^bedrock.*\\.amazonaws\\.com$/,\n name: \"aws-bedrock\"\n },\n { host: /^api\\.elevenlabs\\.io$/, name: \"elevenlabs\" },\n { host: /^api\\.cartesia\\.ai$/, name: \"cartesia\" }\n];\n\n/**\n * The provider table, in declaration order. Hosts do not overlap, so the order\n * only decides which row a future overlapping host would win.\n *\n * @experimental This surface is experimental and may change.\n */\nexport const GATEWAY_PROVIDERS: readonly GatewayProvider[] =\n SPECS.map(buildProvider);\n\n/**\n * A vendor URL mapped onto the universal gateway request.\n *\n * @experimental This surface is experimental and may change.\n */\nexport interface ResolvedGatewayProvider {\n /** The gateway provider slug. */\n provider: GatewayProviderName;\n /** The universal request's `endpoint`. */\n endpoint: string;\n /** Request headers to strip before handing the request to the gateway. */\n authHeaders: readonly string[];\n}\n\n/**\n * The table row for a bare host (`api.anthropic.com`) or for anything a `URL`\n * can be built from. pi-ai models carry a `baseUrl` rather than a full request\n * URL, so both spellings resolve.\n *\n * @experimental This surface is experimental and may change.\n */\nexport function gatewayProviderForHost(\n hostOrUrl: string\n): GatewayProvider | undefined {\n const host = parseUrl(hostOrUrl)?.host ?? hostOf(hostOrUrl);\n if (host === undefined) return undefined;\n return GATEWAY_PROVIDERS.find((provider) => provider.host.test(host));\n}\n\n/** Reads a host out of a bare host, `host/path` or `//host` spelling. */\nfunction hostOf(value: string): string | undefined {\n const host = value.replace(/^\\/\\//, \"\").split(\"/\")[0];\n return host === \"\" ? undefined : host;\n}\n\n/**\n * Maps a vendor request URL onto `{ provider, endpoint, authHeaders }` for the\n * universal gateway request, or `undefined` when the host is not a gateway\n * provider.\n *\n * @experimental This surface is experimental and may change.\n */\nexport function resolveGatewayProvider(\n url: string\n): ResolvedGatewayProvider | undefined {\n const parsed = parseUrl(url);\n if (parsed === undefined) return undefined;\n for (const provider of GATEWAY_PROVIDERS) {\n if (!provider.host.test(parsed.host)) continue;\n const endpoint = provider.endpoint(url);\n if (endpoint === undefined) continue;\n return {\n authHeaders: provider.authHeaders,\n endpoint,\n provider: provider.name\n };\n }\n return undefined;\n}\n\n/**\n * {@link resolveGatewayProvider}, throwing a `TypeError` that names the host\n * and the provider list when the URL belongs to no gateway provider.\n *\n * @experimental This surface is experimental and may change.\n */\nexport function requireGatewayProvider(url: string): ResolvedGatewayProvider {\n const resolved = resolveGatewayProvider(url);\n if (resolved !== undefined) return resolved;\n const host = parseUrl(url)?.host ?? url;\n throw new TypeError(\n `AI Gateway has no provider for ${host}. Requests are routed by host; the supported providers are ${GATEWAY_PROVIDER_NAMES.join(\", \")}.`\n );\n}\n\n/** The host a gateway-shaped base URL points at. */\nconst GATEWAY_HOST = \"gateway.ai.cloudflare.com\";\n\n/**\n * The provider slug of a gateway-shaped base URL —\n * `https://gateway.ai.cloudflare.com/v1/{account}/{gateway}/{slug}`. Generated\n * registries write models that way (pi-ai's Cloudflare AI Gateway catalog\n * leaves the account and gateway as literal placeholders), so the slug is\n * already in the path rather than implied by a vendor host. The account and\n * gateway segments are ignored: the binding has already chosen both.\n */\nfunction gatewayShapedSlug(url: URL): string | undefined {\n if (url.host !== GATEWAY_HOST) return undefined;\n const segments = url.pathname.split(\"/\").filter((part) => part !== \"\");\n if (segments[0] !== \"v1\" || segments.length < 4) return undefined;\n return segments[3];\n}\n\n/**\n * Whether a base URL is written in the gateway's own shape\n * (`https://gateway.ai.cloudflare.com/v1/{account}/{gateway}/{slug}`) rather\n * than as a vendor's. A generated Cloudflare registry writes models that way,\n * and the path after the slug is then the vendor's own, so a caller that\n * derives an endpoint from a base URL has to tell the two apart.\n *\n * @experimental This surface is experimental and may change.\n */\nexport function isGatewayShapedUrl(url: string): boolean {\n return parseUrl(url)?.host === GATEWAY_HOST;\n}\n\nfunction isGatewayProviderName(slug: string): slug is GatewayProviderName {\n return (GATEWAY_PROVIDER_NAMES as readonly string[]).includes(slug);\n}\n\n/**\n * The gateway provider slug a model's base URL belongs to. Two spellings\n * resolve, because two kinds of registry write them:\n *\n * - a vendor's own base URL (`https://api.anthropic.com` → `anthropic`), which\n * is what a provider package configured for the vendor carries;\n * - a gateway-shaped base URL\n * (`https://gateway.ai.cloudflare.com/v1/{account}/{gateway}/anthropic` →\n * `anthropic`), which is what a generated Cloudflare registry carries.\n *\n * A base URL neither shape resolves is a wiring mistake rather than a request\n * failure, so it throws a `TypeError` naming what was not recognised.\n *\n * @experimental This surface is experimental and may change.\n */\nexport function gatewaySlugForBaseUrl(baseUrl: string): GatewayProviderName {\n const url = parseUrl(baseUrl);\n const shaped = url === undefined ? undefined : gatewayShapedSlug(url);\n if (shaped !== undefined) {\n if (isGatewayProviderName(shaped)) return shaped;\n throw new TypeError(\n `AI Gateway has no provider \"${shaped}\" (from ${baseUrl}). The supported providers are ${GATEWAY_PROVIDER_NAMES.join(\", \")}.`\n );\n }\n const provider = gatewayProviderForHost(baseUrl);\n if (provider !== undefined) return provider.name;\n throw new TypeError(\n `AI Gateway has no provider for ${url?.host ?? baseUrl}. Requests are routed by the model's base URL; the supported providers are ${GATEWAY_PROVIDER_NAMES.join(\", \")}.`\n );\n}\n","/**\n * Where a Cloudflare catalog model departs from strict OpenAI chat\n * completions, and how. Every entry is backed by a live capture from the\n * conformance probes (`research/40-*.json`, `41-*.json`); the default for an\n * unknown id is strict OpenAI, so a new conformant model needs no code here.\n *\n * Framework-neutral: both the AI SDK and the pi-ai providers consult this.\n */\n\n/** A request feature that had to be changed or dropped for a model. */\nexport interface CompatWarning {\n feature: string;\n message: string;\n}\n\nexport interface ChatCompletionsQuirks {\n /** Which field carries the output-token cap. OpenAI's current models reject `max_tokens`. */\n maxTokensField: \"max_tokens\" | \"max_completion_tokens\";\n /**\n * How reasoning can be turned off. `chat-template` sends\n * `chat_template_kwargs.enable_thinking = false` (vLLM); `unsupported` drops\n * the request with a warning because the model keeps reasoning regardless.\n */\n reasoningOff: \"chat-template\" | \"unsupported\";\n /**\n * Which `reasoning_effort` levels the model accepts. `openai` is the full\n * set (`minimal` … `xhigh`); `basic` is `low | medium | high`, everything\n * else clamped.\n */\n reasoningEffortLevels: \"openai\" | \"basic\";\n /** Whether `chat_template_kwargs` is accepted at all. */\n chatTemplateKwargs: \"supported\" | \"unsupported\";\n /** Whether `response_format: json_schema` is accepted at all. */\n jsonSchema: \"supported\" | \"unsupported\";\n /** Whether the OpenAI-only `strict` flag belongs on the json_schema envelope. */\n jsonSchemaStrict: boolean;\n /**\n * `tool_choice: \"required\"`. `named-fallback` rewrites it to the single\n * named tool when there is exactly one (glm-4.7-flash answers 400 to\n * `required`, a gateway serialization bug), and drops it otherwise.\n */\n toolChoiceRequired: \"supported\" | \"named-fallback\";\n /** Whether image parts may reference a URL, or must carry inline bytes. */\n imageUrls: \"any\" | \"data-only\";\n /** Whether replayed assistant reasoning (`reasoning_content`) is accepted. */\n reasoningReplay: \"reasoning_content\" | \"drop\";\n /**\n * Whether a `user` turn may directly follow a `tool` turn. Mistral rejects\n * it (\"Unexpected role 'user' after role 'tool'\"), so an empty assistant\n * turn is inserted between them.\n */\n requiresAssistantAfterToolResult: boolean;\n /**\n * What the model accepts as a tool-call id. `alnum-9` is Mistral's rule:\n * exactly nine `[A-Za-z0-9]` characters, anything else is a 400.\n */\n toolCallIds: \"any\" | \"alnum-9\";\n /** A suffix the model echoes on its own id that callers never asked for. */\n modelEchoSuffix: string | undefined;\n /** Whether a replayed assistant turn may carry `content: null`. */\n nullAssistantContent: \"allowed\" | \"empty-string\";\n /**\n * Where the answer lands in a stream once reasoning has been turned off.\n * `reasoning` means the model's streaming parser mislabels the whole answer\n * as reasoning (its non-streaming body is fine), so the normalizer moves\n * those deltas back into `content`.\n */\n reasoningOffStreamLabel: \"content\" | \"reasoning\";\n}\n\nconst STRICT_OPENAI: ChatCompletionsQuirks = {\n chatTemplateKwargs: \"unsupported\",\n imageUrls: \"any\",\n jsonSchema: \"supported\",\n jsonSchemaStrict: false,\n maxTokensField: \"max_tokens\",\n modelEchoSuffix: undefined,\n nullAssistantContent: \"allowed\",\n reasoningEffortLevels: \"basic\",\n reasoningOff: \"unsupported\",\n reasoningOffStreamLabel: \"content\",\n reasoningReplay: \"drop\",\n requiresAssistantAfterToolResult: false,\n toolCallIds: \"any\",\n toolChoiceRequired: \"supported\"\n};\n\n/** Workers AI's vLLM front end: what every `@cf/` model has in common. */\nconst WORKERS_AI: ChatCompletionsQuirks = {\n ...STRICT_OPENAI,\n chatTemplateKwargs: \"supported\",\n imageUrls: \"data-only\",\n nullAssistantContent: \"empty-string\",\n reasoningOff: \"chat-template\",\n reasoningReplay: \"reasoning_content\"\n};\n\n/**\n * Longest-prefix overrides. Keep each one evidence-backed (the capture that\n * proves it is named in the comment) and delete it when the platform fixes\n * the deviation.\n */\nconst OVERRIDES: [prefix: string, quirks: Partial<ChatCompletionsQuirks>][] = [\n // 40-demos-...-E1: `tool_choice: \"required\"` + tools → 400 pydantic parse error.\n [\"@cf/zai-org/glm-4.7-flash\", { toolChoiceRequired: \"named-fallback\" }],\n // 40-demos-kimi-k3-G3 / 40-matt-kimi-k2.7-code-G_ctk: enable_thinking=false\n // leaves reasoning on; nothing turns it off.\n [\"@cf/moonshotai/\", { reasoningOff: \"unsupported\" }],\n // 40-demos-gpt-oss-120b-G3: same.\n [\"@cf/openai/\", { reasoningOff: \"unsupported\" }],\n // 40-demos-...-F1/F2/G3/J1: \"chat_template is not supported for Mistral\n // tokenizers\", \"Unexpected role 'user' after role 'tool'\".\n // 40-matt-mistral-small-3.1-24b-instruct-J: \"Tool call id was call_1 but\n // must be a-z, A-Z, 0-9, with a length of 9.\"\n [\n \"@cf/mistralai/\",\n {\n chatTemplateKwargs: \"unsupported\",\n jsonSchema: \"unsupported\",\n reasoningOff: \"unsupported\",\n requiresAssistantAfterToolResult: true,\n toolCallIds: \"alnum-9\"\n }\n ],\n // 40-demos-gemma-4-26b-a4b-it-A: echoes \"@cf/google/gemma-4-26b-a4b-it-external\".\n [\"@cf/google/\", { modelEchoSuffix: \"-external\" }],\n // 41-matt-nemotron-3-120b-a12b-K_emoji / S_usage_s: with enable_thinking=false\n // every streamed token arrives as `delta.reasoning` and `content` stays\n // empty, while the non-streaming body (A0, 40-...-G_ctk) puts the same\n // answer in `content` with `reasoning: null`.\n [\"@cf/nvidia/nemotron-\", { reasoningOffStreamLabel: \"reasoning\" }]\n];\n\n/** The quirks for a catalog id: base profile plus the longest matching override. */\nexport function quirksFor(modelId: string): ChatCompletionsQuirks {\n const base = modelId.startsWith(\"@cf/\") ? WORKERS_AI : STRICT_OPENAI;\n let best: [string, Partial<ChatCompletionsQuirks>] | undefined;\n for (const entry of OVERRIDES) {\n if (\n modelId.startsWith(entry[0]) &&\n (best === undefined || entry[0].length > best[0].length)\n ) {\n best = entry;\n }\n }\n return best === undefined ? base : { ...base, ...best[1] };\n}\n\n/** Whether an id is a Workers AI model rather than a third-party catalog model. */\nexport function isWorkersAI(modelId: string): boolean {\n return modelId.startsWith(\"@cf/\");\n}\n","/**\n * Rewrites a strict OpenAI chat-completions request body into what a given\n * catalog model accepts. Frameworks build the strict body from their own\n * prompt types; everything Cloudflare- or vendor-specific happens here, once.\n *\n * The rewrite never throws: a feature the model cannot take is dropped and\n * reported as a {@link CompatWarning}.\n */\n\nimport { type CompatWarning, quirksFor } from \"./quirks\";\n\nexport interface PreparedRequest {\n body: Record<string, unknown>;\n warnings: CompatWarning[];\n /**\n * Whether the body turns the model's reasoning off through the chat\n * template. The stream normalizer needs this for models whose streaming\n * parser mislabels the answer once thinking is off.\n */\n reasoningOff: boolean;\n}\n\ntype Message = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction clampEffort(effort: string): string {\n if (effort === \"minimal\") return \"low\";\n if (effort === \"xhigh\") return \"high\";\n return effort;\n}\n\n/** Drops URL image parts (keeps inline data URLs) from a user message. */\nfunction stripImageUrls(message: Message, warnings: CompatWarning[]): Message {\n if (!Array.isArray(message.content)) return message;\n let dropped = 0;\n const content = message.content.filter((part) => {\n if (!isRecord(part) || part.type !== \"image_url\") return true;\n const image = isRecord(part.image_url) ? part.image_url : undefined;\n const url = typeof image?.url === \"string\" ? image.url : \"\";\n if (url.startsWith(\"data:\")) return true;\n dropped += 1;\n return false;\n });\n if (dropped > 0) {\n warnings.push({\n feature: \"image-url\",\n message: `Workers AI models need image bytes; ${dropped} image URL${dropped === 1 ? \" was\" : \"s were\"} dropped.`\n });\n }\n return { ...message, content };\n}\n\n/** Nine `[A-Za-z0-9]` characters: what Mistral accepts as a tool-call id. */\nconst CONFORMANT_TOOL_CALL_ID = /^[0-9A-Za-z]{9}$/;\n\nconst TOOL_CALL_ID_ALPHABET =\n \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n\n/**\n * A deterministic nine-character id for an original id: the same conversation\n * replayed twice produces the same ids, so a provider cache or a log stays\n * comparable. `salt` is bumped only to break a collision.\n */\nfunction hashedToolCallId(original: string, salt: number): string {\n let state = (0x811c9dc5 ^ salt) >>> 0;\n for (let index = 0; index < original.length; index += 1) {\n state = Math.imul(state ^ original.charCodeAt(index), 0x01000193) >>> 0;\n }\n let id = \"\";\n for (let index = 0; index < 9; index += 1) {\n state = Math.imul(state ^ (state >>> 15), 0x01000193) >>> 0;\n id += TOOL_CALL_ID_ALPHABET[state % TOOL_CALL_ID_ALPHABET.length];\n }\n return id;\n}\n\n/** Every tool-call id a message set mentions, in the order it mentions them. */\nfunction toolCallIdsIn(messages: unknown[]): string[] {\n const ids: string[] = [];\n const seen = new Set<string>();\n const add = (value: unknown) => {\n if (typeof value !== \"string\" || seen.has(value)) return;\n seen.add(value);\n ids.push(value);\n };\n for (const message of messages) {\n if (!isRecord(message)) continue;\n if (Array.isArray(message.tool_calls)) {\n for (const call of message.tool_calls) {\n if (isRecord(call)) add(call.id);\n }\n }\n add(message.tool_call_id);\n }\n return ids;\n}\n\n/**\n * Plans the rewrite: which ids have to change, and to what. Ids that already\n * conform are kept exactly as they are — including as reserved values, so a\n * rewritten id can never collide with one.\n */\nfunction planToolCallIds(messages: unknown[]): Map<string, string> {\n const plan = new Map<string, string>();\n const ids = toolCallIdsIn(messages);\n const taken = new Set(ids.filter((id) => CONFORMANT_TOOL_CALL_ID.test(id)));\n for (const id of ids) {\n if (taken.has(id)) continue;\n let replacement = hashedToolCallId(id, 0);\n for (let salt = 1; taken.has(replacement) && salt <= 64; salt += 1) {\n replacement = hashedToolCallId(id, salt);\n }\n taken.add(replacement);\n plan.set(id, replacement);\n }\n return plan;\n}\n\n/** Applies the plan to an assistant `tool_calls` turn or a `tool` result. */\nfunction rewriteToolCallIds(\n message: Message,\n plan: Map<string, string>\n): Message {\n let rewritten = message;\n if (Array.isArray(rewritten.tool_calls)) {\n rewritten = {\n ...rewritten,\n tool_calls: rewritten.tool_calls.map((call) => {\n if (!isRecord(call) || typeof call.id !== \"string\") return call;\n const replacement = plan.get(call.id);\n return replacement === undefined ? call : { ...call, id: replacement };\n })\n };\n }\n if (typeof rewritten.tool_call_id === \"string\") {\n const replacement = plan.get(rewritten.tool_call_id);\n if (replacement !== undefined) {\n rewritten = { ...rewritten, tool_call_id: replacement };\n }\n }\n return rewritten;\n}\n\n/**\n * Applies the model's quirks to a strict OpenAI chat-completions body.\n *\n * Conventions the strict body follows, which this function translates:\n * - `max_tokens` is the cap; it becomes `max_completion_tokens` where needed.\n * - `reasoning_effort: null` means \"turn reasoning off\".\n * - Replayed assistant reasoning sits in `reasoning_content`.\n * - `response_format.json_schema` is the OpenAI `{ name, schema }` envelope.\n * - `chat_template_kwargs` may be present; it is only meaningful on Workers AI.\n */\nexport function prepareChatCompletionsRequest(\n input: Record<string, unknown>,\n modelId: string\n): PreparedRequest {\n const quirks = quirksFor(modelId);\n const warnings: CompatWarning[] = [];\n const body: Record<string, unknown> = { ...input };\n\n // Output-token cap.\n if (\n quirks.maxTokensField === \"max_completion_tokens\" &&\n \"max_tokens\" in body\n ) {\n body.max_completion_tokens = body.max_tokens;\n delete body.max_tokens;\n }\n\n // Reasoning.\n if (\"reasoning_effort\" in body) {\n const effort = body.reasoning_effort;\n if (effort === null) {\n delete body.reasoning_effort;\n if (quirks.reasoningOff === \"chat-template\") {\n body.chat_template_kwargs = {\n ...(isRecord(body.chat_template_kwargs)\n ? body.chat_template_kwargs\n : {}),\n enable_thinking: false\n };\n } else {\n warnings.push({\n feature: \"reasoning-off\",\n message: `Reasoning cannot be turned off on ${modelId}; the request was sent with the model's default effort.`\n });\n }\n } else if (\n typeof effort === \"string\" &&\n quirks.reasoningEffortLevels === \"basic\"\n ) {\n body.reasoning_effort = clampEffort(effort);\n }\n }\n if (\n \"chat_template_kwargs\" in body &&\n quirks.chatTemplateKwargs === \"unsupported\"\n ) {\n delete body.chat_template_kwargs;\n warnings.push({\n feature: \"chat-template-kwargs\",\n message: `${modelId} does not take chat_template_kwargs; they were dropped.`\n });\n }\n\n // Structured output.\n if (isRecord(body.response_format)) {\n if (quirks.jsonSchema === \"unsupported\") {\n delete body.response_format;\n warnings.push({\n feature: \"response-format\",\n message: `${modelId} does not support response_format; the request was sent without it.`\n });\n } else if (\n body.response_format.type === \"json_schema\" &&\n isRecord(body.response_format.json_schema)\n ) {\n const { strict: _strict, ...envelope } = body.response_format.json_schema;\n body.response_format = {\n ...body.response_format,\n json_schema: quirks.jsonSchemaStrict\n ? { ...envelope, strict: true }\n : envelope\n };\n }\n }\n\n // Tools.\n if (\n body.tool_choice === \"required\" &&\n quirks.toolChoiceRequired === \"named-fallback\"\n ) {\n const tools = Array.isArray(body.tools) ? body.tools : [];\n const only =\n tools.length === 1 && isRecord(tools[0]) ? tools[0] : undefined;\n const name =\n only !== undefined &&\n isRecord(only.function) &&\n typeof only.function.name === \"string\"\n ? only.function.name\n : undefined;\n if (name !== undefined) {\n body.tool_choice = { function: { name }, type: \"function\" };\n } else {\n delete body.tool_choice;\n warnings.push({\n feature: \"tool-choice-required\",\n message: `${modelId} rejects tool_choice \"required\"; the model was left free to choose.`\n });\n }\n }\n\n // Messages.\n if (Array.isArray(body.messages)) {\n // Two passes: the ids are planned over the whole conversation first, so an\n // assistant turn and the tool result answering it are rewritten to the\n // same value however far apart they sit.\n const toolCallIds =\n quirks.toolCallIds === \"alnum-9\"\n ? planToolCallIds(body.messages)\n : new Map<string, string>();\n if (toolCallIds.size > 0) {\n warnings.push({\n feature: \"tool-call-id\",\n message: `${modelId} needs 9-character alphanumeric tool-call ids; ${toolCallIds.size} id${toolCallIds.size === 1 ? \" was\" : \"s were\"} rewritten.`\n });\n }\n const messages: Message[] = [];\n let previousRole: unknown;\n for (const entry of body.messages) {\n if (!isRecord(entry)) continue;\n let message: Message = entry;\n if (toolCallIds.size > 0) {\n message = rewriteToolCallIds(message, toolCallIds);\n }\n if (message.role === \"user\" && quirks.imageUrls === \"data-only\") {\n message = stripImageUrls(message, warnings);\n }\n if (\n message.role === \"assistant\" &&\n message.content === null &&\n quirks.nullAssistantContent === \"empty-string\"\n ) {\n // 41-demos-gpt-oss-120b-O_replay_null: a replayed assistant turn with\n // `content: null` is a 400 on Workers AI; `\"\"` is accepted everywhere.\n message = { ...message, content: \"\" };\n }\n if (message.role === \"assistant\" && \"reasoning_content\" in message) {\n if (quirks.reasoningReplay === \"drop\") {\n const { reasoning_content: _reasoning, ...rest } = message;\n message = rest;\n warnings.push({\n feature: \"assistant-reasoning\",\n message: `${modelId} has no field for replayed reasoning; the assistant reasoning was dropped.`\n });\n }\n }\n if (\n quirks.requiresAssistantAfterToolResult &&\n previousRole === \"tool\" &&\n message.role === \"user\"\n ) {\n messages.push({ content: \"\", role: \"assistant\" });\n }\n messages.push(message);\n previousRole = message.role;\n }\n body.messages = messages;\n }\n\n const reasoningOff =\n isRecord(body.chat_template_kwargs) &&\n body.chat_template_kwargs.enable_thinking === false;\n return { body, reasoningOff, warnings };\n}\n","/**\n * Normalizes a chat-completions response body from the run path into the\n * strict OpenAI `chat.completion` shape, so framework parsers never see\n * Workers AI's native envelope or its field spellings.\n */\n\nimport { quirksFor } from \"./quirks\";\n\ntype Record_ = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is Record_ {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\n/** Native `{ name, arguments: object }` → OpenAI `{ id, type, function }`. */\nexport function normalizeToolCall(\n entry: unknown,\n index: number\n): Record_ | undefined {\n if (!isRecord(entry)) return undefined;\n const fn = isRecord(entry.function) ? entry.function : undefined;\n const name =\n typeof fn?.name === \"string\"\n ? fn.name\n : typeof entry.name === \"string\"\n ? entry.name\n : undefined;\n if (name === undefined) return undefined;\n const rawArguments =\n fn !== undefined && \"arguments\" in fn ? fn.arguments : entry.arguments;\n const args =\n typeof rawArguments === \"string\"\n ? rawArguments\n : rawArguments === undefined || rawArguments === null\n ? \"{}\"\n : JSON.stringify(rawArguments);\n return {\n ...(typeof entry.index === \"number\" ? { index: entry.index } : { index }),\n ...(typeof entry.id === \"string\" ? { id: entry.id } : {}),\n function: { arguments: args, name },\n type: \"function\",\n ...(entry.extra_content !== undefined\n ? { extra_content: entry.extra_content }\n : {})\n };\n}\n\n/** Text as the model produced it; structured-output models may return an object. */\nfunction contentText(value: unknown): string | null {\n if (typeof value === \"string\") return value;\n if (value === null || value === undefined) return null;\n return JSON.stringify(value);\n}\n\nfunction stripEchoSuffix(model: unknown, modelId: string): unknown {\n const suffix = quirksFor(modelId).modelEchoSuffix;\n if (typeof model !== \"string\" || suffix === undefined) return model;\n return model.endsWith(suffix) ? model.slice(0, -suffix.length) : model;\n}\n\n/** Puts reasoning under `reasoning_content` whichever spelling the model used. */\nfunction normalizeMessage(message: Record_): Record_ {\n const out: Record_ = { ...message };\n const reasoning =\n typeof out.reasoning_content === \"string\" && out.reasoning_content !== \"\"\n ? out.reasoning_content\n : typeof out.reasoning === \"string\" && out.reasoning !== \"\"\n ? out.reasoning\n : undefined;\n delete out.reasoning;\n if (reasoning !== undefined) out.reasoning_content = reasoning;\n else delete out.reasoning_content;\n if (\"content\" in out) out.content = contentText(out.content);\n if (Array.isArray(out.tool_calls)) {\n const calls = out.tool_calls\n .map((call, index) => normalizeToolCall(call, index))\n .filter((call): call is Record_ => call !== undefined);\n if (calls.length > 0) out.tool_calls = calls;\n else delete out.tool_calls;\n }\n return out;\n}\n\n/**\n * Returns the body in the strict `chat.completion` shape. Already-OpenAI\n * bodies come back with their reasoning spelling unified and the echoed model\n * id cleaned; native Workers AI `{ response, tool_calls, usage }` bodies are\n * lifted into `choices[0]`.\n */\nexport function normalizeChatCompletion(\n body: unknown,\n modelId: string\n): Record_ {\n if (!isRecord(body)) return { choices: [] };\n if (Array.isArray(body.choices)) {\n const choices = body.choices.map((choice) => {\n if (!isRecord(choice)) return choice;\n const message = isRecord(choice.message)\n ? normalizeMessage(choice.message)\n : choice.message;\n const hasToolCalls =\n isRecord(message) &&\n Array.isArray(message.tool_calls) &&\n message.tool_calls.length > 0;\n return {\n ...choice,\n message,\n finish_reason:\n choice.finish_reason ?? (hasToolCalls ? \"tool_calls\" : \"stop\")\n };\n });\n return { ...body, choices, model: stripEchoSuffix(body.model, modelId) };\n }\n if (\"response\" in body || \"tool_calls\" in body) {\n const toolCalls = Array.isArray(body.tool_calls)\n ? body.tool_calls\n .map((call, index) => normalizeToolCall(call, index))\n .filter((call): call is Record_ => call !== undefined)\n : [];\n const { response, tool_calls: _toolCalls, usage, ...rest } = body;\n return {\n ...rest,\n choices: [\n {\n finish_reason:\n typeof body.finish_reason === \"string\"\n ? body.finish_reason\n : toolCalls.length > 0\n ? \"tool_calls\"\n : \"stop\",\n index: 0,\n message: {\n content: contentText(response),\n role: \"assistant\",\n ...(toolCalls.length > 0 ? { tool_calls: toolCalls } : {})\n }\n }\n ],\n model: stripEchoSuffix(body.model, modelId),\n ...(usage !== undefined ? { usage } : {})\n };\n }\n return body;\n}\n","/**\n * Normalizes a chat-completions SSE stream from the run path into strict\n * OpenAI `chat.completion.chunk` events.\n *\n * Every Workers AI model streams the same three-part hybrid (live captures,\n * all families): OpenAI-shaped delta chunks that each carry a per-delta\n * `usage`, then a `choices: []` heartbeat, then a native\n * `{ response: \"\", usage }` tail with the cumulative usage, then `[DONE]`.\n * Some models also emit native `{ response: \"<text>\" }` deltas or top-level\n * `tool_calls`. After this transform a consumer sees only:\n *\n * - delta chunks without per-delta usage and with reasoning under\n * `reasoning_content`;\n * - at most one final `choices: []` chunk carrying the cumulative usage\n * (the OpenAI `stream_options.include_usage` shape);\n * - a `finish_reason` on some chunk before the end, synthesized when the\n * model finished cleanly without sending one;\n * - `[DONE]`.\n *\n * Input and output are SSE `data` payloads (strings), so it slots between the\n * SSE decoder and either framework's OpenAI chunk parser.\n */\n\nimport { isWorkersAI, quirksFor } from \"./quirks\";\nimport { normalizeToolCall } from \"./response\";\n\ntype Record_ = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is Record_ {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nconst NOISE_FIELDS = [\n \"p\",\n \"token_ids\",\n \"prompt_token_ids\",\n \"kv_transfer_params\"\n];\n\n/** Fields the run path adds to every chunk that mean nothing to a consumer. */\nfunction stripNoise(chunk: Record_): Record_ {\n const out = { ...chunk };\n for (const key of NOISE_FIELDS) delete out[key];\n return out;\n}\n\nfunction stripEchoSuffix(chunk: Record_, modelId: string): Record_ {\n const suffix = quirksFor(modelId).modelEchoSuffix;\n if (suffix === undefined || typeof chunk.model !== \"string\") return chunk;\n return chunk.model.endsWith(suffix)\n ? { ...chunk, model: chunk.model.slice(0, -suffix.length) }\n : chunk;\n}\n\nfunction normalizeDelta(delta: Record_, relabelReasoning: boolean): Record_ {\n const out: Record_ = { ...delta };\n const reasoning =\n typeof out.reasoning_content === \"string\" && out.reasoning_content !== \"\"\n ? out.reasoning_content\n : typeof out.reasoning === \"string\" && out.reasoning !== \"\"\n ? out.reasoning\n : undefined;\n delete out.reasoning;\n delete out.reasoning_content;\n if (reasoning !== undefined) {\n if (relabelReasoning) {\n // Reasoning is off, so these tokens are the answer (nemotron-3).\n out.content =\n (typeof out.content === \"string\" ? out.content : \"\") + reasoning;\n } else {\n out.reasoning_content = reasoning;\n }\n }\n if (Array.isArray(out.tool_calls)) {\n out.tool_calls = out.tool_calls.map((call, index) => {\n // Fragments and the null finalizer pass through untouched; only a\n // native complete call needs lifting into the OpenAI shape. A native\n // call names its tool at the top level, where no OpenAI fragment does,\n // and its arguments may be an object or already a string.\n if (!isRecord(call)) return call;\n const fn = isRecord(call.function) ? call.function : undefined;\n const args = fn !== undefined ? fn.arguments : call.arguments;\n const native = fn === undefined && typeof call.name === \"string\";\n return native || isRecord(args)\n ? (normalizeToolCall(call, index) ?? call)\n : call;\n });\n }\n return out;\n}\n\nexport interface StreamNormalizationOptions {\n /** Whether the request turned reasoning off (`PreparedRequest.reasoningOff`). */\n reasoningOff?: boolean;\n}\n\n/**\n * The transform. Backpressure is preserved: nothing is buffered except the\n * single pending usage chunk, which must wait for the tail.\n */\nexport function normalizeChatCompletionsStream(\n modelId: string,\n options: StreamNormalizationOptions = {}\n): TransformStream<string, string> {\n const quirks = quirksFor(modelId);\n const relabelReasoning =\n options.reasoningOff === true &&\n quirks.reasoningOffStreamLabel === \"reasoning\";\n let id: string | undefined;\n let model: string | undefined;\n let created: number | undefined;\n let sawFinishReason = false;\n let sawContent = false;\n let sawToolCalls = false;\n let sawDone = false;\n let finalUsage: unknown;\n let finalUsageTemplate: Record_ | undefined;\n // Workers AI stamps a per-delta usage on every content chunk and sends the\n // cumulative figure in its native tail; other vendors only ever put usage on\n // the final `choices: []` chunk, so theirs is left alone.\n const perDeltaUsage = isWorkersAI(modelId);\n\n const envelope = (extra: Record_): Record_ => ({\n ...(id !== undefined ? { id } : {}),\n object: \"chat.completion.chunk\",\n ...(created !== undefined ? { created } : {}),\n ...(model !== undefined ? { model } : {}),\n ...extra\n });\n\n const emit = (\n controller: TransformStreamDefaultController<string>,\n chunk: Record_\n ) => {\n controller.enqueue(JSON.stringify(chunk));\n };\n\n const emitTail = (controller: TransformStreamDefaultController<string>) => {\n if (!sawFinishReason && sawDone && (sawContent || sawToolCalls)) {\n emit(\n controller,\n envelope({\n choices: [\n {\n delta: {},\n finish_reason: sawToolCalls ? \"tool_calls\" : \"stop\",\n index: 0\n }\n ]\n })\n );\n sawFinishReason = true;\n }\n if (finalUsage !== undefined) {\n emit(controller, {\n ...(finalUsageTemplate ?? envelope({})),\n choices: [],\n usage: finalUsage\n });\n finalUsage = undefined;\n }\n if (sawDone) controller.enqueue(\"[DONE]\");\n };\n\n return new TransformStream<string, string>({\n flush(controller) {\n emitTail(controller);\n },\n transform(data, controller) {\n if (data === \"\") return;\n if (data === \"[DONE]\") {\n // Everything after the tail is emitted at flush, once.\n sawDone = true;\n return;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(data);\n } catch {\n // A malformed event is dropped rather than failing the stream.\n return;\n }\n if (!isRecord(parsed)) return;\n const chunk = stripEchoSuffix(stripNoise(parsed), modelId);\n\n if (typeof chunk.id === \"string\") id ??= chunk.id;\n if (typeof chunk.model === \"string\") model ??= chunk.model;\n if (typeof chunk.created === \"number\") created ??= chunk.created;\n\n // An error payload passes through untouched for the consumer to surface;\n // it also ends the generation, so no finish reason is synthesized after it.\n if (isRecord(chunk.error)) {\n sawFinishReason = true;\n controller.enqueue(JSON.stringify(chunk));\n return;\n }\n\n if (Array.isArray(chunk.choices)) {\n if (chunk.choices.length === 0) {\n // Heartbeat, or OpenAI's own final usage chunk: hold the usage\n // until the end so exactly one usage chunk is emitted.\n if (isRecord(chunk.usage)) {\n finalUsage = chunk.usage;\n finalUsageTemplate = { ...chunk, usage: undefined };\n delete finalUsageTemplate.usage;\n }\n return;\n }\n const choices = chunk.choices.map((choice) => {\n if (!isRecord(choice)) return choice;\n if (typeof choice.finish_reason === \"string\") sawFinishReason = true;\n const delta = isRecord(choice.delta)\n ? normalizeDelta(choice.delta, relabelReasoning)\n : choice.delta;\n if (isRecord(delta)) {\n if (typeof delta.content === \"string\" && delta.content !== \"\")\n sawContent = true;\n if (typeof delta.reasoning_content === \"string\") sawContent = true;\n if (Array.isArray(delta.tool_calls) && delta.tool_calls.length > 0)\n sawToolCalls = true;\n }\n if (!perDeltaUsage) return { ...choice, delta };\n const { usage: _perDeltaUsage, ...rest } = choice;\n return { ...rest, delta };\n });\n if (perDeltaUsage) {\n // The cumulative figure comes with the native tail.\n const { usage: _usage, ...rest } = chunk;\n emit(controller, { ...rest, choices });\n } else {\n emit(controller, { ...chunk, choices });\n }\n return;\n }\n\n // Native Workers AI events.\n if (\"response\" in chunk || \"tool_calls\" in chunk) {\n const text = chunk.response;\n const hasText = typeof text === \"string\" && text !== \"\";\n const calls = Array.isArray(chunk.tool_calls)\n ? chunk.tool_calls\n .map((call, index) => normalizeToolCall(call, index))\n .filter((call): call is Record_ => call !== undefined)\n : [];\n if (hasText || calls.length > 0) {\n if (hasText) sawContent = true;\n if (calls.length > 0) sawToolCalls = true;\n emit(\n controller,\n envelope({\n choices: [\n {\n delta: {\n ...(hasText ? { content: text } : {}),\n ...(calls.length > 0 ? { tool_calls: calls } : {})\n },\n finish_reason: null,\n index: 0\n }\n ]\n })\n );\n }\n if (isRecord(chunk.usage)) {\n // The native tail: cumulative usage for the whole stream.\n finalUsage = chunk.usage;\n finalUsageTemplate = undefined;\n }\n if (typeof chunk.finish_reason === \"string\") {\n sawFinishReason = true;\n emit(\n controller,\n envelope({\n choices: [\n { delta: {}, finish_reason: chunk.finish_reason, index: 0 }\n ]\n })\n );\n }\n }\n }\n });\n}\n","/**\n * Decodes a `text/event-stream` byte stream into the `data` payload of each\n * event, as a `TransformStream` so the whole pipeline keeps backpressure and\n * nothing is ever buffered beyond the current event.\n *\n * Handles all three line terminators the SSE spec allows (LF, CRLF and a bare\n * CR), multi-line `data:` fields (joined with `\\n`, per the spec), comment\n * lines (`:` prefixed), and non-`data` fields (`event:`, `id:`, `retry:`),\n * which are ignored. A trailing event that the server never terminated with a\n * blank line is still flushed.\n *\n * @experimental This surface is experimental and may change.\n */\nexport function sseDataStream(): TransformStream<Uint8Array, string> {\n const decoder = new TextDecoder();\n let buffer = \"\";\n let data: string[] = [];\n\n const flushEvent = (controller: TransformStreamDefaultController<string>) => {\n if (data.length === 0) return;\n controller.enqueue(data.join(\"\\n\"));\n data = [];\n };\n\n const consumeLine = (\n line: string,\n controller: TransformStreamDefaultController<string>\n ) => {\n if (line === \"\") {\n flushEvent(controller);\n return;\n }\n if (line.startsWith(\":\")) return;\n const colon = line.indexOf(\":\");\n const field = colon === -1 ? line : line.slice(0, colon);\n if (field !== \"data\") return;\n let value = colon === -1 ? \"\" : line.slice(colon + 1);\n if (value.startsWith(\" \")) value = value.slice(1);\n data.push(value);\n };\n\n /**\n * Consumes whole lines out of the buffer. A buffer ending in a lone `\\r` is\n * held back while more bytes may arrive, because the next byte decides\n * whether that `\\r` was a CRLF pair or a bare-CR terminator.\n */\n const drain = (\n controller: TransformStreamDefaultController<string>,\n final: boolean\n ) => {\n for (;;) {\n const match = /\\r\\n|[\\r\\n]/.exec(buffer);\n if (match === null) break;\n const end = match.index + match[0].length;\n if (!final && match[0] === \"\\r\" && end === buffer.length) break;\n consumeLine(buffer.slice(0, match.index), controller);\n buffer = buffer.slice(end);\n }\n };\n\n return new TransformStream<Uint8Array, string>({\n flush(controller) {\n buffer += decoder.decode();\n drain(controller, true);\n // A server that closed without a final blank line still owes us the\n // last event; emit whatever is left rather than dropping it.\n if (buffer !== \"\") {\n consumeLine(buffer, controller);\n buffer = \"\";\n }\n flushEvent(controller);\n },\n transform(chunk, controller) {\n buffer += decoder.decode(chunk, { stream: true });\n drain(controller, false);\n }\n });\n}\n","/**\n * Workers AI text-to-image requests and answers, shared by both framework\n * modules.\n *\n * Two things about this catalog are easy to get wrong in one module and right\n * in the other, so neither module owns them: the flux-1 models take a two-key\n * subset of the common input shape, and the media type of a JSON answer is in\n * the bytes rather than in the model name (flux-1-schnell answers JPEG while\n * every other model here answers PNG).\n *\n * @experimental This surface is experimental and may change.\n */\n\nimport type { CompatWarning } from \"./chat-completions\";\n\n/**\n * `flux-1-schnell` takes `{ prompt, steps }` and nothing else — no size, no\n * seed, no guidance. Sending those anyway would be silently ignored, so they\n * come back as warnings instead.\n *\n * @see https://developers.cloudflare.com/workers-ai/models/flux-1-schnell/\n */\nconst PROMPT_AND_STEPS_ONLY = /^@cf\\/black-forest-labs\\/flux-1/;\n\n/**\n * The generation knobs Workers AI text-to-image models share, in this\n * package's own spelling. Each module maps its own call options onto them.\n *\n * @experimental This surface is experimental and may change.\n */\nexport interface ImageGenerationSettings {\n width?: number;\n height?: number;\n /** Diffusion steps. Sent as `num_steps`, or `steps` on the flux-1 models. */\n steps?: number;\n /** Classifier-free guidance scale. */\n guidance?: number;\n /** How strongly img2img transforms the input image, between 0 and 1. */\n strength?: number;\n negativePrompt?: string;\n seed?: number;\n /**\n * Whether the caller has a source image to attach. The field it goes in\n * differs per module, so only the warning is decided here.\n */\n sourceImage?: boolean;\n /** Whether the caller has an inpainting mask to attach. */\n mask?: boolean;\n}\n\n/**\n * A run-path image body with the knobs the model could not take reported.\n *\n * @experimental This surface is experimental and may change.\n */\nexport interface BuiltImageRequest {\n input: Record<string, unknown>;\n warnings: CompatWarning[];\n /**\n * The model takes `{ prompt, steps }` only, so the caller must not attach a\n * source image or a mask either.\n */\n minimal: boolean;\n}\n\n/**\n * Builds the run-path body for a text-to-image model: `prompt`, `width`,\n * `height`, `num_steps`, `guidance`, `strength`, `negative_prompt` and `seed`,\n * or the flux-1 two-key subset with a warning for everything dropped.\n *\n * @experimental This surface is experimental and may change.\n */\nexport function buildImageInput(\n modelId: string,\n prompt: string,\n settings: ImageGenerationSettings\n): BuiltImageRequest {\n const warnings: CompatWarning[] = [];\n const input: Record<string, unknown> = { prompt };\n\n if (PROMPT_AND_STEPS_ONLY.test(modelId)) {\n if (settings.steps !== undefined) input.steps = settings.steps;\n for (const [feature, value] of [\n [\"size\", settings.width ?? settings.height],\n [\"seed\", settings.seed],\n [\"guidance\", settings.guidance],\n [\"negativePrompt\", settings.negativePrompt],\n [\"strength\", settings.strength],\n [\"files\", settings.sourceImage === true ? true : undefined],\n [\"mask\", settings.mask === true ? true : undefined]\n ] as const) {\n if (value !== undefined) {\n warnings.push({\n feature,\n message: `${modelId} takes only a prompt and steps.`\n });\n }\n }\n return { input, minimal: true, warnings };\n }\n\n if (settings.width !== undefined) input.width = settings.width;\n if (settings.height !== undefined) input.height = settings.height;\n if (settings.seed !== undefined) input.seed = settings.seed;\n if (settings.steps !== undefined) input.num_steps = settings.steps;\n if (settings.guidance !== undefined) input.guidance = settings.guidance;\n if (settings.strength !== undefined) input.strength = settings.strength;\n if (settings.negativePrompt !== undefined) {\n input.negative_prompt = settings.negativePrompt;\n }\n return { input, minimal: false, warnings };\n}\n\nconst JPEG_PREFIX = \"/9j/\";\nconst PNG_PREFIX = \"iVBORw0KGgo\";\nconst WEBP_PREFIX = \"UklGR\";\nconst GIF_PREFIX = \"R0lGOD\";\n\n/**\n * Sniffs an image media type from the head of its base64. The bytes decide,\n * never the model name: `flux-1-schnell` answers JPEG where every other model\n * in this catalog answers PNG.\n *\n * @experimental This surface is experimental and may change.\n */\nexport function imageMediaTypeOf(base64: string): string {\n if (base64.startsWith(JPEG_PREFIX)) return \"image/jpeg\";\n if (base64.startsWith(PNG_PREFIX)) return \"image/png\";\n if (base64.startsWith(WEBP_PREFIX)) return \"image/webp\";\n if (base64.startsWith(GIF_PREFIX)) return \"image/gif\";\n return \"image/png\";\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  s as LifecycleCapability,
3
3
  x as Connection
4
- } from "./capability-runner-O5VbQzqg.js";
4
+ } from "./capability-runner-BiVUtjqC.js";
5
5
  //#region src/state/index.d.ts
6
6
  /**
7
7
  * Source of a state change: `"server"` for host code (e.g. `setState()`), or
@@ -13,8 +13,6 @@ type StateChangeSource = Connection | "server";
13
13
  * Options for a {@link State} capability. Validation and the post-change hook
14
14
  * stay on the host, which passes them in; the capability owns storage and
15
15
  * change ordering.
16
- *
17
- * @experimental The API surface may change before stabilizing.
18
16
  */
19
17
  interface StateOptions<T = unknown> {
20
18
  /** Seeded on first access when nothing is stored. `undefined` seeds nothing. */
@@ -40,8 +38,6 @@ interface StateOptions<T = unknown> {
40
38
  * validated persistence. Install the instance with `Lifecycle.use()`. State
41
39
  * validation and the post-change notification hook stay on the host, which
42
40
  * injects both callbacks. This capability never touches connections.
43
- *
44
- * @experimental The API surface may change before stabilizing.
45
41
  */
46
42
  declare class State<T = unknown> extends LifecycleCapability {
47
43
  #private;
@@ -75,4 +71,4 @@ declare class State<T = unknown> extends LifecycleCapability {
75
71
  }
76
72
  //#endregion
77
73
  export { StateChangeSource as n, StateOptions as r, State as t };
78
- //# sourceMappingURL=index-D0A5tbWu.d.ts.map
74
+ //# sourceMappingURL=index-BEL3ZV-s.d.ts.map
@@ -2,12 +2,12 @@ import {
2
2
  r as CapabilityWebSocketUpgradeContext,
3
3
  s as LifecycleCapability,
4
4
  x as Connection
5
- } from "./capability-runner-O5VbQzqg.js";
5
+ } from "./capability-runner-BiVUtjqC.js";
6
6
  import {
7
7
  i as WebSocketsOptions,
8
8
  n as WebSocketHandlers,
9
9
  r as WebSocketMessage
10
- } from "./options-pwTNq9z6.js";
10
+ } from "./options-CiIsJHXR.js";
11
11
 
12
12
  //#region src/websockets/websockets.d.ts
13
13
  /**
@@ -53,8 +53,6 @@ import {
53
53
  * and client updates are validated and applied; the state owner
54
54
  * broadcasts changes with `broadcastState()`. Per-connection readonly
55
55
  * and no-protocol flags live here as well, for every host.
56
- *
57
- * @experimental The API surface may change before stabilizing.
58
56
  */
59
57
  declare class WebSockets extends LifecycleCapability {
60
58
  #private;
@@ -197,4 +195,4 @@ export {
197
195
  registerInternalConnectionKeys as r,
198
196
  CF_NO_PROTOCOL_KEY as t
199
197
  };
200
- //# sourceMappingURL=index-Ib_4dwOo.d.ts.map
198
+ //# sourceMappingURL=index-CBt8oRJt.d.ts.map
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  S as ConnectionContext,
4
4
  T as WSMessage,
5
5
  x as Connection
6
- } from "./capability-runner-O5VbQzqg.js";
6
+ } from "./capability-runner-BiVUtjqC.js";
7
7
  import {
8
8
  a as isDurableObjectStorageReset,
9
9
  c as isPlatformTransientError,
@@ -11,7 +11,7 @@ import {
11
11
  r as isDurableObjectMemoryLimitReset,
12
12
  t as RetryOptions
13
13
  } from "./retries-CV6AkXmQ.js";
14
- import { i as __DO_NOT_USE_WILL_BREAK__agentContext } from "./current-agent-C07C5o5Y.js";
14
+ import { i as __DO_NOT_USE_WILL_BREAK__agentContext } from "./current-agent-CKgT5d1O.js";
15
15
  import {
16
16
  $ as ChatCapableAgentClass,
17
17
  A as getCurrentAgent,
@@ -86,7 +86,7 @@ import {
86
86
  xn as DynamicAgentStub,
87
87
  y as FiberStatus,
88
88
  z as AgentToolEventState
89
- } from "./agent-routing-Bhdbvf7s.js";
89
+ } from "./agent-routing-BMvWTFEp.js";
90
90
  import {
91
91
  a as EmailSendBinding,
92
92
  d as createHeaderBasedEmailResolver,
@@ -104,7 +104,7 @@ import {
104
104
  a as ScheduleCriteria,
105
105
  i as Schedule,
106
106
  o as ScheduleOptions
107
- } from "./scheduler-CrFCnv_J.js";
107
+ } from "./scheduler-BCLESHSC.js";
108
108
  import { i as QueueItem } from "./types-BA4anrjI.js";
109
109
  import {
110
110
  n as callable,
package/dist/index.js CHANGED
@@ -7,9 +7,9 @@ import { MessageType } from "./types.js";
7
7
  import { createHeaderBasedEmailResolver } from "./email.js";
8
8
  import { n as withInvocationScope } from "./cloudflare-Dzvc7V2N.js";
9
9
  import { SUB_PREFIX, buildAgentPath, buildAgentUrl, getSubAgentByName, parseSubAgentPath, routeSubAgentRequest } from "./sub-routing.js";
10
- import { a as routeAgentEmail, i as getCurrentAgent, n as DEFAULT_AGENT_STATIC_OPTIONS, r as StreamingResponse, t as Agent } from "./src-DgCbZtIR.js";
10
+ import { a as routeAgentEmail, i as getCurrentAgent, n as DEFAULT_AGENT_STATIC_OPTIONS, r as StreamingResponse, t as Agent } from "./src-CQxJFv4l.js";
11
11
  import { isDurableObjectCodeUpdateReset, isDurableObjectMemoryLimitReset, isDurableObjectStorageReset, isPlatformTransientError } from "./retries.js";
12
12
  import { SqlError } from "./sql-error.js";
13
- import { i as normalizeServerId, n as MCP_SERVER_ID_MAX_LENGTH } from "./client-1tEQ1Oqz.js";
13
+ import { i as normalizeServerId, n as MCP_SERVER_ID_MAX_LENGTH } from "./client-BnYbNT3z.js";
14
14
  import { DurableObjectOAuthClientProvider } from "./mcp/client/do-oauth-client-provider.js";
15
15
  export { AGENT_TOOL_MILESTONE_PART, AGENT_TOOL_PROGRESS_PART, Agent, DEFAULT_AGENT_STATIC_OPTIONS, DurableObjectOAuthClientProvider, MCP_SERVER_ID_MAX_LENGTH, MessageType, SUB_PREFIX, SqlError, StreamingResponse, __DO_NOT_USE_WILL_BREAK__agentContext, withInvocationScope as __DO_NOT_USE_WILL_BREAK__withInvocationScope, buildAgentPath, buildAgentUrl, callable, camelCaseToKebabCase, createHeaderBasedEmailResolver, getAgentByName, getCurrentAgent, getSubAgentByName, isDurableObjectCodeUpdateReset, isDurableObjectMemoryLimitReset, isDurableObjectStorageReset, isPlatformTransientError, normalizeServerId, parseSubAgentPath, routeAgentEmail, routeAgentRequest, routeSubAgentRequest, unstable_callable };
@@ -0,0 +1,20 @@
1
+ import { d as MAX_WEB_FETCH_URL_LENGTH } from "./tool-CxKsvxjm.js";
2
+ import { z } from "zod";
3
+ //#region src/web/fetch/tools/input-schema.ts
4
+ /**
5
+ * The zod input schema shared by the AI SDK and TanStack AI adapters. Kept
6
+ * out of the core so the pi adapter, which uses TypeBox, does not need zod.
7
+ * Internal — not an entry point.
8
+ */
9
+ /** The model's input schema. */
10
+ function webFetchInputSchema() {
11
+ return z.object({
12
+ url: z.string().min(1).max(MAX_WEB_FETCH_URL_LENGTH).describe("The http(s) URL to read."),
13
+ offset: z.number().int().min(0).optional().describe("Character offset into the content, to continue a long page from the previous result's offset. Default 0."),
14
+ format: z.enum(["auto", "raw"]).optional().describe("\"auto\" (default) converts to the most readable form; \"raw\" returns the body as served.")
15
+ });
16
+ }
17
+ //#endregion
18
+ export { webFetchInputSchema as t };
19
+
20
+ //# sourceMappingURL=input-schema-BQykTEp_.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-schema-BQykTEp_.js","names":[],"sources":["../src/web/fetch/tools/input-schema.ts"],"sourcesContent":["/**\n * The zod input schema shared by the AI SDK and TanStack AI adapters. Kept\n * out of the core so the pi adapter, which uses TypeBox, does not need zod.\n * Internal — not an entry point.\n */\nimport { z } from \"zod\";\nimport { MAX_WEB_FETCH_URL_LENGTH, type WebFetchToolInput } from \"../contract\";\n\n/** The model's input schema. */\nexport function webFetchInputSchema() {\n return z.object({\n url: z\n .string()\n .min(1)\n .max(MAX_WEB_FETCH_URL_LENGTH)\n .describe(\"The http(s) URL to read.\"),\n offset: z\n .number()\n .int()\n .min(0)\n .optional()\n .describe(\n \"Character offset into the content, to continue a long page from the previous result's offset. Default 0.\"\n ),\n format: z\n .enum([\"auto\", \"raw\"])\n .optional()\n .describe(\n '\"auto\" (default) converts to the most readable form; \"raw\" returns the body as served.'\n )\n }) satisfies z.ZodType<WebFetchToolInput>;\n}\n"],"mappings":";;;;;;;;;AASA,SAAgB,sBAAsB;CACpC,OAAO,EAAE,OAAO;EACd,KAAK,EACF,OAAO,CAAC,CACR,IAAI,CAAC,CAAC,CACN,IAAI,wBAAwB,CAAC,CAC7B,SAAS,0BAA0B;EACtC,QAAQ,EACL,OAAO,CAAC,CACR,IAAI,CAAC,CACL,IAAI,CAAC,CAAC,CACN,SAAS,CAAC,CACV,SACC,0GACF;EACF,QAAQ,EACL,KAAK,CAAC,QAAQ,KAAK,CAAC,CAAC,CACrB,SAAS,CAAC,CACV,SACC,4FACF;CACJ,CAAC;AACH"}
@@ -1,6 +1,6 @@
1
- import { u as MAX_WEB_SEARCH_QUERY_LENGTH } from "./tool-3PA8xjB_.js";
1
+ import { u as MAX_WEB_SEARCH_QUERY_LENGTH } from "./tool-VF0qiO7q.js";
2
2
  import { z } from "zod";
3
- //#region src/websearch/tools/input-schema.ts
3
+ //#region src/web/search/tools/input-schema.ts
4
4
  /**
5
5
  * The zod input schema shared by the AI SDK and TanStack AI adapters. Kept
6
6
  * out of the core so the pi adapter, which uses TypeBox, does not need zod.
@@ -20,4 +20,4 @@ function webSearchInputSchema(maxLimit) {
20
20
  //#endregion
21
21
  export { webSearchInputSchema as t };
22
22
 
23
- //# sourceMappingURL=input-schema-DNrpTu49.js.map
23
+ //# sourceMappingURL=input-schema-xBofjBKC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-schema-xBofjBKC.js","names":[],"sources":["../src/web/search/tools/input-schema.ts"],"sourcesContent":["/**\n * The zod input schema shared by the AI SDK and TanStack AI adapters. Kept\n * out of the core so the pi adapter, which uses TypeBox, does not need zod.\n * Internal — not an entry point.\n */\nimport { z } from \"zod\";\nimport {\n MAX_WEB_SEARCH_QUERY_LENGTH,\n type WebSearchToolInput\n} from \"../contract\";\n\n/**\n * The model's input schema. The description tells the model the host's\n * `limit`; a larger value is not rejected (which would cost a validation\n * round trip) but capped by the core.\n */\nexport function webSearchInputSchema(maxLimit: number) {\n return z.object({\n query: z\n .string()\n .min(1)\n .max(MAX_WEB_SEARCH_QUERY_LENGTH)\n .describe(\"What to search for.\"),\n limit: z\n .number()\n .int()\n .min(1)\n .optional()\n .describe(`How many results to return (at most ${maxLimit}).`)\n }) satisfies z.ZodType<WebSearchToolInput>;\n}\n"],"mappings":";;;;;;;;;;;;;AAgBA,SAAgB,qBAAqB,UAAkB;CACrD,OAAO,EAAE,OAAO;EACd,OAAO,EACJ,OAAO,CAAC,CACR,IAAI,CAAC,CAAC,CACN,IAAI,2BAA2B,CAAC,CAChC,SAAS,qBAAqB;EACjC,OAAO,EACJ,OAAO,CAAC,CACR,IAAI,CAAC,CACL,IAAI,CAAC,CAAC,CACN,SAAS,CAAC,CACV,SAAS,uCAAuC,SAAS,GAAG;CACjE,CAAC;AACH"}
@@ -2,7 +2,7 @@ import {
2
2
  i as __DO_NOT_USE_WILL_BREAK__agentContext,
3
3
  n as CurrentAgentContext,
4
4
  t as AgentContextStore
5
- } from "./current-agent-C07C5o5Y.js";
5
+ } from "./current-agent-CKgT5d1O.js";
6
6
  import { t as AgentEmail } from "./internal_context-BlxFEWfn.js";
7
7
  export {
8
8
  type AgentContextStore,
@@ -24,16 +24,16 @@ import {
24
24
  w as ConnectionState,
25
25
  x as Connection,
26
26
  y as LifecycleJobPushOptions
27
- } from "../capability-runner-O5VbQzqg.js";
27
+ } from "../capability-runner-BiVUtjqC.js";
28
28
  import {
29
29
  n as LifecycleOptions,
30
30
  t as Lifecycle
31
- } from "../durable-object-lifecycle-DRqp475_.js";
31
+ } from "../durable-object-lifecycle-DOI_bzCH.js";
32
32
  import {
33
33
  a as getCurrentAgent,
34
34
  n as CurrentAgentContext,
35
35
  r as LifecycleObject
36
- } from "../current-agent-C07C5o5Y.js";
36
+ } from "../current-agent-CKgT5d1O.js";
37
37
  export {
38
38
  type CapabilityRequestContext,
39
39
  type CapabilityStartContext,
@@ -1,4 +1,4 @@
1
1
  import { n as getCurrentAgent } from "../current-agent-DhoDkSnH.js";
2
- import { t as LifecycleCapability } from "../capability-B4WbF81e.js";
3
- import { t as Lifecycle } from "../lifecycle-CFu6OV03.js";
2
+ import { t as LifecycleCapability } from "../capability-DBAKc6UZ.js";
3
+ import { t as Lifecycle } from "../lifecycle-DGorpAmA.js";
4
4
  export { Lifecycle, LifecycleCapability, getCurrentAgent };
@@ -1,7 +1,7 @@
1
1
  import { i as runWithoutCurrentAgent, r as runInLifecycleHostContext } from "./current-agent-DhoDkSnH.js";
2
2
  import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-DZBYAB34.js";
3
3
  import { t as _classPrivateMethodInitSpec } from "./classPrivateMethodInitSpec-qMjJ6sHQ.js";
4
- import { n as bindLifecycleCapability, r as lifecycleCapabilityId, t as LifecycleCapability } from "./capability-B4WbF81e.js";
4
+ import { n as bindLifecycleCapability, r as lifecycleCapabilityId, t as LifecycleCapability } from "./capability-DBAKc6UZ.js";
5
5
  import { n as publishDiagnosticsEvent } from "./diagnostics-BzvaX2UT.js";
6
6
  import { isDurableObjectCodeUpdateReset, isDurableObjectMemoryLimitReset, isPlatformFailure, tryN } from "./retries.js";
7
7
  import { SqlError } from "./sql-error.js";
@@ -826,8 +826,6 @@ function setLifecycleEventSink(lifecycle, sink) {
826
826
  * Construct this as an instance field on a class that directly extends
827
827
  * `DurableObject`, then call {@link Lifecycle.installHandlers}
828
828
  * from that class's constructor.
829
- *
830
- * @experimental The API surface may change before stabilizing.
831
829
  */
832
830
  /** The dispatch hooks a catch-all can monopolize; uniqueness is per hook. */
833
831
  const CATCH_ALL_HOOKS = ["onRequest", "onWebSocketUpgrade"];
@@ -1340,4 +1338,4 @@ async function _resolveJobDispatch(owner) {
1340
1338
  //#endregion
1341
1339
  export { abortWithoutAlarmRetry as a, setLifecycleRouteTransport as i, setLifecycleEventSink as n, setLifecycleHostInvoker as r, Lifecycle as t };
1342
1340
 
1343
- //# sourceMappingURL=lifecycle-CFu6OV03.js.map
1341
+ //# sourceMappingURL=lifecycle-DGorpAmA.js.map