workers-ai-provider 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/index.js +60 -141
- package/dist/index.js.map +1 -1
- package/package.json +42 -41
- package/src/convert-to-workersai-chat-messages.ts +43 -13
- package/src/workersai-chat-language-model.ts +39 -11
package/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2024 Andy Jessop
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
package/dist/index.js
CHANGED
@@ -53,126 +53,15 @@ function createRun(config) {
|
|
53
53
|
};
|
54
54
|
}
|
55
55
|
|
56
|
-
//
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
var _AISDKError = class _AISDKError2 extends Error {
|
61
|
-
/**
|
62
|
-
* Creates an AI SDK Error.
|
63
|
-
*
|
64
|
-
* @param {Object} params - The parameters for creating the error.
|
65
|
-
* @param {string} params.name - The name of the error.
|
66
|
-
* @param {string} params.message - The error message.
|
67
|
-
* @param {unknown} [params.cause] - The underlying cause of the error.
|
68
|
-
*/
|
69
|
-
constructor({
|
70
|
-
name: name14,
|
71
|
-
message,
|
72
|
-
cause
|
73
|
-
}) {
|
74
|
-
super(message);
|
75
|
-
this[_a] = true;
|
76
|
-
this.name = name14;
|
77
|
-
this.cause = cause;
|
78
|
-
}
|
79
|
-
/**
|
80
|
-
* Checks if the given error is an AI SDK Error.
|
81
|
-
* @param {unknown} error - The error to check.
|
82
|
-
* @returns {boolean} True if the error is an AI SDK Error, false otherwise.
|
83
|
-
*/
|
84
|
-
static isInstance(error) {
|
85
|
-
return _AISDKError2.hasMarker(error, marker);
|
86
|
-
}
|
87
|
-
static hasMarker(error, marker15) {
|
88
|
-
const markerSymbol = Symbol.for(marker15);
|
89
|
-
return error != null && typeof error === "object" && markerSymbol in error && typeof error[markerSymbol] === "boolean" && error[markerSymbol] === true;
|
90
|
-
}
|
91
|
-
};
|
92
|
-
_a = symbol;
|
93
|
-
var AISDKError = _AISDKError;
|
94
|
-
var name = "AI_APICallError";
|
95
|
-
var marker2 = `vercel.ai.error.${name}`;
|
96
|
-
var symbol2 = Symbol.for(marker2);
|
97
|
-
var _a2;
|
98
|
-
_a2 = symbol2;
|
99
|
-
var name2 = "AI_EmptyResponseBodyError";
|
100
|
-
var marker3 = `vercel.ai.error.${name2}`;
|
101
|
-
var symbol3 = Symbol.for(marker3);
|
102
|
-
var _a3;
|
103
|
-
_a3 = symbol3;
|
104
|
-
var name3 = "AI_InvalidArgumentError";
|
105
|
-
var marker4 = `vercel.ai.error.${name3}`;
|
106
|
-
var symbol4 = Symbol.for(marker4);
|
107
|
-
var _a4;
|
108
|
-
_a4 = symbol4;
|
109
|
-
var name4 = "AI_InvalidPromptError";
|
110
|
-
var marker5 = `vercel.ai.error.${name4}`;
|
111
|
-
var symbol5 = Symbol.for(marker5);
|
112
|
-
var _a5;
|
113
|
-
_a5 = symbol5;
|
114
|
-
var name5 = "AI_InvalidResponseDataError";
|
115
|
-
var marker6 = `vercel.ai.error.${name5}`;
|
116
|
-
var symbol6 = Symbol.for(marker6);
|
117
|
-
var _a6;
|
118
|
-
_a6 = symbol6;
|
119
|
-
var name6 = "AI_JSONParseError";
|
120
|
-
var marker7 = `vercel.ai.error.${name6}`;
|
121
|
-
var symbol7 = Symbol.for(marker7);
|
122
|
-
var _a7;
|
123
|
-
_a7 = symbol7;
|
124
|
-
var name7 = "AI_LoadAPIKeyError";
|
125
|
-
var marker8 = `vercel.ai.error.${name7}`;
|
126
|
-
var symbol8 = Symbol.for(marker8);
|
127
|
-
var _a8;
|
128
|
-
_a8 = symbol8;
|
129
|
-
var name8 = "AI_LoadSettingError";
|
130
|
-
var marker9 = `vercel.ai.error.${name8}`;
|
131
|
-
var symbol9 = Symbol.for(marker9);
|
132
|
-
var _a9;
|
133
|
-
_a9 = symbol9;
|
134
|
-
var name9 = "AI_NoContentGeneratedError";
|
135
|
-
var marker10 = `vercel.ai.error.${name9}`;
|
136
|
-
var symbol10 = Symbol.for(marker10);
|
137
|
-
var _a10;
|
138
|
-
_a10 = symbol10;
|
139
|
-
var name10 = "AI_NoSuchModelError";
|
140
|
-
var marker11 = `vercel.ai.error.${name10}`;
|
141
|
-
var symbol11 = Symbol.for(marker11);
|
142
|
-
var _a11;
|
143
|
-
_a11 = symbol11;
|
144
|
-
var name11 = "AI_TooManyEmbeddingValuesForCallError";
|
145
|
-
var marker12 = `vercel.ai.error.${name11}`;
|
146
|
-
var symbol12 = Symbol.for(marker12);
|
147
|
-
var _a12;
|
148
|
-
_a12 = symbol12;
|
149
|
-
var name12 = "AI_TypeValidationError";
|
150
|
-
var marker13 = `vercel.ai.error.${name12}`;
|
151
|
-
var symbol13 = Symbol.for(marker13);
|
152
|
-
var _a13;
|
153
|
-
_a13 = symbol13;
|
154
|
-
var name13 = "AI_UnsupportedFunctionalityError";
|
155
|
-
var marker14 = `vercel.ai.error.${name13}`;
|
156
|
-
var symbol14 = Symbol.for(marker14);
|
157
|
-
var _a14;
|
158
|
-
var UnsupportedFunctionalityError = class extends AISDKError {
|
159
|
-
constructor({
|
160
|
-
functionality,
|
161
|
-
message = `'${functionality}' functionality not supported.`
|
162
|
-
}) {
|
163
|
-
super({ name: name13, message });
|
164
|
-
this[_a14] = true;
|
165
|
-
this.functionality = functionality;
|
166
|
-
}
|
167
|
-
static isInstance(error) {
|
168
|
-
return AISDKError.hasMarker(error, marker14);
|
169
|
-
}
|
170
|
-
};
|
171
|
-
_a14 = symbol14;
|
56
|
+
// src/workersai-chat-language-model.ts
|
57
|
+
import {
|
58
|
+
UnsupportedFunctionalityError
|
59
|
+
} from "@ai-sdk/provider";
|
172
60
|
|
173
61
|
// src/convert-to-workersai-chat-messages.ts
|
174
62
|
function convertToWorkersAIChatMessages(prompt) {
|
175
63
|
const messages = [];
|
64
|
+
const images = [];
|
176
65
|
for (const { role, content } of prompt) {
|
177
66
|
switch (role) {
|
178
67
|
case "system": {
|
@@ -188,12 +77,17 @@ function convertToWorkersAIChatMessages(prompt) {
|
|
188
77
|
return part.text;
|
189
78
|
}
|
190
79
|
case "image": {
|
191
|
-
|
192
|
-
|
193
|
-
|
80
|
+
if (part.image instanceof Uint8Array) {
|
81
|
+
images.push({
|
82
|
+
mimeType: part.mimeType,
|
83
|
+
image: part.image,
|
84
|
+
providerMetadata: part.providerMetadata
|
85
|
+
});
|
86
|
+
}
|
87
|
+
return "";
|
194
88
|
}
|
195
89
|
}
|
196
|
-
}).join("")
|
90
|
+
}).join("\n")
|
197
91
|
});
|
198
92
|
break;
|
199
93
|
}
|
@@ -223,18 +117,24 @@ function convertToWorkersAIChatMessages(prompt) {
|
|
223
117
|
}
|
224
118
|
default: {
|
225
119
|
const exhaustiveCheck = part;
|
226
|
-
throw new Error(
|
120
|
+
throw new Error(
|
121
|
+
`Unsupported part: ${exhaustiveCheck}`
|
122
|
+
);
|
227
123
|
}
|
228
124
|
}
|
229
125
|
}
|
230
126
|
messages.push({
|
231
127
|
role: "assistant",
|
232
128
|
content: text,
|
233
|
-
tool_calls: toolCalls.length > 0 ? toolCalls.map(
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
129
|
+
tool_calls: toolCalls.length > 0 ? toolCalls.map(
|
130
|
+
({
|
131
|
+
function: { name, arguments: args }
|
132
|
+
}) => ({
|
133
|
+
id: "null",
|
134
|
+
type: "function",
|
135
|
+
function: { name, arguments: args }
|
136
|
+
})
|
137
|
+
) : void 0
|
238
138
|
});
|
239
139
|
break;
|
240
140
|
}
|
@@ -254,10 +154,10 @@ function convertToWorkersAIChatMessages(prompt) {
|
|
254
154
|
}
|
255
155
|
}
|
256
156
|
}
|
257
|
-
return messages;
|
157
|
+
return { messages, images };
|
258
158
|
}
|
259
159
|
|
260
|
-
// ../../node_modules/fetch-event-stream/esm/deps/jsr.io/@std/streams/0.221.0/text_line_stream.js
|
160
|
+
// ../../node_modules/.pnpm/fetch-event-stream@0.1.5/node_modules/fetch-event-stream/esm/deps/jsr.io/@std/streams/0.221.0/text_line_stream.js
|
261
161
|
var _currentLine;
|
262
162
|
var TextLineStream = class extends TransformStream {
|
263
163
|
/** Constructs a new instance. */
|
@@ -293,7 +193,7 @@ var TextLineStream = class extends TransformStream {
|
|
293
193
|
};
|
294
194
|
_currentLine = new WeakMap();
|
295
195
|
|
296
|
-
// ../../node_modules/fetch-event-stream/esm/utils.js
|
196
|
+
// ../../node_modules/.pnpm/fetch-event-stream@0.1.5/node_modules/fetch-event-stream/esm/utils.js
|
297
197
|
function stream(input) {
|
298
198
|
let decoder = new TextDecoderStream();
|
299
199
|
let split2 = new TextLineStream({ allowCR: true });
|
@@ -311,7 +211,7 @@ function split(input) {
|
|
311
211
|
}
|
312
212
|
}
|
313
213
|
|
314
|
-
// ../../node_modules/fetch-event-stream/esm/mod.js
|
214
|
+
// ../../node_modules/.pnpm/fetch-event-stream@0.1.5/node_modules/fetch-event-stream/esm/mod.js
|
315
215
|
async function* events(res, signal) {
|
316
216
|
if (!res.body)
|
317
217
|
return;
|
@@ -379,7 +279,6 @@ var WorkersAIChatLanguageModel = class {
|
|
379
279
|
}
|
380
280
|
getArgs({
|
381
281
|
mode,
|
382
|
-
prompt,
|
383
282
|
maxTokens,
|
384
283
|
temperature,
|
385
284
|
topP,
|
@@ -410,9 +309,7 @@ var WorkersAIChatLanguageModel = class {
|
|
410
309
|
max_tokens: maxTokens,
|
411
310
|
temperature,
|
412
311
|
top_p: topP,
|
413
|
-
random_seed: seed
|
414
|
-
// messages:
|
415
|
-
messages: convertToWorkersAIChatMessages(prompt)
|
312
|
+
random_seed: seed
|
416
313
|
};
|
417
314
|
switch (type) {
|
418
315
|
case "regular": {
|
@@ -460,14 +357,24 @@ var WorkersAIChatLanguageModel = class {
|
|
460
357
|
async doGenerate(options) {
|
461
358
|
const { args, warnings } = this.getArgs(options);
|
462
359
|
const { gateway, safePrompt, ...passthroughOptions } = this.settings;
|
360
|
+
const { messages, images } = convertToWorkersAIChatMessages(
|
361
|
+
options.prompt
|
362
|
+
);
|
363
|
+
if (images.length !== 0 && images.length !== 1) {
|
364
|
+
throw new Error("Multiple images are not yet supported as input");
|
365
|
+
}
|
366
|
+
const imagePart = images[0];
|
463
367
|
const output = await this.config.binding.run(
|
464
368
|
args.model,
|
465
369
|
{
|
466
|
-
messages
|
370
|
+
messages,
|
467
371
|
max_tokens: args.max_tokens,
|
468
372
|
temperature: args.temperature,
|
469
373
|
tools: args.tools,
|
470
374
|
top_p: args.top_p,
|
375
|
+
// Convert Uint8Array to Array of integers for Llama 3.2 Vision model
|
376
|
+
// TODO: maybe use the base64 string version?
|
377
|
+
...imagePart ? { image: Array.from(imagePart.image) } : {},
|
471
378
|
// @ts-expect-error response_format not yet added to types
|
472
379
|
response_format: args.response_format
|
473
380
|
},
|
@@ -486,14 +393,17 @@ var WorkersAIChatLanguageModel = class {
|
|
486
393
|
})),
|
487
394
|
finishReason: "stop",
|
488
395
|
// TODO: mapWorkersAIFinishReason(response.finish_reason),
|
489
|
-
rawCall: { rawPrompt:
|
396
|
+
rawCall: { rawPrompt: messages, rawSettings: args },
|
490
397
|
usage: mapWorkersAIUsage(output),
|
491
398
|
warnings
|
492
399
|
};
|
493
400
|
}
|
494
401
|
async doStream(options) {
|
495
402
|
const { args, warnings } = this.getArgs(options);
|
496
|
-
|
403
|
+
const { messages, images } = convertToWorkersAIChatMessages(
|
404
|
+
options.prompt
|
405
|
+
);
|
406
|
+
if (args.tools?.length && lastMessageWasUser(messages)) {
|
497
407
|
const response2 = await this.doGenerate(options);
|
498
408
|
if (response2 instanceof ReadableStream) {
|
499
409
|
throw new Error("This shouldn't happen");
|
@@ -523,20 +433,27 @@ var WorkersAIChatLanguageModel = class {
|
|
523
433
|
controller.close();
|
524
434
|
}
|
525
435
|
}),
|
526
|
-
rawCall: { rawPrompt:
|
436
|
+
rawCall: { rawPrompt: messages, rawSettings: args },
|
527
437
|
warnings
|
528
438
|
};
|
529
439
|
}
|
530
440
|
const { gateway, ...passthroughOptions } = this.settings;
|
441
|
+
if (images.length !== 0 && images.length !== 1) {
|
442
|
+
throw new Error("Multiple images are not yet supported as input");
|
443
|
+
}
|
444
|
+
const imagePart = images[0];
|
531
445
|
const response = await this.config.binding.run(
|
532
446
|
args.model,
|
533
447
|
{
|
534
|
-
messages
|
448
|
+
messages,
|
535
449
|
max_tokens: args.max_tokens,
|
536
450
|
stream: true,
|
537
451
|
temperature: args.temperature,
|
538
452
|
tools: args.tools,
|
539
453
|
top_p: args.top_p,
|
454
|
+
// Convert Uint8Array to Array of integers for Llama 3.2 Vision model
|
455
|
+
// TODO: maybe use the base64 string version?
|
456
|
+
...imagePart ? { image: Array.from(imagePart.image) } : {},
|
540
457
|
// @ts-expect-error response_format not yet added to types
|
541
458
|
response_format: args.response_format
|
542
459
|
},
|
@@ -574,7 +491,7 @@ var WorkersAIChatLanguageModel = class {
|
|
574
491
|
controller.close();
|
575
492
|
}
|
576
493
|
}),
|
577
|
-
rawCall: { rawPrompt:
|
494
|
+
rawCall: { rawPrompt: messages, rawSettings: args },
|
578
495
|
warnings
|
579
496
|
};
|
580
497
|
}
|
@@ -610,7 +527,9 @@ function prepareToolsAndToolChoice(mode) {
|
|
610
527
|
// so we filter the tools and force the tool choice through 'any'
|
611
528
|
case "tool":
|
612
529
|
return {
|
613
|
-
tools: mappedTools.filter(
|
530
|
+
tools: mappedTools.filter(
|
531
|
+
(tool) => tool.function.name === toolChoice.toolName
|
532
|
+
),
|
614
533
|
tool_choice: "any"
|
615
534
|
};
|
616
535
|
default: {
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts","../../../node_modules/@ai-sdk/provider/src/errors/ai-sdk-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/api-call-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/empty-response-body-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/get-error-message.ts","../../../node_modules/@ai-sdk/provider/src/errors/invalid-argument-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/invalid-prompt-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/invalid-response-data-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/json-parse-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/load-api-key-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/load-setting-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/no-content-generated-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/no-such-model-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/too-many-embedding-values-for-call-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/type-validation-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/unsupported-functionality-error.ts","../../../node_modules/@ai-sdk/provider/src/json-value/is-json.ts","../src/convert-to-workersai-chat-messages.ts","../../../node_modules/fetch-event-stream/esm/deps/jsr.io/@std/streams/0.221.0/text_line_stream.js","../../../node_modules/fetch-event-stream/esm/utils.js","../../../node_modules/fetch-event-stream/esm/mod.js","../src/map-workersai-usage.ts","../src/workersai-chat-language-model.ts","../src/workersai-image-model.ts","../src/index.ts"],"sourcesContent":["/**\n * General AI run interface with overloads to handle distinct return types.\n *\n * The behaviour depends on the combination of parameters:\n * 1. `returnRawResponse: true` => returns the raw Response object.\n * 2. `stream: true` => returns a ReadableStream (if available).\n * 3. Otherwise => returns post-processed AI results.\n */\nexport interface AiRun {\n\t// (1) Return raw Response if `options.returnRawResponse` is `true`.\n\t<Name extends keyof AiModels>(\n\t\tmodel: Name,\n\t\tinputs: AiModels[Name][\"inputs\"],\n\t\toptions: AiOptions & { returnRawResponse: true },\n\t): Promise<Response>;\n\n\t// (2) Return a stream if the input has `stream: true`.\n\t<Name extends keyof AiModels>(\n\t\tmodel: Name,\n\t\tinputs: AiModels[Name][\"inputs\"] & { stream: true },\n\t\toptions?: AiOptions,\n\t): Promise<ReadableStream<Uint8Array>>;\n\n\t// (3) Return post-processed outputs by default.\n\t<Name extends keyof AiModels>(\n\t\tmodel: Name,\n\t\tinputs: AiModels[Name][\"inputs\"],\n\t\toptions?: AiOptions,\n\t): Promise<AiModels[Name][\"postProcessedOutputs\"]>;\n}\n\nexport type StringLike = string | { toString(): string };\n\n/**\n * Parameters for configuring the Cloudflare-based AI runner.\n */\nexport interface CreateRunConfig {\n\t/** Your Cloudflare account identifier. */\n\taccountId: string;\n\n\t/** Cloudflare API token/key with appropriate permissions. */\n\tapiKey: string;\n}\n\n/**\n * Creates a run method that emulates the Cloudflare Workers AI binding,\n * but uses the Cloudflare REST API under the hood. Headers and abort\n * signals are configured at creation time, rather than per-request.\n *\n * @param config An object containing:\n * - `accountId`: Cloudflare account identifier.\n * - `apiKey`: Cloudflare API token/key with suitable permissions.\n * - `headers`: Optional custom headers to merge with defaults.\n * - `signal`: Optional AbortSignal for request cancellation.\n *\n * @returns A function matching the AiRun interface.\n */\nexport function createRun(config: CreateRunConfig): AiRun {\n\tconst { accountId, apiKey } = config;\n\n\t// Return the AiRun-compatible function.\n\treturn async function run<Name extends keyof AiModels>(\n\t\tmodel: Name,\n\t\tinputs: AiModels[Name][\"inputs\"],\n\t\toptions?: AiOptions & Record<string, StringLike>,\n\t): Promise<Response | ReadableStream<Uint8Array> | AiModels[Name][\"postProcessedOutputs\"]> {\n\t\tconst { gateway, prefix, extraHeaders, returnRawResponse, ...passthroughOptions } =\n\t\t\toptions || {};\n\n\t\tconst urlParams = new URLSearchParams();\n\t\tfor (const [key, value] of Object.entries(passthroughOptions)) {\n\t\t\t// throw a useful error if the value is not to-stringable\n\t\t\ttry {\n\t\t\t\tconst valueStr = value.toString();\n\t\t\t\tif (!valueStr) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\turlParams.append(key, valueStr);\n\t\t\t} catch (error) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Value for option '${key}' is not able to be coerced into a string.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst url = `https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/run/${model}${urlParams ? `?${urlParams}` : \"\"}`;\n\n\t\t// Merge default and custom headers.\n\t\tconst headers = {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAuthorization: `Bearer ${apiKey}`,\n\t\t};\n\n\t\tconst body = JSON.stringify(inputs);\n\n\t\t// Execute the POST request. The optional AbortSignal is applied here.\n\t\tconst response = await fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders,\n\t\t\tbody,\n\t\t});\n\n\t\t// (1) If the user explicitly requests the raw Response, return it as-is.\n\t\tif (returnRawResponse) {\n\t\t\treturn response;\n\t\t}\n\n\t\t// (2) If the AI input requests streaming, return the ReadableStream if available.\n\t\tif ((inputs as AiTextGenerationInput).stream === true) {\n\t\t\tif (response.body) {\n\t\t\t\treturn response.body;\n\t\t\t}\n\t\t\tthrow new Error(\"No readable body available for streaming.\");\n\t\t}\n\n\t\t// (3) In all other cases, parse JSON and return the result field.\n\t\tconst data = await response.json<{\n\t\t\tresult: AiModels[Name][\"postProcessedOutputs\"];\n\t\t}>();\n\t\treturn data.result;\n\t};\n}\n","/**\n * Symbol used for identifying AI SDK Error instances.\n * Enables checking if an error is an instance of AISDKError across package versions.\n */\nconst marker = 'vercel.ai.error';\nconst symbol = Symbol.for(marker);\n\n/**\n * Custom error class for AI SDK related errors.\n * @extends Error\n */\nexport class AISDKError extends Error {\n private readonly [symbol] = true; // used in isInstance\n\n /**\n * The underlying cause of the error, if any.\n */\n readonly cause?: unknown;\n\n /**\n * Creates an AI SDK Error.\n *\n * @param {Object} params - The parameters for creating the error.\n * @param {string} params.name - The name of the error.\n * @param {string} params.message - The error message.\n * @param {unknown} [params.cause] - The underlying cause of the error.\n */\n constructor({\n name,\n message,\n cause,\n }: {\n name: string;\n message: string;\n cause?: unknown;\n }) {\n super(message);\n\n this.name = name;\n this.cause = cause;\n }\n\n /**\n * Checks if the given error is an AI SDK Error.\n * @param {unknown} error - The error to check.\n * @returns {boolean} True if the error is an AI SDK Error, false otherwise.\n */\n static isInstance(error: unknown): error is AISDKError {\n return AISDKError.hasMarker(error, marker);\n }\n\n protected static hasMarker(error: unknown, marker: string): boolean {\n const markerSymbol = Symbol.for(marker);\n return (\n error != null &&\n typeof error === 'object' &&\n markerSymbol in error &&\n typeof error[markerSymbol] === 'boolean' &&\n error[markerSymbol] === true\n );\n }\n}\n","import { AISDKError } from './ai-sdk-error';\n\nconst name = 'AI_APICallError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class APICallError extends AISDKError {\n private readonly [symbol] = true; // used in isInstance\n\n readonly url: string;\n readonly requestBodyValues: unknown;\n readonly statusCode?: number;\n\n readonly responseHeaders?: Record<string, string>;\n readonly responseBody?: string;\n\n readonly isRetryable: boolean;\n readonly data?: unknown;\n\n constructor({\n message,\n url,\n requestBodyValues,\n statusCode,\n responseHeaders,\n responseBody,\n cause,\n isRetryable = statusCode != null &&\n (statusCode === 408 || // request timeout\n statusCode === 409 || // conflict\n statusCode === 429 || // too many requests\n statusCode >= 500), // server error\n data,\n }: {\n message: string;\n url: string;\n requestBodyValues: unknown;\n statusCode?: number;\n responseHeaders?: Record<string, string>;\n responseBody?: string;\n cause?: unknown;\n isRetryable?: boolean;\n data?: unknown;\n }) {\n super({ name, message, cause });\n\n this.url = url;\n this.requestBodyValues = requestBodyValues;\n this.statusCode = statusCode;\n this.responseHeaders = responseHeaders;\n this.responseBody = responseBody;\n this.isRetryable = isRetryable;\n this.data = data;\n }\n\n static isInstance(error: unknown): error is APICallError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n","import { AISDKError } from './ai-sdk-error';\n\nconst name = 'AI_EmptyResponseBodyError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class EmptyResponseBodyError extends AISDKError {\n private readonly [symbol] = true; // used in isInstance\n\n constructor({ message = 'Empty response body' }: { message?: string } = {}) {\n super({ name, message });\n }\n\n static isInstance(error: unknown): error is EmptyResponseBodyError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n","export function getErrorMessage(error: unknown | undefined) {\n if (error == null) {\n return 'unknown error';\n }\n\n if (typeof error === 'string') {\n return error;\n }\n\n if (error instanceof Error) {\n return error.message;\n }\n\n return JSON.stringify(error);\n}\n","import { AISDKError } from './ai-sdk-error';\n\nconst name = 'AI_InvalidArgumentError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\n/**\n * A function argument is invalid.\n */\nexport class InvalidArgumentError extends AISDKError {\n private readonly [symbol] = true; // used in isInstance\n\n readonly argument: string;\n\n constructor({\n message,\n cause,\n argument,\n }: {\n argument: string;\n message: string;\n cause?: unknown;\n }) {\n super({ name, message, cause });\n\n this.argument = argument;\n }\n\n static isInstance(error: unknown): error is InvalidArgumentError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n","import { AISDKError } from './ai-sdk-error';\n\nconst name = 'AI_InvalidPromptError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\n/**\n * A prompt is invalid. This error should be thrown by providers when they cannot\n * process a prompt.\n */\nexport class InvalidPromptError extends AISDKError {\n private readonly [symbol] = true; // used in isInstance\n\n readonly prompt: unknown;\n\n constructor({\n prompt,\n message,\n cause,\n }: {\n prompt: unknown;\n message: string;\n cause?: unknown;\n }) {\n super({ name, message: `Invalid prompt: ${message}`, cause });\n\n this.prompt = prompt;\n }\n\n static isInstance(error: unknown): error is InvalidPromptError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n","import { AISDKError } from './ai-sdk-error';\n\nconst name = 'AI_InvalidResponseDataError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\n/**\n * Server returned a response with invalid data content.\n * This should be thrown by providers when they cannot parse the response from the API.\n */\nexport class InvalidResponseDataError extends AISDKError {\n private readonly [symbol] = true; // used in isInstance\n\n readonly data: unknown;\n\n constructor({\n data,\n message = `Invalid response data: ${JSON.stringify(data)}.`,\n }: {\n data: unknown;\n message?: string;\n }) {\n super({ name, message });\n\n this.data = data;\n }\n\n static isInstance(error: unknown): error is InvalidResponseDataError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n","import { AISDKError } from './ai-sdk-error';\nimport { getErrorMessage } from './get-error-message';\n\nconst name = 'AI_JSONParseError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\n// TODO v5: rename to ParseError\nexport class JSONParseError extends AISDKError {\n private readonly [symbol] = true; // used in isInstance\n\n readonly text: string;\n\n constructor({ text, cause }: { text: string; cause: unknown }) {\n super({\n name,\n message:\n `JSON parsing failed: ` +\n `Text: ${text}.\\n` +\n `Error message: ${getErrorMessage(cause)}`,\n cause,\n });\n\n this.text = text;\n }\n\n static isInstance(error: unknown): error is JSONParseError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n","import { AISDKError } from './ai-sdk-error';\n\nconst name = 'AI_LoadAPIKeyError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class LoadAPIKeyError extends AISDKError {\n private readonly [symbol] = true; // used in isInstance\n\n constructor({ message }: { message: string }) {\n super({ name, message });\n }\n\n static isInstance(error: unknown): error is LoadAPIKeyError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n","import { AISDKError } from './ai-sdk-error';\n\nconst name = 'AI_LoadSettingError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class LoadSettingError extends AISDKError {\n private readonly [symbol] = true; // used in isInstance\n\n constructor({ message }: { message: string }) {\n super({ name, message });\n }\n\n static isInstance(error: unknown): error is LoadSettingError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n","import { AISDKError } from './ai-sdk-error';\n\nconst name = 'AI_NoContentGeneratedError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\n/**\nThrown when the AI provider fails to generate any content.\n */\nexport class NoContentGeneratedError extends AISDKError {\n private readonly [symbol] = true; // used in isInstance\n\n constructor({\n message = 'No content generated.',\n }: { message?: string } = {}) {\n super({ name, message });\n }\n\n static isInstance(error: unknown): error is NoContentGeneratedError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n","import { AISDKError } from './ai-sdk-error';\n\nconst name = 'AI_NoSuchModelError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class NoSuchModelError extends AISDKError {\n private readonly [symbol] = true; // used in isInstance\n\n readonly modelId: string;\n readonly modelType: 'languageModel' | 'textEmbeddingModel' | 'imageModel';\n\n constructor({\n errorName = name,\n modelId,\n modelType,\n message = `No such ${modelType}: ${modelId}`,\n }: {\n errorName?: string;\n modelId: string;\n modelType: 'languageModel' | 'textEmbeddingModel' | 'imageModel';\n message?: string;\n }) {\n super({ name: errorName, message });\n\n this.modelId = modelId;\n this.modelType = modelType;\n }\n\n static isInstance(error: unknown): error is NoSuchModelError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n","import { AISDKError } from './ai-sdk-error';\n\nconst name = 'AI_TooManyEmbeddingValuesForCallError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class TooManyEmbeddingValuesForCallError extends AISDKError {\n private readonly [symbol] = true; // used in isInstance\n\n readonly provider: string;\n readonly modelId: string;\n readonly maxEmbeddingsPerCall: number;\n readonly values: Array<unknown>;\n\n constructor(options: {\n provider: string;\n modelId: string;\n maxEmbeddingsPerCall: number;\n values: Array<unknown>;\n }) {\n super({\n name,\n message:\n `Too many values for a single embedding call. ` +\n `The ${options.provider} model \"${options.modelId}\" can only embed up to ` +\n `${options.maxEmbeddingsPerCall} values per call, but ${options.values.length} values were provided.`,\n });\n\n this.provider = options.provider;\n this.modelId = options.modelId;\n this.maxEmbeddingsPerCall = options.maxEmbeddingsPerCall;\n this.values = options.values;\n }\n\n static isInstance(\n error: unknown,\n ): error is TooManyEmbeddingValuesForCallError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n","import { AISDKError } from './ai-sdk-error';\nimport { getErrorMessage } from './get-error-message';\n\nconst name = 'AI_TypeValidationError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class TypeValidationError extends AISDKError {\n private readonly [symbol] = true; // used in isInstance\n\n readonly value: unknown;\n\n constructor({ value, cause }: { value: unknown; cause: unknown }) {\n super({\n name,\n message:\n `Type validation failed: ` +\n `Value: ${JSON.stringify(value)}.\\n` +\n `Error message: ${getErrorMessage(cause)}`,\n cause,\n });\n\n this.value = value;\n }\n\n static isInstance(error: unknown): error is TypeValidationError {\n return AISDKError.hasMarker(error, marker);\n }\n\n /**\n * Wraps an error into a TypeValidationError.\n * If the cause is already a TypeValidationError with the same value, it returns the cause.\n * Otherwise, it creates a new TypeValidationError.\n *\n * @param {Object} params - The parameters for wrapping the error.\n * @param {unknown} params.value - The value that failed validation.\n * @param {unknown} params.cause - The original error or cause of the validation failure.\n * @returns {TypeValidationError} A TypeValidationError instance.\n */\n static wrap({\n value,\n cause,\n }: {\n value: unknown;\n cause: unknown;\n }): TypeValidationError {\n return TypeValidationError.isInstance(cause) && cause.value === value\n ? cause\n : new TypeValidationError({ value, cause });\n }\n}\n","import { AISDKError } from './ai-sdk-error';\n\nconst name = 'AI_UnsupportedFunctionalityError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class UnsupportedFunctionalityError extends AISDKError {\n private readonly [symbol] = true; // used in isInstance\n\n readonly functionality: string;\n\n constructor({\n functionality,\n message = `'${functionality}' functionality not supported.`,\n }: {\n functionality: string;\n message?: string;\n }) {\n super({ name, message });\n this.functionality = functionality;\n }\n\n static isInstance(error: unknown): error is UnsupportedFunctionalityError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n","import { JSONArray, JSONObject, JSONValue } from './json-value';\n\nexport function isJSONValue(value: unknown): value is JSONValue {\n if (\n value === null ||\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n return true;\n }\n\n if (Array.isArray(value)) {\n return value.every(isJSONValue);\n }\n\n if (typeof value === 'object') {\n return Object.entries(value).every(\n ([key, val]) => typeof key === 'string' && isJSONValue(val),\n );\n }\n\n return false;\n}\n\nexport function isJSONArray(value: unknown): value is JSONArray {\n return Array.isArray(value) && value.every(isJSONValue);\n}\n\nexport function isJSONObject(value: unknown): value is JSONObject {\n return (\n value != null &&\n typeof value === 'object' &&\n Object.entries(value).every(\n ([key, val]) => typeof key === 'string' && isJSONValue(val),\n )\n );\n}\n","import { type LanguageModelV1Prompt, UnsupportedFunctionalityError } from \"@ai-sdk/provider\";\nimport type { WorkersAIChatPrompt } from \"./workersai-chat-prompt\";\n\nexport function convertToWorkersAIChatMessages(prompt: LanguageModelV1Prompt): WorkersAIChatPrompt {\n\tconst messages: WorkersAIChatPrompt = [];\n\n\tfor (const { role, content } of prompt) {\n\t\tswitch (role) {\n\t\t\tcase \"system\": {\n\t\t\t\tmessages.push({ role: \"system\", content });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"user\": {\n\t\t\t\tmessages.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent: content\n\t\t\t\t\t\t.map((part) => {\n\t\t\t\t\t\t\tswitch (part.type) {\n\t\t\t\t\t\t\t\tcase \"text\": {\n\t\t\t\t\t\t\t\t\treturn part.text;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase \"image\": {\n\t\t\t\t\t\t\t\t\tthrow new UnsupportedFunctionalityError({\n\t\t\t\t\t\t\t\t\t\tfunctionality: \"image-part\",\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.join(\"\"),\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"assistant\": {\n\t\t\t\tlet text = \"\";\n\t\t\t\tconst toolCalls: Array<{\n\t\t\t\t\tid: string;\n\t\t\t\t\ttype: \"function\";\n\t\t\t\t\tfunction: { name: string; arguments: string };\n\t\t\t\t}> = [];\n\n\t\t\t\tfor (const part of content) {\n\t\t\t\t\tswitch (part.type) {\n\t\t\t\t\t\tcase \"text\": {\n\t\t\t\t\t\t\ttext += part.text;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase \"tool-call\": {\n\t\t\t\t\t\t\ttext = JSON.stringify({\n\t\t\t\t\t\t\t\tname: part.toolName,\n\t\t\t\t\t\t\t\tparameters: part.args,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\ttoolCalls.push({\n\t\t\t\t\t\t\t\tid: part.toolCallId,\n\t\t\t\t\t\t\t\ttype: \"function\",\n\t\t\t\t\t\t\t\tfunction: {\n\t\t\t\t\t\t\t\t\tname: part.toolName,\n\t\t\t\t\t\t\t\t\targuments: JSON.stringify(part.args),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tconst exhaustiveCheck = part;\n\t\t\t\t\t\t\tthrow new Error(`Unsupported part: ${exhaustiveCheck}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tmessages.push({\n\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\tcontent: text,\n\t\t\t\t\ttool_calls:\n\t\t\t\t\t\ttoolCalls.length > 0\n\t\t\t\t\t\t\t? toolCalls.map(({ function: { name, arguments: args } }) => ({\n\t\t\t\t\t\t\t\t\tid: \"null\",\n\t\t\t\t\t\t\t\t\ttype: \"function\",\n\t\t\t\t\t\t\t\t\tfunction: { name, arguments: args },\n\t\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t});\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"tool\": {\n\t\t\t\tfor (const toolResponse of content) {\n\t\t\t\t\tmessages.push({\n\t\t\t\t\t\trole: \"tool\",\n\t\t\t\t\t\tname: toolResponse.toolName,\n\t\t\t\t\t\tcontent: JSON.stringify(toolResponse.result),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconst exhaustiveCheck = role satisfies never;\n\t\t\t\tthrow new Error(`Unsupported role: ${exhaustiveCheck}`);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn messages;\n}\n","// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.\n// This module is browser compatible.\n/**\n * Transform a stream into a stream where each chunk is divided by a newline,\n * be it `\\n` or `\\r\\n`. `\\r` can be enabled via the `allowCR` option.\n *\n * @example\n * ```ts\n * import { TextLineStream } from \"@std/streams/text-line-stream\";\n *\n * const res = await fetch(\"https://example.com\");\n * const lines = res.body!\n * .pipeThrough(new TextDecoderStream())\n * .pipeThrough(new TextLineStream());\n * ```\n */\nexport class TextLineStream extends TransformStream {\n #currentLine = \"\";\n /** Constructs a new instance. */\n constructor(options = { allowCR: false }) {\n super({\n transform: (chars, controller) => {\n chars = this.#currentLine + chars;\n while (true) {\n const lfIndex = chars.indexOf(\"\\n\");\n const crIndex = options.allowCR ? chars.indexOf(\"\\r\") : -1;\n if (crIndex !== -1 && crIndex !== (chars.length - 1) &&\n (lfIndex === -1 || (lfIndex - 1) > crIndex)) {\n controller.enqueue(chars.slice(0, crIndex));\n chars = chars.slice(crIndex + 1);\n continue;\n }\n if (lfIndex === -1)\n break;\n const endIndex = chars[lfIndex - 1] === \"\\r\" ? lfIndex - 1 : lfIndex;\n controller.enqueue(chars.slice(0, endIndex));\n chars = chars.slice(lfIndex + 1);\n }\n this.#currentLine = chars;\n },\n flush: (controller) => {\n if (this.#currentLine === \"\")\n return;\n const currentLine = options.allowCR && this.#currentLine.endsWith(\"\\r\")\n ? this.#currentLine.slice(0, -1)\n : this.#currentLine;\n controller.enqueue(currentLine);\n },\n });\n }\n}\n","import { TextLineStream } from './deps/jsr.io/@std/streams/0.221.0/text_line_stream.js';\nexport function stream(input) {\n let decoder = new TextDecoderStream();\n let split = new TextLineStream({ allowCR: true });\n return input.pipeThrough(decoder).pipeThrough(split);\n}\nexport function split(input) {\n let rgx = /[:]\\s*/;\n let match = rgx.exec(input);\n // \": comment\" -> index=0 -> ignore\n let idx = match && match.index;\n if (idx) {\n return [\n input.substring(0, idx),\n input.substring(idx + match[0].length),\n ];\n }\n}\nexport function fallback(headers, key, value) {\n let tmp = headers.get(key);\n if (!tmp)\n headers.set(key, value);\n}\n","import * as utils from './utils.js';\n/**\n * Convert a `Response` body containing Server Sent Events (SSE) into an Async Iterator that yields {@linkcode ServerSentEventMessage} objects.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events}\n *\n * @example\n * ```js\n * // Optional\n * let abort = new AbortController;\n *\n * // Manually fetch a Response\n * let res = await fetch('https://...', {\n * method: 'POST',\n * signal: abort.signal,\n * headers: {\n * 'api-key': 'token <value>',\n * 'content-type': 'application/json',\n * },\n * body: JSON.stringify({\n * stream: true, // <- hypothetical\n * // ...\n * })\n * });\n *\n * if (res.ok) {\n * let stream = events(res, abort.signal);\n * for await (let event of stream) {\n * console.log('<<', event.data);\n * }\n * }\n * ```\n */\nexport async function* events(res, signal) {\n // TODO: throw error?\n if (!res.body)\n return;\n let iter = utils.stream(res.body);\n let line, reader = iter.getReader();\n let event;\n for (;;) {\n if (signal && signal.aborted) {\n return reader.cancel();\n }\n line = await reader.read();\n if (line.done)\n return;\n if (!line.value) {\n if (event)\n yield event;\n event = undefined;\n continue;\n }\n let [field, value] = utils.split(line.value) || [];\n if (!field)\n continue; // comment or invalid\n if (field === 'data') {\n event ||= {};\n event[field] = event[field] ? (event[field] + '\\n' + value) : value;\n }\n else if (field === 'event') {\n event ||= {};\n event[field] = value;\n }\n else if (field === 'id') {\n event ||= {};\n event[field] = +value || value;\n }\n else if (field === 'retry') {\n event ||= {};\n event[field] = +value || undefined;\n }\n }\n}\n/**\n * Convenience function that will `fetch` with the given arguments and, if ok, will return the {@linkcode events} async iterator.\n *\n * If the response is not ok (status 200-299), the `Response` is thrown.\n *\n * @example\n * ```js\n * // NOTE: throws `Response` if not 2xx status\n * let events = await stream('https://api.openai.com/...', {\n * method: 'POST',\n * headers: {\n * 'Authorization': 'Bearer <token>',\n * 'Content-Type': 'application/json',\n * },\n * body: JSON.stringify({\n * stream: true,\n * // ...\n * })\n * });\n *\n * for await (let event of events) {\n * console.log('<<', JSON.parse(event.data));\n * }\n * ```\n */\nexport async function stream(input, init) {\n let req = new Request(input, init);\n utils.fallback(req.headers, 'Accept', 'text/event-stream');\n utils.fallback(req.headers, 'Content-Type', 'application/json');\n let r = await fetch(req);\n if (!r.ok)\n throw r;\n return events(r, req.signal);\n}\n","export function mapWorkersAIUsage(output: AiTextGenerationOutput | AiTextToImageOutput) {\n\tconst usage = (\n\t\toutput as {\n\t\t\tusage: { prompt_tokens: number; completion_tokens: number };\n\t\t}\n\t).usage ?? {\n\t\tprompt_tokens: 0,\n\t\tcompletion_tokens: 0,\n\t};\n\n\treturn {\n\t\tpromptTokens: usage.prompt_tokens,\n\t\tcompletionTokens: usage.completion_tokens,\n\t};\n}\n","import {\n\ttype LanguageModelV1,\n\ttype LanguageModelV1CallWarning,\n\ttype LanguageModelV1StreamPart,\n\tUnsupportedFunctionalityError,\n} from \"@ai-sdk/provider\";\nimport { convertToWorkersAIChatMessages } from \"./convert-to-workersai-chat-messages\";\nimport type { WorkersAIChatSettings } from \"./workersai-chat-settings\";\nimport type { TextGenerationModels } from \"./workersai-models\";\n\nimport { events } from \"fetch-event-stream\";\nimport { mapWorkersAIUsage } from \"./map-workersai-usage\";\nimport type { WorkersAIChatPrompt } from \"./workersai-chat-prompt\";\n\ntype WorkersAIChatConfig = {\n\tprovider: string;\n\tbinding: Ai;\n\tgateway?: GatewayOptions;\n};\n\nexport class WorkersAIChatLanguageModel implements LanguageModelV1 {\n\treadonly specificationVersion = \"v1\";\n\treadonly defaultObjectGenerationMode = \"json\";\n\n\treadonly modelId: TextGenerationModels;\n\treadonly settings: WorkersAIChatSettings;\n\n\tprivate readonly config: WorkersAIChatConfig;\n\n\tconstructor(\n\t\tmodelId: TextGenerationModels,\n\t\tsettings: WorkersAIChatSettings,\n\t\tconfig: WorkersAIChatConfig,\n\t) {\n\t\tthis.modelId = modelId;\n\t\tthis.settings = settings;\n\t\tthis.config = config;\n\t}\n\n\tget provider(): string {\n\t\treturn this.config.provider;\n\t}\n\n\tprivate getArgs({\n\t\tmode,\n\t\tprompt,\n\t\tmaxTokens,\n\t\ttemperature,\n\t\ttopP,\n\t\tfrequencyPenalty,\n\t\tpresencePenalty,\n\t\tseed,\n\t}: Parameters<LanguageModelV1[\"doGenerate\"]>[0]) {\n\t\tconst type = mode.type;\n\n\t\tconst warnings: LanguageModelV1CallWarning[] = [];\n\n\t\tif (frequencyPenalty != null) {\n\t\t\twarnings.push({\n\t\t\t\ttype: \"unsupported-setting\",\n\t\t\t\tsetting: \"frequencyPenalty\",\n\t\t\t});\n\t\t}\n\n\t\tif (presencePenalty != null) {\n\t\t\twarnings.push({\n\t\t\t\ttype: \"unsupported-setting\",\n\t\t\t\tsetting: \"presencePenalty\",\n\t\t\t});\n\t\t}\n\n\t\tconst baseArgs = {\n\t\t\t// model id:\n\t\t\tmodel: this.modelId,\n\n\t\t\t// model specific settings:\n\t\t\tsafe_prompt: this.settings.safePrompt,\n\n\t\t\t// standardized settings:\n\t\t\tmax_tokens: maxTokens,\n\t\t\ttemperature,\n\t\t\ttop_p: topP,\n\t\t\trandom_seed: seed,\n\n\t\t\t// messages:\n\t\t\tmessages: convertToWorkersAIChatMessages(prompt),\n\t\t};\n\n\t\tswitch (type) {\n\t\t\tcase \"regular\": {\n\t\t\t\treturn {\n\t\t\t\t\targs: { ...baseArgs, ...prepareToolsAndToolChoice(mode) },\n\t\t\t\t\twarnings,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"object-json\": {\n\t\t\t\treturn {\n\t\t\t\t\targs: {\n\t\t\t\t\t\t...baseArgs,\n\t\t\t\t\t\tresponse_format: {\n\t\t\t\t\t\t\ttype: \"json_schema\",\n\t\t\t\t\t\t\tjson_schema: mode.schema,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttools: undefined,\n\t\t\t\t\t},\n\t\t\t\t\twarnings,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"object-tool\": {\n\t\t\t\treturn {\n\t\t\t\t\targs: {\n\t\t\t\t\t\t...baseArgs,\n\t\t\t\t\t\ttool_choice: \"any\",\n\t\t\t\t\t\ttools: [{ type: \"function\", function: mode.tool }],\n\t\t\t\t\t},\n\t\t\t\t\twarnings,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// @ts-expect-error - this is unreachable code\n\t\t\t// TODO: fixme\n\t\t\tcase \"object-grammar\": {\n\t\t\t\tthrow new UnsupportedFunctionalityError({\n\t\t\t\t\tfunctionality: \"object-grammar mode\",\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tconst exhaustiveCheck = type satisfies never;\n\t\t\t\tthrow new Error(`Unsupported type: ${exhaustiveCheck}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync doGenerate(\n\t\toptions: Parameters<LanguageModelV1[\"doGenerate\"]>[0],\n\t): Promise<Awaited<ReturnType<LanguageModelV1[\"doGenerate\"]>>> {\n\t\tconst { args, warnings } = this.getArgs(options);\n\n\t\tconst { gateway, safePrompt, ...passthroughOptions } = this.settings;\n\n\t\tconst output = await this.config.binding.run(\n\t\t\targs.model,\n\t\t\t{\n\t\t\t\tmessages: args.messages,\n\t\t\t\tmax_tokens: args.max_tokens,\n\t\t\t\ttemperature: args.temperature,\n\t\t\t\ttools: args.tools,\n\t\t\t\ttop_p: args.top_p,\n\t\t\t\t// @ts-expect-error response_format not yet added to types\n\t\t\t\tresponse_format: args.response_format,\n\t\t\t},\n\t\t\t{ gateway: this.config.gateway ?? gateway, ...passthroughOptions },\n\t\t);\n\n\t\tif (output instanceof ReadableStream) {\n\t\t\tthrow new Error(\"This shouldn't happen\");\n\t\t}\n\n\t\treturn {\n\t\t\ttext:\n\t\t\t\ttypeof output.response === \"object\" && output.response !== null\n\t\t\t\t\t? JSON.stringify(output.response) // ai-sdk expects a string here\n\t\t\t\t\t: output.response,\n\t\t\ttoolCalls: output.tool_calls?.map((toolCall) => ({\n\t\t\t\ttoolCallType: \"function\",\n\t\t\t\ttoolCallId: toolCall.name,\n\t\t\t\ttoolName: toolCall.name,\n\t\t\t\targs: JSON.stringify(toolCall.arguments || {}),\n\t\t\t})),\n\t\t\tfinishReason: \"stop\", // TODO: mapWorkersAIFinishReason(response.finish_reason),\n\t\t\trawCall: { rawPrompt: args.messages, rawSettings: args },\n\t\t\tusage: mapWorkersAIUsage(output),\n\t\t\twarnings,\n\t\t};\n\t}\n\n\tasync doStream(\n\t\toptions: Parameters<LanguageModelV1[\"doStream\"]>[0],\n\t): Promise<Awaited<ReturnType<LanguageModelV1[\"doStream\"]>>> {\n\t\tconst { args, warnings } = this.getArgs(options);\n\n\t\t// [1] When the latest message is not a tool response, we use the regular generate function\n\t\t// and simulate it as a streamed response in order to satisfy the AI SDK's interface for\n\t\t// doStream...\n\t\tif (args.tools?.length && lastMessageWasUser(args.messages)) {\n\t\t\tconst response = await this.doGenerate(options);\n\n\t\t\tif (response instanceof ReadableStream) {\n\t\t\t\tthrow new Error(\"This shouldn't happen\");\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tstream: new ReadableStream<LanguageModelV1StreamPart>({\n\t\t\t\t\tasync start(controller) {\n\t\t\t\t\t\tif (response.text) {\n\t\t\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\t\t\ttype: \"text-delta\",\n\t\t\t\t\t\t\t\ttextDelta: response.text,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (response.toolCalls) {\n\t\t\t\t\t\t\tfor (const toolCall of response.toolCalls) {\n\t\t\t\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\t\t\t\ttype: \"tool-call\",\n\t\t\t\t\t\t\t\t\t...toolCall,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\t\ttype: \"finish\",\n\t\t\t\t\t\t\tfinishReason: \"stop\",\n\t\t\t\t\t\t\tusage: response.usage,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontroller.close();\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\trawCall: { rawPrompt: args.messages, rawSettings: args },\n\t\t\t\twarnings,\n\t\t\t};\n\t\t}\n\n\t\t// [2] ...otherwise, we just proceed as normal and stream the response directly from the remote model.\n\t\tconst { gateway, ...passthroughOptions } = this.settings;\n\n\t\tconst response = await this.config.binding.run(\n\t\t\targs.model,\n\t\t\t{\n\t\t\t\tmessages: args.messages,\n\t\t\t\tmax_tokens: args.max_tokens,\n\t\t\t\tstream: true,\n\t\t\t\ttemperature: args.temperature,\n\t\t\t\ttools: args.tools,\n\t\t\t\ttop_p: args.top_p,\n\t\t\t\t// @ts-expect-error response_format not yet added to types\n\t\t\t\tresponse_format: args.response_format,\n\t\t\t},\n\t\t\t{ gateway: this.config.gateway ?? gateway, ...passthroughOptions },\n\t\t);\n\n\t\tif (!(response instanceof ReadableStream)) {\n\t\t\tthrow new Error(\"This shouldn't happen\");\n\t\t}\n\n\t\tconst chunkEvent = events(new Response(response));\n\t\tlet usage = { promptTokens: 0, completionTokens: 0 };\n\n\t\treturn {\n\t\t\tstream: new ReadableStream<LanguageModelV1StreamPart>({\n\t\t\t\tasync start(controller) {\n\t\t\t\t\tfor await (const event of chunkEvent) {\n\t\t\t\t\t\tif (!event.data) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (event.data === \"[DONE]\") {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst chunk = JSON.parse(event.data);\n\t\t\t\t\t\tif (chunk.usage) {\n\t\t\t\t\t\t\tusage = mapWorkersAIUsage(chunk);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tchunk.response?.length &&\n\t\t\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\t\t\ttype: \"text-delta\",\n\t\t\t\t\t\t\t\ttextDelta: chunk.response,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\ttype: \"finish\",\n\t\t\t\t\t\tfinishReason: \"stop\",\n\t\t\t\t\t\tusage: usage,\n\t\t\t\t\t});\n\t\t\t\t\tcontroller.close();\n\t\t\t\t},\n\t\t\t}),\n\t\t\trawCall: { rawPrompt: args.messages, rawSettings: args },\n\t\t\twarnings,\n\t\t};\n\t}\n}\n\nfunction prepareToolsAndToolChoice(\n\tmode: Parameters<LanguageModelV1[\"doGenerate\"]>[0][\"mode\"] & {\n\t\ttype: \"regular\";\n\t},\n) {\n\t// when the tools array is empty, change it to undefined to prevent errors:\n\tconst tools = mode.tools?.length ? mode.tools : undefined;\n\n\tif (tools == null) {\n\t\treturn { tools: undefined, tool_choice: undefined };\n\t}\n\n\tconst mappedTools = tools.map((tool) => ({\n\t\ttype: \"function\",\n\t\tfunction: {\n\t\t\tname: tool.name,\n\t\t\t// @ts-expect-error - description is not a property of tool\n\t\t\tdescription: tool.description,\n\t\t\t// @ts-expect-error - parameters is not a property of tool\n\t\t\tparameters: tool.parameters,\n\t\t},\n\t}));\n\n\tconst toolChoice = mode.toolChoice;\n\n\tif (toolChoice == null) {\n\t\treturn { tools: mappedTools, tool_choice: undefined };\n\t}\n\n\tconst type = toolChoice.type;\n\n\tswitch (type) {\n\t\tcase \"auto\":\n\t\t\treturn { tools: mappedTools, tool_choice: type };\n\t\tcase \"none\":\n\t\t\treturn { tools: mappedTools, tool_choice: type };\n\t\tcase \"required\":\n\t\t\treturn { tools: mappedTools, tool_choice: \"any\" };\n\n\t\t// workersAI does not support tool mode directly,\n\t\t// so we filter the tools and force the tool choice through 'any'\n\t\tcase \"tool\":\n\t\t\treturn {\n\t\t\t\ttools: mappedTools.filter((tool) => tool.function.name === toolChoice.toolName),\n\t\t\t\ttool_choice: \"any\",\n\t\t\t};\n\t\tdefault: {\n\t\t\tconst exhaustiveCheck = type satisfies never;\n\t\t\tthrow new Error(`Unsupported tool choice type: ${exhaustiveCheck}`);\n\t\t}\n\t}\n}\n\nfunction lastMessageWasUser(messages: WorkersAIChatPrompt) {\n\treturn messages.length > 0 && messages[messages.length - 1].role === \"user\";\n}\n","import type { ImageModelV1, ImageModelV1CallWarning } from \"@ai-sdk/provider\";\nimport type { WorkersAIImageConfig } from \"./workersai-image-config\";\nimport type { WorkersAIImageSettings } from \"./workersai-image-settings\";\nimport type { ImageGenerationModels } from \"./workersai-models\";\n\nexport class WorkersAIImageModel implements ImageModelV1 {\n\treadonly specificationVersion = \"v1\";\n\n\tget maxImagesPerCall(): number {\n\t\treturn this.settings.maxImagesPerCall ?? 1;\n\t}\n\n\tget provider(): string {\n\t\treturn this.config.provider;\n\t}\n\tconstructor(\n\t\treadonly modelId: ImageGenerationModels,\n\t\treadonly settings: WorkersAIImageSettings,\n\t\treadonly config: WorkersAIImageConfig,\n\t) {}\n\n\tasync doGenerate({\n\t\tprompt,\n\t\tn,\n\t\tsize,\n\t\taspectRatio,\n\t\tseed,\n\t\t// headers,\n\t\t// abortSignal,\n\t}: Parameters<ImageModelV1[\"doGenerate\"]>[0]): Promise<\n\t\tAwaited<ReturnType<ImageModelV1[\"doGenerate\"]>>\n\t> {\n\t\tconst { width, height } = getDimensionsFromSizeString(size);\n\n\t\tconst warnings: Array<ImageModelV1CallWarning> = [];\n\n\t\tif (aspectRatio != null) {\n\t\t\twarnings.push({\n\t\t\t\ttype: \"unsupported-setting\",\n\t\t\t\tsetting: \"aspectRatio\",\n\t\t\t\tdetails: \"This model does not support aspect ratio. Use `size` instead.\",\n\t\t\t});\n\t\t}\n\n\t\tconst generateImage = async () => {\n\t\t\tconst outputStream: ReadableStream<Uint8Array> = await this.config.binding.run(\n\t\t\t\tthis.modelId,\n\t\t\t\t{\n\t\t\t\t\tprompt,\n\t\t\t\t\tseed,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\t// Convert the output stream to a Uint8Array.\n\t\t\treturn streamToUint8Array(outputStream);\n\t\t};\n\n\t\tconst images: Uint8Array[] = await Promise.all(\n\t\t\tArray.from({ length: n }, () => generateImage()),\n\t\t);\n\n\t\t// type AiTextToImageOutput = ReadableStream<Uint8Array>;\n\n\t\treturn {\n\t\t\timages,\n\t\t\twarnings,\n\t\t\tresponse: {\n\t\t\t\ttimestamp: new Date(),\n\t\t\t\tmodelId: this.modelId,\n\t\t\t\theaders: {},\n\t\t\t},\n\t\t};\n\t}\n}\n\nfunction getDimensionsFromSizeString(size: string | undefined) {\n\tconst [width, height] = size?.split(\"x\") ?? [undefined, undefined];\n\n\treturn {\n\t\twidth: parseInteger(width),\n\t\theight: parseInteger(height),\n\t};\n}\n\nfunction parseInteger(value?: string) {\n\tif (value === \"\" || !value) return undefined;\n\tconst number = Number(value);\n\treturn Number.isInteger(number) ? number : undefined;\n}\n\nasync function streamToUint8Array(stream: ReadableStream<Uint8Array>): Promise<Uint8Array> {\n\tconst reader = stream.getReader();\n\tconst chunks: Uint8Array[] = [];\n\tlet totalLength = 0;\n\n\t// Read the stream until it is finished.\n\twhile (true) {\n\t\tconst { done, value } = await reader.read();\n\t\tif (done) break;\n\t\tchunks.push(value);\n\t\ttotalLength += value.length;\n\t}\n\n\t// Allocate a new Uint8Array to hold all the data.\n\tconst result = new Uint8Array(totalLength);\n\tlet offset = 0;\n\tfor (const chunk of chunks) {\n\t\tresult.set(chunk, offset);\n\t\toffset += chunk.length;\n\t}\n\treturn result;\n}\n","import { createRun } from \"./utils\";\nimport { WorkersAIChatLanguageModel } from \"./workersai-chat-language-model\";\nimport type { WorkersAIChatSettings } from \"./workersai-chat-settings\";\nimport { WorkersAIImageModel } from \"./workersai-image-model\";\nimport type { WorkersAIImageSettings } from \"./workersai-image-settings\";\nimport type { ImageGenerationModels, TextGenerationModels } from \"./workersai-models\";\n\nexport type WorkersAISettings = (\n\t| {\n\t\t\t/**\n\t\t\t * Provide a Cloudflare AI binding.\n\t\t\t */\n\t\t\tbinding: Ai;\n\n\t\t\t/**\n\t\t\t * Credentials must be absent when a binding is given.\n\t\t\t */\n\t\t\taccountId?: never;\n\t\t\tapiKey?: never;\n\t }\n\t| {\n\t\t\t/**\n\t\t\t * Provide Cloudflare API credentials directly. Must be used if a binding is not specified.\n\t\t\t */\n\t\t\taccountId: string;\n\t\t\tapiKey: string;\n\t\t\t/**\n\t\t\t * Both binding must be absent if credentials are used directly.\n\t\t\t */\n\t\t\tbinding?: never;\n\t }\n) & {\n\t/**\n\t * Optionally specify a gateway.\n\t */\n\tgateway?: GatewayOptions;\n};\n\nexport interface WorkersAI {\n\t(modelId: TextGenerationModels, settings?: WorkersAIChatSettings): WorkersAIChatLanguageModel;\n\t/**\n\t * Creates a model for text generation.\n\t **/\n\tchat(\n\t\tmodelId: TextGenerationModels,\n\t\tsettings?: WorkersAIChatSettings,\n\t): WorkersAIChatLanguageModel;\n\n\t/**\n\t * Creates a model for image generation.\n\t **/\n\timage(modelId: ImageGenerationModels, settings?: WorkersAIImageSettings): WorkersAIImageModel;\n}\n\n/**\n * Create a Workers AI provider instance.\n */\nexport function createWorkersAI(options: WorkersAISettings): WorkersAI {\n\t// Use a binding if one is directly provided. Otherwise use credentials to create\n\t// a `run` method that calls the Cloudflare REST API.\n\tlet binding: Ai | undefined;\n\n\tif (options.binding) {\n\t\tbinding = options.binding;\n\t} else {\n\t\tconst { accountId, apiKey } = options;\n\t\tbinding = {\n\t\t\trun: createRun({ accountId, apiKey }),\n\t\t} as Ai;\n\t}\n\n\tif (!binding) {\n\t\tthrow new Error(\"Either a binding or credentials must be provided.\");\n\t}\n\n\tconst createChatModel = (modelId: TextGenerationModels, settings: WorkersAIChatSettings = {}) =>\n\t\tnew WorkersAIChatLanguageModel(modelId, settings, {\n\t\t\tprovider: \"workersai.chat\",\n\t\t\tbinding,\n\t\t\tgateway: options.gateway,\n\t\t});\n\n\tconst createImageModel = (\n\t\tmodelId: ImageGenerationModels,\n\t\tsettings: WorkersAIImageSettings = {},\n\t) =>\n\t\tnew WorkersAIImageModel(modelId, settings, {\n\t\t\tprovider: \"workersai.image\",\n\t\t\tbinding,\n\t\t\tgateway: options.gateway,\n\t\t});\n\n\tconst provider = (modelId: TextGenerationModels, settings?: WorkersAIChatSettings) => {\n\t\tif (new.target) {\n\t\t\tthrow new Error(\"The WorkersAI model function cannot be called with the new keyword.\");\n\t\t}\n\t\treturn createChatModel(modelId, settings);\n\t};\n\n\tprovider.chat = createChatModel;\n\tprovider.image = createImageModel;\n\tprovider.imageModel = createImageModel;\n\n\treturn provider;\n}\n"],"mappings":"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","names":["_AISDKError","name","marker","symbol","_a","_a","symbol","name","marker","_a","symbol","name","marker","symbol","_a","_a","symbol","name","marker","_a","symbol","name","marker","_a","symbol","name","marker","_a","symbol","name","marker","_a","symbol","name","marker","_a","symbol","name","marker","_a","symbol","name","marker","_a","symbol","name","marker","_a","symbol","name","marker","_a","symbol","name","marker","symbol","_a","name","split","response","stream"]}
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/workersai-chat-language-model.ts","../src/convert-to-workersai-chat-messages.ts","../../../node_modules/.pnpm/fetch-event-stream@0.1.5/node_modules/fetch-event-stream/esm/deps/jsr.io/@std/streams/0.221.0/text_line_stream.js","../../../node_modules/.pnpm/fetch-event-stream@0.1.5/node_modules/fetch-event-stream/esm/utils.js","../../../node_modules/.pnpm/fetch-event-stream@0.1.5/node_modules/fetch-event-stream/esm/mod.js","../src/map-workersai-usage.ts","../src/workersai-image-model.ts","../src/index.ts"],"sourcesContent":["/**\n * General AI run interface with overloads to handle distinct return types.\n *\n * The behaviour depends on the combination of parameters:\n * 1. `returnRawResponse: true` => returns the raw Response object.\n * 2. `stream: true` => returns a ReadableStream (if available).\n * 3. Otherwise => returns post-processed AI results.\n */\nexport interface AiRun {\n\t// (1) Return raw Response if `options.returnRawResponse` is `true`.\n\t<Name extends keyof AiModels>(\n\t\tmodel: Name,\n\t\tinputs: AiModels[Name][\"inputs\"],\n\t\toptions: AiOptions & { returnRawResponse: true },\n\t): Promise<Response>;\n\n\t// (2) Return a stream if the input has `stream: true`.\n\t<Name extends keyof AiModels>(\n\t\tmodel: Name,\n\t\tinputs: AiModels[Name][\"inputs\"] & { stream: true },\n\t\toptions?: AiOptions,\n\t): Promise<ReadableStream<Uint8Array>>;\n\n\t// (3) Return post-processed outputs by default.\n\t<Name extends keyof AiModels>(\n\t\tmodel: Name,\n\t\tinputs: AiModels[Name][\"inputs\"],\n\t\toptions?: AiOptions,\n\t): Promise<AiModels[Name][\"postProcessedOutputs\"]>;\n}\n\nexport type StringLike = string | { toString(): string };\n\n/**\n * Parameters for configuring the Cloudflare-based AI runner.\n */\nexport interface CreateRunConfig {\n\t/** Your Cloudflare account identifier. */\n\taccountId: string;\n\n\t/** Cloudflare API token/key with appropriate permissions. */\n\tapiKey: string;\n}\n\n/**\n * Creates a run method that emulates the Cloudflare Workers AI binding,\n * but uses the Cloudflare REST API under the hood. Headers and abort\n * signals are configured at creation time, rather than per-request.\n *\n * @param config An object containing:\n * - `accountId`: Cloudflare account identifier.\n * - `apiKey`: Cloudflare API token/key with suitable permissions.\n * - `headers`: Optional custom headers to merge with defaults.\n * - `signal`: Optional AbortSignal for request cancellation.\n *\n * @returns A function matching the AiRun interface.\n */\nexport function createRun(config: CreateRunConfig): AiRun {\n\tconst { accountId, apiKey } = config;\n\n\t// Return the AiRun-compatible function.\n\treturn async function run<Name extends keyof AiModels>(\n\t\tmodel: Name,\n\t\tinputs: AiModels[Name][\"inputs\"],\n\t\toptions?: AiOptions & Record<string, StringLike>,\n\t): Promise<Response | ReadableStream<Uint8Array> | AiModels[Name][\"postProcessedOutputs\"]> {\n\t\tconst { gateway, prefix, extraHeaders, returnRawResponse, ...passthroughOptions } =\n\t\t\toptions || {};\n\n\t\tconst urlParams = new URLSearchParams();\n\t\tfor (const [key, value] of Object.entries(passthroughOptions)) {\n\t\t\t// throw a useful error if the value is not to-stringable\n\t\t\ttry {\n\t\t\t\tconst valueStr = value.toString();\n\t\t\t\tif (!valueStr) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\turlParams.append(key, valueStr);\n\t\t\t} catch (error) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Value for option '${key}' is not able to be coerced into a string.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst url = `https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/run/${model}${urlParams ? `?${urlParams}` : \"\"}`;\n\n\t\t// Merge default and custom headers.\n\t\tconst headers = {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAuthorization: `Bearer ${apiKey}`,\n\t\t};\n\n\t\tconst body = JSON.stringify(inputs);\n\n\t\t// Execute the POST request. The optional AbortSignal is applied here.\n\t\tconst response = await fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders,\n\t\t\tbody,\n\t\t});\n\n\t\t// (1) If the user explicitly requests the raw Response, return it as-is.\n\t\tif (returnRawResponse) {\n\t\t\treturn response;\n\t\t}\n\n\t\t// (2) If the AI input requests streaming, return the ReadableStream if available.\n\t\tif ((inputs as AiTextGenerationInput).stream === true) {\n\t\t\tif (response.body) {\n\t\t\t\treturn response.body;\n\t\t\t}\n\t\t\tthrow new Error(\"No readable body available for streaming.\");\n\t\t}\n\n\t\t// (3) In all other cases, parse JSON and return the result field.\n\t\tconst data = await response.json<{\n\t\t\tresult: AiModels[Name][\"postProcessedOutputs\"];\n\t\t}>();\n\t\treturn data.result;\n\t};\n}\n","import {\n\ttype LanguageModelV1,\n\ttype LanguageModelV1CallWarning,\n\ttype LanguageModelV1StreamPart,\n\tUnsupportedFunctionalityError,\n} from \"@ai-sdk/provider\";\nimport { convertToWorkersAIChatMessages } from \"./convert-to-workersai-chat-messages\";\nimport type { WorkersAIChatSettings } from \"./workersai-chat-settings\";\nimport type { TextGenerationModels } from \"./workersai-models\";\n\nimport { events } from \"fetch-event-stream\";\nimport { mapWorkersAIUsage } from \"./map-workersai-usage\";\nimport type { WorkersAIChatPrompt } from \"./workersai-chat-prompt\";\n\ntype WorkersAIChatConfig = {\n\tprovider: string;\n\tbinding: Ai;\n\tgateway?: GatewayOptions;\n};\n\nexport class WorkersAIChatLanguageModel implements LanguageModelV1 {\n\treadonly specificationVersion = \"v1\";\n\treadonly defaultObjectGenerationMode = \"json\";\n\n\treadonly modelId: TextGenerationModels;\n\treadonly settings: WorkersAIChatSettings;\n\n\tprivate readonly config: WorkersAIChatConfig;\n\n\tconstructor(\n\t\tmodelId: TextGenerationModels,\n\t\tsettings: WorkersAIChatSettings,\n\t\tconfig: WorkersAIChatConfig,\n\t) {\n\t\tthis.modelId = modelId;\n\t\tthis.settings = settings;\n\t\tthis.config = config;\n\t}\n\n\tget provider(): string {\n\t\treturn this.config.provider;\n\t}\n\n\tprivate getArgs({\n\t\tmode,\n\t\tmaxTokens,\n\t\ttemperature,\n\t\ttopP,\n\t\tfrequencyPenalty,\n\t\tpresencePenalty,\n\t\tseed,\n\t}: Parameters<LanguageModelV1[\"doGenerate\"]>[0]) {\n\t\tconst type = mode.type;\n\n\t\tconst warnings: LanguageModelV1CallWarning[] = [];\n\n\t\tif (frequencyPenalty != null) {\n\t\t\twarnings.push({\n\t\t\t\ttype: \"unsupported-setting\",\n\t\t\t\tsetting: \"frequencyPenalty\",\n\t\t\t});\n\t\t}\n\n\t\tif (presencePenalty != null) {\n\t\t\twarnings.push({\n\t\t\t\ttype: \"unsupported-setting\",\n\t\t\t\tsetting: \"presencePenalty\",\n\t\t\t});\n\t\t}\n\n\t\tconst baseArgs = {\n\t\t\t// model id:\n\t\t\tmodel: this.modelId,\n\n\t\t\t// model specific settings:\n\t\t\tsafe_prompt: this.settings.safePrompt,\n\n\t\t\t// standardized settings:\n\t\t\tmax_tokens: maxTokens,\n\t\t\ttemperature,\n\t\t\ttop_p: topP,\n\t\t\trandom_seed: seed,\n\t\t};\n\n\t\tswitch (type) {\n\t\t\tcase \"regular\": {\n\t\t\t\treturn {\n\t\t\t\t\targs: { ...baseArgs, ...prepareToolsAndToolChoice(mode) },\n\t\t\t\t\twarnings,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"object-json\": {\n\t\t\t\treturn {\n\t\t\t\t\targs: {\n\t\t\t\t\t\t...baseArgs,\n\t\t\t\t\t\tresponse_format: {\n\t\t\t\t\t\t\ttype: \"json_schema\",\n\t\t\t\t\t\t\tjson_schema: mode.schema,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttools: undefined,\n\t\t\t\t\t},\n\t\t\t\t\twarnings,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"object-tool\": {\n\t\t\t\treturn {\n\t\t\t\t\targs: {\n\t\t\t\t\t\t...baseArgs,\n\t\t\t\t\t\ttool_choice: \"any\",\n\t\t\t\t\t\ttools: [{ type: \"function\", function: mode.tool }],\n\t\t\t\t\t},\n\t\t\t\t\twarnings,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// @ts-expect-error - this is unreachable code\n\t\t\t// TODO: fixme\n\t\t\tcase \"object-grammar\": {\n\t\t\t\tthrow new UnsupportedFunctionalityError({\n\t\t\t\t\tfunctionality: \"object-grammar mode\",\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tconst exhaustiveCheck = type satisfies never;\n\t\t\t\tthrow new Error(`Unsupported type: ${exhaustiveCheck}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync doGenerate(\n\t\toptions: Parameters<LanguageModelV1[\"doGenerate\"]>[0],\n\t): Promise<Awaited<ReturnType<LanguageModelV1[\"doGenerate\"]>>> {\n\t\tconst { args, warnings } = this.getArgs(options);\n\n\t\tconst { gateway, safePrompt, ...passthroughOptions } = this.settings;\n\n\t\t// Extract image from messages if present\n\t\tconst { messages, images } = convertToWorkersAIChatMessages(\n\t\t\toptions.prompt,\n\t\t);\n\n\t\t// TODO: support for multiple images\n\t\tif (images.length !== 0 && images.length !== 1) {\n\t\t\tthrow new Error(\"Multiple images are not yet supported as input\");\n\t\t}\n\n\t\tconst imagePart = images[0];\n\n\t\tconst output = await this.config.binding.run(\n\t\t\targs.model,\n\t\t\t{\n\t\t\t\tmessages: messages,\n\t\t\t\tmax_tokens: args.max_tokens,\n\t\t\t\ttemperature: args.temperature,\n\t\t\t\ttools: args.tools,\n\t\t\t\ttop_p: args.top_p,\n\t\t\t\t// Convert Uint8Array to Array of integers for Llama 3.2 Vision model\n\t\t\t\t// TODO: maybe use the base64 string version?\n\t\t\t\t...(imagePart ? { image: Array.from(imagePart.image) } : {}),\n\t\t\t\t// @ts-expect-error response_format not yet added to types\n\t\t\t\tresponse_format: args.response_format,\n\t\t\t},\n\t\t\t{ gateway: this.config.gateway ?? gateway, ...passthroughOptions },\n\t\t);\n\n\t\tif (output instanceof ReadableStream) {\n\t\t\tthrow new Error(\"This shouldn't happen\");\n\t\t}\n\n\t\treturn {\n\t\t\ttext:\n\t\t\t\ttypeof output.response === \"object\" && output.response !== null\n\t\t\t\t\t? JSON.stringify(output.response) // ai-sdk expects a string here\n\t\t\t\t\t: output.response,\n\t\t\ttoolCalls: output.tool_calls?.map((toolCall) => ({\n\t\t\t\ttoolCallType: \"function\",\n\t\t\t\ttoolCallId: toolCall.name,\n\t\t\t\ttoolName: toolCall.name,\n\t\t\t\targs: JSON.stringify(toolCall.arguments || {}),\n\t\t\t})),\n\t\t\tfinishReason: \"stop\", // TODO: mapWorkersAIFinishReason(response.finish_reason),\n\t\t\trawCall: { rawPrompt: messages, rawSettings: args },\n\t\t\tusage: mapWorkersAIUsage(output),\n\t\t\twarnings,\n\t\t};\n\t}\n\n\tasync doStream(\n\t\toptions: Parameters<LanguageModelV1[\"doStream\"]>[0],\n\t): Promise<Awaited<ReturnType<LanguageModelV1[\"doStream\"]>>> {\n\t\tconst { args, warnings } = this.getArgs(options);\n\n\t\t// Extract image from messages if present\n\t\tconst { messages, images } = convertToWorkersAIChatMessages(\n\t\t\toptions.prompt,\n\t\t);\n\n\t\t// [1] When the latest message is not a tool response, we use the regular generate function\n\t\t// and simulate it as a streamed response in order to satisfy the AI SDK's interface for\n\t\t// doStream...\n\t\tif (args.tools?.length && lastMessageWasUser(messages)) {\n\t\t\tconst response = await this.doGenerate(options);\n\n\t\t\tif (response instanceof ReadableStream) {\n\t\t\t\tthrow new Error(\"This shouldn't happen\");\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tstream: new ReadableStream<LanguageModelV1StreamPart>({\n\t\t\t\t\tasync start(controller) {\n\t\t\t\t\t\tif (response.text) {\n\t\t\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\t\t\ttype: \"text-delta\",\n\t\t\t\t\t\t\t\ttextDelta: response.text,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (response.toolCalls) {\n\t\t\t\t\t\t\tfor (const toolCall of response.toolCalls) {\n\t\t\t\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\t\t\t\ttype: \"tool-call\",\n\t\t\t\t\t\t\t\t\t...toolCall,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\t\ttype: \"finish\",\n\t\t\t\t\t\t\tfinishReason: \"stop\",\n\t\t\t\t\t\t\tusage: response.usage,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontroller.close();\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\trawCall: { rawPrompt: messages, rawSettings: args },\n\t\t\t\twarnings,\n\t\t\t};\n\t\t}\n\n\t\t// [2] ...otherwise, we just proceed as normal and stream the response directly from the remote model.\n\t\tconst { gateway, ...passthroughOptions } = this.settings;\n\n\t\t// TODO: support for multiple images\n\t\tif (images.length !== 0 && images.length !== 1) {\n\t\t\tthrow new Error(\"Multiple images are not yet supported as input\");\n\t\t}\n\n\t\tconst imagePart = images[0];\n\n\t\tconst response = await this.config.binding.run(\n\t\t\targs.model,\n\t\t\t{\n\t\t\t\tmessages: messages,\n\t\t\t\tmax_tokens: args.max_tokens,\n\t\t\t\tstream: true,\n\t\t\t\ttemperature: args.temperature,\n\t\t\t\ttools: args.tools,\n\t\t\t\ttop_p: args.top_p,\n\t\t\t\t// Convert Uint8Array to Array of integers for Llama 3.2 Vision model\n\t\t\t\t// TODO: maybe use the base64 string version?\n\t\t\t\t...(imagePart ? { image: Array.from(imagePart.image) } : {}),\n\t\t\t\t// @ts-expect-error response_format not yet added to types\n\t\t\t\tresponse_format: args.response_format,\n\t\t\t},\n\t\t\t{ gateway: this.config.gateway ?? gateway, ...passthroughOptions },\n\t\t);\n\n\t\tif (!(response instanceof ReadableStream)) {\n\t\t\tthrow new Error(\"This shouldn't happen\");\n\t\t}\n\n\t\tconst chunkEvent = events(new Response(response));\n\t\tlet usage = { promptTokens: 0, completionTokens: 0 };\n\n\t\treturn {\n\t\t\tstream: new ReadableStream<LanguageModelV1StreamPart>({\n\t\t\t\tasync start(controller) {\n\t\t\t\t\tfor await (const event of chunkEvent) {\n\t\t\t\t\t\tif (!event.data) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (event.data === \"[DONE]\") {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst chunk = JSON.parse(event.data);\n\t\t\t\t\t\tif (chunk.usage) {\n\t\t\t\t\t\t\tusage = mapWorkersAIUsage(chunk);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tchunk.response?.length &&\n\t\t\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\t\t\ttype: \"text-delta\",\n\t\t\t\t\t\t\t\ttextDelta: chunk.response,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\ttype: \"finish\",\n\t\t\t\t\t\tfinishReason: \"stop\",\n\t\t\t\t\t\tusage: usage,\n\t\t\t\t\t});\n\t\t\t\t\tcontroller.close();\n\t\t\t\t},\n\t\t\t}),\n\t\t\trawCall: { rawPrompt: messages, rawSettings: args },\n\t\t\twarnings,\n\t\t};\n\t}\n}\n\nfunction prepareToolsAndToolChoice(\n\tmode: Parameters<LanguageModelV1[\"doGenerate\"]>[0][\"mode\"] & {\n\t\ttype: \"regular\";\n\t},\n) {\n\t// when the tools array is empty, change it to undefined to prevent errors:\n\tconst tools = mode.tools?.length ? mode.tools : undefined;\n\n\tif (tools == null) {\n\t\treturn { tools: undefined, tool_choice: undefined };\n\t}\n\n\tconst mappedTools = tools.map((tool) => ({\n\t\ttype: \"function\",\n\t\tfunction: {\n\t\t\tname: tool.name,\n\t\t\t// @ts-expect-error - description is not a property of tool\n\t\t\tdescription: tool.description,\n\t\t\t// @ts-expect-error - parameters is not a property of tool\n\t\t\tparameters: tool.parameters,\n\t\t},\n\t}));\n\n\tconst toolChoice = mode.toolChoice;\n\n\tif (toolChoice == null) {\n\t\treturn { tools: mappedTools, tool_choice: undefined };\n\t}\n\n\tconst type = toolChoice.type;\n\n\tswitch (type) {\n\t\tcase \"auto\":\n\t\t\treturn { tools: mappedTools, tool_choice: type };\n\t\tcase \"none\":\n\t\t\treturn { tools: mappedTools, tool_choice: type };\n\t\tcase \"required\":\n\t\t\treturn { tools: mappedTools, tool_choice: \"any\" };\n\n\t\t// workersAI does not support tool mode directly,\n\t\t// so we filter the tools and force the tool choice through 'any'\n\t\tcase \"tool\":\n\t\t\treturn {\n\t\t\t\ttools: mappedTools.filter(\n\t\t\t\t\t(tool) => tool.function.name === toolChoice.toolName,\n\t\t\t\t),\n\t\t\t\ttool_choice: \"any\",\n\t\t\t};\n\t\tdefault: {\n\t\t\tconst exhaustiveCheck = type satisfies never;\n\t\t\tthrow new Error(`Unsupported tool choice type: ${exhaustiveCheck}`);\n\t\t}\n\t}\n}\n\nfunction lastMessageWasUser(messages: WorkersAIChatPrompt) {\n\treturn messages.length > 0 && messages[messages.length - 1].role === \"user\";\n}\n","import type {\n\tLanguageModelV1Prompt,\n\tLanguageModelV1ProviderMetadata,\n} from \"@ai-sdk/provider\";\nimport type { WorkersAIChatPrompt } from \"./workersai-chat-prompt\";\n\nexport function convertToWorkersAIChatMessages(prompt: LanguageModelV1Prompt): {\n\tmessages: WorkersAIChatPrompt;\n\timages: {\n\t\tmimeType: string | undefined;\n\t\timage: Uint8Array;\n\t\tproviderMetadata: LanguageModelV1ProviderMetadata | undefined;\n\t}[];\n} {\n\tconst messages: WorkersAIChatPrompt = [];\n\tconst images: {\n\t\tmimeType: string | undefined;\n\t\timage: Uint8Array;\n\t\tproviderMetadata: LanguageModelV1ProviderMetadata | undefined;\n\t}[] = [];\n\n\tfor (const { role, content } of prompt) {\n\t\tswitch (role) {\n\t\t\tcase \"system\": {\n\t\t\t\tmessages.push({ role: \"system\", content });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"user\": {\n\t\t\t\tmessages.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent: content\n\t\t\t\t\t\t.map((part) => {\n\t\t\t\t\t\t\tswitch (part.type) {\n\t\t\t\t\t\t\t\tcase \"text\": {\n\t\t\t\t\t\t\t\t\treturn part.text;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase \"image\": {\n\t\t\t\t\t\t\t\t\t// Extract image from this part\n\t\t\t\t\t\t\t\t\tif (part.image instanceof Uint8Array) {\n\t\t\t\t\t\t\t\t\t\t// Store the image data directly as Uint8Array\n\t\t\t\t\t\t\t\t\t\t// For Llama 3.2 Vision model, which needs array of integers\n\t\t\t\t\t\t\t\t\t\timages.push({\n\t\t\t\t\t\t\t\t\t\t\tmimeType: part.mimeType,\n\t\t\t\t\t\t\t\t\t\t\timage: part.image,\n\t\t\t\t\t\t\t\t\t\t\tproviderMetadata:\n\t\t\t\t\t\t\t\t\t\t\t\tpart.providerMetadata,\n\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treturn \"\"; // No text for the image part\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.join(\"\\n\"),\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"assistant\": {\n\t\t\t\tlet text = \"\";\n\t\t\t\tconst toolCalls: Array<{\n\t\t\t\t\tid: string;\n\t\t\t\t\ttype: \"function\";\n\t\t\t\t\tfunction: { name: string; arguments: string };\n\t\t\t\t}> = [];\n\n\t\t\t\tfor (const part of content) {\n\t\t\t\t\tswitch (part.type) {\n\t\t\t\t\t\tcase \"text\": {\n\t\t\t\t\t\t\ttext += part.text;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase \"tool-call\": {\n\t\t\t\t\t\t\ttext = JSON.stringify({\n\t\t\t\t\t\t\t\tname: part.toolName,\n\t\t\t\t\t\t\t\tparameters: part.args,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\ttoolCalls.push({\n\t\t\t\t\t\t\t\tid: part.toolCallId,\n\t\t\t\t\t\t\t\ttype: \"function\",\n\t\t\t\t\t\t\t\tfunction: {\n\t\t\t\t\t\t\t\t\tname: part.toolName,\n\t\t\t\t\t\t\t\t\targuments: JSON.stringify(part.args),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tconst exhaustiveCheck = part;\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`Unsupported part: ${exhaustiveCheck}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tmessages.push({\n\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\tcontent: text,\n\t\t\t\t\ttool_calls:\n\t\t\t\t\t\ttoolCalls.length > 0\n\t\t\t\t\t\t\t? toolCalls.map(\n\t\t\t\t\t\t\t\t\t({\n\t\t\t\t\t\t\t\t\t\tfunction: { name, arguments: args },\n\t\t\t\t\t\t\t\t\t}) => ({\n\t\t\t\t\t\t\t\t\t\tid: \"null\",\n\t\t\t\t\t\t\t\t\t\ttype: \"function\",\n\t\t\t\t\t\t\t\t\t\tfunction: { name, arguments: args },\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t});\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"tool\": {\n\t\t\t\tfor (const toolResponse of content) {\n\t\t\t\t\tmessages.push({\n\t\t\t\t\t\trole: \"tool\",\n\t\t\t\t\t\tname: toolResponse.toolName,\n\t\t\t\t\t\tcontent: JSON.stringify(toolResponse.result),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconst exhaustiveCheck = role satisfies never;\n\t\t\t\tthrow new Error(`Unsupported role: ${exhaustiveCheck}`);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { messages, images };\n}\n","// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.\n// This module is browser compatible.\n/**\n * Transform a stream into a stream where each chunk is divided by a newline,\n * be it `\\n` or `\\r\\n`. `\\r` can be enabled via the `allowCR` option.\n *\n * @example\n * ```ts\n * import { TextLineStream } from \"@std/streams/text-line-stream\";\n *\n * const res = await fetch(\"https://example.com\");\n * const lines = res.body!\n * .pipeThrough(new TextDecoderStream())\n * .pipeThrough(new TextLineStream());\n * ```\n */\nexport class TextLineStream extends TransformStream {\n #currentLine = \"\";\n /** Constructs a new instance. */\n constructor(options = { allowCR: false }) {\n super({\n transform: (chars, controller) => {\n chars = this.#currentLine + chars;\n while (true) {\n const lfIndex = chars.indexOf(\"\\n\");\n const crIndex = options.allowCR ? chars.indexOf(\"\\r\") : -1;\n if (crIndex !== -1 && crIndex !== (chars.length - 1) &&\n (lfIndex === -1 || (lfIndex - 1) > crIndex)) {\n controller.enqueue(chars.slice(0, crIndex));\n chars = chars.slice(crIndex + 1);\n continue;\n }\n if (lfIndex === -1)\n break;\n const endIndex = chars[lfIndex - 1] === \"\\r\" ? lfIndex - 1 : lfIndex;\n controller.enqueue(chars.slice(0, endIndex));\n chars = chars.slice(lfIndex + 1);\n }\n this.#currentLine = chars;\n },\n flush: (controller) => {\n if (this.#currentLine === \"\")\n return;\n const currentLine = options.allowCR && this.#currentLine.endsWith(\"\\r\")\n ? this.#currentLine.slice(0, -1)\n : this.#currentLine;\n controller.enqueue(currentLine);\n },\n });\n }\n}\n","import { TextLineStream } from './deps/jsr.io/@std/streams/0.221.0/text_line_stream.js';\nexport function stream(input) {\n let decoder = new TextDecoderStream();\n let split = new TextLineStream({ allowCR: true });\n return input.pipeThrough(decoder).pipeThrough(split);\n}\nexport function split(input) {\n let rgx = /[:]\\s*/;\n let match = rgx.exec(input);\n // \": comment\" -> index=0 -> ignore\n let idx = match && match.index;\n if (idx) {\n return [\n input.substring(0, idx),\n input.substring(idx + match[0].length),\n ];\n }\n}\nexport function fallback(headers, key, value) {\n let tmp = headers.get(key);\n if (!tmp)\n headers.set(key, value);\n}\n","import * as utils from './utils.js';\n/**\n * Convert a `Response` body containing Server Sent Events (SSE) into an Async Iterator that yields {@linkcode ServerSentEventMessage} objects.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events}\n *\n * @example\n * ```js\n * // Optional\n * let abort = new AbortController;\n *\n * // Manually fetch a Response\n * let res = await fetch('https://...', {\n * method: 'POST',\n * signal: abort.signal,\n * headers: {\n * 'api-key': 'token <value>',\n * 'content-type': 'application/json',\n * },\n * body: JSON.stringify({\n * stream: true, // <- hypothetical\n * // ...\n * })\n * });\n *\n * if (res.ok) {\n * let stream = events(res, abort.signal);\n * for await (let event of stream) {\n * console.log('<<', event.data);\n * }\n * }\n * ```\n */\nexport async function* events(res, signal) {\n // TODO: throw error?\n if (!res.body)\n return;\n let iter = utils.stream(res.body);\n let line, reader = iter.getReader();\n let event;\n for (;;) {\n if (signal && signal.aborted) {\n return reader.cancel();\n }\n line = await reader.read();\n if (line.done)\n return;\n if (!line.value) {\n if (event)\n yield event;\n event = undefined;\n continue;\n }\n let [field, value] = utils.split(line.value) || [];\n if (!field)\n continue; // comment or invalid\n if (field === 'data') {\n event ||= {};\n event[field] = event[field] ? (event[field] + '\\n' + value) : value;\n }\n else if (field === 'event') {\n event ||= {};\n event[field] = value;\n }\n else if (field === 'id') {\n event ||= {};\n event[field] = +value || value;\n }\n else if (field === 'retry') {\n event ||= {};\n event[field] = +value || undefined;\n }\n }\n}\n/**\n * Convenience function that will `fetch` with the given arguments and, if ok, will return the {@linkcode events} async iterator.\n *\n * If the response is not ok (status 200-299), the `Response` is thrown.\n *\n * @example\n * ```js\n * // NOTE: throws `Response` if not 2xx status\n * let events = await stream('https://api.openai.com/...', {\n * method: 'POST',\n * headers: {\n * 'Authorization': 'Bearer <token>',\n * 'Content-Type': 'application/json',\n * },\n * body: JSON.stringify({\n * stream: true,\n * // ...\n * })\n * });\n *\n * for await (let event of events) {\n * console.log('<<', JSON.parse(event.data));\n * }\n * ```\n */\nexport async function stream(input, init) {\n let req = new Request(input, init);\n utils.fallback(req.headers, 'Accept', 'text/event-stream');\n utils.fallback(req.headers, 'Content-Type', 'application/json');\n let r = await fetch(req);\n if (!r.ok)\n throw r;\n return events(r, req.signal);\n}\n","export function mapWorkersAIUsage(output: AiTextGenerationOutput | AiTextToImageOutput) {\n\tconst usage = (\n\t\toutput as {\n\t\t\tusage: { prompt_tokens: number; completion_tokens: number };\n\t\t}\n\t).usage ?? {\n\t\tprompt_tokens: 0,\n\t\tcompletion_tokens: 0,\n\t};\n\n\treturn {\n\t\tpromptTokens: usage.prompt_tokens,\n\t\tcompletionTokens: usage.completion_tokens,\n\t};\n}\n","import type { ImageModelV1, ImageModelV1CallWarning } from \"@ai-sdk/provider\";\nimport type { WorkersAIImageConfig } from \"./workersai-image-config\";\nimport type { WorkersAIImageSettings } from \"./workersai-image-settings\";\nimport type { ImageGenerationModels } from \"./workersai-models\";\n\nexport class WorkersAIImageModel implements ImageModelV1 {\n\treadonly specificationVersion = \"v1\";\n\n\tget maxImagesPerCall(): number {\n\t\treturn this.settings.maxImagesPerCall ?? 1;\n\t}\n\n\tget provider(): string {\n\t\treturn this.config.provider;\n\t}\n\tconstructor(\n\t\treadonly modelId: ImageGenerationModels,\n\t\treadonly settings: WorkersAIImageSettings,\n\t\treadonly config: WorkersAIImageConfig,\n\t) {}\n\n\tasync doGenerate({\n\t\tprompt,\n\t\tn,\n\t\tsize,\n\t\taspectRatio,\n\t\tseed,\n\t\t// headers,\n\t\t// abortSignal,\n\t}: Parameters<ImageModelV1[\"doGenerate\"]>[0]): Promise<\n\t\tAwaited<ReturnType<ImageModelV1[\"doGenerate\"]>>\n\t> {\n\t\tconst { width, height } = getDimensionsFromSizeString(size);\n\n\t\tconst warnings: Array<ImageModelV1CallWarning> = [];\n\n\t\tif (aspectRatio != null) {\n\t\t\twarnings.push({\n\t\t\t\ttype: \"unsupported-setting\",\n\t\t\t\tsetting: \"aspectRatio\",\n\t\t\t\tdetails: \"This model does not support aspect ratio. Use `size` instead.\",\n\t\t\t});\n\t\t}\n\n\t\tconst generateImage = async () => {\n\t\t\tconst outputStream: ReadableStream<Uint8Array> = await this.config.binding.run(\n\t\t\t\tthis.modelId,\n\t\t\t\t{\n\t\t\t\t\tprompt,\n\t\t\t\t\tseed,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\t// Convert the output stream to a Uint8Array.\n\t\t\treturn streamToUint8Array(outputStream);\n\t\t};\n\n\t\tconst images: Uint8Array[] = await Promise.all(\n\t\t\tArray.from({ length: n }, () => generateImage()),\n\t\t);\n\n\t\t// type AiTextToImageOutput = ReadableStream<Uint8Array>;\n\n\t\treturn {\n\t\t\timages,\n\t\t\twarnings,\n\t\t\tresponse: {\n\t\t\t\ttimestamp: new Date(),\n\t\t\t\tmodelId: this.modelId,\n\t\t\t\theaders: {},\n\t\t\t},\n\t\t};\n\t}\n}\n\nfunction getDimensionsFromSizeString(size: string | undefined) {\n\tconst [width, height] = size?.split(\"x\") ?? [undefined, undefined];\n\n\treturn {\n\t\twidth: parseInteger(width),\n\t\theight: parseInteger(height),\n\t};\n}\n\nfunction parseInteger(value?: string) {\n\tif (value === \"\" || !value) return undefined;\n\tconst number = Number(value);\n\treturn Number.isInteger(number) ? number : undefined;\n}\n\nasync function streamToUint8Array(stream: ReadableStream<Uint8Array>): Promise<Uint8Array> {\n\tconst reader = stream.getReader();\n\tconst chunks: Uint8Array[] = [];\n\tlet totalLength = 0;\n\n\t// Read the stream until it is finished.\n\twhile (true) {\n\t\tconst { done, value } = await reader.read();\n\t\tif (done) break;\n\t\tchunks.push(value);\n\t\ttotalLength += value.length;\n\t}\n\n\t// Allocate a new Uint8Array to hold all the data.\n\tconst result = new Uint8Array(totalLength);\n\tlet offset = 0;\n\tfor (const chunk of chunks) {\n\t\tresult.set(chunk, offset);\n\t\toffset += chunk.length;\n\t}\n\treturn result;\n}\n","import { createRun } from \"./utils\";\nimport { WorkersAIChatLanguageModel } from \"./workersai-chat-language-model\";\nimport type { WorkersAIChatSettings } from \"./workersai-chat-settings\";\nimport { WorkersAIImageModel } from \"./workersai-image-model\";\nimport type { WorkersAIImageSettings } from \"./workersai-image-settings\";\nimport type { ImageGenerationModels, TextGenerationModels } from \"./workersai-models\";\n\nexport type WorkersAISettings = (\n\t| {\n\t\t\t/**\n\t\t\t * Provide a Cloudflare AI binding.\n\t\t\t */\n\t\t\tbinding: Ai;\n\n\t\t\t/**\n\t\t\t * Credentials must be absent when a binding is given.\n\t\t\t */\n\t\t\taccountId?: never;\n\t\t\tapiKey?: never;\n\t }\n\t| {\n\t\t\t/**\n\t\t\t * Provide Cloudflare API credentials directly. Must be used if a binding is not specified.\n\t\t\t */\n\t\t\taccountId: string;\n\t\t\tapiKey: string;\n\t\t\t/**\n\t\t\t * Both binding must be absent if credentials are used directly.\n\t\t\t */\n\t\t\tbinding?: never;\n\t }\n) & {\n\t/**\n\t * Optionally specify a gateway.\n\t */\n\tgateway?: GatewayOptions;\n};\n\nexport interface WorkersAI {\n\t(modelId: TextGenerationModels, settings?: WorkersAIChatSettings): WorkersAIChatLanguageModel;\n\t/**\n\t * Creates a model for text generation.\n\t **/\n\tchat(\n\t\tmodelId: TextGenerationModels,\n\t\tsettings?: WorkersAIChatSettings,\n\t): WorkersAIChatLanguageModel;\n\n\t/**\n\t * Creates a model for image generation.\n\t **/\n\timage(modelId: ImageGenerationModels, settings?: WorkersAIImageSettings): WorkersAIImageModel;\n}\n\n/**\n * Create a Workers AI provider instance.\n */\nexport function createWorkersAI(options: WorkersAISettings): WorkersAI {\n\t// Use a binding if one is directly provided. Otherwise use credentials to create\n\t// a `run` method that calls the Cloudflare REST API.\n\tlet binding: Ai | undefined;\n\n\tif (options.binding) {\n\t\tbinding = options.binding;\n\t} else {\n\t\tconst { accountId, apiKey } = options;\n\t\tbinding = {\n\t\t\trun: createRun({ accountId, apiKey }),\n\t\t} as Ai;\n\t}\n\n\tif (!binding) {\n\t\tthrow new Error(\"Either a binding or credentials must be provided.\");\n\t}\n\n\tconst createChatModel = (modelId: TextGenerationModels, settings: WorkersAIChatSettings = {}) =>\n\t\tnew WorkersAIChatLanguageModel(modelId, settings, {\n\t\t\tprovider: \"workersai.chat\",\n\t\t\tbinding,\n\t\t\tgateway: options.gateway,\n\t\t});\n\n\tconst createImageModel = (\n\t\tmodelId: ImageGenerationModels,\n\t\tsettings: WorkersAIImageSettings = {},\n\t) =>\n\t\tnew WorkersAIImageModel(modelId, settings, {\n\t\t\tprovider: \"workersai.image\",\n\t\t\tbinding,\n\t\t\tgateway: options.gateway,\n\t\t});\n\n\tconst provider = (modelId: TextGenerationModels, settings?: WorkersAIChatSettings) => {\n\t\tif (new.target) {\n\t\t\tthrow new Error(\"The WorkersAI model function cannot be called with the new keyword.\");\n\t\t}\n\t\treturn createChatModel(modelId, settings);\n\t};\n\n\tprovider.chat = createChatModel;\n\tprovider.image = createImageModel;\n\tprovider.imageModel = createImageModel;\n\n\treturn provider;\n}\n"],"mappings":"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","names":["split","response","stream"]}
|
package/package.json
CHANGED
@@ -1,42 +1,43 @@
|
|
1
1
|
{
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
}
|
2
|
+
"name": "workers-ai-provider",
|
3
|
+
"description": "Workers AI Provider for the vercel AI SDK",
|
4
|
+
"type": "module",
|
5
|
+
"version": "0.3.1",
|
6
|
+
"main": "dist/index.js",
|
7
|
+
"types": "dist/index.d.ts",
|
8
|
+
"repository": {
|
9
|
+
"type": "git",
|
10
|
+
"url": "git://github.com/cloudflare/ai.git"
|
11
|
+
},
|
12
|
+
"bugs": {
|
13
|
+
"url": "https://github.com/cloudflare/ai/issues"
|
14
|
+
},
|
15
|
+
"authors": "Sunil Pai <spai@cloudflare.com>",
|
16
|
+
"license": "MIT",
|
17
|
+
"files": [
|
18
|
+
"dist",
|
19
|
+
"src",
|
20
|
+
"README.md",
|
21
|
+
"package.json"
|
22
|
+
],
|
23
|
+
"keywords": [
|
24
|
+
"workers",
|
25
|
+
"cloudflare",
|
26
|
+
"ai",
|
27
|
+
"vercel",
|
28
|
+
"sdk",
|
29
|
+
"provider",
|
30
|
+
"chat",
|
31
|
+
"serverless"
|
32
|
+
],
|
33
|
+
"dependencies": {
|
34
|
+
"@cloudflare/workers-types": "^4.20250313.0",
|
35
|
+
"@ai-sdk/provider": "^1.1.2"
|
36
|
+
},
|
37
|
+
"scripts": {
|
38
|
+
"build": "rm -rf dist && tsup src/index.ts --dts --sourcemap --format esm --target es2020",
|
39
|
+
"format": "biome format --write",
|
40
|
+
"test:ci": "vitest --watch=false",
|
41
|
+
"test": "vitest"
|
42
|
+
}
|
43
|
+
}
|
@@ -1,8 +1,23 @@
|
|
1
|
-
import
|
1
|
+
import type {
|
2
|
+
LanguageModelV1Prompt,
|
3
|
+
LanguageModelV1ProviderMetadata,
|
4
|
+
} from "@ai-sdk/provider";
|
2
5
|
import type { WorkersAIChatPrompt } from "./workersai-chat-prompt";
|
3
6
|
|
4
|
-
export function convertToWorkersAIChatMessages(prompt: LanguageModelV1Prompt):
|
7
|
+
export function convertToWorkersAIChatMessages(prompt: LanguageModelV1Prompt): {
|
8
|
+
messages: WorkersAIChatPrompt;
|
9
|
+
images: {
|
10
|
+
mimeType: string | undefined;
|
11
|
+
image: Uint8Array;
|
12
|
+
providerMetadata: LanguageModelV1ProviderMetadata | undefined;
|
13
|
+
}[];
|
14
|
+
} {
|
5
15
|
const messages: WorkersAIChatPrompt = [];
|
16
|
+
const images: {
|
17
|
+
mimeType: string | undefined;
|
18
|
+
image: Uint8Array;
|
19
|
+
providerMetadata: LanguageModelV1ProviderMetadata | undefined;
|
20
|
+
}[] = [];
|
6
21
|
|
7
22
|
for (const { role, content } of prompt) {
|
8
23
|
switch (role) {
|
@@ -21,13 +36,22 @@ export function convertToWorkersAIChatMessages(prompt: LanguageModelV1Prompt): W
|
|
21
36
|
return part.text;
|
22
37
|
}
|
23
38
|
case "image": {
|
24
|
-
|
25
|
-
|
26
|
-
|
39
|
+
// Extract image from this part
|
40
|
+
if (part.image instanceof Uint8Array) {
|
41
|
+
// Store the image data directly as Uint8Array
|
42
|
+
// For Llama 3.2 Vision model, which needs array of integers
|
43
|
+
images.push({
|
44
|
+
mimeType: part.mimeType,
|
45
|
+
image: part.image,
|
46
|
+
providerMetadata:
|
47
|
+
part.providerMetadata,
|
48
|
+
});
|
49
|
+
}
|
50
|
+
return ""; // No text for the image part
|
27
51
|
}
|
28
52
|
}
|
29
53
|
})
|
30
|
-
.join(""),
|
54
|
+
.join("\n"),
|
31
55
|
});
|
32
56
|
break;
|
33
57
|
}
|
@@ -64,7 +88,9 @@ export function convertToWorkersAIChatMessages(prompt: LanguageModelV1Prompt): W
|
|
64
88
|
}
|
65
89
|
default: {
|
66
90
|
const exhaustiveCheck = part;
|
67
|
-
throw new Error(
|
91
|
+
throw new Error(
|
92
|
+
`Unsupported part: ${exhaustiveCheck}`,
|
93
|
+
);
|
68
94
|
}
|
69
95
|
}
|
70
96
|
}
|
@@ -74,11 +100,15 @@ export function convertToWorkersAIChatMessages(prompt: LanguageModelV1Prompt): W
|
|
74
100
|
content: text,
|
75
101
|
tool_calls:
|
76
102
|
toolCalls.length > 0
|
77
|
-
? toolCalls.map(
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
103
|
+
? toolCalls.map(
|
104
|
+
({
|
105
|
+
function: { name, arguments: args },
|
106
|
+
}) => ({
|
107
|
+
id: "null",
|
108
|
+
type: "function",
|
109
|
+
function: { name, arguments: args },
|
110
|
+
}),
|
111
|
+
)
|
82
112
|
: undefined,
|
83
113
|
});
|
84
114
|
|
@@ -101,5 +131,5 @@ export function convertToWorkersAIChatMessages(prompt: LanguageModelV1Prompt): W
|
|
101
131
|
}
|
102
132
|
}
|
103
133
|
|
104
|
-
return messages;
|
134
|
+
return { messages, images };
|
105
135
|
}
|
@@ -43,7 +43,6 @@ export class WorkersAIChatLanguageModel implements LanguageModelV1 {
|
|
43
43
|
|
44
44
|
private getArgs({
|
45
45
|
mode,
|
46
|
-
prompt,
|
47
46
|
maxTokens,
|
48
47
|
temperature,
|
49
48
|
topP,
|
@@ -81,9 +80,6 @@ export class WorkersAIChatLanguageModel implements LanguageModelV1 {
|
|
81
80
|
temperature,
|
82
81
|
top_p: topP,
|
83
82
|
random_seed: seed,
|
84
|
-
|
85
|
-
// messages:
|
86
|
-
messages: convertToWorkersAIChatMessages(prompt),
|
87
83
|
};
|
88
84
|
|
89
85
|
switch (type) {
|
@@ -141,14 +137,29 @@ export class WorkersAIChatLanguageModel implements LanguageModelV1 {
|
|
141
137
|
|
142
138
|
const { gateway, safePrompt, ...passthroughOptions } = this.settings;
|
143
139
|
|
140
|
+
// Extract image from messages if present
|
141
|
+
const { messages, images } = convertToWorkersAIChatMessages(
|
142
|
+
options.prompt,
|
143
|
+
);
|
144
|
+
|
145
|
+
// TODO: support for multiple images
|
146
|
+
if (images.length !== 0 && images.length !== 1) {
|
147
|
+
throw new Error("Multiple images are not yet supported as input");
|
148
|
+
}
|
149
|
+
|
150
|
+
const imagePart = images[0];
|
151
|
+
|
144
152
|
const output = await this.config.binding.run(
|
145
153
|
args.model,
|
146
154
|
{
|
147
|
-
messages:
|
155
|
+
messages: messages,
|
148
156
|
max_tokens: args.max_tokens,
|
149
157
|
temperature: args.temperature,
|
150
158
|
tools: args.tools,
|
151
159
|
top_p: args.top_p,
|
160
|
+
// Convert Uint8Array to Array of integers for Llama 3.2 Vision model
|
161
|
+
// TODO: maybe use the base64 string version?
|
162
|
+
...(imagePart ? { image: Array.from(imagePart.image) } : {}),
|
152
163
|
// @ts-expect-error response_format not yet added to types
|
153
164
|
response_format: args.response_format,
|
154
165
|
},
|
@@ -171,7 +182,7 @@ export class WorkersAIChatLanguageModel implements LanguageModelV1 {
|
|
171
182
|
args: JSON.stringify(toolCall.arguments || {}),
|
172
183
|
})),
|
173
184
|
finishReason: "stop", // TODO: mapWorkersAIFinishReason(response.finish_reason),
|
174
|
-
rawCall: { rawPrompt:
|
185
|
+
rawCall: { rawPrompt: messages, rawSettings: args },
|
175
186
|
usage: mapWorkersAIUsage(output),
|
176
187
|
warnings,
|
177
188
|
};
|
@@ -182,10 +193,15 @@ export class WorkersAIChatLanguageModel implements LanguageModelV1 {
|
|
182
193
|
): Promise<Awaited<ReturnType<LanguageModelV1["doStream"]>>> {
|
183
194
|
const { args, warnings } = this.getArgs(options);
|
184
195
|
|
196
|
+
// Extract image from messages if present
|
197
|
+
const { messages, images } = convertToWorkersAIChatMessages(
|
198
|
+
options.prompt,
|
199
|
+
);
|
200
|
+
|
185
201
|
// [1] When the latest message is not a tool response, we use the regular generate function
|
186
202
|
// and simulate it as a streamed response in order to satisfy the AI SDK's interface for
|
187
203
|
// doStream...
|
188
|
-
if (args.tools?.length && lastMessageWasUser(
|
204
|
+
if (args.tools?.length && lastMessageWasUser(messages)) {
|
189
205
|
const response = await this.doGenerate(options);
|
190
206
|
|
191
207
|
if (response instanceof ReadableStream) {
|
@@ -217,7 +233,7 @@ export class WorkersAIChatLanguageModel implements LanguageModelV1 {
|
|
217
233
|
controller.close();
|
218
234
|
},
|
219
235
|
}),
|
220
|
-
rawCall: { rawPrompt:
|
236
|
+
rawCall: { rawPrompt: messages, rawSettings: args },
|
221
237
|
warnings,
|
222
238
|
};
|
223
239
|
}
|
@@ -225,15 +241,25 @@ export class WorkersAIChatLanguageModel implements LanguageModelV1 {
|
|
225
241
|
// [2] ...otherwise, we just proceed as normal and stream the response directly from the remote model.
|
226
242
|
const { gateway, ...passthroughOptions } = this.settings;
|
227
243
|
|
244
|
+
// TODO: support for multiple images
|
245
|
+
if (images.length !== 0 && images.length !== 1) {
|
246
|
+
throw new Error("Multiple images are not yet supported as input");
|
247
|
+
}
|
248
|
+
|
249
|
+
const imagePart = images[0];
|
250
|
+
|
228
251
|
const response = await this.config.binding.run(
|
229
252
|
args.model,
|
230
253
|
{
|
231
|
-
messages:
|
254
|
+
messages: messages,
|
232
255
|
max_tokens: args.max_tokens,
|
233
256
|
stream: true,
|
234
257
|
temperature: args.temperature,
|
235
258
|
tools: args.tools,
|
236
259
|
top_p: args.top_p,
|
260
|
+
// Convert Uint8Array to Array of integers for Llama 3.2 Vision model
|
261
|
+
// TODO: maybe use the base64 string version?
|
262
|
+
...(imagePart ? { image: Array.from(imagePart.image) } : {}),
|
237
263
|
// @ts-expect-error response_format not yet added to types
|
238
264
|
response_format: args.response_format,
|
239
265
|
},
|
@@ -275,7 +301,7 @@ export class WorkersAIChatLanguageModel implements LanguageModelV1 {
|
|
275
301
|
controller.close();
|
276
302
|
},
|
277
303
|
}),
|
278
|
-
rawCall: { rawPrompt:
|
304
|
+
rawCall: { rawPrompt: messages, rawSettings: args },
|
279
305
|
warnings,
|
280
306
|
};
|
281
307
|
}
|
@@ -324,7 +350,9 @@ function prepareToolsAndToolChoice(
|
|
324
350
|
// so we filter the tools and force the tool choice through 'any'
|
325
351
|
case "tool":
|
326
352
|
return {
|
327
|
-
tools: mappedTools.filter(
|
353
|
+
tools: mappedTools.filter(
|
354
|
+
(tool) => tool.function.name === toolChoice.toolName,
|
355
|
+
),
|
328
356
|
tool_choice: "any",
|
329
357
|
};
|
330
358
|
default: {
|