agents 0.28.1 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/dist/{agent-routing-BMvWTFEp.d.ts → agent-routing-CDbpVjYq.d.ts} +7 -8
  2. package/dist/agent-routing.d.ts +1 -1
  3. package/dist/agent-tool-types.d.ts +1 -1
  4. package/dist/{agent-tools-ohoewW-B.d.ts → agent-tools-C8DH8Yii.d.ts} +2 -2
  5. package/dist/agent-tools.d.ts +1 -1
  6. package/dist/{ai-ahruGw7e.d.ts → ai-iXw0uOGj.d.ts} +3 -3
  7. package/dist/{ai-sdk-C2iTAwUd.js → ai-sdk-DRPh2rRa.js} +185 -125
  8. package/dist/ai-sdk-DRPh2rRa.js.map +1 -0
  9. package/dist/browser/ai.d.ts +1 -1
  10. package/dist/browser/ai.js +2 -2
  11. package/dist/browser/index.d.ts +8 -8
  12. package/dist/browser/index.js +3 -3
  13. package/dist/browser/tools/ai-sdk.d.ts +2 -2
  14. package/dist/browser/tools/ai-sdk.js +1 -1
  15. package/dist/browser/tools/pi.d.ts +7 -3
  16. package/dist/browser/tools/pi.js +9 -5
  17. package/dist/browser/tools/pi.js.map +1 -1
  18. package/dist/browser/tools/tanstack-ai.d.ts +2 -2
  19. package/dist/browser/tools/tanstack-ai.js +1 -1
  20. package/dist/{browser-CEdNlsaD.js → browser-DccPw_wW.js} +130 -79
  21. package/dist/browser-DccPw_wW.js.map +1 -0
  22. package/dist/{browser-D30VlpcA.d.ts → browser-DlXhSAdf.d.ts} +41 -37
  23. package/dist/{browser-tool-4iomavs_.js → browser-tool-B1mhifin.js} +3 -3
  24. package/dist/{browser-tool-4iomavs_.js.map → browser-tool-B1mhifin.js.map} +1 -1
  25. package/dist/{browser-tool-vtrPOV8e.d.ts → browser-tool-Cxjk5sgG.d.ts} +2 -2
  26. package/dist/chat/index.d.ts +143 -71
  27. package/dist/chat/index.js +269 -110
  28. package/dist/chat/index.js.map +1 -1
  29. package/dist/chat-sdk/index.d.ts +1 -1
  30. package/dist/chat-sdk/index.js +1 -1
  31. package/dist/cli.js +53 -52
  32. package/dist/{client-Bp-JwL3p.d.ts → client-C27CtRZr.d.ts} +2 -2
  33. package/dist/client.d.ts +1 -1
  34. package/dist/{connector-DEXzVoaY.d.ts → connector-20DJ6p4k.d.ts} +2 -2
  35. package/dist/{connector-CtZylXdk.js → connector-DAXBOIIi.js} +2 -2
  36. package/dist/{connector-CtZylXdk.js.map → connector-DAXBOIIi.js.map} +1 -1
  37. package/dist/experimental/channels/web/index.js +1 -1
  38. package/dist/harness/container/index.js +1 -1
  39. package/dist/harness/container/index.js.map +1 -1
  40. package/dist/harness/opencode/index.js +1 -1
  41. package/dist/harness/pi/index.d.ts +70 -40
  42. package/dist/harness/pi/index.js +266 -330
  43. package/dist/harness/pi/index.js.map +1 -1
  44. package/dist/{images-C4hiIexM.js → images-xaDv2Fqe.js} +636 -168
  45. package/dist/images-xaDv2Fqe.js.map +1 -0
  46. package/dist/index-DCxk3OSJ.d.ts +378 -0
  47. package/dist/{index-kbSUIer3.d.ts → index-iv9FTXX9.d.ts} +80 -112
  48. package/dist/index.d.ts +1 -1
  49. package/dist/index.js +1 -1
  50. package/dist/{input-schema-xBofjBKC.js → input-schema-B0Etuo-o.js} +2 -2
  51. package/dist/{input-schema-xBofjBKC.js.map → input-schema-B0Etuo-o.js.map} +1 -1
  52. package/dist/lifecycle/index.js +1 -1
  53. package/dist/{lifecycle-DGorpAmA.js → lifecycle-v1rKHV2C.js} +67 -19
  54. package/dist/lifecycle-v1rKHV2C.js.map +1 -0
  55. package/dist/mcp/client/index.d.ts +1 -1
  56. package/dist/mcp/index.d.ts +1 -1
  57. package/dist/mcp/index.js +1 -1
  58. package/dist/models/ai-sdk/index.d.ts +29 -352
  59. package/dist/models/ai-sdk/index.js +1 -1
  60. package/dist/models/opencode/index.d.ts +25 -13
  61. package/dist/models/opencode/index.js +16 -11
  62. package/dist/models/opencode/index.js.map +1 -1
  63. package/dist/models/pi-ai/index.d.ts +13 -14
  64. package/dist/models/pi-ai/index.js +87 -34
  65. package/dist/models/pi-ai/index.js.map +1 -1
  66. package/dist/react.d.ts +2 -2
  67. package/dist/routing/index.d.ts +1 -1
  68. package/dist/serializable.d.ts +1 -1
  69. package/dist/{session-store-DoPY12xM.d.ts → session-store-_IK6dV-w.d.ts} +14 -2
  70. package/dist/{session-store-Do4xkDcf.js → session-store-yvwq1f9x.js} +55 -2
  71. package/dist/session-store-yvwq1f9x.js.map +1 -0
  72. package/dist/{settings-BjAiPd6Z.js → settings-Dk2il2Hf.js} +4 -1
  73. package/dist/settings-Dk2il2Hf.js.map +1 -0
  74. package/dist/skills/index.d.ts +22 -28
  75. package/dist/skills/index.js +183 -143
  76. package/dist/skills/index.js.map +1 -1
  77. package/dist/{src-CQxJFv4l.js → src-DfLzdwlK.js} +3 -3
  78. package/dist/src-DfLzdwlK.js.map +1 -0
  79. package/dist/sub-routing.d.ts +1 -1
  80. package/dist/{tool-VF0qiO7q.js → tool-DkT_DJBm.js} +2 -2
  81. package/dist/tool-DkT_DJBm.js.map +1 -0
  82. package/dist/transport-CPh7YGiw.d.ts +623 -0
  83. package/dist/voice/index.d.ts +1 -1
  84. package/dist/web/fetch/tools/pi.d.ts +10 -6
  85. package/dist/web/fetch/tools/pi.js +12 -8
  86. package/dist/web/fetch/tools/pi.js.map +1 -1
  87. package/dist/web/search/index.js +1 -1
  88. package/dist/web/search/tools/ai-sdk.js +2 -2
  89. package/dist/web/search/tools/pi.d.ts +10 -6
  90. package/dist/web/search/tools/pi.js +13 -9
  91. package/dist/web/search/tools/pi.js.map +1 -1
  92. package/dist/web/search/tools/tanstack-ai.js +2 -2
  93. package/dist/websockets/index.js +1 -1
  94. package/dist/{websockets-C3zy8YR0.js → websockets-CyoeosdO.js} +2 -2
  95. package/dist/{websockets-C3zy8YR0.js.map → websockets-CyoeosdO.js.map} +1 -1
  96. package/dist/workflow-types.d.ts +1 -1
  97. package/dist/workflows.d.ts +1 -1
  98. package/dist/workflows.js +1 -1
  99. package/docs/browse-the-web.md +1 -1
  100. package/docs/chat-agents.md +19 -18
  101. package/docs/harnesses/pi.md +101 -38
  102. package/docs/lifecycle.md +7 -1
  103. package/docs/models-pi-ai.md +66 -20
  104. package/docs/models.md +197 -172
  105. package/package.json +12 -7
  106. package/dist/ai-sdk-C2iTAwUd.js.map +0 -1
  107. package/dist/browser-CEdNlsaD.js.map +0 -1
  108. package/dist/images-C4hiIexM.js.map +0 -1
  109. package/dist/lifecycle-DGorpAmA.js.map +0 -1
  110. package/dist/session-store-Do4xkDcf.js.map +0 -1
  111. package/dist/settings-BjAiPd6Z.js.map +0 -1
  112. package/dist/settings-DnD__xuE.d.ts +0 -349
  113. package/dist/src-CQxJFv4l.js.map +0 -1
  114. package/dist/tool-VF0qiO7q.js.map +0 -1
  115. package/dist/transport-DCyarnwm.d.ts +0 -200
@@ -4492,13 +4492,12 @@ interface AgentStaticOptions {
4492
4492
  * reset (the isolate exceeded its 128 MB limit) before the alarm-boundary
4493
4493
  * circuit breaker stops the platform's auto-retry loop and seals the looping
4494
4494
  * recovery work (#1825). Default: 3. Set to `0` to seal on the first such
4495
- * reset. This is the universal backstop for the case where the in-DO recovery
4496
- * budgets (`chatRecovery.maxOomRetries` / `maxRecoveryWork`) can't engage
4497
- * because the OOM bypasses them — e.g. it is thrown before the budget code
4498
- * runs, or its own writes also OOM. The boundary handler runs at the outermost
4499
- * alarm frame, after the heavy turn has unwound and GC has reclaimed its
4500
- * footprint, so its small seal/purge writes can land where mid-turn writes
4501
- * could not.
4495
+ * reset. The strike counter is written after the reset, so it only advances
4496
+ * when that isolate's storage still accepts writes, for example when the
4497
+ * reset error came from another isolate such as D1. A Durable Object's own
4498
+ * memory-limit reset rejects every later storage call in that invocation, so
4499
+ * chat recovery does not rely on this counter: it counts each interrupted
4500
+ * attempt in the next isolate (`chatRecovery.maxInterruptedAttempts`, #2613).
4502
4501
  */
4503
4502
  maxAlarmMemoryLimitStrikes?: number;
4504
4503
  }
@@ -7046,4 +7045,4 @@ export {
7046
7045
  AgentToolEventState as z,
7047
7046
  MCPClientOAuthResult as zt
7048
7047
  };
7049
- //# sourceMappingURL=agent-routing-BMvWTFEp.d.ts.map
7048
+ //# sourceMappingURL=agent-routing-CDbpVjYq.d.ts.map
@@ -4,7 +4,7 @@ import {
4
4
  n as AgentOptions,
5
5
  r as RoutingRetryOptions,
6
6
  t as AgentGetOptions
7
- } from "./agent-routing-BMvWTFEp.js";
7
+ } from "./agent-routing-CDbpVjYq.js";
8
8
  export {
9
9
  AgentGetOptions,
10
10
  AgentOptions,
@@ -27,7 +27,7 @@ import {
27
27
  rt as RunAgentToolResult,
28
28
  tt as DetachedRunAgentToolResult,
29
29
  z as AgentToolEventState
30
- } from "./agent-routing-BMvWTFEp.js";
30
+ } from "./agent-routing-CDbpVjYq.js";
31
31
  export {
32
32
  AGENT_TOOL_MILESTONE_PART,
33
33
  AGENT_TOOL_PROGRESS_PART,
@@ -4,7 +4,7 @@ import {
4
4
  W as AgentToolProgress,
5
5
  Z as AgentToolStoredChunk,
6
6
  z as AgentToolEventState
7
- } from "./agent-routing-BMvWTFEp.js";
7
+ } from "./agent-routing-CDbpVjYq.js";
8
8
 
9
9
  //#region src/chat/agent-tools.d.ts
10
10
  type AgentToolProgressEmitResult = "emitted" | "coalesced" | "inactive";
@@ -144,4 +144,4 @@ export {
144
144
  interceptAgentToolBroadcast as s,
145
145
  AgentToolBroadcastHooks as t
146
146
  };
147
- //# sourceMappingURL=agent-tools-ohoewW-B.d.ts.map
147
+ //# sourceMappingURL=agent-tools-C8DH8Yii.d.ts.map
@@ -20,7 +20,7 @@ import {
20
20
  rt as RunAgentToolResult,
21
21
  tt as DetachedRunAgentToolResult,
22
22
  z as AgentToolEventState
23
- } from "./agent-routing-BMvWTFEp.js";
23
+ } from "./agent-routing-CDbpVjYq.js";
24
24
  import { FlexibleSchema, InferSchema, Tool } from "ai";
25
25
 
26
26
  //#region src/agent-tools.d.ts
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  d as BrowserBinding,
3
3
  n as BrowserSessionStore
4
- } from "./session-store-DoPY12xM.js";
4
+ } from "./session-store-_IK6dV-w.js";
5
5
  import {
6
6
  l as QuickActionBinding,
7
7
  r as BrowserConnectorSessionOptions,
8
8
  t as BrowserConnector,
9
9
  u as QuickActionCommonOptions
10
- } from "./connector-DEXzVoaY.js";
10
+ } from "./connector-20DJ6p4k.js";
11
11
  import { ToolSet } from "ai";
12
12
  import { CodemodeRuntimeHandle } from "@cloudflare/codemode";
13
13
 
@@ -236,4 +236,4 @@ export {
236
236
  createQuickActionTools as s,
237
237
  BrowserRuntime as t
238
238
  };
239
- //# sourceMappingURL=ai-ahruGw7e.d.ts.map
239
+ //# sourceMappingURL=ai-iXw0uOGj.d.ts.map
@@ -1,52 +1,40 @@
1
1
  import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-DZBYAB34.js";
2
2
  import { t as _classPrivateMethodInitSpec } from "./classPrivateMethodInitSpec-qMjJ6sHQ.js";
3
- import { C as isDynamicRouteId, S as isRetryableStatus, _ as isGatewayErrorEnvelope, a as normalizeChatCompletion, b as classifyStatus, f as createTransport$1, g as headersToObject, h as errorFromResponse$1, i as normalizeChatCompletionsStream, m as errorFromGatewayEnvelope$1, n as imageMediaTypeOf, o as prepareChatCompletionsRequest, p as definedHeaders, r as sseDataStream, t as buildImageInput, u as requireGatewayProvider, v as unwrapEnvelope$1, w as isRunPathLanguageModelId, x as isAbortError, y as CloudflareAIError$1 } from "./images-C4hiIexM.js";
4
- import { a as parseModelOptions, i as mergeModelOptions, n as PROVIDER_OPTIONS_KEY, o as resolveOptions, r as gatewayLayerOf } from "./settings-BjAiPd6Z.js";
3
+ import { C as isCatalogModelId, S as isRetryableStatus, T as isRunPathLanguageModelId, _ as isGatewayErrorEnvelope, a as normalizeChatCompletion, b as classifyStatus, f as createTransport$1, g as headersToObject, h as errorFromResponse$1, i as normalizeChatCompletionsStream, m as errorFromGatewayEnvelope$1, n as imageMediaTypeOf, o as prepareChatCompletionsRequest, p as definedHeaders, r as sseDataStream, t as buildImageInput, u as requireGatewayProvider, v as unwrapEnvelope$1, w as isDynamicRouteId, x as isAbortError, y as CloudflareAIError$1 } from "./images-xaDv2Fqe.js";
4
+ import { a as parseModelOptions, i as mergeModelOptions, n as PROVIDER_OPTIONS_KEY, o as resolveOptions, r as gatewayLayerOf } from "./settings-Dk2il2Hf.js";
5
5
  import { APICallError, TooManyEmbeddingValuesForCallError } from "@ai-sdk/provider";
6
6
  //#region src/models/ai-sdk/errors.ts
7
- /** The provider packages worth naming when someone passes a vendor id. */
8
- const VENDOR_PACKAGES = {
9
- anthropic: {
10
- call: "anthropic(\"claude-opus-4-8\")",
11
- package: "@ai-sdk/anthropic"
12
- },
13
- google: {
14
- call: "google(\"gemini-3-flash\")",
15
- package: "@ai-sdk/google"
16
- },
17
- openai: {
18
- call: "openai(\"gpt-5-mini\")",
19
- package: "@ai-sdk/openai"
20
- }
21
- };
22
7
  /**
23
- * The one error a bad model id produces. Workers AI ids are the only strings
24
- * this provider knows; a third-party model is a model object built by that
25
- * vendor's own provider package.
8
+ * The error a string that names no model this provider runs produces.
9
+ * Language models take Workers AI ids, AI Gateway catalog ids and dynamic
10
+ * routes; the modality methods take Workers AI ids only.
26
11
  */
27
- function notAWorkersAIId(modelId, accepts = "workers-ai") {
28
- const vendor = VENDOR_PACKAGES[modelId.split("/")[0] ?? ""];
29
- const advice = vendor === void 0 ? "install its AI SDK provider package and pass the model object, e.g. ai(anthropic(\"claude-opus-4-8\"))" : `install ${vendor.package} and pass the model object: ai(${vendor.call})`;
30
- return /* @__PURE__ */ new TypeError(`"${modelId}" is not a Workers AI model id. Workers AI ids start with "@cf/"${accepts === "workers-ai-or-route" ? " (and AI Gateway dynamic routes with \"dynamic/\")" : ""}, and they are the only ids this provider takes: a third-party model goes through its own provider and is only routed by AI Gateway — ${advice}.`);
12
+ function notAModelId(modelId, accepts) {
13
+ return /* @__PURE__ */ new TypeError(accepts === "language" ? `"${modelId}" is not a model id this provider knows. Use a Workers AI id ("@cf/zai-org/glm-4.7-flash"), an AI Gateway catalog id ("<author>/<model>", e.g. "openai/gpt-5.5" or "anthropic/claude-opus-4.8"), or a dynamic route ("dynamic/<route>").` : `"${modelId}" is not a Workers AI model id. The embedding, image, speech, transcription and reranking methods take Workers AI ids, which start with "@cf/".`);
31
14
  }
32
15
  /**
33
- * The gate every string that names a model passes through, wherever it enters
34
- * the module: `ai("…")`, a per-model fallback leg, or a leg read out of the
35
- * per-call `providerOptions.cloudflare` bag. One rule, one message, thrown at
36
- * the line that supplied the id rather than at the request it would have made.
16
+ * The gate for the modality methods — embedding, image, speech,
17
+ * transcription, reranking — and their fallback legs: a Workers AI id and
18
+ * nothing else. Catalog models and dynamic routes are chat models here.
37
19
  */
38
20
  function requireWorkersAIId(modelId) {
39
21
  if (isDynamicRouteId(modelId)) throw new TypeError(`"${modelId}" is an AI Gateway dynamic route, and a dynamic route is a chat model: it answers in the chat-completions shape. Use it as ai("${modelId}"); the embedding, image, speech, transcription and reranking methods take "@cf/" ids.`);
40
- if (!modelId.startsWith("@cf/")) throw notAWorkersAIId(modelId);
22
+ if (!modelId.startsWith("@cf/")) throw notAModelId(modelId, "workers-ai");
41
23
  return modelId;
42
24
  }
25
+ /** Whether a string names a language model: any of the three id kinds. */
26
+ function isLanguageModelId(modelId) {
27
+ return isRunPathLanguageModelId(modelId) || isCatalogModelId(modelId);
28
+ }
43
29
  /**
44
- * The gate for ids that name a language model: a Workers AI id, or an AI
45
- * Gateway dynamic route. Both run on `env.AI.run`; any other string is a
46
- * vendor id, which is never a string here.
30
+ * The gate every string that names a language model passes through, wherever
31
+ * it enters the module: `ai("…")`, a per-model fallback leg, or a leg read
32
+ * out of the per-call `providerOptions.cloudflare` bag. All three kinds run on
33
+ * `env.AI.run`. Thrown at the line that supplied the id rather than at the
34
+ * request it would have made.
47
35
  */
48
36
  function requireLanguageModelId(modelId) {
49
- if (!isRunPathLanguageModelId(modelId)) throw notAWorkersAIId(modelId, "workers-ai-or-route");
37
+ if (!isLanguageModelId(modelId)) throw notAModelId(modelId, "language");
50
38
  return modelId;
51
39
  }
52
40
  /**
@@ -187,7 +175,7 @@ function withoutCallFallback(options) {
187
175
  //#region src/models/ai-sdk/transport.ts
188
176
  /**
189
177
  * The typed AI SDK error for the gateway's own error envelope — a missing
190
- * gateway, an unpaid account — on the universal path.
178
+ * gateway, an unpaid account — on the provider-native path.
191
179
  */
192
180
  function errorFromGatewayEnvelope(body, context) {
193
181
  return CloudflareAIError.fromCore(errorFromGatewayEnvelope$1(body, context));
@@ -217,16 +205,16 @@ function createTransport(settings) {
217
205
  const inner = createTransport$1(settings);
218
206
  return {
219
207
  logIdFallback: (response) => inner.logIdFallback(response),
220
- async run(request) {
208
+ async native(request) {
221
209
  try {
222
- return await inner.run(request);
210
+ return await inner.native(request);
223
211
  } catch (error) {
224
212
  throw toAISDKError(error);
225
213
  }
226
214
  },
227
- async universal(request) {
215
+ async run(request) {
228
216
  try {
229
- return await inner.universal(request);
217
+ return await inner.run(request);
230
218
  } catch (error) {
231
219
  throw toAISDKError(error);
232
220
  }
@@ -1152,12 +1140,12 @@ function callHeaders(options, resolved) {
1152
1140
  * attaches to its result. Shared with the non-language models in
1153
1141
  * `models/modality.ts`.
1154
1142
  */
1155
- function cloudflareMetadata(model, resolved, response, transport, provider) {
1143
+ function cloudflareMetadata(model, gateway, response, transport, provider) {
1156
1144
  const headers = response.headers;
1157
1145
  const rawStep = headers.get("cf-aig-step");
1158
1146
  const step = rawStep === null ? NaN : Number(rawStep);
1159
1147
  const metadata = {
1160
- gateway: resolved.gateway.id,
1148
+ ...gateway === void 0 ? {} : { gateway },
1161
1149
  model,
1162
1150
  ...provider === void 0 ? {} : { provider },
1163
1151
  ...Number.isNaN(step) ? {} : { step }
@@ -1325,7 +1313,7 @@ var CloudflareLanguageModel = class {
1325
1313
  return {
1326
1314
  content: generation.content,
1327
1315
  finishReason: generation.finishReason,
1328
- providerMetadata: cloudflareMetadata(modelId, resolved, response, _classPrivateFieldGet2(_config$2, this).transport),
1316
+ providerMetadata: cloudflareMetadata(modelId, resolved.gateway.id, response, _classPrivateFieldGet2(_config$2, this).transport),
1329
1317
  request: { body: request.body },
1330
1318
  response: {
1331
1319
  headers: headersToObject(response.headers),
@@ -1345,7 +1333,7 @@ var CloudflareLanguageModel = class {
1345
1333
  return _assertClassBrand(_CloudflareLanguageModel_brand, this, _withFallback$1).call(this, call, (model) => model.doStream(legOptions), async (modelId) => {
1346
1334
  const request = buildRequest(modelId, options, resolved, true);
1347
1335
  const response = await _assertClassBrand(_CloudflareLanguageModel_brand, this, _send).call(this, modelId, request, options, resolved);
1348
- const providerMetadata = cloudflareMetadata(modelId, resolved, response, _classPrivateFieldGet2(_config$2, this).transport);
1336
+ const providerMetadata = cloudflareMetadata(modelId, resolved.gateway.id, response, _classPrivateFieldGet2(_config$2, this).transport);
1349
1337
  const contentType = response.headers.get("content-type") ?? "";
1350
1338
  const decorate = decorateStream(request.warnings, providerMetadata);
1351
1339
  let parts;
@@ -1391,6 +1379,7 @@ function _resolve$1(call) {
1391
1379
  }
1392
1380
  async function _send(modelId, request, options, resolved) {
1393
1381
  const response = await _classPrivateFieldGet2(_config$2, this).transport.run({
1382
+ format: "chat-completions",
1394
1383
  gateway: resolved.gateway,
1395
1384
  headers: callHeaders(options, resolved),
1396
1385
  input: request.body,
@@ -1464,27 +1453,24 @@ function requestUrl(input) {
1464
1453
  }
1465
1454
  /**
1466
1455
  * The body of either `fetch` call form: the `RequestInit`'s when one was
1467
- * given, else the `Request`'s own, read from a clone so the caller's object
1468
- * is neither consumed nor mutated.
1456
+ * given, else the `Request`'s own, from a clone so the caller's object is
1457
+ * neither consumed nor mutated.
1469
1458
  */
1470
- async function requestBody(input, init) {
1459
+ function requestBody(input, init) {
1471
1460
  if (init?.body !== void 0) return init.body;
1472
- if (input instanceof Request && input.body !== null) return await input.clone().text();
1461
+ if (input instanceof Request && input.body !== null) return input.clone().body;
1473
1462
  }
1474
- /**
1475
- * The vendor's body as the universal request's `query`. Only JSON travels:
1476
- * the gateway's universal request has one JSON field for the whole upstream
1477
- * body, so a multipart upload or a streamed body cannot be expressed.
1478
- */
1479
- function universalQuery(body) {
1480
- if (typeof body !== "string") {
1481
- const kind = body === null || body === void 0 ? "an empty" : body instanceof FormData ? "a FormData" : `a ${body.constructor?.name ?? typeof body}`;
1482
- throw new TypeError(`AI Gateway's universal request carries a JSON body only, and this model sent ${kind} body. File uploads and other multipart requests cannot be routed through the gateway; call the vendor directly for those.`);
1483
- }
1463
+ /** The method of either `fetch` call form. */
1464
+ function requestMethod(input, init) {
1465
+ return init?.method ?? (input instanceof Request ? input.method : "POST");
1466
+ }
1467
+ /** The vendor model id out of a JSON body, for error reporting. */
1468
+ function modelOfBody(body) {
1469
+ if (typeof body !== "string") return void 0;
1484
1470
  try {
1485
- return JSON.parse(body);
1486
- } catch (error) {
1487
- throw new TypeError(`AI Gateway's universal request carries a JSON body only, and this model sent a body that is not JSON: ${String(error)}`);
1471
+ return modelOf(JSON.parse(body));
1472
+ } catch {
1473
+ return;
1488
1474
  }
1489
1475
  }
1490
1476
  /**
@@ -1511,42 +1497,42 @@ function replayed(response, text) {
1511
1497
  });
1512
1498
  }
1513
1499
  /**
1514
- * The `fetch` a routed model is given. It never reaches the vendor: it maps
1515
- * the vendor's URL onto a gateway provider slug and endpoint, hands the body
1516
- * over untouched, and returns the gateway's answer as the vendor's own.
1500
+ * The `fetch` a routed model is given. It maps the vendor's URL onto a gateway
1501
+ * provider slug and endpoint and sends the request there unchanged, through
1502
+ * the binding; the answer is the vendor's own.
1517
1503
  */
1518
1504
  function routedFetch(context) {
1519
1505
  const routed = async (input, init) => {
1520
1506
  const route = requireGatewayProvider(requestUrl(input));
1521
- const query = universalQuery(await requestBody(input, init));
1507
+ const body = requestBody(input, init);
1522
1508
  const { resolved } = context;
1523
- const extraHeaders = {
1524
- ...resolved.headers,
1525
- ...resolved.sessionAffinity === void 0 ? {} : { "x-session-affinity": resolved.sessionAffinity }
1526
- };
1527
- const response = await context.config.transport.universal({
1509
+ const response = await context.config.transport.native({
1510
+ body,
1528
1511
  endpoint: route.endpoint,
1529
- ...Object.keys(extraHeaders).length > 0 ? { extraHeaders } : {},
1530
1512
  gateway: resolved.gateway,
1531
- headers: forwardedHeaders(init, input, route, context.vendorKey),
1513
+ headers: {
1514
+ ...forwardedHeaders(init, input, route, context.vendorKey),
1515
+ ...resolved.headers,
1516
+ ...resolved.sessionAffinity === void 0 ? {} : { "x-session-affinity": resolved.sessionAffinity }
1517
+ },
1518
+ method: requestMethod(input, init),
1532
1519
  provider: route.provider,
1533
- query,
1534
1520
  signal: init?.signal ?? (input instanceof Request ? input.signal : void 0) ?? context.signal
1535
1521
  });
1536
1522
  context.capture.provider = route.provider;
1537
1523
  context.capture.response = response;
1538
1524
  if (response.ok) return response;
1539
1525
  const text = await response.text();
1540
- let body;
1526
+ let envelope;
1541
1527
  try {
1542
- body = JSON.parse(text);
1528
+ envelope = JSON.parse(text);
1543
1529
  } catch {
1544
1530
  return replayed(response, text);
1545
1531
  }
1546
- if (!isGatewayErrorEnvelope(body)) return replayed(response, text);
1547
- throw errorFromGatewayEnvelope(body, {
1548
- model: modelOf(query) ?? route.provider,
1549
- requestBodyValues: query,
1532
+ if (!isGatewayErrorEnvelope(envelope)) return replayed(response, text);
1533
+ throw errorFromGatewayEnvelope(envelope, {
1534
+ model: modelOfBody(body) ?? route.provider,
1535
+ requestBodyValues: void 0,
1550
1536
  responseBody: text,
1551
1537
  responseHeaders: headersToObject(response.headers),
1552
1538
  status: response.status,
@@ -1742,7 +1728,7 @@ function _resolve(call) {
1742
1728
  }
1743
1729
  function _metadata(resolved, capture) {
1744
1730
  const response = capture.response ?? new Response(null);
1745
- return cloudflareMetadata(this.modelId, resolved, response, _classPrivateFieldGet2(_config$1, this).transport, capture.provider);
1731
+ return cloudflareMetadata(this.modelId, resolved.gateway.id, response, _classPrivateFieldGet2(_config$1, this).transport, capture.provider);
1746
1732
  }
1747
1733
  function _response(response, capture) {
1748
1734
  if (capture.response === void 0) return response;
@@ -1784,7 +1770,7 @@ function _workersAI(modelId) {
1784
1770
  }
1785
1771
  /**
1786
1772
  * Routes any other AI SDK v4 model the vendor built — embedding, image,
1787
- * speech, transcription — through the same universal gateway request. Only
1773
+ * speech, transcription — through the same provider-native request. Only
1788
1774
  * `fetch` is swapped; every `do…` method stays the vendor's, and its result
1789
1775
  * gains `providerMetadata.cloudflare` when the result is an object that can
1790
1776
  * carry one.
@@ -1813,13 +1799,18 @@ function routed(model, options, config) {
1813
1799
  return {
1814
1800
  ...result,
1815
1801
  ...routedWarnings(result, resolved),
1816
- providerMetadata: mergeMetadata(existing, metadataFor(result, cloudflareMetadata(String(target.modelId ?? ""), resolved, capture.response ?? new Response(null), config.transport, capture.provider)))
1802
+ providerMetadata: mergeMetadata(existing, metadataFor(result, cloudflareMetadata(String(target.modelId ?? ""), resolved.gateway.id, capture.response ?? new Response(null), config.transport, capture.provider)))
1817
1803
  };
1818
1804
  };
1819
1805
  } });
1820
1806
  }
1821
1807
  //#endregion
1822
1808
  //#region src/models/ai-sdk/models/modality.ts
1809
+ /** Whether the caller set any gateway option, the id included. */
1810
+ function gatewayConfigured(gateway) {
1811
+ const { id, ...options } = gateway;
1812
+ return id !== "default" || Object.keys(options).length > 0;
1813
+ }
1823
1814
  /** The `unsupported` warning shape, which every modality needs. */
1824
1815
  function unsupported(feature, details) {
1825
1816
  return {
@@ -1873,7 +1864,17 @@ var CloudflareModalityModel = class {
1873
1864
  const transport = _classPrivateFieldGet2(_config, this).transport;
1874
1865
  return withFallback(this.modelId, resolved.fallback, transport.url, async (modelId) => {
1875
1866
  const request = call.build(modelId);
1867
+ const direct = request.audio !== void 0;
1868
+ const sent = request.audio === void 0 ? request.input : {
1869
+ ...request.input,
1870
+ audio: {
1871
+ body: toBase64(request.audio.bytes),
1872
+ contentType: request.audio.contentType
1873
+ }
1874
+ };
1875
+ const warnings = direct && gatewayConfigured(resolved.gateway) ? [...request.warnings, unsupported("gateway", `${modelId} goes to Workers AI directly, so the gateway options do not apply.`)] : request.warnings;
1876
1876
  const response = await transport.run({
1877
+ ...request.audio === void 0 ? {} : { audio: request.audio },
1877
1878
  gateway: resolved.gateway,
1878
1879
  headers: {
1879
1880
  ...definedHeaders(call.headers),
@@ -1886,20 +1887,20 @@ var CloudflareModalityModel = class {
1886
1887
  });
1887
1888
  if (!response.ok) throw await errorFromResponse(response, {
1888
1889
  model: modelId,
1889
- requestBodyValues: request.input,
1890
+ requestBodyValues: sent,
1890
1891
  url: transport.url
1891
1892
  });
1892
1893
  const mediaType = (response.headers.get("content-type") ?? "").split(";")[0].trim().toLowerCase();
1893
- const body = await _assertClassBrand(_CloudflareModalityModel_brand, this, _decode).call(this, response, modelId, request.input, mediaType);
1894
+ const body = await _assertClassBrand(_CloudflareModalityModel_brand, this, _decode).call(this, response, modelId, sent, mediaType);
1894
1895
  const answer = {
1895
1896
  headers: headersToObject(response.headers),
1896
- input: request.input,
1897
+ input: sent,
1897
1898
  mediaType,
1898
1899
  modelId,
1899
- providerMetadata: cloudflareMetadata(modelId, resolved, response, transport),
1900
+ providerMetadata: cloudflareMetadata(modelId, direct ? void 0 : resolved.gateway.id, response, transport),
1900
1901
  timestamp: /* @__PURE__ */ new Date(),
1901
1902
  url: transport.url,
1902
- warnings: request.warnings,
1903
+ warnings,
1903
1904
  ...body
1904
1905
  };
1905
1906
  call.check?.(answer);
@@ -2270,13 +2271,13 @@ var CloudflareSpeechModel = class extends CloudflareModalityModel {
2270
2271
  */
2271
2272
  const BYTE_ARRAY_AUDIO = /* @__PURE__ */ new Set(["@cf/openai/whisper", "@cf/openai/whisper-tiny-en"]);
2272
2273
  /**
2273
- * Deepgram's recognition models declare `audio: { body: object, contentType }`.
2274
- * Every documented encoding of that shape answered `400 required properties at
2275
- * '/audio' are 'body,contentType'` on the live run path, because `body` has to
2276
- * be the audio object itself and JSON cannot carry it. Refuse early rather
2277
- * than send a body known to fail.
2274
+ * Models that declare `audio: { body, contentType }`. JSON cannot carry that
2275
+ * body (base64 and byte arrays answer `400 required properties at '/audio' are
2276
+ * 'body,contentType'`), so the audio travels as a raw body.
2278
2277
  */
2279
- const UNSUPPORTED = /* @__PURE__ */ new Set(["@cf/deepgram/nova-3", "@cf/deepgram/flux"]);
2278
+ const RAW_AUDIO = /* @__PURE__ */ new Set(["@cf/deepgram/nova-3"]);
2279
+ /** Deepgram's Flux answers `only supports websocket connections` over HTTP. */
2280
+ const WEBSOCKET_ONLY = /* @__PURE__ */ new Set(["@cf/deepgram/flux"]);
2280
2281
  function transcriptionOptions(providerOptions) {
2281
2282
  const raw = record(providerOptions?.["cloudflare"]) ?? {};
2282
2283
  const vadFilter = raw.vadFilter;
@@ -2288,10 +2289,32 @@ function transcriptionOptions(providerOptions) {
2288
2289
  ...typeof vadFilter === "boolean" ? { vadFilter } : {}
2289
2290
  };
2290
2291
  }
2291
- /** Builds the run-path body for one whisper leg. */
2292
+ /**
2293
+ * Builds the request for a raw-audio model: the audio as a raw body, and
2294
+ * `language` as a field. The whisper-only options have no equivalent there.
2295
+ */
2296
+ function buildRawAudioRequest(modelId, options, extra) {
2297
+ const warnings = [];
2298
+ for (const feature of [
2299
+ "task",
2300
+ "initialPrompt",
2301
+ "prefix",
2302
+ "vadFilter"
2303
+ ]) if (extra[feature] !== void 0) warnings.push(unsupported(feature, `${modelId} has no ${feature}.`));
2304
+ return {
2305
+ audio: {
2306
+ bytes: toBytes(options.audio),
2307
+ contentType: options.mediaType
2308
+ },
2309
+ input: extra.language === void 0 ? {} : { language: extra.language },
2310
+ warnings
2311
+ };
2312
+ }
2313
+ /** Builds the run-path body for one leg. */
2292
2314
  function buildTranscriptionRequest(modelId, options) {
2293
2315
  const warnings = [];
2294
2316
  const extra = transcriptionOptions(options.providerOptions);
2317
+ if (RAW_AUDIO.has(modelId)) return buildRawAudioRequest(modelId, options, extra);
2295
2318
  const input = BYTE_ARRAY_AUDIO.has(modelId) ? { audio: Array.from(toBytes(options.audio)) } : { audio: toBase64(options.audio) };
2296
2319
  if (extra.language !== void 0) input.language = extra.language;
2297
2320
  if (extra.task !== void 0) input.task = extra.task;
@@ -2303,6 +2326,45 @@ function buildTranscriptionRequest(modelId, options) {
2303
2326
  warnings
2304
2327
  };
2305
2328
  }
2329
+ /** Reads a timed `{ text|word, start, end }` entry as a segment. */
2330
+ function timed(entry, textKeys) {
2331
+ const item = record(entry);
2332
+ if (item === void 0) return [];
2333
+ const value = textKeys.map((key) => text(item[key])).find(Boolean);
2334
+ if (value === void 0) return [];
2335
+ return [{
2336
+ endSecond: count(item.end) ?? 0,
2337
+ startSecond: count(item.start) ?? 0,
2338
+ text: value
2339
+ }];
2340
+ }
2341
+ /**
2342
+ * Reads a Deepgram answer: `results.channels[0].alternatives[0]`. Its
2343
+ * sentences are the segments when it sends paragraphs, and its words
2344
+ * otherwise.
2345
+ */
2346
+ function readDeepgram(body) {
2347
+ const channel = record(array(record(body.results)?.channels)?.[0]);
2348
+ const alternative = record(array(channel?.alternatives)?.[0]);
2349
+ const sentences = (array(record(alternative?.paragraphs)?.paragraphs) ?? []).flatMap((paragraph) => array(record(paragraph)?.sentences) ?? []);
2350
+ const segments = sentences.length > 0 ? sentences.flatMap((sentence) => timed(sentence, ["text"])) : (array(alternative?.words) ?? []).flatMap((word) => timed(word, ["punctuated_word", "word"]));
2351
+ return {
2352
+ durationInSeconds: count(record(body.metadata)?.duration),
2353
+ language: text(array(alternative?.languages)?.[0]) ?? text(channel?.detected_language),
2354
+ segments,
2355
+ text: text(alternative?.transcript) ?? ""
2356
+ };
2357
+ }
2358
+ /** Reads a whisper answer. */
2359
+ function readWhisper(body) {
2360
+ const info = record(body.transcription_info);
2361
+ return {
2362
+ durationInSeconds: count(info?.duration),
2363
+ language: text(info?.language),
2364
+ segments: readSegments(body),
2365
+ text: text(body.text) ?? ""
2366
+ };
2367
+ }
2306
2368
  /**
2307
2369
  * Reads segments out of a whisper answer. `segments` is what the large models
2308
2370
  * send; the smaller ones send only `words`, whose timings are the best segment
@@ -2344,10 +2406,10 @@ var CloudflareTranscriptionModel = class extends CloudflareModalityModel {
2344
2406
  const answer = await this.send({
2345
2407
  abortSignal: options.abortSignal,
2346
2408
  build: (modelId) => {
2347
- if (UNSUPPORTED.has(modelId)) throw new CloudflareAIError({
2409
+ if (WEBSOCKET_ONLY.has(modelId)) throw new CloudflareAIError({
2348
2410
  code: "bad-request",
2349
2411
  isRetryable: false,
2350
- message: `${modelId} takes the audio as an object body, which the JSON run path cannot carry. Use @cf/openai/whisper-large-v3-turbo.`,
2412
+ message: `${modelId} takes websocket connections only. Use @cf/deepgram/nova-3 or @cf/openai/whisper-large-v3-turbo.`,
2351
2413
  model: modelId,
2352
2414
  requestBodyValues: void 0,
2353
2415
  url: this.endpoint
@@ -2358,11 +2420,10 @@ var CloudflareTranscriptionModel = class extends CloudflareModalityModel {
2358
2420
  providerOptions: options.providerOptions
2359
2421
  });
2360
2422
  const body = record(answer.json) ?? {};
2361
- const info = record(body.transcription_info);
2362
- const language = text(info?.language);
2423
+ const transcript = record(body.results) === void 0 ? readWhisper(body) : readDeepgram(body);
2363
2424
  return {
2364
- durationInSeconds: count(info?.duration),
2365
- language,
2425
+ durationInSeconds: transcript.durationInSeconds,
2426
+ language: transcript.language,
2366
2427
  providerMetadata: answer.providerMetadata,
2367
2428
  request: { body: JSON.stringify(answer.input) },
2368
2429
  response: {
@@ -2371,8 +2432,8 @@ var CloudflareTranscriptionModel = class extends CloudflareModalityModel {
2371
2432
  modelId: answer.modelId,
2372
2433
  timestamp: answer.timestamp
2373
2434
  },
2374
- segments: readSegments(body),
2375
- text: text(body.text) ?? "",
2435
+ segments: transcript.segments,
2436
+ text: transcript.text,
2376
2437
  warnings: answer.warnings
2377
2438
  };
2378
2439
  }
@@ -2384,21 +2445,22 @@ function isModel(value) {
2384
2445
  return typeof value === "object" && value !== null;
2385
2446
  }
2386
2447
  /**
2387
- * Creates a provider over Workers AI, and over every vendor AI Gateway can
2388
- * reach.
2448
+ * Creates a provider over Workers AI and the AI Gateway catalog.
2389
2449
  *
2390
- * The Workers AI binding is the only way in — Workers AI models go through
2391
- * `env.AI.run`, vendor models through `env.AI.gateway(id).run`, and there is
2392
- * no HTTP transport and no API token. Gateway options are flat (`id`,
2393
- * `cacheTtl`, …) or nested under `gateway`; per-model options and per-call
2394
- * `providerOptions.cloudflare` override them in that order.
2450
+ * A Workers AI id goes to Workers AI and a catalog id or dynamic route to AI
2451
+ * Gateway's `/run`, both on `env.AI.run`; a vendor's model object goes to AI
2452
+ * Gateway's provider-native path. With `{ accountId, apiToken }` instead of
2453
+ * `binding`, the same requests go to the REST API and to
2454
+ * `gateway.ai.cloudflare.com`. Gateway
2455
+ * options are flat (`id`, `cacheTtl`, …) or nested under `gateway`; per-model
2456
+ * options and per-call `providerOptions.cloudflare` override them in that
2457
+ * order.
2395
2458
  *
2396
2459
  * ```ts
2397
2460
  * const ai = createAI({ binding: env.AI, id: "prod", cacheTtl: 60 });
2398
- * const anthropic = createAnthropic({ apiKey: "cloudflare" });
2399
2461
  *
2400
2462
  * ai("@cf/zai-org/glm-4.7-flash");
2401
- * ai(anthropic("claude-opus-4-8"), { fallback: [ai("@cf/zai-org/glm-4.7-flash")] });
2463
+ * ai("anthropic/claude-opus-4.8", { fallback: ["openai/gpt-5.5"] });
2402
2464
  * ai.embedding("@cf/baai/bge-base-en-v1.5");
2403
2465
  * ```
2404
2466
  *
@@ -2410,13 +2472,13 @@ function createAI(settings) {
2410
2472
  transport: createTransport(settings)
2411
2473
  };
2412
2474
  /**
2413
- * Fallback legs are normalized once, here: a model object becomes a routed
2414
- * model, so every leg a model runs is already this provider's.
2475
+ * Fallback legs are normalized once, here. A leg written as an id is gated
2476
+ * at the line that wrote it; a model object is routed like `ai(model)`.
2415
2477
  *
2416
2478
  * A leg inherits the chain's *gateway* options and nothing else. The rest of
2417
2479
  * the bag — `reasoningEffort`, `chatTemplateKwargs`, `headers`,
2418
- * `sessionAffinity` — was written for the model it was written on, and a leg
2419
- * that was configured with its own keeps every one of them.
2480
+ * `sessionAffinity`, `vendorKey` — was written for the model it was written
2481
+ * on, and a leg that was configured with its own keeps every one of them.
2420
2482
  */
2421
2483
  const normalize = (options) => {
2422
2484
  if (options?.fallback === void 0) return options;
@@ -2428,18 +2490,16 @@ function createAI(settings) {
2428
2490
  };
2429
2491
  function languageModel(model, options) {
2430
2492
  const resolved = normalize(options);
2431
- if (isModel(model)) {
2432
- if (model instanceof CloudflareLanguageModel) {
2433
- const merged = normalize(mergeModelOptions(optionsOf(model), resolved));
2434
- return new CloudflareLanguageModel(model.modelId, merged, config);
2435
- }
2436
- if (model instanceof GatewayLanguageModel) {
2437
- const merged = normalize(mergeModelOptions(optionsOf(model), resolved));
2438
- return new GatewayLanguageModel(model.model, merged, config);
2439
- }
2440
- return new GatewayLanguageModel(model, resolved, config);
2493
+ if (!isModel(model)) return new CloudflareLanguageModel(requireLanguageModelId(model), resolved, config);
2494
+ if (model instanceof CloudflareLanguageModel) {
2495
+ const merged = normalize(mergeModelOptions(optionsOf(model), resolved));
2496
+ return new CloudflareLanguageModel(model.modelId, merged, config);
2497
+ }
2498
+ if (model instanceof GatewayLanguageModel) {
2499
+ const merged = normalize(mergeModelOptions(optionsOf(model), resolved));
2500
+ return new GatewayLanguageModel(model.model, merged, config);
2441
2501
  }
2442
- return new CloudflareLanguageModel(requireLanguageModelId(model), resolved, config);
2502
+ return new GatewayLanguageModel(model, resolved, config);
2443
2503
  }
2444
2504
  const embedding = (modelId, options) => new CloudflareEmbeddingModel(modelId, options, config);
2445
2505
  const image = (modelId, options) => new CloudflareImageModel(modelId, options, config);
@@ -2467,4 +2527,4 @@ function createAI(settings) {
2467
2527
  //#endregion
2468
2528
  export { GatewayLanguageModel as n, CloudflareAIError as r, createAI as t };
2469
2529
 
2470
- //# sourceMappingURL=ai-sdk-C2iTAwUd.js.map
2530
+ //# sourceMappingURL=ai-sdk-DRPh2rRa.js.map