agents 0.28.0 → 0.29.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.
- package/dist/{agent-routing-QDcchcQP.d.ts → agent-routing-CDbpVjYq.d.ts} +18 -8
- package/dist/agent-routing.d.ts +1 -1
- package/dist/agent-tool-types.d.ts +1 -1
- package/dist/{agent-tools-DHL2XI7u.d.ts → agent-tools-C8DH8Yii.d.ts} +2 -2
- package/dist/agent-tools.d.ts +1 -1
- package/dist/{ai-ahruGw7e.d.ts → ai-iXw0uOGj.d.ts} +3 -3
- package/dist/{ai-sdk-Bdsf6mSA.js → ai-sdk-DRPh2rRa.js} +218 -132
- package/dist/ai-sdk-DRPh2rRa.js.map +1 -0
- package/dist/browser/ai.d.ts +1 -1
- package/dist/browser/ai.js +2 -2
- package/dist/browser/index.d.ts +8 -8
- package/dist/browser/index.js +3 -3
- package/dist/browser/tools/ai-sdk.d.ts +2 -2
- package/dist/browser/tools/ai-sdk.js +1 -1
- package/dist/browser/tools/pi.d.ts +1 -1
- package/dist/browser/tools/pi.js +3 -3
- package/dist/browser/tools/pi.js.map +1 -1
- package/dist/browser/tools/tanstack-ai.d.ts +2 -2
- package/dist/browser/tools/tanstack-ai.js +1 -1
- package/dist/{browser-CEdNlsaD.js → browser-DccPw_wW.js} +130 -79
- package/dist/browser-DccPw_wW.js.map +1 -0
- package/dist/{browser-D30VlpcA.d.ts → browser-DlXhSAdf.d.ts} +41 -37
- package/dist/{browser-tool-4iomavs_.js → browser-tool-B1mhifin.js} +3 -3
- package/dist/{browser-tool-4iomavs_.js.map → browser-tool-B1mhifin.js.map} +1 -1
- package/dist/{browser-tool-vtrPOV8e.d.ts → browser-tool-Cxjk5sgG.d.ts} +2 -2
- package/dist/chat/index.d.ts +143 -71
- package/dist/chat/index.js +269 -110
- package/dist/chat/index.js.map +1 -1
- package/dist/chat-sdk/index.d.ts +1 -1
- package/dist/chat-sdk/index.js +1 -1
- package/dist/cli.js +33 -33
- package/dist/{client-BGIQKJhX.d.ts → client-C27CtRZr.d.ts} +2 -2
- package/dist/client.d.ts +1 -1
- package/dist/{connector-DEXzVoaY.d.ts → connector-20DJ6p4k.d.ts} +2 -2
- package/dist/{connector-CtZylXdk.js → connector-DAXBOIIi.js} +2 -2
- package/dist/{connector-CtZylXdk.js.map → connector-DAXBOIIi.js.map} +1 -1
- package/dist/experimental/channels/web/index.js +1 -1
- package/dist/{handler-stateless-VvrWSAVA.js → handler-stateless-Bly_nSH3.js} +12 -3
- package/dist/handler-stateless-Bly_nSH3.js.map +1 -0
- package/dist/harness/container/index.js +1 -1
- package/dist/harness/container/index.js.map +1 -1
- package/dist/harness/opencode/index.d.ts +182 -6
- package/dist/harness/opencode/index.js +354 -23
- package/dist/harness/opencode/index.js.map +1 -1
- package/dist/harness/pi/index.d.ts +13 -5
- package/dist/harness/pi/index.js +8 -214
- package/dist/harness/pi/index.js.map +1 -1
- package/dist/{images-Ce9SCu3X.js → images-xaDv2Fqe.js} +662 -152
- package/dist/images-xaDv2Fqe.js.map +1 -0
- package/dist/index-DCxk3OSJ.d.ts +378 -0
- package/dist/{index-kbSUIer3.d.ts → index-iv9FTXX9.d.ts} +80 -112
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{input-schema-D2QAtHZH.js → input-schema-B0Etuo-o.js} +2 -2
- package/dist/{input-schema-D2QAtHZH.js.map → input-schema-B0Etuo-o.js.map} +1 -1
- package/dist/lifecycle/index.js +1 -1
- package/dist/{lifecycle-DGorpAmA.js → lifecycle-ClT4DmF2.js} +11 -3
- package/dist/lifecycle-ClT4DmF2.js.map +1 -0
- package/dist/mcp/client/index.d.ts +1 -1
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +17 -3
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/server/index.js +1 -1
- package/dist/models/ai-sdk/index.d.ts +31 -326
- package/dist/models/ai-sdk/index.js +1 -1
- package/dist/models/opencode/index.d.ts +25 -13
- package/dist/models/opencode/index.js +16 -11
- package/dist/models/opencode/index.js.map +1 -1
- package/dist/models/pi-ai/index.d.ts +17 -13
- package/dist/models/pi-ai/index.js +89 -36
- package/dist/models/pi-ai/index.js.map +1 -1
- package/dist/react.d.ts +2 -2
- package/dist/routing/index.d.ts +1 -1
- package/dist/serializable.d.ts +1 -1
- package/dist/{session-store-DoPY12xM.d.ts → session-store-_IK6dV-w.d.ts} +14 -2
- package/dist/{session-store-Do4xkDcf.js → session-store-yvwq1f9x.js} +55 -2
- package/dist/session-store-yvwq1f9x.js.map +1 -0
- package/dist/{settings-C45hDliX.js → settings-Dk2il2Hf.js} +10 -4
- package/dist/settings-Dk2il2Hf.js.map +1 -0
- package/dist/skills/index.d.ts +22 -28
- package/dist/skills/index.js +183 -143
- package/dist/skills/index.js.map +1 -1
- package/dist/{src-CQxJFv4l.js → src-6lr7MtM_.js} +3 -3
- package/dist/src-6lr7MtM_.js.map +1 -0
- package/dist/sub-routing.d.ts +1 -1
- package/dist/{tool-cQRkwSZZ.js → tool-DkT_DJBm.js} +2 -2
- package/dist/tool-DkT_DJBm.js.map +1 -0
- package/dist/transport-CPh7YGiw.d.ts +623 -0
- package/dist/voice/index.d.ts +1 -1
- package/dist/web/fetch/tools/pi.js +2 -2
- package/dist/web/fetch/tools/pi.js.map +1 -1
- package/dist/web/search/index.js +1 -1
- package/dist/web/search/tools/ai-sdk.js +2 -2
- package/dist/web/search/tools/pi.js +3 -3
- package/dist/web/search/tools/pi.js.map +1 -1
- package/dist/web/search/tools/tanstack-ai.js +2 -2
- package/dist/websockets/index.js +1 -1
- package/dist/{websockets-C3zy8YR0.js → websockets-CqxnntmE.js} +2 -2
- package/dist/{websockets-C3zy8YR0.js.map → websockets-CqxnntmE.js.map} +1 -1
- package/dist/workflow-types.d.ts +1 -1
- package/dist/workflows.d.ts +1 -1
- package/dist/workflows.js +1 -1
- package/docs/browse-the-web.md +1 -1
- package/docs/chat-agents.md +19 -18
- package/docs/harnesses/pi.md +47 -18
- package/docs/mcp-client.md +1 -1
- package/docs/mcp-servers.md +1 -1
- package/docs/models-pi-ai.md +70 -17
- package/docs/models.md +219 -152
- package/package.json +14 -14
- package/dist/ai-sdk-Bdsf6mSA.js.map +0 -1
- package/dist/browser-CEdNlsaD.js.map +0 -1
- package/dist/handler-stateless-VvrWSAVA.js.map +0 -1
- package/dist/images-Ce9SCu3X.js.map +0 -1
- package/dist/lifecycle-DGorpAmA.js.map +0 -1
- package/dist/session-store-Do4xkDcf.js.map +0 -1
- package/dist/settings-C45hDliX.js.map +0 -1
- package/dist/settings-NgGwF7Qt.d.ts +0 -331
- package/dist/src-CQxJFv4l.js.map +0 -1
- package/dist/tool-cQRkwSZZ.js.map +0 -1
- package/dist/transport-k2mFrtL8.d.ts +0 -200
|
@@ -1,42 +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 { 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, x as isAbortError, y as CloudflareAIError$1 } from "./images-
|
|
4
|
-
import { a as parseModelOptions, i as mergeModelOptions, n as PROVIDER_OPTIONS_KEY, o as resolveOptions, r as gatewayLayerOf } from "./settings-
|
|
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
|
|
24
|
-
*
|
|
25
|
-
*
|
|
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
|
|
28
|
-
|
|
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/", 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
|
|
34
|
-
*
|
|
35
|
-
*
|
|
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
|
-
if (
|
|
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.`);
|
|
22
|
+
if (!modelId.startsWith("@cf/")) throw notAModelId(modelId, "workers-ai");
|
|
23
|
+
return modelId;
|
|
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
|
+
}
|
|
29
|
+
/**
|
|
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.
|
|
35
|
+
*/
|
|
36
|
+
function requireLanguageModelId(modelId) {
|
|
37
|
+
if (!isLanguageModelId(modelId)) throw notAModelId(modelId, "language");
|
|
40
38
|
return modelId;
|
|
41
39
|
}
|
|
42
40
|
/**
|
|
@@ -117,6 +115,19 @@ function fallbackLegs(model, call) {
|
|
|
117
115
|
* @experimental This surface is experimental and may change.
|
|
118
116
|
*/
|
|
119
117
|
function parseCallOptions(providerOptions) {
|
|
118
|
+
const options = parseModelOptions(providerOptions?.[PROVIDER_OPTIONS_KEY]);
|
|
119
|
+
for (const leg of options?.fallback ?? []) requireLanguageModelId(leg);
|
|
120
|
+
return options;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Per-call options for the modality models — embedding, image, speech,
|
|
124
|
+
* transcription, reranking. The same bag as {@link parseCallOptions}, but a
|
|
125
|
+
* fallback leg must be a Workers AI id: a dynamic route answers in the
|
|
126
|
+
* chat-completions shape, which none of those models can read.
|
|
127
|
+
*
|
|
128
|
+
* @experimental This surface is experimental and may change.
|
|
129
|
+
*/
|
|
130
|
+
function parseModalityCallOptions(providerOptions) {
|
|
120
131
|
const options = parseModelOptions(providerOptions?.[PROVIDER_OPTIONS_KEY]);
|
|
121
132
|
for (const leg of options?.fallback ?? []) requireWorkersAIId(leg);
|
|
122
133
|
return options;
|
|
@@ -164,7 +175,7 @@ function withoutCallFallback(options) {
|
|
|
164
175
|
//#region src/models/ai-sdk/transport.ts
|
|
165
176
|
/**
|
|
166
177
|
* The typed AI SDK error for the gateway's own error envelope — a missing
|
|
167
|
-
* gateway, an unpaid account — on the
|
|
178
|
+
* gateway, an unpaid account — on the provider-native path.
|
|
168
179
|
*/
|
|
169
180
|
function errorFromGatewayEnvelope(body, context) {
|
|
170
181
|
return CloudflareAIError.fromCore(errorFromGatewayEnvelope$1(body, context));
|
|
@@ -194,16 +205,16 @@ function createTransport(settings) {
|
|
|
194
205
|
const inner = createTransport$1(settings);
|
|
195
206
|
return {
|
|
196
207
|
logIdFallback: (response) => inner.logIdFallback(response),
|
|
197
|
-
async
|
|
208
|
+
async native(request) {
|
|
198
209
|
try {
|
|
199
|
-
return await inner.
|
|
210
|
+
return await inner.native(request);
|
|
200
211
|
} catch (error) {
|
|
201
212
|
throw toAISDKError(error);
|
|
202
213
|
}
|
|
203
214
|
},
|
|
204
|
-
async
|
|
215
|
+
async run(request) {
|
|
205
216
|
try {
|
|
206
|
-
return await inner.
|
|
217
|
+
return await inner.run(request);
|
|
207
218
|
} catch (error) {
|
|
208
219
|
throw toAISDKError(error);
|
|
209
220
|
}
|
|
@@ -489,7 +500,7 @@ var CloudflareEmbeddingModel = class {
|
|
|
489
500
|
provider: this.provider,
|
|
490
501
|
values: options.values
|
|
491
502
|
});
|
|
492
|
-
const resolved = resolveOptions(_classPrivateFieldGet2(_config$3, this).providerGateway, _classPrivateFieldGet2(_options$3, this),
|
|
503
|
+
const resolved = resolveOptions(_classPrivateFieldGet2(_config$3, this).providerGateway, _classPrivateFieldGet2(_options$3, this), parseModalityCallOptions(options.providerOptions));
|
|
493
504
|
const input = { text: options.values };
|
|
494
505
|
const transport = _classPrivateFieldGet2(_config$3, this).transport;
|
|
495
506
|
return withFallback(this.modelId, resolved.fallback, transport.url, async (modelId) => {
|
|
@@ -1129,12 +1140,12 @@ function callHeaders(options, resolved) {
|
|
|
1129
1140
|
* attaches to its result. Shared with the non-language models in
|
|
1130
1141
|
* `models/modality.ts`.
|
|
1131
1142
|
*/
|
|
1132
|
-
function cloudflareMetadata(model,
|
|
1143
|
+
function cloudflareMetadata(model, gateway, response, transport, provider) {
|
|
1133
1144
|
const headers = response.headers;
|
|
1134
1145
|
const rawStep = headers.get("cf-aig-step");
|
|
1135
1146
|
const step = rawStep === null ? NaN : Number(rawStep);
|
|
1136
1147
|
const metadata = {
|
|
1137
|
-
gateway:
|
|
1148
|
+
...gateway === void 0 ? {} : { gateway },
|
|
1138
1149
|
model,
|
|
1139
1150
|
...provider === void 0 ? {} : { provider },
|
|
1140
1151
|
...Number.isNaN(step) ? {} : { step }
|
|
@@ -1302,7 +1313,7 @@ var CloudflareLanguageModel = class {
|
|
|
1302
1313
|
return {
|
|
1303
1314
|
content: generation.content,
|
|
1304
1315
|
finishReason: generation.finishReason,
|
|
1305
|
-
providerMetadata: cloudflareMetadata(modelId, resolved, response, _classPrivateFieldGet2(_config$2, this).transport),
|
|
1316
|
+
providerMetadata: cloudflareMetadata(modelId, resolved.gateway.id, response, _classPrivateFieldGet2(_config$2, this).transport),
|
|
1306
1317
|
request: { body: request.body },
|
|
1307
1318
|
response: {
|
|
1308
1319
|
headers: headersToObject(response.headers),
|
|
@@ -1322,7 +1333,7 @@ var CloudflareLanguageModel = class {
|
|
|
1322
1333
|
return _assertClassBrand(_CloudflareLanguageModel_brand, this, _withFallback$1).call(this, call, (model) => model.doStream(legOptions), async (modelId) => {
|
|
1323
1334
|
const request = buildRequest(modelId, options, resolved, true);
|
|
1324
1335
|
const response = await _assertClassBrand(_CloudflareLanguageModel_brand, this, _send).call(this, modelId, request, options, resolved);
|
|
1325
|
-
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);
|
|
1326
1337
|
const contentType = response.headers.get("content-type") ?? "";
|
|
1327
1338
|
const decorate = decorateStream(request.warnings, providerMetadata);
|
|
1328
1339
|
let parts;
|
|
@@ -1368,6 +1379,7 @@ function _resolve$1(call) {
|
|
|
1368
1379
|
}
|
|
1369
1380
|
async function _send(modelId, request, options, resolved) {
|
|
1370
1381
|
const response = await _classPrivateFieldGet2(_config$2, this).transport.run({
|
|
1382
|
+
format: "chat-completions",
|
|
1371
1383
|
gateway: resolved.gateway,
|
|
1372
1384
|
headers: callHeaders(options, resolved),
|
|
1373
1385
|
input: request.body,
|
|
@@ -1394,7 +1406,7 @@ function _withFallback$1(call, runLeg, runSelf, mode = "generate") {
|
|
|
1394
1406
|
model: this.modelId,
|
|
1395
1407
|
run: () => runSelf(this.modelId)
|
|
1396
1408
|
}, ...legs.map((leg) => typeof leg === "string" ? {
|
|
1397
|
-
model:
|
|
1409
|
+
model: requireLanguageModelId(leg),
|
|
1398
1410
|
run: () => runSelf(leg)
|
|
1399
1411
|
} : {
|
|
1400
1412
|
model: leg.modelId,
|
|
@@ -1441,36 +1453,34 @@ function requestUrl(input) {
|
|
|
1441
1453
|
}
|
|
1442
1454
|
/**
|
|
1443
1455
|
* The body of either `fetch` call form: the `RequestInit`'s when one was
|
|
1444
|
-
* given, else the `Request`'s own,
|
|
1445
|
-
*
|
|
1456
|
+
* given, else the `Request`'s own, from a clone so the caller's object is
|
|
1457
|
+
* neither consumed nor mutated.
|
|
1446
1458
|
*/
|
|
1447
|
-
|
|
1459
|
+
function requestBody(input, init) {
|
|
1448
1460
|
if (init?.body !== void 0) return init.body;
|
|
1449
|
-
if (input instanceof Request && input.body !== null) return
|
|
1461
|
+
if (input instanceof Request && input.body !== null) return input.clone().body;
|
|
1450
1462
|
}
|
|
1451
|
-
/**
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
*/
|
|
1456
|
-
function
|
|
1457
|
-
if (typeof body !== "string")
|
|
1458
|
-
const kind = body === null || body === void 0 ? "an empty" : body instanceof FormData ? "a FormData" : `a ${body.constructor?.name ?? typeof body}`;
|
|
1459
|
-
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.`);
|
|
1460
|
-
}
|
|
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;
|
|
1461
1470
|
try {
|
|
1462
|
-
return JSON.parse(body);
|
|
1463
|
-
} catch
|
|
1464
|
-
|
|
1471
|
+
return modelOf(JSON.parse(body));
|
|
1472
|
+
} catch {
|
|
1473
|
+
return;
|
|
1465
1474
|
}
|
|
1466
1475
|
}
|
|
1467
1476
|
/**
|
|
1468
|
-
* The vendor's own request headers, minus the
|
|
1469
|
-
*
|
|
1477
|
+
* The vendor's own request headers, minus the length of a body we are about
|
|
1478
|
+
* to re-serialize, and minus the vendor's credential unless the model asked
|
|
1479
|
+
* for it to be forwarded.
|
|
1470
1480
|
*/
|
|
1471
|
-
function forwardedHeaders(init, input, route) {
|
|
1481
|
+
function forwardedHeaders(init, input, route, vendorKey) {
|
|
1472
1482
|
const source = init?.headers ?? (input instanceof Request ? input.headers : void 0);
|
|
1473
|
-
const dropped = /* @__PURE__ */ new Set([...route.authHeaders, "content-length"]);
|
|
1483
|
+
const dropped = /* @__PURE__ */ new Set([...vendorKey === "request" ? [] : route.authHeaders, "content-length"]);
|
|
1474
1484
|
const headers = {};
|
|
1475
1485
|
new Headers(source).forEach((value, key) => {
|
|
1476
1486
|
if (!dropped.has(key.toLowerCase())) headers[key] = value;
|
|
@@ -1487,42 +1497,42 @@ function replayed(response, text) {
|
|
|
1487
1497
|
});
|
|
1488
1498
|
}
|
|
1489
1499
|
/**
|
|
1490
|
-
* The `fetch` a routed model is given. It
|
|
1491
|
-
*
|
|
1492
|
-
*
|
|
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.
|
|
1493
1503
|
*/
|
|
1494
1504
|
function routedFetch(context) {
|
|
1495
1505
|
const routed = async (input, init) => {
|
|
1496
1506
|
const route = requireGatewayProvider(requestUrl(input));
|
|
1497
|
-
const
|
|
1507
|
+
const body = requestBody(input, init);
|
|
1498
1508
|
const { resolved } = context;
|
|
1499
|
-
const
|
|
1500
|
-
|
|
1501
|
-
...resolved.sessionAffinity === void 0 ? {} : { "x-session-affinity": resolved.sessionAffinity }
|
|
1502
|
-
};
|
|
1503
|
-
const response = await context.config.transport.universal({
|
|
1509
|
+
const response = await context.config.transport.native({
|
|
1510
|
+
body,
|
|
1504
1511
|
endpoint: route.endpoint,
|
|
1505
|
-
...Object.keys(extraHeaders).length > 0 ? { extraHeaders } : {},
|
|
1506
1512
|
gateway: resolved.gateway,
|
|
1507
|
-
headers:
|
|
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),
|
|
1508
1519
|
provider: route.provider,
|
|
1509
|
-
query,
|
|
1510
1520
|
signal: init?.signal ?? (input instanceof Request ? input.signal : void 0) ?? context.signal
|
|
1511
1521
|
});
|
|
1512
1522
|
context.capture.provider = route.provider;
|
|
1513
1523
|
context.capture.response = response;
|
|
1514
1524
|
if (response.ok) return response;
|
|
1515
1525
|
const text = await response.text();
|
|
1516
|
-
let
|
|
1526
|
+
let envelope;
|
|
1517
1527
|
try {
|
|
1518
|
-
|
|
1528
|
+
envelope = JSON.parse(text);
|
|
1519
1529
|
} catch {
|
|
1520
1530
|
return replayed(response, text);
|
|
1521
1531
|
}
|
|
1522
|
-
if (!isGatewayErrorEnvelope(
|
|
1523
|
-
throw errorFromGatewayEnvelope(
|
|
1524
|
-
model:
|
|
1525
|
-
requestBodyValues:
|
|
1532
|
+
if (!isGatewayErrorEnvelope(envelope)) return replayed(response, text);
|
|
1533
|
+
throw errorFromGatewayEnvelope(envelope, {
|
|
1534
|
+
model: modelOfBody(body) ?? route.provider,
|
|
1535
|
+
requestBodyValues: void 0,
|
|
1526
1536
|
responseBody: text,
|
|
1527
1537
|
responseHeaders: headersToObject(response.headers),
|
|
1528
1538
|
status: response.status,
|
|
@@ -1709,7 +1719,8 @@ function _route(resolved, capture, signal) {
|
|
|
1709
1719
|
capture,
|
|
1710
1720
|
config: _classPrivateFieldGet2(_config$1, this),
|
|
1711
1721
|
resolved,
|
|
1712
|
-
signal
|
|
1722
|
+
signal,
|
|
1723
|
+
vendorKey: _classPrivateFieldGet2(_options$1, this)?.vendorKey ?? "gateway"
|
|
1713
1724
|
}));
|
|
1714
1725
|
}
|
|
1715
1726
|
function _resolve(call) {
|
|
@@ -1717,7 +1728,7 @@ function _resolve(call) {
|
|
|
1717
1728
|
}
|
|
1718
1729
|
function _metadata(resolved, capture) {
|
|
1719
1730
|
const response = capture.response ?? new Response(null);
|
|
1720
|
-
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);
|
|
1721
1732
|
}
|
|
1722
1733
|
function _response(response, capture) {
|
|
1723
1734
|
if (capture.response === void 0) return response;
|
|
@@ -1752,14 +1763,14 @@ function _withFallback(call, runLeg, run, mode = "generate") {
|
|
|
1752
1763
|
}
|
|
1753
1764
|
/** A Workers AI leg, carrying this model's gateway options but no chain. */
|
|
1754
1765
|
function _workersAI(modelId) {
|
|
1755
|
-
return new CloudflareLanguageModel(
|
|
1766
|
+
return new CloudflareLanguageModel(requireLanguageModelId(modelId), {
|
|
1756
1767
|
..._classPrivateFieldGet2(_options$1, this),
|
|
1757
1768
|
fallback: void 0
|
|
1758
1769
|
}, _classPrivateFieldGet2(_config$1, this));
|
|
1759
1770
|
}
|
|
1760
1771
|
/**
|
|
1761
1772
|
* Routes any other AI SDK v4 model the vendor built — embedding, image,
|
|
1762
|
-
* speech, transcription — through the same
|
|
1773
|
+
* speech, transcription — through the same provider-native request. Only
|
|
1763
1774
|
* `fetch` is swapped; every `do…` method stays the vendor's, and its result
|
|
1764
1775
|
* gains `providerMetadata.cloudflare` when the result is an object that can
|
|
1765
1776
|
* carry one.
|
|
@@ -1779,7 +1790,8 @@ function routed(model, options, config) {
|
|
|
1779
1790
|
capture,
|
|
1780
1791
|
config,
|
|
1781
1792
|
resolved,
|
|
1782
|
-
signal: call?.abortSignal
|
|
1793
|
+
signal: call?.abortSignal,
|
|
1794
|
+
vendorKey: options?.vendorKey ?? "gateway"
|
|
1783
1795
|
}));
|
|
1784
1796
|
const result = await Reflect.get(clone, property).call(clone, upstream);
|
|
1785
1797
|
if (result === null || typeof result !== "object") return result;
|
|
@@ -1787,13 +1799,18 @@ function routed(model, options, config) {
|
|
|
1787
1799
|
return {
|
|
1788
1800
|
...result,
|
|
1789
1801
|
...routedWarnings(result, resolved),
|
|
1790
|
-
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)))
|
|
1791
1803
|
};
|
|
1792
1804
|
};
|
|
1793
1805
|
} });
|
|
1794
1806
|
}
|
|
1795
1807
|
//#endregion
|
|
1796
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
|
+
}
|
|
1797
1814
|
/** The `unsupported` warning shape, which every modality needs. */
|
|
1798
1815
|
function unsupported(feature, details) {
|
|
1799
1816
|
return {
|
|
@@ -1843,11 +1860,21 @@ var CloudflareModalityModel = class {
|
|
|
1843
1860
|
* as JSON or as raw bytes depending on what the model sent back.
|
|
1844
1861
|
*/
|
|
1845
1862
|
async send(call) {
|
|
1846
|
-
const resolved = resolveOptions(_classPrivateFieldGet2(_config, this).providerGateway, _classPrivateFieldGet2(_options, this),
|
|
1863
|
+
const resolved = resolveOptions(_classPrivateFieldGet2(_config, this).providerGateway, _classPrivateFieldGet2(_options, this), parseModalityCallOptions(call.providerOptions));
|
|
1847
1864
|
const transport = _classPrivateFieldGet2(_config, this).transport;
|
|
1848
1865
|
return withFallback(this.modelId, resolved.fallback, transport.url, async (modelId) => {
|
|
1849
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;
|
|
1850
1876
|
const response = await transport.run({
|
|
1877
|
+
...request.audio === void 0 ? {} : { audio: request.audio },
|
|
1851
1878
|
gateway: resolved.gateway,
|
|
1852
1879
|
headers: {
|
|
1853
1880
|
...definedHeaders(call.headers),
|
|
@@ -1860,20 +1887,20 @@ var CloudflareModalityModel = class {
|
|
|
1860
1887
|
});
|
|
1861
1888
|
if (!response.ok) throw await errorFromResponse(response, {
|
|
1862
1889
|
model: modelId,
|
|
1863
|
-
requestBodyValues:
|
|
1890
|
+
requestBodyValues: sent,
|
|
1864
1891
|
url: transport.url
|
|
1865
1892
|
});
|
|
1866
1893
|
const mediaType = (response.headers.get("content-type") ?? "").split(";")[0].trim().toLowerCase();
|
|
1867
|
-
const body = await _assertClassBrand(_CloudflareModalityModel_brand, this, _decode).call(this, response, modelId,
|
|
1894
|
+
const body = await _assertClassBrand(_CloudflareModalityModel_brand, this, _decode).call(this, response, modelId, sent, mediaType);
|
|
1868
1895
|
const answer = {
|
|
1869
1896
|
headers: headersToObject(response.headers),
|
|
1870
|
-
input:
|
|
1897
|
+
input: sent,
|
|
1871
1898
|
mediaType,
|
|
1872
1899
|
modelId,
|
|
1873
|
-
providerMetadata: cloudflareMetadata(modelId, resolved, response, transport),
|
|
1900
|
+
providerMetadata: cloudflareMetadata(modelId, direct ? void 0 : resolved.gateway.id, response, transport),
|
|
1874
1901
|
timestamp: /* @__PURE__ */ new Date(),
|
|
1875
1902
|
url: transport.url,
|
|
1876
|
-
warnings
|
|
1903
|
+
warnings,
|
|
1877
1904
|
...body
|
|
1878
1905
|
};
|
|
1879
1906
|
call.check?.(answer);
|
|
@@ -2244,13 +2271,13 @@ var CloudflareSpeechModel = class extends CloudflareModalityModel {
|
|
|
2244
2271
|
*/
|
|
2245
2272
|
const BYTE_ARRAY_AUDIO = /* @__PURE__ */ new Set(["@cf/openai/whisper", "@cf/openai/whisper-tiny-en"]);
|
|
2246
2273
|
/**
|
|
2247
|
-
*
|
|
2248
|
-
*
|
|
2249
|
-
* '
|
|
2250
|
-
* be the audio object itself and JSON cannot carry it. Refuse early rather
|
|
2251
|
-
* 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.
|
|
2252
2277
|
*/
|
|
2253
|
-
const
|
|
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"]);
|
|
2254
2281
|
function transcriptionOptions(providerOptions) {
|
|
2255
2282
|
const raw = record(providerOptions?.["cloudflare"]) ?? {};
|
|
2256
2283
|
const vadFilter = raw.vadFilter;
|
|
@@ -2262,10 +2289,32 @@ function transcriptionOptions(providerOptions) {
|
|
|
2262
2289
|
...typeof vadFilter === "boolean" ? { vadFilter } : {}
|
|
2263
2290
|
};
|
|
2264
2291
|
}
|
|
2265
|
-
/**
|
|
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. */
|
|
2266
2314
|
function buildTranscriptionRequest(modelId, options) {
|
|
2267
2315
|
const warnings = [];
|
|
2268
2316
|
const extra = transcriptionOptions(options.providerOptions);
|
|
2317
|
+
if (RAW_AUDIO.has(modelId)) return buildRawAudioRequest(modelId, options, extra);
|
|
2269
2318
|
const input = BYTE_ARRAY_AUDIO.has(modelId) ? { audio: Array.from(toBytes(options.audio)) } : { audio: toBase64(options.audio) };
|
|
2270
2319
|
if (extra.language !== void 0) input.language = extra.language;
|
|
2271
2320
|
if (extra.task !== void 0) input.task = extra.task;
|
|
@@ -2277,6 +2326,45 @@ function buildTranscriptionRequest(modelId, options) {
|
|
|
2277
2326
|
warnings
|
|
2278
2327
|
};
|
|
2279
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
|
+
}
|
|
2280
2368
|
/**
|
|
2281
2369
|
* Reads segments out of a whisper answer. `segments` is what the large models
|
|
2282
2370
|
* send; the smaller ones send only `words`, whose timings are the best segment
|
|
@@ -2318,10 +2406,10 @@ var CloudflareTranscriptionModel = class extends CloudflareModalityModel {
|
|
|
2318
2406
|
const answer = await this.send({
|
|
2319
2407
|
abortSignal: options.abortSignal,
|
|
2320
2408
|
build: (modelId) => {
|
|
2321
|
-
if (
|
|
2409
|
+
if (WEBSOCKET_ONLY.has(modelId)) throw new CloudflareAIError({
|
|
2322
2410
|
code: "bad-request",
|
|
2323
2411
|
isRetryable: false,
|
|
2324
|
-
message: `${modelId} takes
|
|
2412
|
+
message: `${modelId} takes websocket connections only. Use @cf/deepgram/nova-3 or @cf/openai/whisper-large-v3-turbo.`,
|
|
2325
2413
|
model: modelId,
|
|
2326
2414
|
requestBodyValues: void 0,
|
|
2327
2415
|
url: this.endpoint
|
|
@@ -2332,11 +2420,10 @@ var CloudflareTranscriptionModel = class extends CloudflareModalityModel {
|
|
|
2332
2420
|
providerOptions: options.providerOptions
|
|
2333
2421
|
});
|
|
2334
2422
|
const body = record(answer.json) ?? {};
|
|
2335
|
-
const
|
|
2336
|
-
const language = text(info?.language);
|
|
2423
|
+
const transcript = record(body.results) === void 0 ? readWhisper(body) : readDeepgram(body);
|
|
2337
2424
|
return {
|
|
2338
|
-
durationInSeconds:
|
|
2339
|
-
language,
|
|
2425
|
+
durationInSeconds: transcript.durationInSeconds,
|
|
2426
|
+
language: transcript.language,
|
|
2340
2427
|
providerMetadata: answer.providerMetadata,
|
|
2341
2428
|
request: { body: JSON.stringify(answer.input) },
|
|
2342
2429
|
response: {
|
|
@@ -2345,8 +2432,8 @@ var CloudflareTranscriptionModel = class extends CloudflareModalityModel {
|
|
|
2345
2432
|
modelId: answer.modelId,
|
|
2346
2433
|
timestamp: answer.timestamp
|
|
2347
2434
|
},
|
|
2348
|
-
segments:
|
|
2349
|
-
text:
|
|
2435
|
+
segments: transcript.segments,
|
|
2436
|
+
text: transcript.text,
|
|
2350
2437
|
warnings: answer.warnings
|
|
2351
2438
|
};
|
|
2352
2439
|
}
|
|
@@ -2358,21 +2445,22 @@ function isModel(value) {
|
|
|
2358
2445
|
return typeof value === "object" && value !== null;
|
|
2359
2446
|
}
|
|
2360
2447
|
/**
|
|
2361
|
-
* Creates a provider over Workers AI
|
|
2362
|
-
* reach.
|
|
2448
|
+
* Creates a provider over Workers AI and the AI Gateway catalog.
|
|
2363
2449
|
*
|
|
2364
|
-
*
|
|
2365
|
-
*
|
|
2366
|
-
*
|
|
2367
|
-
* `
|
|
2368
|
-
* `
|
|
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.
|
|
2369
2458
|
*
|
|
2370
2459
|
* ```ts
|
|
2371
2460
|
* const ai = createAI({ binding: env.AI, id: "prod", cacheTtl: 60 });
|
|
2372
|
-
* const anthropic = createAnthropic({ apiKey: "cloudflare" });
|
|
2373
2461
|
*
|
|
2374
2462
|
* ai("@cf/zai-org/glm-4.7-flash");
|
|
2375
|
-
* ai(anthropic
|
|
2463
|
+
* ai("anthropic/claude-opus-4.8", { fallback: ["openai/gpt-5.5"] });
|
|
2376
2464
|
* ai.embedding("@cf/baai/bge-base-en-v1.5");
|
|
2377
2465
|
* ```
|
|
2378
2466
|
*
|
|
@@ -2384,36 +2472,34 @@ function createAI(settings) {
|
|
|
2384
2472
|
transport: createTransport(settings)
|
|
2385
2473
|
};
|
|
2386
2474
|
/**
|
|
2387
|
-
* Fallback legs are normalized once, here
|
|
2388
|
-
*
|
|
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)`.
|
|
2389
2477
|
*
|
|
2390
2478
|
* A leg inherits the chain's *gateway* options and nothing else. The rest of
|
|
2391
2479
|
* the bag — `reasoningEffort`, `chatTemplateKwargs`, `headers`,
|
|
2392
|
-
* `sessionAffinity` — was written for the model it was written
|
|
2393
|
-
* 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.
|
|
2394
2482
|
*/
|
|
2395
2483
|
const normalize = (options) => {
|
|
2396
2484
|
if (options?.fallback === void 0) return options;
|
|
2397
2485
|
const inherited = gatewayLayerOf(options);
|
|
2398
2486
|
return {
|
|
2399
2487
|
...options,
|
|
2400
|
-
fallback: options.fallback.map((leg) => typeof leg === "string" ?
|
|
2488
|
+
fallback: options.fallback.map((leg) => typeof leg === "string" ? requireLanguageModelId(leg) : languageModel(leg, inherited))
|
|
2401
2489
|
};
|
|
2402
2490
|
};
|
|
2403
2491
|
function languageModel(model, options) {
|
|
2404
2492
|
const resolved = normalize(options);
|
|
2405
|
-
if (isModel(model))
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
}
|
|
2414
|
-
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);
|
|
2415
2501
|
}
|
|
2416
|
-
return new
|
|
2502
|
+
return new GatewayLanguageModel(model, resolved, config);
|
|
2417
2503
|
}
|
|
2418
2504
|
const embedding = (modelId, options) => new CloudflareEmbeddingModel(modelId, options, config);
|
|
2419
2505
|
const image = (modelId, options) => new CloudflareImageModel(modelId, options, config);
|
|
@@ -2441,4 +2527,4 @@ function createAI(settings) {
|
|
|
2441
2527
|
//#endregion
|
|
2442
2528
|
export { GatewayLanguageModel as n, CloudflareAIError as r, createAI as t };
|
|
2443
2529
|
|
|
2444
|
-
//# sourceMappingURL=ai-sdk-
|
|
2530
|
+
//# sourceMappingURL=ai-sdk-DRPh2rRa.js.map
|