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,17 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
o as CloudflareEmbeddingModelId,
|
|
4
|
-
p as WorkersAIModelId,
|
|
5
|
-
r as ModelOptions,
|
|
6
|
-
t as AISettings
|
|
7
|
-
} from "../../settings-NgGwF7Qt.js";
|
|
8
|
-
import {
|
|
2
|
+
_ as DynamicRouteId,
|
|
9
3
|
a as CloudflareAIError,
|
|
4
|
+
b as WorkersAIModelId,
|
|
5
|
+
c as GatewayOptions,
|
|
6
|
+
f as CloudflareEmbeddingModelId,
|
|
10
7
|
i as CloudflareAIAttempt,
|
|
8
|
+
l as ModelOptions,
|
|
11
9
|
n as GATEWAY_PROVIDER_NAMES,
|
|
12
10
|
o as CloudflareAIErrorCode,
|
|
13
|
-
r as GatewayProviderName
|
|
14
|
-
|
|
11
|
+
r as GatewayProviderName,
|
|
12
|
+
s as AISettings
|
|
13
|
+
} from "../../transport-CPh7YGiw.js";
|
|
15
14
|
import {
|
|
16
15
|
Api,
|
|
17
16
|
AssistantImages,
|
|
@@ -107,7 +106,7 @@ declare const CLOUDFLARE_AI_API = "cloudflare-ai";
|
|
|
107
106
|
type CloudflareAIApi = typeof CLOUDFLARE_AI_API;
|
|
108
107
|
/**
|
|
109
108
|
* The pi-ai provider id. A `Models` registry resolves specifiers as
|
|
110
|
-
* `cloudflare/<id>`, e.g. `cloudflare/anthropic/claude-opus-4
|
|
109
|
+
* `cloudflare/<id>`, e.g. `cloudflare/anthropic/claude-opus-4.8`.
|
|
111
110
|
*
|
|
112
111
|
* @beta This surface is in beta and may change.
|
|
113
112
|
*/
|
|
@@ -201,6 +200,8 @@ type StreamFn = (
|
|
|
201
200
|
interface AI {
|
|
202
201
|
/** A Workers AI model: Cloudflare's own catalog, on the run path. */
|
|
203
202
|
(modelId: WorkersAIModelId, options?: PiModelOptions): CloudflareModel;
|
|
203
|
+
/** An AI Gateway dynamic route, `dynamic/<route>`, on the Workers AI wire. */
|
|
204
|
+
(route: DynamicRouteId, options?: PiModelOptions): CloudflareModel;
|
|
204
205
|
/** Any pi-ai model, routed through AI Gateway with its metadata intact. */
|
|
205
206
|
<TApi extends Api>(model: Model<TApi>, options?: PiModelOptions): Model<TApi>;
|
|
206
207
|
/**
|
|
@@ -210,6 +211,7 @@ interface AI {
|
|
|
210
211
|
(target: string | Model<Api>, options?: PiModelOptions): RoutedModel;
|
|
211
212
|
/** Same as calling the provider directly. */
|
|
212
213
|
model(modelId: WorkersAIModelId, options?: PiModelOptions): CloudflareModel;
|
|
214
|
+
model(route: DynamicRouteId, options?: PiModelOptions): CloudflareModel;
|
|
213
215
|
model<TApi extends Api>(
|
|
214
216
|
model: Model<TApi>,
|
|
215
217
|
options?: PiModelOptions
|
|
@@ -263,9 +265,10 @@ interface AI {
|
|
|
263
265
|
/**
|
|
264
266
|
* Creates a pi-ai provider over Cloudflare's AI.
|
|
265
267
|
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
268
|
+
* Workers AI and catalog models go through `env.AI.run`, other model objects
|
|
269
|
+
* through the binding's `fetch` to AI Gateway's provider-native path. With
|
|
270
|
+
* `{ accountId, apiToken }` instead of `binding`, the same requests go to the
|
|
271
|
+
* REST API and to `gateway.ai.cloudflare.com`. Gateway options may be given flat
|
|
269
272
|
* (`{ binding, id: "prod", cacheTtl: 60 }`) or nested under `gateway`;
|
|
270
273
|
* per-model options and per-call pi-ai options (`headers`, `metadata`,
|
|
271
274
|
* `sessionId`) override them in that order.
|
|
@@ -297,6 +300,7 @@ export {
|
|
|
297
300
|
type CloudflareEmbeddingModelId,
|
|
298
301
|
type CloudflareImagesModel,
|
|
299
302
|
type CloudflareModel,
|
|
303
|
+
type DynamicRouteId,
|
|
300
304
|
FALLBACK_DIAGNOSTIC,
|
|
301
305
|
type FallbackAttempt,
|
|
302
306
|
GATEWAY_PROVIDER_NAMES,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { _ as isGatewayErrorEnvelope, a as normalizeChatCompletion, c as gatewaySlugForBaseUrl, d as resolveGatewayProvider, f as createTransport, g as headersToObject, h as errorFromResponse, i as normalizeChatCompletionsStream, l as isGatewayShapedUrl, m as errorFromGatewayEnvelope, n as imageMediaTypeOf, o as prepareChatCompletionsRequest, r as sseDataStream, s as GATEWAY_PROVIDER_NAMES, t as buildImageInput, v as unwrapEnvelope, x as isAbortError, y as CloudflareAIError } from "../../images-
|
|
2
|
-
import { i as mergeModelOptions, o as resolveOptions, r as gatewayLayerOf } from "../../settings-
|
|
1
|
+
import { C as isCatalogModelId, T as isRunPathLanguageModelId, _ as isGatewayErrorEnvelope, a as normalizeChatCompletion, c as gatewaySlugForBaseUrl, d as resolveGatewayProvider, f as createTransport, g as headersToObject, h as errorFromResponse, i as normalizeChatCompletionsStream, l as isGatewayShapedUrl, m as errorFromGatewayEnvelope, n as imageMediaTypeOf, o as prepareChatCompletionsRequest, r as sseDataStream, s as GATEWAY_PROVIDER_NAMES, t as buildImageInput, v as unwrapEnvelope, x as isAbortError, y as CloudflareAIError } from "../../images-xaDv2Fqe.js";
|
|
2
|
+
import { i as mergeModelOptions, o as resolveOptions, r as gatewayLayerOf } from "../../settings-Dk2il2Hf.js";
|
|
3
3
|
import { calculateCost, clampThinkingLevel, createAssistantMessageEventStream, createProvider, getCurrentTools, normalizeContext, parseStreamingJson } from "@earendil-works/pi-ai";
|
|
4
4
|
import { CLOUDFLARE_AI_GATEWAY_MODELS } from "@earendil-works/pi-ai/providers/cloudflare-ai-gateway.models";
|
|
5
5
|
import { CLOUDFLARE_WORKERS_AI_MODELS } from "@earendil-works/pi-ai/providers/cloudflare-workers-ai.models";
|
|
@@ -19,7 +19,7 @@ import { clampOpenAIPromptCacheKey } from "@earendil-works/pi-ai/api/openai-prom
|
|
|
19
19
|
const CLOUDFLARE_AI_API = "cloudflare-ai";
|
|
20
20
|
/**
|
|
21
21
|
* The pi-ai provider id. A `Models` registry resolves specifiers as
|
|
22
|
-
* `cloudflare/<id>`, e.g. `cloudflare/anthropic/claude-opus-4
|
|
22
|
+
* `cloudflare/<id>`, e.g. `cloudflare/anthropic/claude-opus-4.8`.
|
|
23
23
|
*
|
|
24
24
|
* @beta This surface is in beta and may change.
|
|
25
25
|
*/
|
|
@@ -125,9 +125,22 @@ function buildWorkersAIModel(modelId, options) {
|
|
|
125
125
|
function slugOf(entry) {
|
|
126
126
|
return entry.baseUrl.split("/").filter((part) => part !== "").at(-1);
|
|
127
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* The id AI Gateway's model catalog — `env.AI.run` — knows a registry entry
|
|
130
|
+
* by. pi-ai spells Claude ids as Anthropic does (`claude-opus-4-8`), because pi
|
|
131
|
+
* sends them through the gateway's Anthropic passthrough, while the catalog
|
|
132
|
+
* puts a dot between version numbers (`anthropic/claude-opus-4.8`) and answers
|
|
133
|
+
* `Model not found` to the dashed spelling. Checked against the live catalog
|
|
134
|
+
* for every entry in pi-ai 1.2: that dot is the only difference, and only
|
|
135
|
+
* Anthropic ids have it.
|
|
136
|
+
*/
|
|
137
|
+
function gatewayCatalogId(slug, id) {
|
|
138
|
+
return `${slug}/${slug === "anthropic" ? id.replace(/(\d)-(\d)(?!\d)/g, "$1.$2") : id}`;
|
|
139
|
+
}
|
|
128
140
|
let gatewayRegistry;
|
|
129
141
|
/**
|
|
130
|
-
* pi-ai's generated Cloudflare AI Gateway registry, keyed by
|
|
142
|
+
* pi-ai's generated Cloudflare AI Gateway registry, keyed by the id AI
|
|
143
|
+
* Gateway's catalog runs each entry under (see {@link gatewayCatalogId}).
|
|
131
144
|
* `/compat` entries are skipped: they alias `@cf/` ids the Workers AI registry
|
|
132
145
|
* already declares, and those belong on the run path.
|
|
133
146
|
*/
|
|
@@ -136,7 +149,7 @@ function buildGatewayRegistry() {
|
|
|
136
149
|
for (const entry of Object.values(CLOUDFLARE_AI_GATEWAY_MODELS)) {
|
|
137
150
|
const slug = slugOf(entry);
|
|
138
151
|
if (slug === void 0 || slug === "compat") continue;
|
|
139
|
-
map.set(
|
|
152
|
+
map.set(gatewayCatalogId(slug, entry.id), entry);
|
|
140
153
|
}
|
|
141
154
|
return map;
|
|
142
155
|
}
|
|
@@ -205,7 +218,7 @@ const API_PATHS = {
|
|
|
205
218
|
"openai-responses": "responses"
|
|
206
219
|
};
|
|
207
220
|
/**
|
|
208
|
-
* The
|
|
221
|
+
* The provider-native `endpoint` for a gateway-shaped base URL, whose path
|
|
209
222
|
* already ends at the provider slug, so what follows is the vendor's own path.
|
|
210
223
|
*/
|
|
211
224
|
const GATEWAY_ENDPOINTS = {
|
|
@@ -482,26 +495,61 @@ function openAIVendorHeaders() {
|
|
|
482
495
|
};
|
|
483
496
|
}
|
|
484
497
|
/**
|
|
485
|
-
*
|
|
498
|
+
* The AI Gateway catalog id a model runs under on `/run`, when it has one: the
|
|
499
|
+
* `<author>/<model>` specifier it was resolved from, spelled as the gateway's
|
|
500
|
+
* catalog spells it (`anthropic/claude-opus-4.8`, not pi's `claude-opus-4-8`).
|
|
501
|
+
*/
|
|
502
|
+
function catalogIdOf(model) {
|
|
503
|
+
const specifier = specifierOf(model);
|
|
504
|
+
return specifier !== void 0 && isCatalogModelId(specifier) ? specifier : void 0;
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Sends a vendor-format request body through AI Gateway, by the binding.
|
|
508
|
+
*
|
|
509
|
+
* A model from pi's Cloudflare AI Gateway catalog runs on `env.AI.run` under
|
|
510
|
+
* its catalog id, in its native `format`: `/run` converts nothing, so the
|
|
511
|
+
* answer — streams included — is the shape this wire parses. Any other model
|
|
512
|
+
* goes to the gateway's provider-native path with the request unchanged; the
|
|
513
|
+
* provider slug comes from the model's base URL and the endpoint from its
|
|
514
|
+
* `api`.
|
|
486
515
|
*
|
|
487
|
-
* The
|
|
488
|
-
*
|
|
489
|
-
*
|
|
490
|
-
*
|
|
491
|
-
* `CloudflareAIError` so fallback and retry classification behave as they do on
|
|
492
|
-
* the Workers AI run path; a vendor's own error response is left alone for the
|
|
493
|
-
* wire's parser to read.
|
|
516
|
+
* The gateway's *own* failures (no such gateway, unified billing unpaid, an
|
|
517
|
+
* unknown catalog model) become a `CloudflareAIError`, so fallback and retry
|
|
518
|
+
* behave as they do on the Workers AI run path; a vendor's own error response
|
|
519
|
+
* on the provider-native path is left for the wire's parser to read.
|
|
494
520
|
*/
|
|
495
|
-
async function
|
|
521
|
+
async function sendGateway(request, transport, body, vendorHeaders, format, onResponse) {
|
|
496
522
|
const { model, options, resolved } = request;
|
|
523
|
+
const catalogId = catalogIdOf(model);
|
|
524
|
+
if (catalogId !== void 0) {
|
|
525
|
+
const { model: _vendorId, ...input } = body;
|
|
526
|
+
const response = await transport.run({
|
|
527
|
+
format,
|
|
528
|
+
gateway: resolved.gateway,
|
|
529
|
+
headers: request.headers,
|
|
530
|
+
input,
|
|
531
|
+
model: catalogId,
|
|
532
|
+
signal: options.signal
|
|
533
|
+
});
|
|
534
|
+
onResponse?.(response);
|
|
535
|
+
if (!response.ok) throw await errorFromResponse(response, {
|
|
536
|
+
model: catalogId,
|
|
537
|
+
requestBodyValues: input,
|
|
538
|
+
url: transport.url
|
|
539
|
+
});
|
|
540
|
+
return response;
|
|
541
|
+
}
|
|
497
542
|
const route = routeForModel(model);
|
|
498
|
-
const response = await transport.
|
|
543
|
+
const response = await transport.native({
|
|
544
|
+
body: JSON.stringify(body),
|
|
499
545
|
endpoint: route.endpoint,
|
|
500
|
-
extraHeaders: Object.keys(request.headers).length > 0 ? request.headers : void 0,
|
|
501
546
|
gateway: resolved.gateway,
|
|
502
|
-
headers:
|
|
547
|
+
headers: {
|
|
548
|
+
...vendorHeaders,
|
|
549
|
+
...request.headers
|
|
550
|
+
},
|
|
551
|
+
method: "POST",
|
|
503
552
|
provider: route.provider,
|
|
504
|
-
query: body,
|
|
505
553
|
signal: options.signal
|
|
506
554
|
});
|
|
507
555
|
onResponse?.(response);
|
|
@@ -599,7 +647,7 @@ async function assertOk(response, context) {
|
|
|
599
647
|
//#region src/models/pi-ai/wires/chat-completions.ts
|
|
600
648
|
/**
|
|
601
649
|
* Chat-completions wire: Workers AI on the run path, and any pi-ai model whose
|
|
602
|
-
* `api` is `openai-completions
|
|
650
|
+
* `api` is `openai-completions`, through AI Gateway.
|
|
603
651
|
*
|
|
604
652
|
* The request is shaped with pi-ai's own message converter so replay rules
|
|
605
653
|
* (tool-call id normalization, reasoning replay, role bridging) match pi's
|
|
@@ -836,7 +884,7 @@ var CompletionAssembler = class {
|
|
|
836
884
|
const choice = chunk.choices?.[0];
|
|
837
885
|
if (chunk.id !== void 0) this.output.responseId ??= chunk.id;
|
|
838
886
|
if (typeof chunk.model === "string" && chunk.model.length > 0 && chunk.model !== this.model.id) this.output.responseModel ??= chunk.model;
|
|
839
|
-
if (chunk.usage !== void 0) this.output.usage = usageFromOpenAI(this.model, chunk.usage);
|
|
887
|
+
if (chunk.usage !== void 0 && chunk.usage !== null) this.output.usage = usageFromOpenAI(this.model, chunk.usage);
|
|
840
888
|
const finished = this.applyFinishReason(choice?.finish_reason);
|
|
841
889
|
const delta = choice?.delta ?? choice?.message;
|
|
842
890
|
if (delta !== void 0) {
|
|
@@ -960,12 +1008,13 @@ function streamCompletions(request, transport) {
|
|
|
960
1008
|
const overridden = await options.onPayload?.(prepared.body, model);
|
|
961
1009
|
const payload = overridden === void 0 ? prepared.body : overridden;
|
|
962
1010
|
response = workersAI ? await transport.run({
|
|
1011
|
+
format: "chat-completions",
|
|
963
1012
|
gateway: resolved.gateway,
|
|
964
1013
|
headers: request.headers,
|
|
965
1014
|
input: payload,
|
|
966
1015
|
model: model.id,
|
|
967
1016
|
signal: options.signal
|
|
968
|
-
}) : await
|
|
1017
|
+
}) : await sendGateway(request, transport, payload, openAIVendorHeaders(), "chat-completions");
|
|
969
1018
|
await options.onResponse?.(responseInfo(response), model);
|
|
970
1019
|
attachCorrelation(output, correlationDetails(request, response, transport));
|
|
971
1020
|
await assertOk(response, {
|
|
@@ -1257,7 +1306,7 @@ function buildRequest(model, context, options, simple, config) {
|
|
|
1257
1306
|
//#region src/models/pi-ai/wires/anthropic.ts
|
|
1258
1307
|
/**
|
|
1259
1308
|
* Anthropic Messages wire: pi-ai's own Anthropic implementation, over AI
|
|
1260
|
-
* Gateway
|
|
1309
|
+
* Gateway — `/run` for a catalog model, the provider-native path otherwise.
|
|
1261
1310
|
*
|
|
1262
1311
|
* Everything about the wire — request shaping, thinking, tool use, stream
|
|
1263
1312
|
* parsing, thinking-signature replay — is pi-ai's. It accepts a `client` whose
|
|
@@ -1317,7 +1366,7 @@ function streamAnthropic(request, transport) {
|
|
|
1317
1366
|
model: wireModelId(model)
|
|
1318
1367
|
};
|
|
1319
1368
|
try {
|
|
1320
|
-
const response = await
|
|
1369
|
+
const response = await sendGateway(request, transport, body, anthropicVendorHeaders(Array.isArray(betas) ? betas : []), "messages", (raw) => {
|
|
1321
1370
|
correlation = correlationDetails(request, raw, transport);
|
|
1322
1371
|
});
|
|
1323
1372
|
await assertOk(response, {
|
|
@@ -1380,7 +1429,8 @@ function streamAnthropic(request, transport) {
|
|
|
1380
1429
|
//#region src/models/pi-ai/wires/responses.ts
|
|
1381
1430
|
/**
|
|
1382
1431
|
* OpenAI Responses wire: pi-ai's own Responses converters and stream
|
|
1383
|
-
* processor, over AI Gateway
|
|
1432
|
+
* processor, over AI Gateway: `/run` for a catalog model, the provider-native
|
|
1433
|
+
* path otherwise.
|
|
1384
1434
|
*
|
|
1385
1435
|
* Only the transport differs from talking to OpenAI directly: the body goes to
|
|
1386
1436
|
* the gateway, which forwards it to `api.openai.com/v1/responses` with the key
|
|
@@ -1445,7 +1495,7 @@ function streamResponses(request, transport) {
|
|
|
1445
1495
|
if (sampling !== void 0) Object.assign(body, sampling);
|
|
1446
1496
|
const overridden = await options.onPayload?.(body, model);
|
|
1447
1497
|
const payload = overridden === void 0 ? body : overridden;
|
|
1448
|
-
response = await
|
|
1498
|
+
response = await sendGateway(request, transport, payload, openAIVendorHeaders(), "responses");
|
|
1449
1499
|
await options.onResponse?.(responseInfo(response), model);
|
|
1450
1500
|
attachCorrelation(output, correlationDetails(request, response, transport));
|
|
1451
1501
|
recordWarnings(output, ignoredWorkersAIKnobs(request));
|
|
@@ -1612,7 +1662,8 @@ function streamWithFallback(legs, signal) {
|
|
|
1612
1662
|
* The `api` is the model author's declaration, not a guess of ours: Workers AI
|
|
1613
1663
|
* models carry {@link CLOUDFLARE_AI_API} and run on `env.AI.run`; every other
|
|
1614
1664
|
* model carries whatever protocol its registry says it speaks, and goes to AI
|
|
1615
|
-
* Gateway
|
|
1665
|
+
* Gateway in that protocol: `/run` for a catalog model, the provider-native
|
|
1666
|
+
* path otherwise.
|
|
1616
1667
|
*/
|
|
1617
1668
|
/** A stream that fails immediately, for a model this provider cannot route. */
|
|
1618
1669
|
function failedStream(request, error) {
|
|
@@ -1646,7 +1697,7 @@ function legOptions(options) {
|
|
|
1646
1697
|
}
|
|
1647
1698
|
/** A leg may be given as a Workers AI id or as a model of any kind. */
|
|
1648
1699
|
function legModel(leg, options) {
|
|
1649
|
-
if (typeof leg === "string") return leg
|
|
1700
|
+
if (typeof leg === "string") return isRunPathLanguageModelId(leg) ? buildWorkersAIModel(leg, options) : buildGatewayModel(leg, options);
|
|
1650
1701
|
const own = optionsOf(leg);
|
|
1651
1702
|
const inherited = gatewayLayerOf(options);
|
|
1652
1703
|
return withOptions(leg, mergeModelOptions(own, Object.keys(inherited).length > 0 ? inherited : void 0));
|
|
@@ -1700,8 +1751,9 @@ function createStreams(config) {
|
|
|
1700
1751
|
* ```
|
|
1701
1752
|
*
|
|
1702
1753
|
* Workers AI runs on `env.AI.run` with Cloudflare's own compat layer. Every
|
|
1703
|
-
* other model goes to AI Gateway
|
|
1704
|
-
*
|
|
1754
|
+
* other model goes to AI Gateway in its own protocol — `/run` for a model
|
|
1755
|
+
* from the gateway's catalog, the provider-native path otherwise — and the
|
|
1756
|
+
* gateway calls the vendor with the key it holds, so no
|
|
1705
1757
|
* provider key, and no vendor wire format, lives in your Worker. The model's
|
|
1706
1758
|
* metadata (`api`, `compat`, `thinkingLevelMap`, cost, limits) is whatever its
|
|
1707
1759
|
* own registry says, and pi-ai's converters and stream processors do the rest.
|
|
@@ -1724,25 +1776,26 @@ const VENDOR_HINTS = {
|
|
|
1724
1776
|
*/
|
|
1725
1777
|
function unroutableString(specifier) {
|
|
1726
1778
|
const hint = VENDOR_HINTS[specifier.split("/")[0] ?? ""];
|
|
1727
|
-
return /* @__PURE__ */ new TypeError(`ai("${specifier}") is not a model this provider knows. Workers AI ids start with "@cf/". A third-party model comes from its own pi-ai registry: ai(getBuiltinModel(${hint === void 0 ? "\"<provider>\"" : `"${hint}"`}, "<model id>")) from "@earendil-works/pi-ai/providers/all", or any Model object you built yourself.`);
|
|
1779
|
+
return /* @__PURE__ */ new TypeError(`ai("${specifier}") is not a model this provider knows. Workers AI ids start with "@cf/", AI Gateway dynamic routes with "dynamic/". A third-party model comes from its own pi-ai registry: ai(getBuiltinModel(${hint === void 0 ? "\"<provider>\"" : `"${hint}"`}, "<model id>")) from "@earendil-works/pi-ai/providers/all", or any Model object you built yourself.`);
|
|
1728
1780
|
}
|
|
1729
1781
|
function buildModel(target, options) {
|
|
1730
1782
|
for (const leg of options?.fallback ?? []) {
|
|
1731
|
-
if (typeof leg !== "string" || leg
|
|
1783
|
+
if (typeof leg !== "string" || isRunPathLanguageModelId(leg)) continue;
|
|
1732
1784
|
if (!leg.includes("/")) throw unroutableString(leg);
|
|
1733
1785
|
buildGatewayModel(leg, void 0);
|
|
1734
1786
|
}
|
|
1735
1787
|
if (typeof target !== "string") return withOptions(target, options);
|
|
1736
|
-
if (target
|
|
1788
|
+
if (isRunPathLanguageModelId(target)) return buildWorkersAIModel(target, options);
|
|
1737
1789
|
if (!target.includes("/")) throw unroutableString(target);
|
|
1738
1790
|
return buildGatewayModel(target, options);
|
|
1739
1791
|
}
|
|
1740
1792
|
/**
|
|
1741
1793
|
* Creates a pi-ai provider over Cloudflare's AI.
|
|
1742
1794
|
*
|
|
1743
|
-
*
|
|
1744
|
-
*
|
|
1745
|
-
*
|
|
1795
|
+
* Workers AI and catalog models go through `env.AI.run`, other model objects
|
|
1796
|
+
* through the binding's `fetch` to AI Gateway's provider-native path. With
|
|
1797
|
+
* `{ accountId, apiToken }` instead of `binding`, the same requests go to the
|
|
1798
|
+
* REST API and to `gateway.ai.cloudflare.com`. Gateway options may be given flat
|
|
1746
1799
|
* (`{ binding, id: "prod", cacheTtl: 60 }`) or nested under `gateway`;
|
|
1747
1800
|
* per-model options and per-call pi-ai options (`headers`, `metadata`,
|
|
1748
1801
|
* `sessionId`) override them in that order.
|