workers-ai-provider 3.1.13 → 3.2.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/README.md +183 -31
- package/dist/anthropic.d.mts +14 -0
- package/dist/anthropic.mjs +21 -0
- package/dist/anthropic.mjs.map +1 -0
- package/dist/gateway-delegate-BfaUTwDZ.d.mts +385 -0
- package/dist/gateway-provider-1USFWm7c.mjs +583 -0
- package/dist/gateway-provider-1USFWm7c.mjs.map +1 -0
- package/dist/gateway-provider.d.mts +80 -0
- package/dist/gateway-provider.mjs +2 -0
- package/dist/google.d.mts +14 -0
- package/dist/google.mjs +21 -0
- package/dist/google.mjs.map +1 -0
- package/dist/index.d.mts +64 -7
- package/dist/index.mjs +967 -327
- package/dist/index.mjs.map +1 -1
- package/dist/openai.d.mts +20 -0
- package/dist/openai.mjs +27 -0
- package/dist/openai.mjs.map +1 -0
- package/package.json +47 -6
- package/src/anthropic.ts +17 -0
- package/src/client-fallback.ts +70 -0
- package/src/convert-to-workersai-chat-messages.ts +33 -7
- package/src/errors.ts +216 -0
- package/src/gateway-delegate.ts +696 -0
- package/src/gateway-provider.ts +167 -0
- package/src/gateway-providers.ts +457 -0
- package/src/google.ts +19 -0
- package/src/index.ts +180 -9
- package/src/openai.ts +25 -0
- package/src/resumable-stream.ts +223 -0
- package/src/streaming.ts +103 -30
- package/src/utils.ts +206 -6
- package/src/workersai-chat-language-model.ts +87 -26
- package/src/workersai-chat-settings.ts +1 -1
- package/src/workersai-models.ts +11 -3
|
@@ -0,0 +1,583 @@
|
|
|
1
|
+
//#region \0@oxc-project+runtime@0.135.0/helpers/esm/typeof.js
|
|
2
|
+
function _typeof(o) {
|
|
3
|
+
"@babel/helpers - typeof";
|
|
4
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|
5
|
+
return typeof o;
|
|
6
|
+
} : function(o) {
|
|
7
|
+
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
8
|
+
}, _typeof(o);
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region \0@oxc-project+runtime@0.135.0/helpers/esm/toPrimitive.js
|
|
12
|
+
function toPrimitive(t, r) {
|
|
13
|
+
if ("object" != _typeof(t) || !t) return t;
|
|
14
|
+
var e = t[Symbol.toPrimitive];
|
|
15
|
+
if (void 0 !== e) {
|
|
16
|
+
var i = e.call(t, r || "default");
|
|
17
|
+
if ("object" != _typeof(i)) return i;
|
|
18
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
19
|
+
}
|
|
20
|
+
return ("string" === r ? String : Number)(t);
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region \0@oxc-project+runtime@0.135.0/helpers/esm/toPropertyKey.js
|
|
24
|
+
function toPropertyKey(t) {
|
|
25
|
+
var i = toPrimitive(t, "string");
|
|
26
|
+
return "symbol" == _typeof(i) ? i : i + "";
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
//#region \0@oxc-project+runtime@0.135.0/helpers/esm/defineProperty.js
|
|
30
|
+
function _defineProperty(e, r, t) {
|
|
31
|
+
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
32
|
+
value: t,
|
|
33
|
+
enumerable: !0,
|
|
34
|
+
configurable: !0,
|
|
35
|
+
writable: !0
|
|
36
|
+
}) : e[r] = t, e;
|
|
37
|
+
}
|
|
38
|
+
//#endregion
|
|
39
|
+
//#region src/errors.ts
|
|
40
|
+
/** Map an HTTP status to a {@link GatewayErrorCode} + recoverability hint. */
|
|
41
|
+
function classifyStatus(status) {
|
|
42
|
+
if (status === 401 || status === 403) return {
|
|
43
|
+
code: "auth",
|
|
44
|
+
recoverable: false
|
|
45
|
+
};
|
|
46
|
+
if (status === 429) return {
|
|
47
|
+
code: "rate-limit",
|
|
48
|
+
recoverable: true
|
|
49
|
+
};
|
|
50
|
+
if (status === 404) return {
|
|
51
|
+
code: "not-found",
|
|
52
|
+
recoverable: false
|
|
53
|
+
};
|
|
54
|
+
if (status === 400 || status === 422) return {
|
|
55
|
+
code: "bad-request",
|
|
56
|
+
recoverable: false
|
|
57
|
+
};
|
|
58
|
+
if (status >= 500) return {
|
|
59
|
+
code: "provider-error",
|
|
60
|
+
recoverable: true
|
|
61
|
+
};
|
|
62
|
+
return {
|
|
63
|
+
code: "unknown",
|
|
64
|
+
recoverable: false
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/** Best-effort extraction of a human message from a CF/provider error envelope. */
|
|
68
|
+
function extractErrorMessage(raw) {
|
|
69
|
+
if (typeof raw === "string") {
|
|
70
|
+
const trimmed = raw.trim();
|
|
71
|
+
if (!trimmed) return void 0;
|
|
72
|
+
try {
|
|
73
|
+
return extractErrorMessage(JSON.parse(trimmed));
|
|
74
|
+
} catch {
|
|
75
|
+
return trimmed.slice(0, 500);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
79
|
+
const obj = raw;
|
|
80
|
+
if (Array.isArray(obj.errors) && obj.errors.length > 0) {
|
|
81
|
+
const first = obj.errors[0];
|
|
82
|
+
if (typeof first?.message === "string") return first.message;
|
|
83
|
+
}
|
|
84
|
+
if (obj.error && typeof obj.error === "object") {
|
|
85
|
+
const err = obj.error;
|
|
86
|
+
if (typeof err.message === "string") return err.message;
|
|
87
|
+
}
|
|
88
|
+
if (typeof obj.error === "string") return obj.error;
|
|
89
|
+
if (typeof obj.message === "string") return obj.message;
|
|
90
|
+
}
|
|
91
|
+
/** A single dispatch failure through AI Gateway (run or gateway path). */
|
|
92
|
+
var WorkersAIGatewayError = class WorkersAIGatewayError extends Error {
|
|
93
|
+
constructor(code, message, opts = {}) {
|
|
94
|
+
super(message);
|
|
95
|
+
_defineProperty(this, "code", void 0);
|
|
96
|
+
_defineProperty(this, "recoverable", void 0);
|
|
97
|
+
_defineProperty(this, "status", void 0);
|
|
98
|
+
_defineProperty(this, "context", void 0);
|
|
99
|
+
_defineProperty(this, "raw", void 0);
|
|
100
|
+
_defineProperty(this, "cause", void 0);
|
|
101
|
+
this.name = "WorkersAIGatewayError";
|
|
102
|
+
this.code = code;
|
|
103
|
+
this.recoverable = opts.recoverable ?? false;
|
|
104
|
+
this.status = opts.status ?? null;
|
|
105
|
+
this.context = opts.context ?? {};
|
|
106
|
+
this.raw = opts.raw;
|
|
107
|
+
this.cause = opts.cause;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Classify an arbitrary thrown value. Understands AI SDK `APICallError`
|
|
111
|
+
* (reads `statusCode` / `responseBody` / `isRetryable`); falls back to a
|
|
112
|
+
* recoverable `gateway-error` for transport/connection failures so a fallback
|
|
113
|
+
* chain keeps trying.
|
|
114
|
+
*/
|
|
115
|
+
static fromUnknown(e) {
|
|
116
|
+
if (e instanceof WorkersAIGatewayError) return e;
|
|
117
|
+
const obj = e && typeof e === "object" ? e : {};
|
|
118
|
+
const status = typeof obj.statusCode === "number" ? obj.statusCode : null;
|
|
119
|
+
const responseBody = typeof obj.responseBody === "string" ? obj.responseBody : void 0;
|
|
120
|
+
if (status !== null) {
|
|
121
|
+
const classified = classifyStatus(status);
|
|
122
|
+
const recoverable = typeof obj.isRetryable === "boolean" ? obj.isRetryable : classified.recoverable;
|
|
123
|
+
const message = extractErrorMessage(responseBody) ?? (e instanceof Error ? e.message : `Gateway dispatch failed (HTTP ${status}).`);
|
|
124
|
+
let raw = responseBody;
|
|
125
|
+
try {
|
|
126
|
+
raw = responseBody ? JSON.parse(responseBody) : responseBody;
|
|
127
|
+
} catch {}
|
|
128
|
+
return new WorkersAIGatewayError(classified.code, message, {
|
|
129
|
+
recoverable,
|
|
130
|
+
status,
|
|
131
|
+
raw,
|
|
132
|
+
cause: e
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return new WorkersAIGatewayError("gateway-error", e instanceof Error ? e.message : String(e), {
|
|
136
|
+
recoverable: true,
|
|
137
|
+
cause: e
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/** Build from an HTTP `Response` (reads the body for the envelope). */
|
|
141
|
+
static async fromResponse(resp, context = {}) {
|
|
142
|
+
const text = await resp.text().catch(() => "");
|
|
143
|
+
const { code, recoverable } = classifyStatus(resp.status);
|
|
144
|
+
const message = extractErrorMessage(text) ?? `Gateway dispatch failed (HTTP ${resp.status}).`;
|
|
145
|
+
let raw = text;
|
|
146
|
+
try {
|
|
147
|
+
raw = text ? JSON.parse(text) : text;
|
|
148
|
+
} catch {}
|
|
149
|
+
return new WorkersAIGatewayError(code, message, {
|
|
150
|
+
recoverable,
|
|
151
|
+
status: resp.status,
|
|
152
|
+
raw,
|
|
153
|
+
context: {
|
|
154
|
+
...context,
|
|
155
|
+
status: resp.status,
|
|
156
|
+
logId: resp.headers.get("cf-aig-log-id"),
|
|
157
|
+
runId: resp.headers.get("cf-aig-run-id")
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
/** Every model in a client-side fallback chain failed. */
|
|
163
|
+
var WorkersAIFallbackError = class extends Error {
|
|
164
|
+
constructor(attempts, message) {
|
|
165
|
+
const tried = attempts.map((a) => a.model).join(" → ");
|
|
166
|
+
super(message ?? `All fallback models failed: ${tried}.`);
|
|
167
|
+
_defineProperty(this, "attempts", void 0);
|
|
168
|
+
this.name = "WorkersAIFallbackError";
|
|
169
|
+
this.attempts = attempts;
|
|
170
|
+
}
|
|
171
|
+
/** The last (most recent) attempt's error, if any. */
|
|
172
|
+
get lastError() {
|
|
173
|
+
for (let i = this.attempts.length - 1; i >= 0; i--) {
|
|
174
|
+
const e = this.attempts[i].error;
|
|
175
|
+
if (e) return e;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
//#endregion
|
|
180
|
+
//#region src/gateway-providers.ts
|
|
181
|
+
/** Strip a leading `https://<host>/` prefix, leaving the endpoint path + query. */
|
|
182
|
+
function hostStrip(pattern) {
|
|
183
|
+
return (url) => url.replace(pattern, "");
|
|
184
|
+
}
|
|
185
|
+
const OPENAI_HOST = /^https:\/\/api\.openai\.com\//;
|
|
186
|
+
const ANTHROPIC_HOST = /^https:\/\/api\.anthropic\.com\//;
|
|
187
|
+
const GOOGLE_HOST = /^https:\/\/generativelanguage\.googleapis\.com\//;
|
|
188
|
+
const VERTEX_HOST = /^https:\/\/(?:[a-z0-9-]+-)?aiplatform\.googleapis\.com\//;
|
|
189
|
+
const XAI_HOST = /^https:\/\/api\.x\.ai\//;
|
|
190
|
+
const GROQ_HOST = /^https:\/\/api\.groq\.com\/openai\/v1\//;
|
|
191
|
+
const DEEPSEEK_HOST = /^https:\/\/api\.deepseek\.com\//;
|
|
192
|
+
const MISTRAL_HOST = /^https:\/\/api\.mistral\.ai\//;
|
|
193
|
+
const PERPLEXITY_HOST = /^https:\/\/api\.perplexity\.ai\//;
|
|
194
|
+
const CEREBRAS_HOST = /^https:\/\/api\.cerebras\.ai\//;
|
|
195
|
+
const OPENROUTER_HOST = /^https:\/\/openrouter\.ai\/api\//;
|
|
196
|
+
const FIREWORKS_HOST = /^https:\/\/api\.fireworks\.ai\/inference\/v1\//;
|
|
197
|
+
const COHERE_HOST = /^https:\/\/api\.cohere\.(?:com|ai)\//;
|
|
198
|
+
const REPLICATE_HOST = /^https:\/\/api\.replicate\.com\//;
|
|
199
|
+
const HUGGINGFACE_HOST = /^https:\/\/api-inference\.huggingface\.co\/models\//;
|
|
200
|
+
const CARTESIA_HOST = /^https:\/\/api\.cartesia\.ai\//;
|
|
201
|
+
const FAL_HOST = /^https:\/\/fal\.run\//;
|
|
202
|
+
const IDEOGRAM_HOST = /^https:\/\/api\.ideogram\.ai\//;
|
|
203
|
+
const DEEPGRAM_HOST = /^https:\/\/api\.deepgram\.com\//;
|
|
204
|
+
const ELEVENLABS_HOST = /^https:\/\/api\.elevenlabs\.io\//;
|
|
205
|
+
const GROK_KEY = "grok";
|
|
206
|
+
const BEDROCK_HOST = /^https:\/\/bedrock-runtime\.(?<region>[^.]+)\.amazonaws\.com\//;
|
|
207
|
+
function bedrockTransform(url) {
|
|
208
|
+
const m = url.match(/^https:\/\/bedrock-runtime\.(?<region>[^.]+)\.amazonaws\.com\/(?<rest>.*)$/);
|
|
209
|
+
if (!m?.groups) return url;
|
|
210
|
+
const { region, rest } = m.groups;
|
|
211
|
+
if (!region || rest === void 0) return url;
|
|
212
|
+
return `bedrock-runtime/${region}/${rest}`;
|
|
213
|
+
}
|
|
214
|
+
const AZURE_HOST = /^https:\/\/(?<resource>[^.]+)\.openai\.azure\.com\/openai\/deployments\/(?<deployment>[^/]+)\/(?<rest>.*)$/;
|
|
215
|
+
function azureTransform(url) {
|
|
216
|
+
const m = url.match(AZURE_HOST);
|
|
217
|
+
if (!m?.groups) return url;
|
|
218
|
+
const { resource, deployment, rest } = m.groups;
|
|
219
|
+
if (!resource || !deployment || !rest) return url;
|
|
220
|
+
return `${resource}/${deployment}/${rest}`;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* The provider table. Order matters only for `detectProviderByUrl` (first match
|
|
224
|
+
* wins); slugs are looked up by `resolverKey`.
|
|
225
|
+
*/
|
|
226
|
+
const GATEWAY_PROVIDERS = [
|
|
227
|
+
{
|
|
228
|
+
resolverKey: "openai",
|
|
229
|
+
gatewayProviderId: "openai",
|
|
230
|
+
wireFormat: "openai",
|
|
231
|
+
runCatalog: true,
|
|
232
|
+
billing: "unified",
|
|
233
|
+
authHeaders: ["authorization"],
|
|
234
|
+
hostPattern: OPENAI_HOST,
|
|
235
|
+
transformEndpoint: hostStrip(OPENAI_HOST)
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
resolverKey: "anthropic",
|
|
239
|
+
gatewayProviderId: "anthropic",
|
|
240
|
+
wireFormat: "anthropic",
|
|
241
|
+
runWireFormat: "anthropic",
|
|
242
|
+
runCatalog: true,
|
|
243
|
+
billing: "unified",
|
|
244
|
+
authHeaders: ["x-api-key", "authorization"],
|
|
245
|
+
hostPattern: ANTHROPIC_HOST,
|
|
246
|
+
transformEndpoint: hostStrip(ANTHROPIC_HOST)
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
resolverKey: "google",
|
|
250
|
+
gatewayProviderId: "google-ai-studio",
|
|
251
|
+
wireFormat: "google",
|
|
252
|
+
runCatalog: true,
|
|
253
|
+
billing: "unified",
|
|
254
|
+
authHeaders: ["x-goog-api-key", "authorization"],
|
|
255
|
+
hostPattern: GOOGLE_HOST,
|
|
256
|
+
transformEndpoint: hostStrip(GOOGLE_HOST)
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
resolverKey: "xai",
|
|
260
|
+
gatewayProviderId: GROK_KEY,
|
|
261
|
+
wireFormat: "openai",
|
|
262
|
+
baseURL: "https://api.x.ai/v1",
|
|
263
|
+
runCatalog: true,
|
|
264
|
+
billing: "unified",
|
|
265
|
+
authHeaders: ["authorization"],
|
|
266
|
+
hostPattern: XAI_HOST,
|
|
267
|
+
transformEndpoint: hostStrip(XAI_HOST)
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
resolverKey: "groq",
|
|
271
|
+
gatewayProviderId: "groq",
|
|
272
|
+
wireFormat: "openai",
|
|
273
|
+
baseURL: "https://api.groq.com/openai/v1",
|
|
274
|
+
runCatalog: true,
|
|
275
|
+
billing: "unified",
|
|
276
|
+
authHeaders: ["authorization"],
|
|
277
|
+
hostPattern: GROQ_HOST,
|
|
278
|
+
transformEndpoint: hostStrip(GROQ_HOST)
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
resolverKey: "alibaba",
|
|
282
|
+
gatewayProviderId: "alibaba",
|
|
283
|
+
wireFormat: "openai",
|
|
284
|
+
runCatalog: true,
|
|
285
|
+
gatewayPath: false,
|
|
286
|
+
billing: "unified",
|
|
287
|
+
authHeaders: ["authorization"]
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
resolverKey: "minimax",
|
|
291
|
+
gatewayProviderId: "minimax",
|
|
292
|
+
wireFormat: "openai",
|
|
293
|
+
runCatalog: true,
|
|
294
|
+
gatewayPath: false,
|
|
295
|
+
billing: "unified",
|
|
296
|
+
authHeaders: ["authorization"]
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
resolverKey: "google-vertex",
|
|
300
|
+
gatewayProviderId: "google-vertex-ai",
|
|
301
|
+
runCatalog: false,
|
|
302
|
+
billing: "unified",
|
|
303
|
+
authHeaders: ["authorization"],
|
|
304
|
+
hostPattern: VERTEX_HOST,
|
|
305
|
+
transformEndpoint: hostStrip(VERTEX_HOST)
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
resolverKey: "deepseek",
|
|
309
|
+
gatewayProviderId: "deepseek",
|
|
310
|
+
wireFormat: "openai",
|
|
311
|
+
baseURL: "https://api.deepseek.com",
|
|
312
|
+
runCatalog: false,
|
|
313
|
+
billing: "byok",
|
|
314
|
+
authHeaders: ["authorization"],
|
|
315
|
+
hostPattern: DEEPSEEK_HOST,
|
|
316
|
+
transformEndpoint: hostStrip(DEEPSEEK_HOST)
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
resolverKey: "mistral",
|
|
320
|
+
gatewayProviderId: "mistral",
|
|
321
|
+
wireFormat: "openai",
|
|
322
|
+
baseURL: "https://api.mistral.ai/v1",
|
|
323
|
+
runCatalog: false,
|
|
324
|
+
billing: "byok",
|
|
325
|
+
authHeaders: ["authorization"],
|
|
326
|
+
hostPattern: MISTRAL_HOST,
|
|
327
|
+
transformEndpoint: hostStrip(MISTRAL_HOST)
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
resolverKey: "perplexity",
|
|
331
|
+
gatewayProviderId: "perplexity-ai",
|
|
332
|
+
wireFormat: "openai",
|
|
333
|
+
baseURL: "https://api.perplexity.ai",
|
|
334
|
+
runCatalog: false,
|
|
335
|
+
billing: "byok",
|
|
336
|
+
authHeaders: ["authorization"],
|
|
337
|
+
hostPattern: PERPLEXITY_HOST,
|
|
338
|
+
transformEndpoint: hostStrip(PERPLEXITY_HOST)
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
resolverKey: "cerebras",
|
|
342
|
+
gatewayProviderId: "cerebras",
|
|
343
|
+
wireFormat: "openai",
|
|
344
|
+
baseURL: "https://api.cerebras.ai/v1",
|
|
345
|
+
runCatalog: false,
|
|
346
|
+
billing: "byok",
|
|
347
|
+
authHeaders: ["authorization"],
|
|
348
|
+
hostPattern: CEREBRAS_HOST,
|
|
349
|
+
transformEndpoint: hostStrip(CEREBRAS_HOST)
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
resolverKey: "openrouter",
|
|
353
|
+
gatewayProviderId: "openrouter",
|
|
354
|
+
wireFormat: "openai",
|
|
355
|
+
baseURL: "https://openrouter.ai/api/v1",
|
|
356
|
+
runCatalog: false,
|
|
357
|
+
billing: "byok",
|
|
358
|
+
authHeaders: ["authorization"],
|
|
359
|
+
hostPattern: OPENROUTER_HOST,
|
|
360
|
+
transformEndpoint: hostStrip(OPENROUTER_HOST)
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
resolverKey: "fireworks",
|
|
364
|
+
gatewayProviderId: "fireworks",
|
|
365
|
+
wireFormat: "openai",
|
|
366
|
+
baseURL: "https://api.fireworks.ai/inference/v1",
|
|
367
|
+
runCatalog: false,
|
|
368
|
+
billing: "byok",
|
|
369
|
+
authHeaders: ["authorization"],
|
|
370
|
+
hostPattern: FIREWORKS_HOST,
|
|
371
|
+
transformEndpoint: hostStrip(FIREWORKS_HOST)
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
resolverKey: "cohere",
|
|
375
|
+
gatewayProviderId: "cohere",
|
|
376
|
+
runCatalog: false,
|
|
377
|
+
billing: "byok",
|
|
378
|
+
authHeaders: ["authorization"],
|
|
379
|
+
hostPattern: COHERE_HOST,
|
|
380
|
+
transformEndpoint: hostStrip(COHERE_HOST)
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
resolverKey: "baseten",
|
|
384
|
+
gatewayProviderId: "baseten",
|
|
385
|
+
runCatalog: false,
|
|
386
|
+
billing: "byok",
|
|
387
|
+
authHeaders: ["authorization"]
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
resolverKey: "parallel",
|
|
391
|
+
gatewayProviderId: "parallel",
|
|
392
|
+
runCatalog: false,
|
|
393
|
+
billing: "byok",
|
|
394
|
+
authHeaders: ["authorization", "x-api-key"]
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
resolverKey: "azure-openai",
|
|
398
|
+
gatewayProviderId: "azure-openai",
|
|
399
|
+
runCatalog: false,
|
|
400
|
+
billing: "byok",
|
|
401
|
+
authHeaders: ["api-key", "authorization"],
|
|
402
|
+
hostPattern: AZURE_HOST,
|
|
403
|
+
transformEndpoint: azureTransform
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
resolverKey: "aws-bedrock",
|
|
407
|
+
gatewayProviderId: "aws-bedrock",
|
|
408
|
+
runCatalog: false,
|
|
409
|
+
billing: "byok",
|
|
410
|
+
authHeaders: ["authorization"],
|
|
411
|
+
hostPattern: BEDROCK_HOST,
|
|
412
|
+
transformEndpoint: bedrockTransform
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
resolverKey: "huggingface",
|
|
416
|
+
gatewayProviderId: "huggingface",
|
|
417
|
+
runCatalog: false,
|
|
418
|
+
billing: "byok",
|
|
419
|
+
authHeaders: ["authorization"],
|
|
420
|
+
hostPattern: HUGGINGFACE_HOST,
|
|
421
|
+
transformEndpoint: hostStrip(HUGGINGFACE_HOST)
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
resolverKey: "replicate",
|
|
425
|
+
gatewayProviderId: "replicate",
|
|
426
|
+
runCatalog: false,
|
|
427
|
+
billing: "byok",
|
|
428
|
+
authHeaders: ["authorization"],
|
|
429
|
+
hostPattern: REPLICATE_HOST,
|
|
430
|
+
transformEndpoint: hostStrip(REPLICATE_HOST)
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
resolverKey: "fal",
|
|
434
|
+
gatewayProviderId: "fal",
|
|
435
|
+
runCatalog: false,
|
|
436
|
+
billing: "byok",
|
|
437
|
+
authHeaders: ["authorization"],
|
|
438
|
+
hostPattern: FAL_HOST,
|
|
439
|
+
transformEndpoint: hostStrip(FAL_HOST)
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
resolverKey: "ideogram",
|
|
443
|
+
gatewayProviderId: "ideogram",
|
|
444
|
+
runCatalog: false,
|
|
445
|
+
billing: "byok",
|
|
446
|
+
authHeaders: ["authorization"],
|
|
447
|
+
hostPattern: IDEOGRAM_HOST,
|
|
448
|
+
transformEndpoint: hostStrip(IDEOGRAM_HOST)
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
resolverKey: "cartesia",
|
|
452
|
+
gatewayProviderId: "cartesia",
|
|
453
|
+
runCatalog: false,
|
|
454
|
+
billing: "byok",
|
|
455
|
+
authHeaders: ["authorization", "x-api-key"],
|
|
456
|
+
hostPattern: CARTESIA_HOST,
|
|
457
|
+
transformEndpoint: hostStrip(CARTESIA_HOST)
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
resolverKey: "deepgram",
|
|
461
|
+
gatewayProviderId: "deepgram",
|
|
462
|
+
runCatalog: false,
|
|
463
|
+
billing: "byok",
|
|
464
|
+
authHeaders: ["authorization", "token"],
|
|
465
|
+
hostPattern: DEEPGRAM_HOST,
|
|
466
|
+
transformEndpoint: hostStrip(DEEPGRAM_HOST)
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
resolverKey: "elevenlabs",
|
|
470
|
+
gatewayProviderId: "elevenlabs",
|
|
471
|
+
runCatalog: false,
|
|
472
|
+
billing: "byok",
|
|
473
|
+
authHeaders: ["xi-api-key", "authorization"],
|
|
474
|
+
hostPattern: ELEVENLABS_HOST,
|
|
475
|
+
transformEndpoint: hostStrip(ELEVENLABS_HOST)
|
|
476
|
+
}
|
|
477
|
+
];
|
|
478
|
+
/** Aliases that map a friendly slug prefix to a canonical `resolverKey`. */
|
|
479
|
+
const RESOLVER_ALIASES = {
|
|
480
|
+
grok: "xai",
|
|
481
|
+
"google-ai-studio": "google",
|
|
482
|
+
"google-vertex-ai": "google-vertex",
|
|
483
|
+
bedrock: "aws-bedrock",
|
|
484
|
+
azure: "azure-openai"
|
|
485
|
+
};
|
|
486
|
+
const BY_RESOLVER_KEY = new Map(GATEWAY_PROVIDERS.map((p) => [p.resolverKey, p]));
|
|
487
|
+
/** Look up a provider by the slug prefix the user typed (honoring aliases). */
|
|
488
|
+
function findProviderBySlug(resolverKey) {
|
|
489
|
+
const canonical = RESOLVER_ALIASES[resolverKey] ?? resolverKey;
|
|
490
|
+
return BY_RESOLVER_KEY.get(canonical);
|
|
491
|
+
}
|
|
492
|
+
/** Detect the gateway provider from a wrapped provider's request URL (BYOG). */
|
|
493
|
+
function detectProviderByUrl(url) {
|
|
494
|
+
return GATEWAY_PROVIDERS.find((p) => p.hostPattern?.test(url));
|
|
495
|
+
}
|
|
496
|
+
/** All slug keys with a built-in parser (auto-wireable by the slug delegate). */
|
|
497
|
+
function wireableProviders() {
|
|
498
|
+
return GATEWAY_PROVIDERS.filter((p) => p.wireFormat !== void 0);
|
|
499
|
+
}
|
|
500
|
+
//#endregion
|
|
501
|
+
//#region src/gateway-provider.ts
|
|
502
|
+
const STRIP_HEADERS_BASE = new Set(["content-length", "host"]);
|
|
503
|
+
function asText(body) {
|
|
504
|
+
if (typeof body === "string") return body;
|
|
505
|
+
if (body instanceof Uint8Array) return new TextDecoder().decode(body);
|
|
506
|
+
if (body instanceof ArrayBuffer) return new TextDecoder().decode(body);
|
|
507
|
+
return "{}";
|
|
508
|
+
}
|
|
509
|
+
function headersToObject(h) {
|
|
510
|
+
const out = {};
|
|
511
|
+
if (!h) return out;
|
|
512
|
+
if (h instanceof Headers) for (const [k, v] of h) out[k] = v;
|
|
513
|
+
else if (Array.isArray(h)) for (const [k, v] of h) out[k] = v;
|
|
514
|
+
else Object.assign(out, h);
|
|
515
|
+
return out;
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* A `fetch` that dispatches the wrapped provider's request through AI Gateway.
|
|
519
|
+
* Detects the gateway provider id from the request URL (or uses `config.provider`),
|
|
520
|
+
* strips the provider host to the endpoint path, and forwards the body verbatim.
|
|
521
|
+
*/
|
|
522
|
+
function createGatewayFetch(config) {
|
|
523
|
+
if (!config?.binding) throw new WorkersAIGatewayError("gateway-error", "createGatewayFetch requires a `binding` (e.g. { binding: env.AI }).");
|
|
524
|
+
const gatewayId = typeof config.gateway === "string" ? config.gateway : config.gateway?.id;
|
|
525
|
+
if (!gatewayId) throw new WorkersAIGatewayError("gateway-error", "createGatewayFetch requires a `gateway` id (e.g. gateway: \"my-gateway\").");
|
|
526
|
+
return (async (input, init) => {
|
|
527
|
+
const rawUrl = typeof input === "string" ? input : input.toString();
|
|
528
|
+
let info;
|
|
529
|
+
if (config.provider) info = void 0;
|
|
530
|
+
else {
|
|
531
|
+
info = detectProviderByUrl(rawUrl);
|
|
532
|
+
if (!info) throw new WorkersAIGatewayError("gateway-error", `Could not detect a gateway provider from URL "${rawUrl}". Pass \`provider: "<gateway-provider-id>"\` explicitly.`, { recoverable: false });
|
|
533
|
+
}
|
|
534
|
+
const providerId = config.provider ?? info.gatewayProviderId;
|
|
535
|
+
const endpoint = info?.transformEndpoint ? info.transformEndpoint(rawUrl) : rawUrl.replace(/^https?:\/\/[^/]+\//, "");
|
|
536
|
+
const body = JSON.parse(asText(init?.body));
|
|
537
|
+
const strip = new Set(STRIP_HEADERS_BASE);
|
|
538
|
+
if (!config.byok && info) for (const h of info.authHeaders) strip.add(h.toLowerCase());
|
|
539
|
+
const headers = {};
|
|
540
|
+
for (const [k, v] of Object.entries(headersToObject(init?.headers))) if (!strip.has(k.toLowerCase())) headers[k] = v;
|
|
541
|
+
if (config.extraHeaders) Object.assign(headers, config.extraHeaders);
|
|
542
|
+
if (config.cacheTtl !== void 0) headers["cf-aig-cache-ttl"] = String(config.cacheTtl);
|
|
543
|
+
if (config.skipCache) headers["cf-aig-skip-cache"] = "true";
|
|
544
|
+
const entry = {
|
|
545
|
+
provider: providerId,
|
|
546
|
+
endpoint,
|
|
547
|
+
headers,
|
|
548
|
+
query: body
|
|
549
|
+
};
|
|
550
|
+
const gw = config.binding.gateway(gatewayId);
|
|
551
|
+
const runOptions = {};
|
|
552
|
+
if (init?.signal) runOptions.signal = init.signal;
|
|
553
|
+
return gw.run([entry], runOptions);
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Wrap an `@ai-sdk/*` provider factory so its traffic flows through AI Gateway.
|
|
558
|
+
* A thin convenience over {@link createGatewayFetch} — it injects the gateway
|
|
559
|
+
* `fetch` (and a placeholder `apiKey` unless you supply one for BYOK).
|
|
560
|
+
*
|
|
561
|
+
* @example
|
|
562
|
+
* ```ts
|
|
563
|
+
* import { createOpenAI } from "@ai-sdk/openai";
|
|
564
|
+
* import { createGatewayProvider } from "workers-ai-provider/gateway";
|
|
565
|
+
*
|
|
566
|
+
* const openai = createGatewayProvider(createOpenAI, {
|
|
567
|
+
* binding: env.AI,
|
|
568
|
+
* gateway: "my-gw",
|
|
569
|
+
* });
|
|
570
|
+
* const model = openai("gpt-5");
|
|
571
|
+
* ```
|
|
572
|
+
*/
|
|
573
|
+
function createGatewayProvider(factory, config) {
|
|
574
|
+
return factory({
|
|
575
|
+
apiKey: config.apiKey ?? "unused",
|
|
576
|
+
...config.baseURL ? { baseURL: config.baseURL } : {},
|
|
577
|
+
fetch: createGatewayFetch(config)
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
//#endregion
|
|
581
|
+
export { findProviderBySlug as a, WorkersAIGatewayError as c, detectProviderByUrl as i, _defineProperty as l, createGatewayProvider as n, wireableProviders as o, GATEWAY_PROVIDERS as r, WorkersAIFallbackError as s, createGatewayFetch as t };
|
|
582
|
+
|
|
583
|
+
//# sourceMappingURL=gateway-provider-1USFWm7c.mjs.map
|