@openrouter/ai-sdk-provider 0.7.1 → 1.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __defProps = Object.defineProperties;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
6
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
7
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
8
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
+ var __getProtoOf = Object.getPrototypeOf;
8
10
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
11
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
12
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -20,21 +22,9 @@ var __spreadValues = (a, b) => {
20
22
  return a;
21
23
  };
22
24
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
23
- var __objRest = (source, exclude) => {
24
- var target = {};
25
- for (var prop in source)
26
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
27
- target[prop] = source[prop];
28
- if (source != null && __getOwnPropSymbols)
29
- for (var prop of __getOwnPropSymbols(source)) {
30
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
31
- target[prop] = source[prop];
32
- }
33
- return target;
34
- };
35
25
  var __export = (target, all) => {
36
- for (var name in all)
37
- __defProp(target, name, { get: all[name], enumerable: true });
26
+ for (var name14 in all)
27
+ __defProp(target, name14, { get: all[name14], enumerable: true });
38
28
  };
39
29
  var __copyProps = (to, from, except, desc) => {
40
30
  if (from && typeof from === "object" || typeof from === "function") {
@@ -44,6 +34,14 @@ var __copyProps = (to, from, except, desc) => {
44
34
  }
45
35
  return to;
46
36
  };
37
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
38
+ // If the importer is in node compatibility mode or this is not an ESM
39
+ // file that has been converted to a CommonJS file using a Babel-
40
+ // compatible transform (i.e. "__esModule" has not been set), then set
41
+ // "default" to the CommonJS "module.exports" for node compatibility.
42
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
43
+ mod
44
+ ));
47
45
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
48
46
 
49
47
  // src/index.ts
@@ -55,75 +53,974 @@ __export(index_exports, {
55
53
  });
56
54
  module.exports = __toCommonJS(index_exports);
57
55
 
58
- // src/openrouter-facade.ts
59
- var import_provider_utils5 = require("@ai-sdk/provider-utils");
56
+ // node_modules/.pnpm/@ai-sdk+provider@2.0.0-beta.1/node_modules/@ai-sdk/provider/dist/index.mjs
57
+ var marker = "vercel.ai.error";
58
+ var symbol = Symbol.for(marker);
59
+ var _a;
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
+ var APICallError = class extends AISDKError {
99
+ constructor({
100
+ message,
101
+ url,
102
+ requestBodyValues,
103
+ statusCode,
104
+ responseHeaders,
105
+ responseBody,
106
+ cause,
107
+ isRetryable = statusCode != null && (statusCode === 408 || // request timeout
108
+ statusCode === 409 || // conflict
109
+ statusCode === 429 || // too many requests
110
+ statusCode >= 500),
111
+ // server error
112
+ data
113
+ }) {
114
+ super({ name, message, cause });
115
+ this[_a2] = true;
116
+ this.url = url;
117
+ this.requestBodyValues = requestBodyValues;
118
+ this.statusCode = statusCode;
119
+ this.responseHeaders = responseHeaders;
120
+ this.responseBody = responseBody;
121
+ this.isRetryable = isRetryable;
122
+ this.data = data;
123
+ }
124
+ static isInstance(error) {
125
+ return AISDKError.hasMarker(error, marker2);
126
+ }
127
+ };
128
+ _a2 = symbol2;
129
+ var name2 = "AI_EmptyResponseBodyError";
130
+ var marker3 = `vercel.ai.error.${name2}`;
131
+ var symbol3 = Symbol.for(marker3);
132
+ var _a3;
133
+ var EmptyResponseBodyError = class extends AISDKError {
134
+ // used in isInstance
135
+ constructor({ message = "Empty response body" } = {}) {
136
+ super({ name: name2, message });
137
+ this[_a3] = true;
138
+ }
139
+ static isInstance(error) {
140
+ return AISDKError.hasMarker(error, marker3);
141
+ }
142
+ };
143
+ _a3 = symbol3;
144
+ function getErrorMessage(error) {
145
+ if (error == null) {
146
+ return "unknown error";
147
+ }
148
+ if (typeof error === "string") {
149
+ return error;
150
+ }
151
+ if (error instanceof Error) {
152
+ return error.message;
153
+ }
154
+ return JSON.stringify(error);
155
+ }
156
+ var name3 = "AI_InvalidArgumentError";
157
+ var marker4 = `vercel.ai.error.${name3}`;
158
+ var symbol4 = Symbol.for(marker4);
159
+ var _a4;
160
+ var InvalidArgumentError = class extends AISDKError {
161
+ constructor({
162
+ message,
163
+ cause,
164
+ argument
165
+ }) {
166
+ super({ name: name3, message, cause });
167
+ this[_a4] = true;
168
+ this.argument = argument;
169
+ }
170
+ static isInstance(error) {
171
+ return AISDKError.hasMarker(error, marker4);
172
+ }
173
+ };
174
+ _a4 = symbol4;
175
+ var name4 = "AI_InvalidPromptError";
176
+ var marker5 = `vercel.ai.error.${name4}`;
177
+ var symbol5 = Symbol.for(marker5);
178
+ var _a5;
179
+ var InvalidPromptError = class extends AISDKError {
180
+ constructor({
181
+ prompt,
182
+ message,
183
+ cause
184
+ }) {
185
+ super({ name: name4, message: `Invalid prompt: ${message}`, cause });
186
+ this[_a5] = true;
187
+ this.prompt = prompt;
188
+ }
189
+ static isInstance(error) {
190
+ return AISDKError.hasMarker(error, marker5);
191
+ }
192
+ };
193
+ _a5 = symbol5;
194
+ var name5 = "AI_InvalidResponseDataError";
195
+ var marker6 = `vercel.ai.error.${name5}`;
196
+ var symbol6 = Symbol.for(marker6);
197
+ var _a6;
198
+ var InvalidResponseDataError = class extends AISDKError {
199
+ constructor({
200
+ data,
201
+ message = `Invalid response data: ${JSON.stringify(data)}.`
202
+ }) {
203
+ super({ name: name5, message });
204
+ this[_a6] = true;
205
+ this.data = data;
206
+ }
207
+ static isInstance(error) {
208
+ return AISDKError.hasMarker(error, marker6);
209
+ }
210
+ };
211
+ _a6 = symbol6;
212
+ var name6 = "AI_JSONParseError";
213
+ var marker7 = `vercel.ai.error.${name6}`;
214
+ var symbol7 = Symbol.for(marker7);
215
+ var _a7;
216
+ var JSONParseError = class extends AISDKError {
217
+ constructor({ text, cause }) {
218
+ super({
219
+ name: name6,
220
+ message: `JSON parsing failed: Text: ${text}.
221
+ Error message: ${getErrorMessage(cause)}`,
222
+ cause
223
+ });
224
+ this[_a7] = true;
225
+ this.text = text;
226
+ }
227
+ static isInstance(error) {
228
+ return AISDKError.hasMarker(error, marker7);
229
+ }
230
+ };
231
+ _a7 = symbol7;
232
+ var name7 = "AI_LoadAPIKeyError";
233
+ var marker8 = `vercel.ai.error.${name7}`;
234
+ var symbol8 = Symbol.for(marker8);
235
+ var _a8;
236
+ var LoadAPIKeyError = class extends AISDKError {
237
+ // used in isInstance
238
+ constructor({ message }) {
239
+ super({ name: name7, message });
240
+ this[_a8] = true;
241
+ }
242
+ static isInstance(error) {
243
+ return AISDKError.hasMarker(error, marker8);
244
+ }
245
+ };
246
+ _a8 = symbol8;
247
+ var name8 = "AI_LoadSettingError";
248
+ var marker9 = `vercel.ai.error.${name8}`;
249
+ var symbol9 = Symbol.for(marker9);
250
+ var _a9;
251
+ _a9 = symbol9;
252
+ var name9 = "AI_NoContentGeneratedError";
253
+ var marker10 = `vercel.ai.error.${name9}`;
254
+ var symbol10 = Symbol.for(marker10);
255
+ var _a10;
256
+ _a10 = symbol10;
257
+ var name10 = "AI_NoSuchModelError";
258
+ var marker11 = `vercel.ai.error.${name10}`;
259
+ var symbol11 = Symbol.for(marker11);
260
+ var _a11;
261
+ _a11 = symbol11;
262
+ var name11 = "AI_TooManyEmbeddingValuesForCallError";
263
+ var marker12 = `vercel.ai.error.${name11}`;
264
+ var symbol12 = Symbol.for(marker12);
265
+ var _a12;
266
+ _a12 = symbol12;
267
+ var name12 = "AI_TypeValidationError";
268
+ var marker13 = `vercel.ai.error.${name12}`;
269
+ var symbol13 = Symbol.for(marker13);
270
+ var _a13;
271
+ var _TypeValidationError = class _TypeValidationError2 extends AISDKError {
272
+ constructor({ value, cause }) {
273
+ super({
274
+ name: name12,
275
+ message: `Type validation failed: Value: ${JSON.stringify(value)}.
276
+ Error message: ${getErrorMessage(cause)}`,
277
+ cause
278
+ });
279
+ this[_a13] = true;
280
+ this.value = value;
281
+ }
282
+ static isInstance(error) {
283
+ return AISDKError.hasMarker(error, marker13);
284
+ }
285
+ /**
286
+ * Wraps an error into a TypeValidationError.
287
+ * If the cause is already a TypeValidationError with the same value, it returns the cause.
288
+ * Otherwise, it creates a new TypeValidationError.
289
+ *
290
+ * @param {Object} params - The parameters for wrapping the error.
291
+ * @param {unknown} params.value - The value that failed validation.
292
+ * @param {unknown} params.cause - The original error or cause of the validation failure.
293
+ * @returns {TypeValidationError} A TypeValidationError instance.
294
+ */
295
+ static wrap({
296
+ value,
297
+ cause
298
+ }) {
299
+ return _TypeValidationError2.isInstance(cause) && cause.value === value ? cause : new _TypeValidationError2({ value, cause });
300
+ }
301
+ };
302
+ _a13 = symbol13;
303
+ var TypeValidationError = _TypeValidationError;
304
+ var name13 = "AI_UnsupportedFunctionalityError";
305
+ var marker14 = `vercel.ai.error.${name13}`;
306
+ var symbol14 = Symbol.for(marker14);
307
+ var _a14;
308
+ var UnsupportedFunctionalityError = class extends AISDKError {
309
+ constructor({
310
+ functionality,
311
+ message = `'${functionality}' functionality not supported.`
312
+ }) {
313
+ super({ name: name13, message });
314
+ this[_a14] = true;
315
+ this.functionality = functionality;
316
+ }
317
+ static isInstance(error) {
318
+ return AISDKError.hasMarker(error, marker14);
319
+ }
320
+ };
321
+ _a14 = symbol14;
60
322
 
61
- // src/schemas/reasoning-details.ts
323
+ // node_modules/.pnpm/eventsource-parser@3.0.3/node_modules/eventsource-parser/dist/index.js
324
+ var ParseError = class extends Error {
325
+ constructor(message, options) {
326
+ super(message), this.name = "ParseError", this.type = options.type, this.field = options.field, this.value = options.value, this.line = options.line;
327
+ }
328
+ };
329
+ function noop(_arg) {
330
+ }
331
+ function createParser(callbacks) {
332
+ if (typeof callbacks == "function")
333
+ throw new TypeError(
334
+ "`callbacks` must be an object, got a function instead. Did you mean `{onEvent: fn}`?"
335
+ );
336
+ const { onEvent = noop, onError = noop, onRetry = noop, onComment } = callbacks;
337
+ let incompleteLine = "", isFirstChunk = true, id, data = "", eventType = "";
338
+ function feed(newChunk) {
339
+ const chunk = isFirstChunk ? newChunk.replace(/^\xEF\xBB\xBF/, "") : newChunk, [complete, incomplete] = splitLines(`${incompleteLine}${chunk}`);
340
+ for (const line of complete)
341
+ parseLine(line);
342
+ incompleteLine = incomplete, isFirstChunk = false;
343
+ }
344
+ function parseLine(line) {
345
+ if (line === "") {
346
+ dispatchEvent();
347
+ return;
348
+ }
349
+ if (line.startsWith(":")) {
350
+ onComment && onComment(line.slice(line.startsWith(": ") ? 2 : 1));
351
+ return;
352
+ }
353
+ const fieldSeparatorIndex = line.indexOf(":");
354
+ if (fieldSeparatorIndex !== -1) {
355
+ const field = line.slice(0, fieldSeparatorIndex), offset = line[fieldSeparatorIndex + 1] === " " ? 2 : 1, value = line.slice(fieldSeparatorIndex + offset);
356
+ processField(field, value, line);
357
+ return;
358
+ }
359
+ processField(line, "", line);
360
+ }
361
+ function processField(field, value, line) {
362
+ switch (field) {
363
+ case "event":
364
+ eventType = value;
365
+ break;
366
+ case "data":
367
+ data = `${data}${value}
368
+ `;
369
+ break;
370
+ case "id":
371
+ id = value.includes("\0") ? void 0 : value;
372
+ break;
373
+ case "retry":
374
+ /^\d+$/.test(value) ? onRetry(parseInt(value, 10)) : onError(
375
+ new ParseError(`Invalid \`retry\` value: "${value}"`, {
376
+ type: "invalid-retry",
377
+ value,
378
+ line
379
+ })
380
+ );
381
+ break;
382
+ default:
383
+ onError(
384
+ new ParseError(
385
+ `Unknown field "${field.length > 20 ? `${field.slice(0, 20)}\u2026` : field}"`,
386
+ { type: "unknown-field", field, value, line }
387
+ )
388
+ );
389
+ break;
390
+ }
391
+ }
392
+ function dispatchEvent() {
393
+ data.length > 0 && onEvent({
394
+ id,
395
+ event: eventType || void 0,
396
+ // If the data buffer's last character is a U+000A LINE FEED (LF) character,
397
+ // then remove the last character from the data buffer.
398
+ data: data.endsWith(`
399
+ `) ? data.slice(0, -1) : data
400
+ }), id = void 0, data = "", eventType = "";
401
+ }
402
+ function reset(options = {}) {
403
+ incompleteLine && options.consume && parseLine(incompleteLine), isFirstChunk = true, id = void 0, data = "", eventType = "", incompleteLine = "";
404
+ }
405
+ return { feed, reset };
406
+ }
407
+ function splitLines(chunk) {
408
+ const lines = [];
409
+ let incompleteLine = "", searchIndex = 0;
410
+ for (; searchIndex < chunk.length; ) {
411
+ const crIndex = chunk.indexOf("\r", searchIndex), lfIndex = chunk.indexOf(`
412
+ `, searchIndex);
413
+ let lineEnd = -1;
414
+ if (crIndex !== -1 && lfIndex !== -1 ? lineEnd = Math.min(crIndex, lfIndex) : crIndex !== -1 ? lineEnd = crIndex : lfIndex !== -1 && (lineEnd = lfIndex), lineEnd === -1) {
415
+ incompleteLine = chunk.slice(searchIndex);
416
+ break;
417
+ } else {
418
+ const line = chunk.slice(searchIndex, lineEnd);
419
+ lines.push(line), searchIndex = lineEnd + 1, chunk[searchIndex - 1] === "\r" && chunk[searchIndex] === `
420
+ ` && searchIndex++;
421
+ }
422
+ }
423
+ return [lines, incompleteLine];
424
+ }
425
+
426
+ // node_modules/.pnpm/eventsource-parser@3.0.3/node_modules/eventsource-parser/dist/stream.js
427
+ var EventSourceParserStream = class extends TransformStream {
428
+ constructor({ onError, onRetry, onComment } = {}) {
429
+ let parser;
430
+ super({
431
+ start(controller) {
432
+ parser = createParser({
433
+ onEvent: (event) => {
434
+ controller.enqueue(event);
435
+ },
436
+ onError(error) {
437
+ onError === "terminate" ? controller.error(error) : typeof onError == "function" && onError(error);
438
+ },
439
+ onRetry,
440
+ onComment
441
+ });
442
+ },
443
+ transform(chunk) {
444
+ parser.feed(chunk);
445
+ }
446
+ });
447
+ }
448
+ };
449
+
450
+ // node_modules/.pnpm/@ai-sdk+provider-utils@3.0.0-beta.2_zod@3.25.74/node_modules/@ai-sdk/provider-utils/dist/index.mjs
451
+ var z4 = __toESM(require("zod/v4"), 1);
452
+
453
+ // node_modules/.pnpm/zod-to-json-schema@3.24.5_zod@3.25.74/node_modules/zod-to-json-schema/dist/esm/Options.js
454
+ var ignoreOverride = Symbol("Let zodToJsonSchema decide on which parser to use");
455
+
456
+ // node_modules/.pnpm/zod-to-json-schema@3.24.5_zod@3.25.74/node_modules/zod-to-json-schema/dist/esm/selectParser.js
457
+ var import_zod4 = require("zod");
458
+
459
+ // node_modules/.pnpm/zod-to-json-schema@3.24.5_zod@3.25.74/node_modules/zod-to-json-schema/dist/esm/parsers/array.js
62
460
  var import_zod = require("zod");
63
- var ReasoningDetailSummarySchema = import_zod.z.object({
64
- type: import_zod.z.literal("reasoning.summary" /* Summary */),
65
- summary: import_zod.z.string()
461
+
462
+ // node_modules/.pnpm/zod-to-json-schema@3.24.5_zod@3.25.74/node_modules/zod-to-json-schema/dist/esm/parsers/record.js
463
+ var import_zod2 = require("zod");
464
+
465
+ // node_modules/.pnpm/zod-to-json-schema@3.24.5_zod@3.25.74/node_modules/zod-to-json-schema/dist/esm/parsers/string.js
466
+ var ALPHA_NUMERIC = new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");
467
+
468
+ // node_modules/.pnpm/zod-to-json-schema@3.24.5_zod@3.25.74/node_modules/zod-to-json-schema/dist/esm/parsers/object.js
469
+ var import_zod3 = require("zod");
470
+
471
+ // node_modules/.pnpm/@ai-sdk+provider-utils@3.0.0-beta.2_zod@3.25.74/node_modules/@ai-sdk/provider-utils/dist/index.mjs
472
+ function combineHeaders(...headers) {
473
+ return headers.reduce(
474
+ (combinedHeaders, currentHeaders) => __spreadValues(__spreadValues({}, combinedHeaders), currentHeaders != null ? currentHeaders : {}),
475
+ {}
476
+ );
477
+ }
478
+ function extractResponseHeaders(response) {
479
+ return Object.fromEntries([...response.headers]);
480
+ }
481
+ var createIdGenerator = ({
482
+ prefix,
483
+ size = 16,
484
+ alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
485
+ separator = "-"
486
+ } = {}) => {
487
+ const generator = () => {
488
+ const alphabetLength = alphabet.length;
489
+ const chars = new Array(size);
490
+ for (let i = 0; i < size; i++) {
491
+ chars[i] = alphabet[Math.random() * alphabetLength | 0];
492
+ }
493
+ return chars.join("");
494
+ };
495
+ if (prefix == null) {
496
+ return generator;
497
+ }
498
+ if (alphabet.includes(separator)) {
499
+ throw new InvalidArgumentError({
500
+ argument: "separator",
501
+ message: `The separator "${separator}" must not be part of the alphabet "${alphabet}".`
502
+ });
503
+ }
504
+ return () => `${prefix}${separator}${generator()}`;
505
+ };
506
+ var generateId = createIdGenerator();
507
+ function isAbortError(error) {
508
+ return error instanceof Error && (error.name === "AbortError" || error.name === "TimeoutError");
509
+ }
510
+ var FETCH_FAILED_ERROR_MESSAGES = ["fetch failed", "failed to fetch"];
511
+ function handleFetchError({
512
+ error,
513
+ url,
514
+ requestBodyValues
515
+ }) {
516
+ if (isAbortError(error)) {
517
+ return error;
518
+ }
519
+ if (error instanceof TypeError && FETCH_FAILED_ERROR_MESSAGES.includes(error.message.toLowerCase())) {
520
+ const cause = error.cause;
521
+ if (cause != null) {
522
+ return new APICallError({
523
+ message: `Cannot connect to API: ${cause.message}`,
524
+ cause,
525
+ url,
526
+ requestBodyValues,
527
+ isRetryable: true
528
+ // retry when network error
529
+ });
530
+ }
531
+ }
532
+ return error;
533
+ }
534
+ function removeUndefinedEntries(record) {
535
+ return Object.fromEntries(
536
+ Object.entries(record).filter(([_key, value]) => value != null)
537
+ );
538
+ }
539
+ function loadApiKey({
540
+ apiKey,
541
+ environmentVariableName,
542
+ apiKeyParameterName = "apiKey",
543
+ description
544
+ }) {
545
+ if (typeof apiKey === "string") {
546
+ return apiKey;
547
+ }
548
+ if (apiKey != null) {
549
+ throw new LoadAPIKeyError({
550
+ message: `${description} API key must be a string.`
551
+ });
552
+ }
553
+ if (typeof process === "undefined") {
554
+ throw new LoadAPIKeyError({
555
+ message: `${description} API key is missing. Pass it using the '${apiKeyParameterName}' parameter. Environment variables is not supported in this environment.`
556
+ });
557
+ }
558
+ apiKey = process.env[environmentVariableName];
559
+ if (apiKey == null) {
560
+ throw new LoadAPIKeyError({
561
+ message: `${description} API key is missing. Pass it using the '${apiKeyParameterName}' parameter or the ${environmentVariableName} environment variable.`
562
+ });
563
+ }
564
+ if (typeof apiKey !== "string") {
565
+ throw new LoadAPIKeyError({
566
+ message: `${description} API key must be a string. The value of the ${environmentVariableName} environment variable is not a string.`
567
+ });
568
+ }
569
+ return apiKey;
570
+ }
571
+ var suspectProtoRx = /"__proto__"\s*:/;
572
+ var suspectConstructorRx = /"constructor"\s*:/;
573
+ function _parse(text) {
574
+ const obj = JSON.parse(text);
575
+ if (obj === null || typeof obj !== "object") {
576
+ return obj;
577
+ }
578
+ if (suspectProtoRx.test(text) === false && suspectConstructorRx.test(text) === false) {
579
+ return obj;
580
+ }
581
+ return filter(obj);
582
+ }
583
+ function filter(obj) {
584
+ let next = [obj];
585
+ while (next.length) {
586
+ const nodes = next;
587
+ next = [];
588
+ for (const node of nodes) {
589
+ if (Object.prototype.hasOwnProperty.call(node, "__proto__")) {
590
+ throw new SyntaxError("Object contains forbidden prototype property");
591
+ }
592
+ if (Object.prototype.hasOwnProperty.call(node, "constructor") && Object.prototype.hasOwnProperty.call(node.constructor, "prototype")) {
593
+ throw new SyntaxError("Object contains forbidden prototype property");
594
+ }
595
+ for (const key in node) {
596
+ const value = node[key];
597
+ if (value && typeof value === "object") {
598
+ next.push(value);
599
+ }
600
+ }
601
+ }
602
+ }
603
+ return obj;
604
+ }
605
+ function secureJsonParse(text) {
606
+ const { stackTraceLimit } = Error;
607
+ Error.stackTraceLimit = 0;
608
+ try {
609
+ return _parse(text);
610
+ } finally {
611
+ Error.stackTraceLimit = stackTraceLimit;
612
+ }
613
+ }
614
+ var validatorSymbol = Symbol.for("vercel.ai.validator");
615
+ function validator(validate) {
616
+ return { [validatorSymbol]: true, validate };
617
+ }
618
+ function isValidator(value) {
619
+ return typeof value === "object" && value !== null && validatorSymbol in value && value[validatorSymbol] === true && "validate" in value;
620
+ }
621
+ function asValidator(value) {
622
+ return isValidator(value) ? value : standardSchemaValidator(value);
623
+ }
624
+ function standardSchemaValidator(standardSchema) {
625
+ return validator(async (value) => {
626
+ const result = await standardSchema["~standard"].validate(value);
627
+ return result.issues == null ? { success: true, value: result.value } : {
628
+ success: false,
629
+ error: new TypeValidationError({
630
+ value,
631
+ cause: result.issues
632
+ })
633
+ };
634
+ });
635
+ }
636
+ async function validateTypes({
637
+ value,
638
+ schema
639
+ }) {
640
+ const result = await safeValidateTypes({ value, schema });
641
+ if (!result.success) {
642
+ throw TypeValidationError.wrap({ value, cause: result.error });
643
+ }
644
+ return result.value;
645
+ }
646
+ async function safeValidateTypes({
647
+ value,
648
+ schema
649
+ }) {
650
+ const validator2 = asValidator(schema);
651
+ try {
652
+ if (validator2.validate == null) {
653
+ return { success: true, value, rawValue: value };
654
+ }
655
+ const result = await validator2.validate(value);
656
+ if (result.success) {
657
+ return { success: true, value: result.value, rawValue: value };
658
+ }
659
+ return {
660
+ success: false,
661
+ error: TypeValidationError.wrap({ value, cause: result.error }),
662
+ rawValue: value
663
+ };
664
+ } catch (error) {
665
+ return {
666
+ success: false,
667
+ error: TypeValidationError.wrap({ value, cause: error }),
668
+ rawValue: value
669
+ };
670
+ }
671
+ }
672
+ async function parseJSON({
673
+ text,
674
+ schema
675
+ }) {
676
+ try {
677
+ const value = secureJsonParse(text);
678
+ if (schema == null) {
679
+ return value;
680
+ }
681
+ return validateTypes({ value, schema });
682
+ } catch (error) {
683
+ if (JSONParseError.isInstance(error) || TypeValidationError.isInstance(error)) {
684
+ throw error;
685
+ }
686
+ throw new JSONParseError({ text, cause: error });
687
+ }
688
+ }
689
+ async function safeParseJSON({
690
+ text,
691
+ schema
692
+ }) {
693
+ try {
694
+ const value = secureJsonParse(text);
695
+ if (schema == null) {
696
+ return { success: true, value, rawValue: value };
697
+ }
698
+ return await safeValidateTypes({ value, schema });
699
+ } catch (error) {
700
+ return {
701
+ success: false,
702
+ error: JSONParseError.isInstance(error) ? error : new JSONParseError({ text, cause: error }),
703
+ rawValue: void 0
704
+ };
705
+ }
706
+ }
707
+ function isParsableJson(input) {
708
+ try {
709
+ secureJsonParse(input);
710
+ return true;
711
+ } catch (e) {
712
+ return false;
713
+ }
714
+ }
715
+ function parseJsonEventStream({
716
+ stream,
717
+ schema
718
+ }) {
719
+ return stream.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream()).pipeThrough(
720
+ new TransformStream({
721
+ async transform({ data }, controller) {
722
+ if (data === "[DONE]") {
723
+ return;
724
+ }
725
+ controller.enqueue(await safeParseJSON({ text: data, schema }));
726
+ }
727
+ })
728
+ );
729
+ }
730
+ var getOriginalFetch2 = () => globalThis.fetch;
731
+ var postJsonToApi = async ({
732
+ url,
733
+ headers,
734
+ body,
735
+ failedResponseHandler,
736
+ successfulResponseHandler,
737
+ abortSignal,
738
+ fetch
739
+ }) => postToApi({
740
+ url,
741
+ headers: __spreadValues({
742
+ "Content-Type": "application/json"
743
+ }, headers),
744
+ body: {
745
+ content: JSON.stringify(body),
746
+ values: body
747
+ },
748
+ failedResponseHandler,
749
+ successfulResponseHandler,
750
+ abortSignal,
751
+ fetch
66
752
  });
67
- var ReasoningDetailEncryptedSchema = import_zod.z.object({
68
- type: import_zod.z.literal("reasoning.encrypted" /* Encrypted */),
69
- data: import_zod.z.string()
753
+ var postToApi = async ({
754
+ url,
755
+ headers = {},
756
+ body,
757
+ successfulResponseHandler,
758
+ failedResponseHandler,
759
+ abortSignal,
760
+ fetch = getOriginalFetch2()
761
+ }) => {
762
+ try {
763
+ const response = await fetch(url, {
764
+ method: "POST",
765
+ headers: removeUndefinedEntries(headers),
766
+ body: body.content,
767
+ signal: abortSignal
768
+ });
769
+ const responseHeaders = extractResponseHeaders(response);
770
+ if (!response.ok) {
771
+ let errorInformation;
772
+ try {
773
+ errorInformation = await failedResponseHandler({
774
+ response,
775
+ url,
776
+ requestBodyValues: body.values
777
+ });
778
+ } catch (error) {
779
+ if (isAbortError(error) || APICallError.isInstance(error)) {
780
+ throw error;
781
+ }
782
+ throw new APICallError({
783
+ message: "Failed to process error response",
784
+ cause: error,
785
+ statusCode: response.status,
786
+ url,
787
+ responseHeaders,
788
+ requestBodyValues: body.values
789
+ });
790
+ }
791
+ throw errorInformation.value;
792
+ }
793
+ try {
794
+ return await successfulResponseHandler({
795
+ response,
796
+ url,
797
+ requestBodyValues: body.values
798
+ });
799
+ } catch (error) {
800
+ if (error instanceof Error) {
801
+ if (isAbortError(error) || APICallError.isInstance(error)) {
802
+ throw error;
803
+ }
804
+ }
805
+ throw new APICallError({
806
+ message: "Failed to process successful response",
807
+ cause: error,
808
+ statusCode: response.status,
809
+ url,
810
+ responseHeaders,
811
+ requestBodyValues: body.values
812
+ });
813
+ }
814
+ } catch (error) {
815
+ throw handleFetchError({ error, url, requestBodyValues: body.values });
816
+ }
817
+ };
818
+ var createJsonErrorResponseHandler = ({
819
+ errorSchema,
820
+ errorToMessage,
821
+ isRetryable
822
+ }) => async ({ response, url, requestBodyValues }) => {
823
+ const responseBody = await response.text();
824
+ const responseHeaders = extractResponseHeaders(response);
825
+ if (responseBody.trim() === "") {
826
+ return {
827
+ responseHeaders,
828
+ value: new APICallError({
829
+ message: response.statusText,
830
+ url,
831
+ requestBodyValues,
832
+ statusCode: response.status,
833
+ responseHeaders,
834
+ responseBody,
835
+ isRetryable: isRetryable == null ? void 0 : isRetryable(response)
836
+ })
837
+ };
838
+ }
839
+ try {
840
+ const parsedError = await parseJSON({
841
+ text: responseBody,
842
+ schema: errorSchema
843
+ });
844
+ return {
845
+ responseHeaders,
846
+ value: new APICallError({
847
+ message: errorToMessage(parsedError),
848
+ url,
849
+ requestBodyValues,
850
+ statusCode: response.status,
851
+ responseHeaders,
852
+ responseBody,
853
+ data: parsedError,
854
+ isRetryable: isRetryable == null ? void 0 : isRetryable(response, parsedError)
855
+ })
856
+ };
857
+ } catch (parseError) {
858
+ return {
859
+ responseHeaders,
860
+ value: new APICallError({
861
+ message: response.statusText,
862
+ url,
863
+ requestBodyValues,
864
+ statusCode: response.status,
865
+ responseHeaders,
866
+ responseBody,
867
+ isRetryable: isRetryable == null ? void 0 : isRetryable(response)
868
+ })
869
+ };
870
+ }
871
+ };
872
+ var createEventSourceResponseHandler = (chunkSchema) => async ({ response }) => {
873
+ const responseHeaders = extractResponseHeaders(response);
874
+ if (response.body == null) {
875
+ throw new EmptyResponseBodyError({});
876
+ }
877
+ return {
878
+ responseHeaders,
879
+ value: parseJsonEventStream({
880
+ stream: response.body,
881
+ schema: chunkSchema
882
+ })
883
+ };
884
+ };
885
+ var createJsonResponseHandler = (responseSchema) => async ({ response, url, requestBodyValues }) => {
886
+ const responseBody = await response.text();
887
+ const parsedResult = await safeParseJSON({
888
+ text: responseBody,
889
+ schema: responseSchema
890
+ });
891
+ const responseHeaders = extractResponseHeaders(response);
892
+ if (!parsedResult.success) {
893
+ throw new APICallError({
894
+ message: "Invalid JSON response",
895
+ cause: parsedResult.error,
896
+ statusCode: response.status,
897
+ responseHeaders,
898
+ responseBody,
899
+ url,
900
+ requestBodyValues
901
+ });
902
+ }
903
+ return {
904
+ responseHeaders,
905
+ value: parsedResult.value,
906
+ rawValue: parsedResult.rawValue
907
+ };
908
+ };
909
+ var schemaSymbol = Symbol.for("vercel.ai.schema");
910
+ var { btoa, atob } = globalThis;
911
+ function convertUint8ArrayToBase64(array) {
912
+ let latin1string = "";
913
+ for (let i = 0; i < array.length; i++) {
914
+ latin1string += String.fromCodePoint(array[i]);
915
+ }
916
+ return btoa(latin1string);
917
+ }
918
+ function withoutTrailingSlash(url) {
919
+ return url == null ? void 0 : url.replace(/\/$/, "");
920
+ }
921
+
922
+ // src/chat/index.ts
923
+ var import_v44 = require("zod/v4");
924
+
925
+ // src/schemas/reasoning-details.ts
926
+ var import_v4 = require("zod/v4");
927
+ var ReasoningDetailSummarySchema = import_v4.z.object({
928
+ type: import_v4.z.literal("reasoning.summary" /* Summary */),
929
+ summary: import_v4.z.string()
930
+ });
931
+ var ReasoningDetailEncryptedSchema = import_v4.z.object({
932
+ type: import_v4.z.literal("reasoning.encrypted" /* Encrypted */),
933
+ data: import_v4.z.string()
70
934
  });
71
- var ReasoningDetailTextSchema = import_zod.z.object({
72
- type: import_zod.z.literal("reasoning.text" /* Text */),
73
- text: import_zod.z.string().nullish(),
74
- signature: import_zod.z.string().nullish()
935
+ var ReasoningDetailTextSchema = import_v4.z.object({
936
+ type: import_v4.z.literal("reasoning.text" /* Text */),
937
+ text: import_v4.z.string().nullish(),
938
+ signature: import_v4.z.string().nullish()
75
939
  });
76
- var ReasoningDetailUnionSchema = import_zod.z.union([
940
+ var ReasoningDetailUnionSchema = import_v4.z.union([
77
941
  ReasoningDetailSummarySchema,
78
942
  ReasoningDetailEncryptedSchema,
79
943
  ReasoningDetailTextSchema
80
944
  ]);
81
- var ReasoningDetailsWithUnknownSchema = import_zod.z.union([
945
+ var ReasoningDetailsWithUnknownSchema = import_v4.z.union([
82
946
  ReasoningDetailUnionSchema,
83
- import_zod.z.unknown().transform(() => null)
947
+ import_v4.z.unknown().transform(() => null)
84
948
  ]);
85
- var ReasoningDetailArraySchema = import_zod.z.array(ReasoningDetailsWithUnknownSchema).transform((d) => d.filter((d2) => !!d2));
949
+ var ReasoningDetailArraySchema = import_v4.z.array(ReasoningDetailsWithUnknownSchema).transform((d) => d.filter((d2) => !!d2));
86
950
 
87
- // src/openrouter-chat-language-model.ts
88
- var import_provider = require("@ai-sdk/provider");
89
- var import_provider_utils3 = require("@ai-sdk/provider-utils");
90
- var import_zod3 = require("zod");
951
+ // src/schemas/error-response.ts
952
+ var import_v42 = require("zod/v4");
953
+ var OpenRouterErrorResponseSchema = import_v42.z.object({
954
+ error: import_v42.z.object({
955
+ code: import_v42.z.union([import_v42.z.string(), import_v42.z.number()]).nullable(),
956
+ message: import_v42.z.string(),
957
+ type: import_v42.z.string().nullable(),
958
+ param: import_v42.z.any().nullable()
959
+ })
960
+ });
961
+ var openrouterFailedResponseHandler = createJsonErrorResponseHandler({
962
+ errorSchema: OpenRouterErrorResponseSchema,
963
+ errorToMessage: (data) => data.error.message
964
+ });
965
+
966
+ // src/utils/map-finish-reason.ts
967
+ function mapOpenRouterFinishReason(finishReason) {
968
+ switch (finishReason) {
969
+ case "stop":
970
+ return "stop";
971
+ case "length":
972
+ return "length";
973
+ case "content_filter":
974
+ return "content-filter";
975
+ case "function_call":
976
+ case "tool_calls":
977
+ return "tool-calls";
978
+ default:
979
+ return "unknown";
980
+ }
981
+ }
91
982
 
92
- // src/convert-to-openrouter-chat-messages.ts
93
- var import_provider_utils = require("@ai-sdk/provider-utils");
983
+ // src/chat/convert-to-openrouter-chat-messages.ts
94
984
  function getCacheControl(providerMetadata) {
95
- var _a, _b, _c;
985
+ var _a15, _b, _c;
96
986
  const anthropic = providerMetadata == null ? void 0 : providerMetadata.anthropic;
97
987
  const openrouter2 = providerMetadata == null ? void 0 : providerMetadata.openrouter;
98
- return (_c = (_b = (_a = openrouter2 == null ? void 0 : openrouter2.cacheControl) != null ? _a : openrouter2 == null ? void 0 : openrouter2.cache_control) != null ? _b : anthropic == null ? void 0 : anthropic.cacheControl) != null ? _c : anthropic == null ? void 0 : anthropic.cache_control;
988
+ return (_c = (_b = (_a15 = openrouter2 == null ? void 0 : openrouter2.cacheControl) != null ? _a15 : openrouter2 == null ? void 0 : openrouter2.cache_control) != null ? _b : anthropic == null ? void 0 : anthropic.cacheControl) != null ? _c : anthropic == null ? void 0 : anthropic.cache_control;
99
989
  }
100
990
  function convertToOpenRouterChatMessages(prompt) {
101
- var _a, _b, _c;
991
+ var _a15, _b, _c;
102
992
  const messages = [];
103
- for (const { role, content, providerMetadata } of prompt) {
993
+ for (const { role, content, providerOptions } of prompt) {
104
994
  switch (role) {
105
995
  case "system": {
106
996
  messages.push({
107
997
  role: "system",
108
998
  content,
109
- cache_control: getCacheControl(providerMetadata)
999
+ cache_control: getCacheControl(providerOptions)
110
1000
  });
111
1001
  break;
112
1002
  }
113
1003
  case "user": {
114
- if (content.length === 1 && ((_a = content[0]) == null ? void 0 : _a.type) === "text") {
1004
+ if (content.length === 1 && ((_a15 = content[0]) == null ? void 0 : _a15.type) === "text") {
1005
+ const cacheControl = (_b = getCacheControl(providerOptions)) != null ? _b : getCacheControl(content[0].providerOptions);
1006
+ const contentWithCacheControl = cacheControl ? [
1007
+ {
1008
+ type: "text",
1009
+ text: content[0].text,
1010
+ cache_control: cacheControl
1011
+ }
1012
+ ] : content[0].text;
115
1013
  messages.push({
116
1014
  role: "user",
117
- content: content[0].text,
118
- cache_control: (_b = getCacheControl(providerMetadata)) != null ? _b : getCacheControl(content[0].providerMetadata)
1015
+ content: contentWithCacheControl
119
1016
  });
120
1017
  break;
121
1018
  }
122
- const messageCacheControl = getCacheControl(providerMetadata);
1019
+ const messageCacheControl = getCacheControl(providerOptions);
123
1020
  const contentParts = content.map(
124
1021
  (part) => {
125
- var _a2, _b2, _c2, _d;
126
- const cacheControl = (_a2 = getCacheControl(part.providerMetadata)) != null ? _a2 : messageCacheControl;
1022
+ var _a16, _b2, _c2, _d, _e, _f, _g;
1023
+ const cacheControl = (_a16 = getCacheControl(part.providerOptions)) != null ? _a16 : messageCacheControl;
127
1024
  switch (part.type) {
128
1025
  case "text":
129
1026
  return {
@@ -132,33 +1029,35 @@ function convertToOpenRouterChatMessages(prompt) {
132
1029
  // For text parts, only use part-specific cache control
133
1030
  cache_control: cacheControl
134
1031
  };
135
- case "image":
136
- return {
137
- type: "image_url",
138
- image_url: {
139
- url: part.image instanceof URL ? part.image.toString() : `data:${(_b2 = part.mimeType) != null ? _b2 : "image/jpeg"};base64,${(0, import_provider_utils.convertUint8ArrayToBase64)(
140
- part.image
141
- )}`
142
- },
143
- // For image parts, use part-specific or message-level cache control
144
- cache_control: cacheControl
145
- };
146
1032
  case "file":
1033
+ if ((_b2 = part.mediaType) == null ? void 0 : _b2.startsWith("image/")) {
1034
+ return {
1035
+ type: "image_url",
1036
+ image_url: {
1037
+ url: part.data instanceof URL ? part.data.toString() : `data:${(_c2 = part.mediaType) != null ? _c2 : "image/jpeg"};base64,${convertUint8ArrayToBase64(
1038
+ part.data instanceof Uint8Array ? part.data : new Uint8Array()
1039
+ )}`
1040
+ },
1041
+ // For image parts, use part-specific or message-level cache control
1042
+ cache_control: cacheControl
1043
+ };
1044
+ }
147
1045
  return {
148
1046
  type: "file",
149
1047
  file: {
150
1048
  filename: String(
151
- (_d = (_c2 = part.providerMetadata) == null ? void 0 : _c2.openrouter) == null ? void 0 : _d.filename
1049
+ (_g = (_f = (_e = (_d = part.providerOptions) == null ? void 0 : _d.openrouter) == null ? void 0 : _e.filename) != null ? _f : part.filename) != null ? _g : ""
152
1050
  ),
153
- file_data: part.data instanceof Uint8Array ? `data:${part.mimeType};base64,${(0, import_provider_utils.convertUint8ArrayToBase64)(part.data)}` : `data:${part.mimeType};base64,${part.data}`
1051
+ file_data: part.data instanceof Uint8Array ? `data:${part.mediaType};base64,${convertUint8ArrayToBase64(part.data)}` : `data:${part.mediaType};base64,${part.data}`
154
1052
  },
155
1053
  cache_control: cacheControl
156
1054
  };
157
1055
  default: {
158
- const _exhaustiveCheck = part;
159
- throw new Error(
160
- `Unsupported content part type: ${_exhaustiveCheck}`
161
- );
1056
+ return {
1057
+ type: "text",
1058
+ text: "",
1059
+ cache_control: cacheControl
1060
+ };
162
1061
  }
163
1062
  }
164
1063
  }
@@ -186,7 +1085,7 @@ function convertToOpenRouterChatMessages(prompt) {
186
1085
  type: "function",
187
1086
  function: {
188
1087
  name: part.toolName,
189
- arguments: JSON.stringify(part.args)
1088
+ arguments: JSON.stringify(part.input)
190
1089
  }
191
1090
  });
192
1091
  break;
@@ -195,23 +1094,14 @@ function convertToOpenRouterChatMessages(prompt) {
195
1094
  reasoning += part.text;
196
1095
  reasoningDetails.push({
197
1096
  type: "reasoning.text" /* Text */,
198
- text: part.text,
199
- signature: part.signature
200
- });
201
- break;
202
- }
203
- case "redacted-reasoning": {
204
- reasoningDetails.push({
205
- type: "reasoning.encrypted" /* Encrypted */,
206
- data: part.data
1097
+ text: part.text
207
1098
  });
208
1099
  break;
209
1100
  }
210
1101
  case "file":
211
1102
  break;
212
1103
  default: {
213
- const _exhaustiveCheck = part;
214
- throw new Error(`Unsupported part: ${_exhaustiveCheck}`);
1104
+ break;
215
1105
  }
216
1106
  }
217
1107
  }
@@ -221,95 +1111,86 @@ function convertToOpenRouterChatMessages(prompt) {
221
1111
  tool_calls: toolCalls.length > 0 ? toolCalls : void 0,
222
1112
  reasoning: reasoning || void 0,
223
1113
  reasoning_details: reasoningDetails.length > 0 ? reasoningDetails : void 0,
224
- cache_control: getCacheControl(providerMetadata)
1114
+ cache_control: getCacheControl(providerOptions)
225
1115
  });
226
1116
  break;
227
1117
  }
228
1118
  case "tool": {
229
1119
  for (const toolResponse of content) {
1120
+ const content2 = getToolResultContent(toolResponse);
230
1121
  messages.push({
231
1122
  role: "tool",
232
1123
  tool_call_id: toolResponse.toolCallId,
233
- content: JSON.stringify(toolResponse.result),
234
- cache_control: (_c = getCacheControl(providerMetadata)) != null ? _c : getCacheControl(toolResponse.providerMetadata)
1124
+ content: content2,
1125
+ cache_control: (_c = getCacheControl(providerOptions)) != null ? _c : getCacheControl(toolResponse.providerOptions)
235
1126
  });
236
1127
  }
237
1128
  break;
238
1129
  }
239
1130
  default: {
240
- const _exhaustiveCheck = role;
241
- throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
1131
+ break;
242
1132
  }
243
1133
  }
244
1134
  }
245
1135
  return messages;
246
1136
  }
247
-
248
- // src/map-openrouter-chat-logprobs.ts
249
- function mapOpenRouterChatLogProbsOutput(logprobs) {
250
- var _a, _b;
251
- return (_b = (_a = logprobs == null ? void 0 : logprobs.content) == null ? void 0 : _a.map(({ token, logprob, top_logprobs }) => ({
252
- token,
253
- logprob,
254
- topLogprobs: top_logprobs ? top_logprobs.map(({ token: token2, logprob: logprob2 }) => ({
255
- token: token2,
256
- logprob: logprob2
257
- })) : []
258
- }))) != null ? _b : void 0;
1137
+ function getToolResultContent(input) {
1138
+ return input.output.type === "text" ? input.output.value : JSON.stringify(input.output.value);
259
1139
  }
260
1140
 
261
- // src/map-openrouter-finish-reason.ts
262
- function mapOpenRouterFinishReason(finishReason) {
263
- switch (finishReason) {
264
- case "stop":
265
- return "stop";
266
- case "length":
267
- return "length";
268
- case "content_filter":
269
- return "content-filter";
270
- case "function_call":
271
- case "tool_calls":
272
- return "tool-calls";
273
- default:
274
- return "unknown";
1141
+ // src/chat/get-tool-choice.ts
1142
+ var import_v43 = require("zod/v4");
1143
+ var ChatCompletionToolChoiceSchema = import_v43.z.union([
1144
+ import_v43.z.literal("auto"),
1145
+ import_v43.z.literal("none"),
1146
+ import_v43.z.literal("required"),
1147
+ import_v43.z.object({
1148
+ type: import_v43.z.literal("function"),
1149
+ function: import_v43.z.object({
1150
+ name: import_v43.z.string()
1151
+ })
1152
+ })
1153
+ ]);
1154
+ function getChatCompletionToolChoice(toolChoice) {
1155
+ switch (toolChoice.type) {
1156
+ case "auto":
1157
+ case "none":
1158
+ case "required":
1159
+ return toolChoice.type;
1160
+ case "tool": {
1161
+ return {
1162
+ type: "function",
1163
+ function: { name: toolChoice.toolName }
1164
+ };
1165
+ }
1166
+ default: {
1167
+ toolChoice;
1168
+ throw new Error(`Invalid tool choice type: ${toolChoice}`);
1169
+ }
275
1170
  }
276
1171
  }
277
1172
 
278
- // src/openrouter-error.ts
279
- var import_provider_utils2 = require("@ai-sdk/provider-utils");
280
- var import_zod2 = require("zod");
281
- var OpenRouterErrorResponseSchema = import_zod2.z.object({
282
- error: import_zod2.z.object({
283
- message: import_zod2.z.string(),
284
- type: import_zod2.z.string(),
285
- param: import_zod2.z.any().nullable(),
286
- code: import_zod2.z.string().nullable()
287
- })
288
- });
289
- var openrouterFailedResponseHandler = (0, import_provider_utils2.createJsonErrorResponseHandler)({
290
- errorSchema: OpenRouterErrorResponseSchema,
291
- errorToMessage: (data) => data.error.message
292
- });
293
-
294
- // src/openrouter-chat-language-model.ts
295
- function isFunctionTool(tool) {
296
- return "parameters" in tool;
297
- }
1173
+ // src/chat/index.ts
298
1174
  var OpenRouterChatLanguageModel = class {
299
1175
  constructor(modelId, settings, config) {
300
- this.specificationVersion = "v1";
1176
+ this.specificationVersion = "v2";
1177
+ this.provider = "openrouter";
301
1178
  this.defaultObjectGenerationMode = "tool";
1179
+ this.supportedUrls = {
1180
+ "image/*": [
1181
+ /^data:image\/[a-zA-Z]+;base64,/,
1182
+ /^https?:\/\/.+\.(jpg|jpeg|png|gif|webp)$/i
1183
+ ],
1184
+ // 'text/*': [/^data:text\//, /^https?:\/\/.+$/],
1185
+ "application/*": [/^data:application\//, /^https?:\/\/.+$/]
1186
+ };
302
1187
  this.modelId = modelId;
303
1188
  this.settings = settings;
304
1189
  this.config = config;
305
1190
  }
306
- get provider() {
307
- return this.config.provider;
308
- }
309
1191
  getArgs({
310
- mode,
311
1192
  prompt,
312
- maxTokens,
1193
+ maxOutputTokens,
313
1194
  temperature,
314
1195
  topP,
315
1196
  frequencyPenalty,
@@ -318,12 +1199,10 @@ var OpenRouterChatLanguageModel = class {
318
1199
  stopSequences,
319
1200
  responseFormat,
320
1201
  topK,
321
- providerMetadata
1202
+ tools,
1203
+ toolChoice
322
1204
  }) {
323
- var _a;
324
- const type = mode.type;
325
- const extraCallingBody = (_a = providerMetadata == null ? void 0 : providerMetadata.openrouter) != null ? _a : {};
326
- const baseArgs = __spreadValues(__spreadValues(__spreadValues({
1205
+ const baseArgs = __spreadValues(__spreadValues({
327
1206
  // model id:
328
1207
  model: this.modelId,
329
1208
  models: this.settings.models,
@@ -334,7 +1213,7 @@ var OpenRouterChatLanguageModel = class {
334
1213
  user: this.settings.user,
335
1214
  parallel_tool_calls: this.settings.parallelToolCalls,
336
1215
  // standardized settings:
337
- max_tokens: maxTokens,
1216
+ max_tokens: maxOutputTokens,
338
1217
  temperature,
339
1218
  top_p: topP,
340
1219
  frequency_penalty: frequencyPenalty,
@@ -349,97 +1228,74 @@ var OpenRouterChatLanguageModel = class {
349
1228
  include_reasoning: this.settings.includeReasoning,
350
1229
  reasoning: this.settings.reasoning,
351
1230
  usage: this.settings.usage
352
- }, this.config.extraBody), this.settings.extraBody), extraCallingBody);
353
- switch (type) {
354
- case "regular": {
355
- return __spreadValues(__spreadValues({}, baseArgs), prepareToolsAndToolChoice(mode));
356
- }
357
- case "object-json": {
358
- return __spreadProps(__spreadValues({}, baseArgs), {
359
- response_format: { type: "json_object" }
360
- });
361
- }
362
- case "object-tool": {
363
- return __spreadProps(__spreadValues({}, baseArgs), {
364
- tool_choice: { type: "function", function: { name: mode.tool.name } },
365
- tools: [
366
- {
367
- type: "function",
368
- function: {
369
- name: mode.tool.name,
370
- description: mode.tool.description,
371
- parameters: mode.tool.parameters
372
- }
373
- }
374
- ]
375
- });
376
- }
377
- // Handle all non-text types with a single default case
378
- default: {
379
- const _exhaustiveCheck = type;
380
- throw new import_provider.UnsupportedFunctionalityError({
381
- functionality: `${_exhaustiveCheck} mode`
382
- });
383
- }
1231
+ }, this.config.extraBody), this.settings.extraBody);
1232
+ if ((responseFormat == null ? void 0 : responseFormat.type) === "json") {
1233
+ return __spreadProps(__spreadValues({}, baseArgs), {
1234
+ response_format: { type: "json_object" }
1235
+ });
384
1236
  }
1237
+ if (tools && tools.length > 0) {
1238
+ const mappedTools = tools.filter((tool) => tool.type === "function").map((tool) => ({
1239
+ type: "function",
1240
+ function: {
1241
+ name: tool.name,
1242
+ description: tool.type,
1243
+ parameters: tool.inputSchema
1244
+ }
1245
+ }));
1246
+ return __spreadProps(__spreadValues({}, baseArgs), {
1247
+ tools: mappedTools,
1248
+ tool_choice: toolChoice ? getChatCompletionToolChoice(toolChoice) : void 0
1249
+ });
1250
+ }
1251
+ return baseArgs;
385
1252
  }
386
1253
  async doGenerate(options) {
387
- var _b, _c, _d, _e, _f, _g, _h, _i, _j;
388
- const args = this.getArgs(options);
389
- const { responseHeaders, value: response } = await (0, import_provider_utils3.postJsonToApi)({
1254
+ var _a15, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t;
1255
+ const providerOptions = options.providerOptions || {};
1256
+ const openrouterOptions = providerOptions.openrouter || {};
1257
+ const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
1258
+ const { value: response, responseHeaders } = await postJsonToApi({
390
1259
  url: this.config.url({
391
1260
  path: "/chat/completions",
392
1261
  modelId: this.modelId
393
1262
  }),
394
- headers: (0, import_provider_utils3.combineHeaders)(this.config.headers(), options.headers),
1263
+ headers: combineHeaders(this.config.headers(), options.headers),
395
1264
  body: args,
396
1265
  failedResponseHandler: openrouterFailedResponseHandler,
397
- successfulResponseHandler: (0, import_provider_utils3.createJsonResponseHandler)(
1266
+ successfulResponseHandler: createJsonResponseHandler(
398
1267
  OpenRouterNonStreamChatCompletionResponseSchema
399
1268
  ),
400
1269
  abortSignal: options.abortSignal,
401
1270
  fetch: this.config.fetch
402
1271
  });
403
- const _a = args, { messages: rawPrompt } = _a, rawSettings = __objRest(_a, ["messages"]);
404
1272
  const choice = response.choices[0];
405
1273
  if (!choice) {
406
1274
  throw new Error("No choice in response");
407
1275
  }
408
1276
  const usageInfo = response.usage ? {
409
- promptTokens: (_b = response.usage.prompt_tokens) != null ? _b : 0,
410
- completionTokens: (_c = response.usage.completion_tokens) != null ? _c : 0
1277
+ inputTokens: (_a15 = response.usage.prompt_tokens) != null ? _a15 : 0,
1278
+ outputTokens: (_b = response.usage.completion_tokens) != null ? _b : 0,
1279
+ totalTokens: ((_c = response.usage.prompt_tokens) != null ? _c : 0) + ((_d = response.usage.completion_tokens) != null ? _d : 0),
1280
+ reasoningTokens: (_f = (_e = response.usage.completion_tokens_details) == null ? void 0 : _e.reasoning_tokens) != null ? _f : 0,
1281
+ cachedInputTokens: (_h = (_g = response.usage.prompt_tokens_details) == null ? void 0 : _g.cached_tokens) != null ? _h : 0
411
1282
  } : {
412
- promptTokens: 0,
413
- completionTokens: 0
1283
+ inputTokens: 0,
1284
+ outputTokens: 0,
1285
+ totalTokens: 0,
1286
+ reasoningTokens: 0,
1287
+ cachedInputTokens: 0
414
1288
  };
415
- const providerMetadata = {};
416
- if (response.usage && ((_d = this.settings.usage) == null ? void 0 : _d.include)) {
417
- providerMetadata.openrouter = {
418
- usage: {
419
- promptTokens: response.usage.prompt_tokens,
420
- promptTokensDetails: response.usage.prompt_tokens_details ? {
421
- cachedTokens: (_e = response.usage.prompt_tokens_details.cached_tokens) != null ? _e : 0
422
- } : void 0,
423
- completionTokens: response.usage.completion_tokens,
424
- completionTokensDetails: response.usage.completion_tokens_details ? {
425
- reasoningTokens: (_f = response.usage.completion_tokens_details.reasoning_tokens) != null ? _f : 0
426
- } : void 0,
427
- cost: response.usage.cost,
428
- totalTokens: (_g = response.usage.total_tokens) != null ? _g : 0
429
- }
430
- };
431
- }
432
- const hasProviderMetadata = Object.keys(providerMetadata).length > 0;
433
- const reasoningDetails = (_h = choice.message.reasoning_details) != null ? _h : [];
434
- const reasoning = reasoningDetails.length > 0 ? reasoningDetails.map((detail) => {
435
- var _a2;
1289
+ const reasoningDetails = (_i = choice.message.reasoning_details) != null ? _i : [];
1290
+ reasoningDetails.length > 0 ? reasoningDetails.map((detail) => {
1291
+ var _a16;
436
1292
  switch (detail.type) {
437
1293
  case "reasoning.text" /* Text */: {
438
1294
  if (detail.text) {
439
1295
  return {
440
1296
  type: "text",
441
1297
  text: detail.text,
442
- signature: (_a2 = detail.signature) != null ? _a2 : void 0
1298
+ signature: (_a16 = detail.signature) != null ? _a16 : void 0
443
1299
  };
444
1300
  }
445
1301
  break;
@@ -473,68 +1329,92 @@ var OpenRouterChatLanguageModel = class {
473
1329
  text: choice.message.reasoning
474
1330
  }
475
1331
  ] : [];
476
- return __spreadValues({
477
- response: {
478
- id: response.id,
479
- modelId: response.model
480
- },
481
- text: (_i = choice.message.content) != null ? _i : void 0,
482
- reasoning,
483
- toolCalls: (_j = choice.message.tool_calls) == null ? void 0 : _j.map((toolCall) => {
484
- var _a2;
485
- return {
486
- toolCallType: "function",
487
- toolCallId: (_a2 = toolCall.id) != null ? _a2 : (0, import_provider_utils3.generateId)(),
1332
+ const content = [];
1333
+ if (choice.message.content) {
1334
+ content.push({
1335
+ type: "text",
1336
+ text: choice.message.content
1337
+ });
1338
+ }
1339
+ if (choice.message.tool_calls) {
1340
+ for (const toolCall of choice.message.tool_calls) {
1341
+ content.push({
1342
+ type: "tool-call",
1343
+ toolCallId: (_j = toolCall.id) != null ? _j : generateId(),
488
1344
  toolName: toolCall.function.name,
489
- args: toolCall.function.arguments
490
- };
491
- }),
1345
+ input: toolCall.function.arguments
1346
+ });
1347
+ }
1348
+ }
1349
+ return {
1350
+ content,
492
1351
  finishReason: mapOpenRouterFinishReason(choice.finish_reason),
493
1352
  usage: usageInfo,
494
- rawCall: { rawPrompt, rawSettings },
495
- rawResponse: { headers: responseHeaders },
496
1353
  warnings: [],
497
- logprobs: mapOpenRouterChatLogProbsOutput(choice.logprobs)
498
- }, hasProviderMetadata ? { providerMetadata } : {});
1354
+ providerMetadata: {
1355
+ openrouter: {
1356
+ usage: {
1357
+ promptTokens: (_k = usageInfo.inputTokens) != null ? _k : 0,
1358
+ completionTokens: (_l = usageInfo.outputTokens) != null ? _l : 0,
1359
+ totalTokens: (_m = usageInfo.totalTokens) != null ? _m : 0,
1360
+ cost: (_n = response.usage) == null ? void 0 : _n.cost,
1361
+ promptTokensDetails: {
1362
+ cachedTokens: (_q = (_p = (_o = response.usage) == null ? void 0 : _o.prompt_tokens_details) == null ? void 0 : _p.cached_tokens) != null ? _q : 0
1363
+ },
1364
+ completionTokensDetails: {
1365
+ reasoningTokens: (_t = (_s = (_r = response.usage) == null ? void 0 : _r.completion_tokens_details) == null ? void 0 : _s.reasoning_tokens) != null ? _t : 0
1366
+ }
1367
+ }
1368
+ }
1369
+ },
1370
+ request: { body: args },
1371
+ response: {
1372
+ id: response.id,
1373
+ modelId: response.model,
1374
+ headers: responseHeaders
1375
+ }
1376
+ };
499
1377
  }
500
1378
  async doStream(options) {
501
- var _a, _c;
502
- const args = this.getArgs(options);
503
- const { responseHeaders, value: response } = await (0, import_provider_utils3.postJsonToApi)({
1379
+ var _a15;
1380
+ const providerOptions = options.providerOptions || {};
1381
+ const openrouterOptions = providerOptions.openrouter || {};
1382
+ const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
1383
+ const { value: response, responseHeaders } = await postJsonToApi({
504
1384
  url: this.config.url({
505
1385
  path: "/chat/completions",
506
1386
  modelId: this.modelId
507
1387
  }),
508
- headers: (0, import_provider_utils3.combineHeaders)(this.config.headers(), options.headers),
1388
+ headers: combineHeaders(this.config.headers(), options.headers),
509
1389
  body: __spreadProps(__spreadValues({}, args), {
510
1390
  stream: true,
511
1391
  // only include stream_options when in strict compatibility mode:
512
1392
  stream_options: this.config.compatibility === "strict" ? __spreadValues({
513
1393
  include_usage: true
514
- }, ((_a = this.settings.usage) == null ? void 0 : _a.include) ? { include_usage: true } : {}) : void 0
1394
+ }, ((_a15 = this.settings.usage) == null ? void 0 : _a15.include) ? { include_usage: true } : {}) : void 0
515
1395
  }),
516
1396
  failedResponseHandler: openrouterFailedResponseHandler,
517
- successfulResponseHandler: (0, import_provider_utils3.createEventSourceResponseHandler)(
1397
+ successfulResponseHandler: createEventSourceResponseHandler(
518
1398
  OpenRouterStreamChatCompletionChunkSchema
519
1399
  ),
520
1400
  abortSignal: options.abortSignal,
521
1401
  fetch: this.config.fetch
522
1402
  });
523
- const _b = args, { messages: rawPrompt } = _b, rawSettings = __objRest(_b, ["messages"]);
524
1403
  const toolCalls = [];
525
1404
  let finishReason = "other";
526
- let usage = {
527
- promptTokens: Number.NaN,
528
- completionTokens: Number.NaN
1405
+ const usage = {
1406
+ inputTokens: Number.NaN,
1407
+ outputTokens: Number.NaN,
1408
+ totalTokens: Number.NaN,
1409
+ reasoningTokens: Number.NaN,
1410
+ cachedInputTokens: Number.NaN
529
1411
  };
530
- let logprobs;
531
1412
  const openrouterUsage = {};
532
- const shouldIncludeUsageAccounting = !!((_c = this.settings.usage) == null ? void 0 : _c.include);
533
1413
  return {
534
1414
  stream: response.pipeThrough(
535
1415
  new TransformStream({
536
1416
  transform(chunk, controller) {
537
- var _a2, _b2, _c2, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
1417
+ var _a16, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
538
1418
  if (!chunk.success) {
539
1419
  finishReason = "error";
540
1420
  controller.enqueue({ type: "error", error: chunk.error });
@@ -559,20 +1439,23 @@ var OpenRouterChatLanguageModel = class {
559
1439
  });
560
1440
  }
561
1441
  if (value.usage != null) {
562
- usage = {
563
- promptTokens: value.usage.prompt_tokens,
564
- completionTokens: value.usage.completion_tokens
565
- };
1442
+ usage.inputTokens = value.usage.prompt_tokens;
1443
+ usage.outputTokens = value.usage.completion_tokens;
1444
+ usage.totalTokens = value.usage.prompt_tokens + value.usage.completion_tokens;
566
1445
  openrouterUsage.promptTokens = value.usage.prompt_tokens;
567
1446
  if (value.usage.prompt_tokens_details) {
1447
+ const cachedInputTokens = (_a16 = value.usage.prompt_tokens_details.cached_tokens) != null ? _a16 : 0;
1448
+ usage.cachedInputTokens = cachedInputTokens;
568
1449
  openrouterUsage.promptTokensDetails = {
569
- cachedTokens: (_a2 = value.usage.prompt_tokens_details.cached_tokens) != null ? _a2 : 0
1450
+ cachedTokens: cachedInputTokens
570
1451
  };
571
1452
  }
572
1453
  openrouterUsage.completionTokens = value.usage.completion_tokens;
573
1454
  if (value.usage.completion_tokens_details) {
1455
+ const reasoningTokens = (_b = value.usage.completion_tokens_details.reasoning_tokens) != null ? _b : 0;
1456
+ usage.reasoningTokens = reasoningTokens;
574
1457
  openrouterUsage.completionTokensDetails = {
575
- reasoningTokens: (_b2 = value.usage.completion_tokens_details.reasoning_tokens) != null ? _b2 : 0
1458
+ reasoningTokens
576
1459
  };
577
1460
  }
578
1461
  openrouterUsage.cost = value.usage.cost;
@@ -589,13 +1472,15 @@ var OpenRouterChatLanguageModel = class {
589
1472
  if (delta.content != null) {
590
1473
  controller.enqueue({
591
1474
  type: "text-delta",
592
- textDelta: delta.content
1475
+ delta: delta.content,
1476
+ id: generateId()
593
1477
  });
594
1478
  }
595
1479
  if (delta.reasoning != null) {
596
1480
  controller.enqueue({
597
- type: "reasoning",
598
- textDelta: delta.reasoning
1481
+ type: "reasoning-delta",
1482
+ delta: delta.reasoning,
1483
+ id: generateId()
599
1484
  });
600
1485
  }
601
1486
  if (delta.reasoning_details && delta.reasoning_details.length > 0) {
@@ -604,14 +1489,15 @@ var OpenRouterChatLanguageModel = class {
604
1489
  case "reasoning.text" /* Text */: {
605
1490
  if (detail.text) {
606
1491
  controller.enqueue({
607
- type: "reasoning",
608
- textDelta: detail.text
1492
+ type: "reasoning-delta",
1493
+ delta: detail.text,
1494
+ id: generateId()
609
1495
  });
610
1496
  }
611
1497
  if (detail.signature) {
612
1498
  controller.enqueue({
613
- type: "reasoning-signature",
614
- signature: detail.signature
1499
+ type: "reasoning-end",
1500
+ id: generateId()
615
1501
  });
616
1502
  }
617
1503
  break;
@@ -619,8 +1505,9 @@ var OpenRouterChatLanguageModel = class {
619
1505
  case "reasoning.encrypted" /* Encrypted */: {
620
1506
  if (detail.data) {
621
1507
  controller.enqueue({
622
- type: "redacted-reasoning",
623
- data: detail.data
1508
+ type: "reasoning-delta",
1509
+ delta: "[REDACTED]",
1510
+ id: generateId()
624
1511
  });
625
1512
  }
626
1513
  break;
@@ -628,8 +1515,9 @@ var OpenRouterChatLanguageModel = class {
628
1515
  case "reasoning.summary" /* Summary */: {
629
1516
  if (detail.summary) {
630
1517
  controller.enqueue({
631
- type: "reasoning",
632
- textDelta: detail.summary
1518
+ type: "reasoning-delta",
1519
+ delta: detail.summary,
1520
+ id: generateId()
633
1521
  });
634
1522
  }
635
1523
  break;
@@ -641,33 +1529,24 @@ var OpenRouterChatLanguageModel = class {
641
1529
  }
642
1530
  }
643
1531
  }
644
- const mappedLogprobs = mapOpenRouterChatLogProbsOutput(
645
- choice == null ? void 0 : choice.logprobs
646
- );
647
- if (mappedLogprobs == null ? void 0 : mappedLogprobs.length) {
648
- if (logprobs === void 0) {
649
- logprobs = [];
650
- }
651
- logprobs.push(...mappedLogprobs);
652
- }
653
1532
  if (delta.tool_calls != null) {
654
1533
  for (const toolCallDelta of delta.tool_calls) {
655
1534
  const index = toolCallDelta.index;
656
1535
  if (toolCalls[index] == null) {
657
1536
  if (toolCallDelta.type !== "function") {
658
- throw new import_provider.InvalidResponseDataError({
1537
+ throw new InvalidResponseDataError({
659
1538
  data: toolCallDelta,
660
1539
  message: `Expected 'function' type.`
661
1540
  });
662
1541
  }
663
1542
  if (toolCallDelta.id == null) {
664
- throw new import_provider.InvalidResponseDataError({
1543
+ throw new InvalidResponseDataError({
665
1544
  data: toolCallDelta,
666
1545
  message: `Expected 'id' to be a string.`
667
1546
  });
668
1547
  }
669
- if (((_c2 = toolCallDelta.function) == null ? void 0 : _c2.name) == null) {
670
- throw new import_provider.InvalidResponseDataError({
1548
+ if (((_c = toolCallDelta.function) == null ? void 0 : _c.name) == null) {
1549
+ throw new InvalidResponseDataError({
671
1550
  data: toolCallDelta,
672
1551
  message: `Expected 'function.name' to be a string.`
673
1552
  });
@@ -685,20 +1564,26 @@ var OpenRouterChatLanguageModel = class {
685
1564
  if (toolCall2 == null) {
686
1565
  throw new Error("Tool call is missing");
687
1566
  }
688
- if (((_e = toolCall2.function) == null ? void 0 : _e.name) != null && ((_f = toolCall2.function) == null ? void 0 : _f.arguments) != null && (0, import_provider_utils3.isParsableJson)(toolCall2.function.arguments)) {
1567
+ if (((_e = toolCall2.function) == null ? void 0 : _e.name) != null && ((_f = toolCall2.function) == null ? void 0 : _f.arguments) != null && isParsableJson(toolCall2.function.arguments)) {
689
1568
  controller.enqueue({
690
- type: "tool-call-delta",
691
- toolCallType: "function",
692
- toolCallId: toolCall2.id,
693
- toolName: toolCall2.function.name,
694
- argsTextDelta: toolCall2.function.arguments
1569
+ type: "tool-input-start",
1570
+ id: toolCall2.id,
1571
+ toolName: toolCall2.function.name
1572
+ });
1573
+ controller.enqueue({
1574
+ type: "tool-input-delta",
1575
+ id: toolCall2.id,
1576
+ delta: toolCall2.function.arguments
1577
+ });
1578
+ controller.enqueue({
1579
+ type: "tool-input-end",
1580
+ id: toolCall2.id
695
1581
  });
696
1582
  controller.enqueue({
697
1583
  type: "tool-call",
698
- toolCallType: "function",
699
- toolCallId: (_g = toolCall2.id) != null ? _g : (0, import_provider_utils3.generateId)(),
1584
+ toolCallId: toolCall2.id,
700
1585
  toolName: toolCall2.function.name,
701
- args: toolCall2.function.arguments
1586
+ input: toolCall2.function.arguments
702
1587
  });
703
1588
  toolCall2.sent = true;
704
1589
  }
@@ -708,23 +1593,27 @@ var OpenRouterChatLanguageModel = class {
708
1593
  if (toolCall == null) {
709
1594
  throw new Error("Tool call is missing");
710
1595
  }
1596
+ if (((_g = toolCallDelta.function) == null ? void 0 : _g.name) != null) {
1597
+ controller.enqueue({
1598
+ type: "tool-input-start",
1599
+ id: toolCall.id,
1600
+ toolName: toolCall.function.name
1601
+ });
1602
+ }
711
1603
  if (((_h = toolCallDelta.function) == null ? void 0 : _h.arguments) != null) {
712
1604
  toolCall.function.arguments += (_j = (_i = toolCallDelta.function) == null ? void 0 : _i.arguments) != null ? _j : "";
713
1605
  }
714
1606
  controller.enqueue({
715
- type: "tool-call-delta",
716
- toolCallType: "function",
717
- toolCallId: toolCall.id,
718
- toolName: toolCall.function.name,
719
- argsTextDelta: (_k = toolCallDelta.function.arguments) != null ? _k : ""
1607
+ type: "tool-input-delta",
1608
+ id: toolCall.id,
1609
+ delta: (_k = toolCallDelta.function.arguments) != null ? _k : ""
720
1610
  });
721
- if (((_l = toolCall.function) == null ? void 0 : _l.name) != null && ((_m = toolCall.function) == null ? void 0 : _m.arguments) != null && (0, import_provider_utils3.isParsableJson)(toolCall.function.arguments)) {
1611
+ if (((_l = toolCall.function) == null ? void 0 : _l.name) != null && ((_m = toolCall.function) == null ? void 0 : _m.arguments) != null && isParsableJson(toolCall.function.arguments)) {
722
1612
  controller.enqueue({
723
1613
  type: "tool-call",
724
- toolCallType: "function",
725
- toolCallId: (_n = toolCall.id) != null ? _n : (0, import_provider_utils3.generateId)(),
1614
+ toolCallId: (_n = toolCall.id) != null ? _n : generateId(),
726
1615
  toolName: toolCall.function.name,
727
- args: toolCall.function.arguments
1616
+ input: toolCall.function.arguments
728
1617
  });
729
1618
  toolCall.sent = true;
730
1619
  }
@@ -732,198 +1621,141 @@ var OpenRouterChatLanguageModel = class {
732
1621
  }
733
1622
  },
734
1623
  flush(controller) {
735
- var _a2;
1624
+ var _a16;
736
1625
  if (finishReason === "tool-calls") {
737
1626
  for (const toolCall of toolCalls) {
738
1627
  if (!toolCall.sent) {
739
1628
  controller.enqueue({
740
1629
  type: "tool-call",
741
- toolCallType: "function",
742
- toolCallId: (_a2 = toolCall.id) != null ? _a2 : (0, import_provider_utils3.generateId)(),
1630
+ toolCallId: (_a16 = toolCall.id) != null ? _a16 : generateId(),
743
1631
  toolName: toolCall.function.name,
744
1632
  // Coerce invalid arguments to an empty JSON object
745
- args: (0, import_provider_utils3.isParsableJson)(toolCall.function.arguments) ? toolCall.function.arguments : "{}"
1633
+ input: isParsableJson(toolCall.function.arguments) ? toolCall.function.arguments : "{}"
746
1634
  });
747
1635
  toolCall.sent = true;
748
1636
  }
749
1637
  }
750
1638
  }
751
- const providerMetadata = {};
752
- if (shouldIncludeUsageAccounting && (openrouterUsage.totalTokens !== void 0 || openrouterUsage.cost !== void 0 || openrouterUsage.promptTokensDetails !== void 0 || openrouterUsage.completionTokensDetails !== void 0)) {
753
- providerMetadata.openrouter = {
754
- usage: openrouterUsage
755
- };
756
- }
757
- const hasProviderMetadata = Object.keys(providerMetadata).length > 0 && shouldIncludeUsageAccounting;
758
- controller.enqueue(__spreadValues({
1639
+ controller.enqueue({
759
1640
  type: "finish",
760
1641
  finishReason,
761
- logprobs,
762
- usage
763
- }, hasProviderMetadata ? { providerMetadata } : {}));
1642
+ usage,
1643
+ providerMetadata: {
1644
+ openrouter: {
1645
+ usage: openrouterUsage
1646
+ }
1647
+ }
1648
+ });
764
1649
  }
765
1650
  })
766
1651
  ),
767
- rawCall: { rawPrompt, rawSettings },
768
- rawResponse: { headers: responseHeaders },
769
- warnings: []
1652
+ warnings: [],
1653
+ request: { body: args },
1654
+ response: { headers: responseHeaders }
770
1655
  };
771
1656
  }
772
1657
  };
773
- var OpenRouterChatCompletionBaseResponseSchema = import_zod3.z.object({
774
- id: import_zod3.z.string().optional(),
775
- model: import_zod3.z.string().optional(),
776
- usage: import_zod3.z.object({
777
- prompt_tokens: import_zod3.z.number(),
778
- prompt_tokens_details: import_zod3.z.object({
779
- cached_tokens: import_zod3.z.number()
1658
+ var OpenRouterChatCompletionBaseResponseSchema = import_v44.z.object({
1659
+ id: import_v44.z.string().optional(),
1660
+ model: import_v44.z.string().optional(),
1661
+ usage: import_v44.z.object({
1662
+ prompt_tokens: import_v44.z.number(),
1663
+ prompt_tokens_details: import_v44.z.object({
1664
+ cached_tokens: import_v44.z.number()
780
1665
  }).nullish(),
781
- completion_tokens: import_zod3.z.number(),
782
- completion_tokens_details: import_zod3.z.object({
783
- reasoning_tokens: import_zod3.z.number()
1666
+ completion_tokens: import_v44.z.number(),
1667
+ completion_tokens_details: import_v44.z.object({
1668
+ reasoning_tokens: import_v44.z.number()
784
1669
  }).nullish(),
785
- total_tokens: import_zod3.z.number(),
786
- cost: import_zod3.z.number().optional()
1670
+ total_tokens: import_v44.z.number(),
1671
+ cost: import_v44.z.number().optional()
787
1672
  }).nullish()
788
1673
  });
789
1674
  var OpenRouterNonStreamChatCompletionResponseSchema = OpenRouterChatCompletionBaseResponseSchema.extend({
790
- choices: import_zod3.z.array(
791
- import_zod3.z.object({
792
- message: import_zod3.z.object({
793
- role: import_zod3.z.literal("assistant"),
794
- content: import_zod3.z.string().nullable().optional(),
795
- reasoning: import_zod3.z.string().nullable().optional(),
1675
+ choices: import_v44.z.array(
1676
+ import_v44.z.object({
1677
+ message: import_v44.z.object({
1678
+ role: import_v44.z.literal("assistant"),
1679
+ content: import_v44.z.string().nullable().optional(),
1680
+ reasoning: import_v44.z.string().nullable().optional(),
796
1681
  reasoning_details: ReasoningDetailArraySchema.nullish(),
797
- tool_calls: import_zod3.z.array(
798
- import_zod3.z.object({
799
- id: import_zod3.z.string().optional().nullable(),
800
- type: import_zod3.z.literal("function"),
801
- function: import_zod3.z.object({
802
- name: import_zod3.z.string(),
803
- arguments: import_zod3.z.string()
1682
+ tool_calls: import_v44.z.array(
1683
+ import_v44.z.object({
1684
+ id: import_v44.z.string().optional().nullable(),
1685
+ type: import_v44.z.literal("function"),
1686
+ function: import_v44.z.object({
1687
+ name: import_v44.z.string(),
1688
+ arguments: import_v44.z.string()
804
1689
  })
805
1690
  })
806
1691
  ).optional()
807
1692
  }),
808
- index: import_zod3.z.number(),
809
- logprobs: import_zod3.z.object({
810
- content: import_zod3.z.array(
811
- import_zod3.z.object({
812
- token: import_zod3.z.string(),
813
- logprob: import_zod3.z.number(),
814
- top_logprobs: import_zod3.z.array(
815
- import_zod3.z.object({
816
- token: import_zod3.z.string(),
817
- logprob: import_zod3.z.number()
1693
+ index: import_v44.z.number(),
1694
+ logprobs: import_v44.z.object({
1695
+ content: import_v44.z.array(
1696
+ import_v44.z.object({
1697
+ token: import_v44.z.string(),
1698
+ logprob: import_v44.z.number(),
1699
+ top_logprobs: import_v44.z.array(
1700
+ import_v44.z.object({
1701
+ token: import_v44.z.string(),
1702
+ logprob: import_v44.z.number()
818
1703
  })
819
1704
  )
820
1705
  })
821
1706
  ).nullable()
822
1707
  }).nullable().optional(),
823
- finish_reason: import_zod3.z.string().optional().nullable()
1708
+ finish_reason: import_v44.z.string().optional().nullable()
824
1709
  })
825
1710
  )
826
1711
  });
827
- var OpenRouterStreamChatCompletionChunkSchema = import_zod3.z.union([
1712
+ var OpenRouterStreamChatCompletionChunkSchema = import_v44.z.union([
828
1713
  OpenRouterChatCompletionBaseResponseSchema.extend({
829
- choices: import_zod3.z.array(
830
- import_zod3.z.object({
831
- delta: import_zod3.z.object({
832
- role: import_zod3.z.enum(["assistant"]).optional(),
833
- content: import_zod3.z.string().nullish(),
834
- reasoning: import_zod3.z.string().nullish().optional(),
1714
+ choices: import_v44.z.array(
1715
+ import_v44.z.object({
1716
+ delta: import_v44.z.object({
1717
+ role: import_v44.z.enum(["assistant"]).optional(),
1718
+ content: import_v44.z.string().nullish(),
1719
+ reasoning: import_v44.z.string().nullish().optional(),
835
1720
  reasoning_details: ReasoningDetailArraySchema.nullish(),
836
- tool_calls: import_zod3.z.array(
837
- import_zod3.z.object({
838
- index: import_zod3.z.number(),
839
- id: import_zod3.z.string().nullish(),
840
- type: import_zod3.z.literal("function").optional(),
841
- function: import_zod3.z.object({
842
- name: import_zod3.z.string().nullish(),
843
- arguments: import_zod3.z.string().nullish()
1721
+ tool_calls: import_v44.z.array(
1722
+ import_v44.z.object({
1723
+ index: import_v44.z.number(),
1724
+ id: import_v44.z.string().nullish(),
1725
+ type: import_v44.z.literal("function").optional(),
1726
+ function: import_v44.z.object({
1727
+ name: import_v44.z.string().nullish(),
1728
+ arguments: import_v44.z.string().nullish()
844
1729
  })
845
1730
  })
846
1731
  ).nullish()
847
1732
  }).nullish(),
848
- logprobs: import_zod3.z.object({
849
- content: import_zod3.z.array(
850
- import_zod3.z.object({
851
- token: import_zod3.z.string(),
852
- logprob: import_zod3.z.number(),
853
- top_logprobs: import_zod3.z.array(
854
- import_zod3.z.object({
855
- token: import_zod3.z.string(),
856
- logprob: import_zod3.z.number()
1733
+ logprobs: import_v44.z.object({
1734
+ content: import_v44.z.array(
1735
+ import_v44.z.object({
1736
+ token: import_v44.z.string(),
1737
+ logprob: import_v44.z.number(),
1738
+ top_logprobs: import_v44.z.array(
1739
+ import_v44.z.object({
1740
+ token: import_v44.z.string(),
1741
+ logprob: import_v44.z.number()
857
1742
  })
858
1743
  )
859
1744
  })
860
1745
  ).nullable()
861
1746
  }).nullish(),
862
- finish_reason: import_zod3.z.string().nullable().optional(),
863
- index: import_zod3.z.number()
1747
+ finish_reason: import_v44.z.string().nullable().optional(),
1748
+ index: import_v44.z.number()
864
1749
  })
865
1750
  )
866
1751
  }),
867
1752
  OpenRouterErrorResponseSchema
868
1753
  ]);
869
- function prepareToolsAndToolChoice(mode) {
870
- var _a;
871
- const tools = ((_a = mode.tools) == null ? void 0 : _a.length) ? mode.tools : void 0;
872
- if (tools == null) {
873
- return { tools: void 0, tool_choice: void 0 };
874
- }
875
- const mappedTools = tools.map((tool) => {
876
- if (isFunctionTool(tool)) {
877
- return {
878
- type: "function",
879
- function: {
880
- name: tool.name,
881
- description: tool.description,
882
- parameters: tool.parameters
883
- }
884
- };
885
- }
886
- return {
887
- type: "function",
888
- function: {
889
- name: tool.name
890
- }
891
- };
892
- });
893
- const toolChoice = mode.toolChoice;
894
- if (toolChoice == null) {
895
- return { tools: mappedTools, tool_choice: void 0 };
896
- }
897
- const type = toolChoice.type;
898
- switch (type) {
899
- case "auto":
900
- case "none":
901
- case "required":
902
- return { tools: mappedTools, tool_choice: type };
903
- case "tool":
904
- return {
905
- tools: mappedTools,
906
- tool_choice: {
907
- type: "function",
908
- function: {
909
- name: toolChoice.toolName
910
- }
911
- }
912
- };
913
- default: {
914
- const _exhaustiveCheck = type;
915
- throw new Error(`Unsupported tool choice type: ${_exhaustiveCheck}`);
916
- }
917
- }
918
- }
919
1754
 
920
- // src/openrouter-completion-language-model.ts
921
- var import_provider3 = require("@ai-sdk/provider");
922
- var import_provider_utils4 = require("@ai-sdk/provider-utils");
923
- var import_zod4 = require("zod");
1755
+ // src/completion/index.ts
1756
+ var import_v45 = require("zod/v4");
924
1757
 
925
- // src/convert-to-openrouter-completion-prompt.ts
926
- var import_provider2 = require("@ai-sdk/provider");
1758
+ // src/completion/convert-to-openrouter-completion-prompt.ts
927
1759
  function convertToOpenRouterCompletionPrompt({
928
1760
  prompt,
929
1761
  inputFormat,
@@ -943,8 +1775,8 @@ function convertToOpenRouterCompletionPrompt({
943
1775
  for (const { role, content } of prompt) {
944
1776
  switch (role) {
945
1777
  case "system": {
946
- throw new import_provider2.InvalidPromptError({
947
- message: "Unexpected system message in prompt: ${content}",
1778
+ throw new InvalidPromptError({
1779
+ message: `Unexpected system message in prompt: ${content}`,
948
1780
  prompt
949
1781
  });
950
1782
  }
@@ -954,21 +1786,13 @@ function convertToOpenRouterCompletionPrompt({
954
1786
  case "text": {
955
1787
  return part.text;
956
1788
  }
957
- case "image": {
958
- throw new import_provider2.UnsupportedFunctionalityError({
959
- functionality: "images"
960
- });
961
- }
962
1789
  case "file": {
963
- throw new import_provider2.UnsupportedFunctionalityError({
1790
+ throw new UnsupportedFunctionalityError({
964
1791
  functionality: "file attachments"
965
1792
  });
966
1793
  }
967
1794
  default: {
968
- const _exhaustiveCheck = part;
969
- throw new Error(
970
- `Unsupported content type: ${_exhaustiveCheck}`
971
- );
1795
+ return "";
972
1796
  }
973
1797
  }
974
1798
  }).join("");
@@ -979,39 +1803,38 @@ ${userMessage}
979
1803
  break;
980
1804
  }
981
1805
  case "assistant": {
982
- const assistantMessage = content.map((part) => {
983
- switch (part.type) {
984
- case "text": {
985
- return part.text;
986
- }
987
- case "tool-call": {
988
- throw new import_provider2.UnsupportedFunctionalityError({
989
- functionality: "tool-call messages"
990
- });
991
- }
992
- case "reasoning": {
993
- throw new import_provider2.UnsupportedFunctionalityError({
994
- functionality: "reasoning messages"
995
- });
996
- }
997
- case "redacted-reasoning": {
998
- throw new import_provider2.UnsupportedFunctionalityError({
999
- functionality: "redacted reasoning messages"
1000
- });
1001
- }
1002
- case "file": {
1003
- throw new import_provider2.UnsupportedFunctionalityError({
1004
- functionality: "file attachments"
1005
- });
1006
- }
1007
- default: {
1008
- const _exhaustiveCheck = part;
1009
- throw new Error(
1010
- `Unsupported content type: ${_exhaustiveCheck}`
1011
- );
1806
+ const assistantMessage = content.map(
1807
+ (part) => {
1808
+ switch (part.type) {
1809
+ case "text": {
1810
+ return part.text;
1811
+ }
1812
+ case "tool-call": {
1813
+ throw new UnsupportedFunctionalityError({
1814
+ functionality: "tool-call messages"
1815
+ });
1816
+ }
1817
+ case "tool-result": {
1818
+ throw new UnsupportedFunctionalityError({
1819
+ functionality: "tool-result messages"
1820
+ });
1821
+ }
1822
+ case "reasoning": {
1823
+ throw new UnsupportedFunctionalityError({
1824
+ functionality: "reasoning messages"
1825
+ });
1826
+ }
1827
+ case "file": {
1828
+ throw new UnsupportedFunctionalityError({
1829
+ functionality: "file attachments"
1830
+ });
1831
+ }
1832
+ default: {
1833
+ return "";
1834
+ }
1012
1835
  }
1013
1836
  }
1014
- }).join("");
1837
+ ).join("");
1015
1838
  text += `${assistant}:
1016
1839
  ${assistantMessage}
1017
1840
 
@@ -1019,13 +1842,12 @@ ${assistantMessage}
1019
1842
  break;
1020
1843
  }
1021
1844
  case "tool": {
1022
- throw new import_provider2.UnsupportedFunctionalityError({
1845
+ throw new UnsupportedFunctionalityError({
1023
1846
  functionality: "tool messages"
1024
1847
  });
1025
1848
  }
1026
1849
  default: {
1027
- const _exhaustiveCheck = role;
1028
- throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
1850
+ break;
1029
1851
  }
1030
1852
  }
1031
1853
  }
@@ -1036,40 +1858,60 @@ ${assistantMessage}
1036
1858
  };
1037
1859
  }
1038
1860
 
1039
- // src/map-openrouter-completion-logprobs.ts
1040
- function mapOpenRouterCompletionLogProbs(logprobs) {
1041
- return logprobs == null ? void 0 : logprobs.tokens.map((token, index) => {
1042
- var _a, _b;
1043
- return {
1044
- token,
1045
- logprob: (_a = logprobs.token_logprobs[index]) != null ? _a : 0,
1046
- topLogprobs: logprobs.top_logprobs ? Object.entries((_b = logprobs.top_logprobs[index]) != null ? _b : {}).map(
1047
- ([token2, logprob]) => ({
1048
- token: token2,
1049
- logprob
1050
- })
1051
- ) : []
1052
- };
1053
- });
1054
- }
1055
-
1056
- // src/openrouter-completion-language-model.ts
1861
+ // src/completion/index.ts
1862
+ var OpenRouterCompletionChunkSchema = import_v45.z.union([
1863
+ import_v45.z.object({
1864
+ id: import_v45.z.string().optional(),
1865
+ model: import_v45.z.string().optional(),
1866
+ choices: import_v45.z.array(
1867
+ import_v45.z.object({
1868
+ text: import_v45.z.string(),
1869
+ reasoning: import_v45.z.string().nullish().optional(),
1870
+ reasoning_details: ReasoningDetailArraySchema.nullish(),
1871
+ finish_reason: import_v45.z.string().nullish(),
1872
+ index: import_v45.z.number(),
1873
+ logprobs: import_v45.z.object({
1874
+ tokens: import_v45.z.array(import_v45.z.string()),
1875
+ token_logprobs: import_v45.z.array(import_v45.z.number()),
1876
+ top_logprobs: import_v45.z.array(import_v45.z.record(import_v45.z.string(), import_v45.z.number())).nullable()
1877
+ }).nullable().optional()
1878
+ })
1879
+ ),
1880
+ usage: import_v45.z.object({
1881
+ prompt_tokens: import_v45.z.number(),
1882
+ prompt_tokens_details: import_v45.z.object({
1883
+ cached_tokens: import_v45.z.number()
1884
+ }).nullish(),
1885
+ completion_tokens: import_v45.z.number(),
1886
+ completion_tokens_details: import_v45.z.object({
1887
+ reasoning_tokens: import_v45.z.number()
1888
+ }).nullish(),
1889
+ total_tokens: import_v45.z.number(),
1890
+ cost: import_v45.z.number().optional()
1891
+ }).nullish()
1892
+ }),
1893
+ OpenRouterErrorResponseSchema
1894
+ ]);
1057
1895
  var OpenRouterCompletionLanguageModel = class {
1058
1896
  constructor(modelId, settings, config) {
1059
- this.specificationVersion = "v1";
1897
+ this.specificationVersion = "v2";
1898
+ this.provider = "openrouter";
1899
+ this.supportedUrls = {
1900
+ "image/*": [
1901
+ /^data:image\/[a-zA-Z]+;base64,/,
1902
+ /^https?:\/\/.+\.(jpg|jpeg|png|gif|webp)$/i
1903
+ ],
1904
+ "text/*": [/^data:text\//, /^https?:\/\/.+$/],
1905
+ "application/*": [/^data:application\//, /^https?:\/\/.+$/]
1906
+ };
1060
1907
  this.defaultObjectGenerationMode = void 0;
1061
1908
  this.modelId = modelId;
1062
1909
  this.settings = settings;
1063
1910
  this.config = config;
1064
1911
  }
1065
- get provider() {
1066
- return this.config.provider;
1067
- }
1068
1912
  getArgs({
1069
- mode,
1070
- inputFormat,
1071
1913
  prompt,
1072
- maxTokens,
1914
+ maxOutputTokens,
1073
1915
  temperature,
1074
1916
  topP,
1075
1917
  frequencyPenalty,
@@ -1078,16 +1920,24 @@ var OpenRouterCompletionLanguageModel = class {
1078
1920
  responseFormat,
1079
1921
  topK,
1080
1922
  stopSequences,
1081
- providerMetadata
1923
+ tools,
1924
+ toolChoice
1082
1925
  }) {
1083
- var _a, _b;
1084
- const type = mode.type;
1085
- const extraCallingBody = (_a = providerMetadata == null ? void 0 : providerMetadata.openrouter) != null ? _a : {};
1086
1926
  const { prompt: completionPrompt } = convertToOpenRouterCompletionPrompt({
1087
1927
  prompt,
1088
- inputFormat
1928
+ inputFormat: "prompt"
1089
1929
  });
1090
- const baseArgs = __spreadValues(__spreadValues(__spreadValues({
1930
+ if (tools == null ? void 0 : tools.length) {
1931
+ throw new UnsupportedFunctionalityError({
1932
+ functionality: "tools"
1933
+ });
1934
+ }
1935
+ if (toolChoice) {
1936
+ throw new UnsupportedFunctionalityError({
1937
+ functionality: "toolChoice"
1938
+ });
1939
+ }
1940
+ return __spreadValues(__spreadValues({
1091
1941
  // model id:
1092
1942
  model: this.modelId,
1093
1943
  models: this.settings.models,
@@ -1097,7 +1947,7 @@ var OpenRouterCompletionLanguageModel = class {
1097
1947
  suffix: this.settings.suffix,
1098
1948
  user: this.settings.user,
1099
1949
  // standardized settings:
1100
- max_tokens: maxTokens,
1950
+ max_tokens: maxOutputTokens,
1101
1951
  temperature,
1102
1952
  top_p: topP,
1103
1953
  frequency_penalty: frequencyPenalty,
@@ -1111,58 +1961,27 @@ var OpenRouterCompletionLanguageModel = class {
1111
1961
  // OpenRouter specific settings:
1112
1962
  include_reasoning: this.settings.includeReasoning,
1113
1963
  reasoning: this.settings.reasoning
1114
- }, this.config.extraBody), this.settings.extraBody), extraCallingBody);
1115
- switch (type) {
1116
- case "regular": {
1117
- if ((_b = mode.tools) == null ? void 0 : _b.length) {
1118
- throw new import_provider3.UnsupportedFunctionalityError({
1119
- functionality: "tools"
1120
- });
1121
- }
1122
- if (mode.toolChoice) {
1123
- throw new import_provider3.UnsupportedFunctionalityError({
1124
- functionality: "toolChoice"
1125
- });
1126
- }
1127
- return baseArgs;
1128
- }
1129
- case "object-json": {
1130
- throw new import_provider3.UnsupportedFunctionalityError({
1131
- functionality: "object-json mode"
1132
- });
1133
- }
1134
- case "object-tool": {
1135
- throw new import_provider3.UnsupportedFunctionalityError({
1136
- functionality: "object-tool mode"
1137
- });
1138
- }
1139
- // Handle all non-text types with a single default case
1140
- default: {
1141
- const _exhaustiveCheck = type;
1142
- throw new import_provider3.UnsupportedFunctionalityError({
1143
- functionality: `${_exhaustiveCheck} mode`
1144
- });
1145
- }
1146
- }
1964
+ }, this.config.extraBody), this.settings.extraBody);
1147
1965
  }
1148
1966
  async doGenerate(options) {
1149
- var _b, _c, _d, _e, _f;
1150
- const args = this.getArgs(options);
1151
- const { responseHeaders, value: response } = await (0, import_provider_utils4.postJsonToApi)({
1967
+ var _a15, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
1968
+ const providerOptions = options.providerOptions || {};
1969
+ const openrouterOptions = providerOptions.openrouter || {};
1970
+ const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
1971
+ const { value: response, responseHeaders } = await postJsonToApi({
1152
1972
  url: this.config.url({
1153
1973
  path: "/completions",
1154
1974
  modelId: this.modelId
1155
1975
  }),
1156
- headers: (0, import_provider_utils4.combineHeaders)(this.config.headers(), options.headers),
1976
+ headers: combineHeaders(this.config.headers(), options.headers),
1157
1977
  body: args,
1158
1978
  failedResponseHandler: openrouterFailedResponseHandler,
1159
- successfulResponseHandler: (0, import_provider_utils4.createJsonResponseHandler)(
1979
+ successfulResponseHandler: createJsonResponseHandler(
1160
1980
  OpenRouterCompletionChunkSchema
1161
1981
  ),
1162
1982
  abortSignal: options.abortSignal,
1163
1983
  fetch: this.config.fetch
1164
1984
  });
1165
- const _a = args, { prompt: rawPrompt } = _a, rawSettings = __objRest(_a, ["prompt"]);
1166
1985
  if ("error" in response) {
1167
1986
  throw new Error(`${response.error.message}`);
1168
1987
  }
@@ -1171,54 +1990,62 @@ var OpenRouterCompletionLanguageModel = class {
1171
1990
  throw new Error("No choice in OpenRouter completion response");
1172
1991
  }
1173
1992
  return {
1174
- response: {
1175
- id: response.id,
1176
- modelId: response.model
1177
- },
1178
- text: (_b = choice.text) != null ? _b : "",
1179
- reasoning: choice.reasoning || void 0,
1993
+ content: [
1994
+ {
1995
+ type: "text",
1996
+ text: (_a15 = choice.text) != null ? _a15 : ""
1997
+ }
1998
+ ],
1999
+ finishReason: mapOpenRouterFinishReason(choice.finish_reason),
1180
2000
  usage: {
1181
- promptTokens: (_d = (_c = response.usage) == null ? void 0 : _c.prompt_tokens) != null ? _d : 0,
1182
- completionTokens: (_f = (_e = response.usage) == null ? void 0 : _e.completion_tokens) != null ? _f : 0
2001
+ inputTokens: (_c = (_b = response.usage) == null ? void 0 : _b.prompt_tokens) != null ? _c : 0,
2002
+ outputTokens: (_e = (_d = response.usage) == null ? void 0 : _d.completion_tokens) != null ? _e : 0,
2003
+ totalTokens: ((_g = (_f = response.usage) == null ? void 0 : _f.prompt_tokens) != null ? _g : 0) + ((_i = (_h = response.usage) == null ? void 0 : _h.completion_tokens) != null ? _i : 0),
2004
+ reasoningTokens: (_l = (_k = (_j = response.usage) == null ? void 0 : _j.completion_tokens_details) == null ? void 0 : _k.reasoning_tokens) != null ? _l : 0,
2005
+ cachedInputTokens: (_o = (_n = (_m = response.usage) == null ? void 0 : _m.prompt_tokens_details) == null ? void 0 : _n.cached_tokens) != null ? _o : 0
1183
2006
  },
1184
- finishReason: mapOpenRouterFinishReason(choice.finish_reason),
1185
- logprobs: mapOpenRouterCompletionLogProbs(choice.logprobs),
1186
- rawCall: { rawPrompt, rawSettings },
1187
- rawResponse: { headers: responseHeaders },
1188
- warnings: []
2007
+ warnings: [],
2008
+ response: {
2009
+ headers: responseHeaders
2010
+ }
1189
2011
  };
1190
2012
  }
1191
2013
  async doStream(options) {
1192
- const args = this.getArgs(options);
1193
- const { responseHeaders, value: response } = await (0, import_provider_utils4.postJsonToApi)({
2014
+ const providerOptions = options.providerOptions || {};
2015
+ const openrouterOptions = providerOptions.openrouter || {};
2016
+ const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
2017
+ const { value: response, responseHeaders } = await postJsonToApi({
1194
2018
  url: this.config.url({
1195
2019
  path: "/completions",
1196
2020
  modelId: this.modelId
1197
2021
  }),
1198
- headers: (0, import_provider_utils4.combineHeaders)(this.config.headers(), options.headers),
1199
- body: __spreadProps(__spreadValues({}, this.getArgs(options)), {
2022
+ headers: combineHeaders(this.config.headers(), options.headers),
2023
+ body: __spreadProps(__spreadValues({}, args), {
1200
2024
  stream: true,
1201
2025
  // only include stream_options when in strict compatibility mode:
1202
2026
  stream_options: this.config.compatibility === "strict" ? { include_usage: true } : void 0
1203
2027
  }),
1204
2028
  failedResponseHandler: openrouterFailedResponseHandler,
1205
- successfulResponseHandler: (0, import_provider_utils4.createEventSourceResponseHandler)(
2029
+ successfulResponseHandler: createEventSourceResponseHandler(
1206
2030
  OpenRouterCompletionChunkSchema
1207
2031
  ),
1208
2032
  abortSignal: options.abortSignal,
1209
2033
  fetch: this.config.fetch
1210
2034
  });
1211
- const _a = args, { prompt: rawPrompt } = _a, rawSettings = __objRest(_a, ["prompt"]);
1212
2035
  let finishReason = "other";
1213
- let usage = {
1214
- promptTokens: Number.NaN,
1215
- completionTokens: Number.NaN
2036
+ const usage = {
2037
+ inputTokens: Number.NaN,
2038
+ outputTokens: Number.NaN,
2039
+ totalTokens: Number.NaN,
2040
+ reasoningTokens: Number.NaN,
2041
+ cachedInputTokens: Number.NaN
1216
2042
  };
1217
- let logprobs;
2043
+ const openrouterUsage = {};
1218
2044
  return {
1219
2045
  stream: response.pipeThrough(
1220
2046
  new TransformStream({
1221
2047
  transform(chunk, controller) {
2048
+ var _a15, _b;
1222
2049
  if (!chunk.success) {
1223
2050
  finishReason = "error";
1224
2051
  controller.enqueue({ type: "error", error: chunk.error });
@@ -1231,10 +2058,27 @@ var OpenRouterCompletionLanguageModel = class {
1231
2058
  return;
1232
2059
  }
1233
2060
  if (value.usage != null) {
1234
- usage = {
1235
- promptTokens: value.usage.prompt_tokens,
1236
- completionTokens: value.usage.completion_tokens
1237
- };
2061
+ usage.inputTokens = value.usage.prompt_tokens;
2062
+ usage.outputTokens = value.usage.completion_tokens;
2063
+ usage.totalTokens = value.usage.prompt_tokens + value.usage.completion_tokens;
2064
+ openrouterUsage.promptTokens = value.usage.prompt_tokens;
2065
+ if (value.usage.prompt_tokens_details) {
2066
+ const cachedInputTokens = (_a15 = value.usage.prompt_tokens_details.cached_tokens) != null ? _a15 : 0;
2067
+ usage.cachedInputTokens = cachedInputTokens;
2068
+ openrouterUsage.promptTokensDetails = {
2069
+ cachedTokens: cachedInputTokens
2070
+ };
2071
+ }
2072
+ openrouterUsage.completionTokens = value.usage.completion_tokens;
2073
+ if (value.usage.completion_tokens_details) {
2074
+ const reasoningTokens = (_b = value.usage.completion_tokens_details.reasoning_tokens) != null ? _b : 0;
2075
+ usage.reasoningTokens = reasoningTokens;
2076
+ openrouterUsage.completionTokensDetails = {
2077
+ reasoningTokens
2078
+ };
2079
+ }
2080
+ openrouterUsage.cost = value.usage.cost;
2081
+ openrouterUsage.totalTokens = value.usage.total_tokens;
1238
2082
  }
1239
2083
  const choice = value.choices[0];
1240
2084
  if ((choice == null ? void 0 : choice.finish_reason) != null) {
@@ -1243,69 +2087,40 @@ var OpenRouterCompletionLanguageModel = class {
1243
2087
  if ((choice == null ? void 0 : choice.text) != null) {
1244
2088
  controller.enqueue({
1245
2089
  type: "text-delta",
1246
- textDelta: choice.text
2090
+ delta: choice.text,
2091
+ id: generateId()
1247
2092
  });
1248
2093
  }
1249
- const mappedLogprobs = mapOpenRouterCompletionLogProbs(
1250
- choice == null ? void 0 : choice.logprobs
1251
- );
1252
- if (mappedLogprobs == null ? void 0 : mappedLogprobs.length) {
1253
- if (logprobs === void 0) {
1254
- logprobs = [];
1255
- }
1256
- logprobs.push(...mappedLogprobs);
1257
- }
1258
2094
  },
1259
2095
  flush(controller) {
1260
2096
  controller.enqueue({
1261
2097
  type: "finish",
1262
2098
  finishReason,
1263
- logprobs,
1264
- usage
2099
+ usage,
2100
+ providerMetadata: {
2101
+ openrouter: {
2102
+ usage: openrouterUsage
2103
+ }
2104
+ }
1265
2105
  });
1266
2106
  }
1267
2107
  })
1268
2108
  ),
1269
- rawCall: { rawPrompt, rawSettings },
1270
- rawResponse: { headers: responseHeaders },
1271
- warnings: []
2109
+ response: {
2110
+ headers: responseHeaders
2111
+ }
1272
2112
  };
1273
2113
  }
1274
2114
  };
1275
- var OpenRouterCompletionChunkSchema = import_zod4.z.union([
1276
- import_zod4.z.object({
1277
- id: import_zod4.z.string().optional(),
1278
- model: import_zod4.z.string().optional(),
1279
- choices: import_zod4.z.array(
1280
- import_zod4.z.object({
1281
- text: import_zod4.z.string(),
1282
- reasoning: import_zod4.z.string().nullish().optional(),
1283
- reasoning_details: ReasoningDetailArraySchema.nullish(),
1284
- finish_reason: import_zod4.z.string().nullish(),
1285
- index: import_zod4.z.number(),
1286
- logprobs: import_zod4.z.object({
1287
- tokens: import_zod4.z.array(import_zod4.z.string()),
1288
- token_logprobs: import_zod4.z.array(import_zod4.z.number()),
1289
- top_logprobs: import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.number())).nullable()
1290
- }).nullable().optional()
1291
- })
1292
- ),
1293
- usage: import_zod4.z.object({
1294
- prompt_tokens: import_zod4.z.number(),
1295
- completion_tokens: import_zod4.z.number()
1296
- }).optional().nullable()
1297
- }),
1298
- OpenRouterErrorResponseSchema
1299
- ]);
1300
2115
 
1301
- // src/openrouter-facade.ts
2116
+ // src/facade.ts
1302
2117
  var OpenRouter = class {
1303
2118
  /**
1304
2119
  * Creates a new OpenRouter provider instance.
1305
2120
  */
1306
2121
  constructor(options = {}) {
1307
- var _a, _b;
1308
- this.baseURL = (_b = (0, import_provider_utils5.withoutTrailingSlash)((_a = options.baseURL) != null ? _a : options.baseUrl)) != null ? _b : "https://openrouter.ai/api/v1";
2122
+ var _a15, _b;
2123
+ this.baseURL = (_b = withoutTrailingSlash((_a15 = options.baseURL) != null ? _a15 : options.baseUrl)) != null ? _b : "https://openrouter.ai/api/v1";
1309
2124
  this.apiKey = options.apiKey;
1310
2125
  this.headers = options.headers;
1311
2126
  }
@@ -1313,7 +2128,7 @@ var OpenRouter = class {
1313
2128
  return {
1314
2129
  baseURL: this.baseURL,
1315
2130
  headers: () => __spreadValues({
1316
- Authorization: `Bearer ${(0, import_provider_utils5.loadApiKey)({
2131
+ Authorization: `Bearer ${loadApiKey({
1317
2132
  apiKey: this.apiKey,
1318
2133
  environmentVariableName: "OPENROUTER_API_KEY",
1319
2134
  description: "OpenRouter"
@@ -1339,14 +2154,13 @@ var OpenRouter = class {
1339
2154
  }
1340
2155
  };
1341
2156
 
1342
- // src/openrouter-provider.ts
1343
- var import_provider_utils6 = require("@ai-sdk/provider-utils");
2157
+ // src/provider.ts
1344
2158
  function createOpenRouter(options = {}) {
1345
- var _a, _b, _c;
1346
- const baseURL = (_b = (0, import_provider_utils6.withoutTrailingSlash)((_a = options.baseURL) != null ? _a : options.baseUrl)) != null ? _b : "https://openrouter.ai/api/v1";
2159
+ var _a15, _b, _c;
2160
+ const baseURL = (_b = withoutTrailingSlash((_a15 = options.baseURL) != null ? _a15 : options.baseUrl)) != null ? _b : "https://openrouter.ai/api/v1";
1347
2161
  const compatibility = (_c = options.compatibility) != null ? _c : "compatible";
1348
2162
  const getHeaders = () => __spreadValues({
1349
- Authorization: `Bearer ${(0, import_provider_utils6.loadApiKey)({
2163
+ Authorization: `Bearer ${loadApiKey({
1350
2164
  apiKey: options.apiKey,
1351
2165
  environmentVariableName: "OPENROUTER_API_KEY",
1352
2166
  description: "OpenRouter"