@openrouter/ai-sdk-provider 0.7.2 → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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,971 @@ __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/schemas/reasoning-details.ts
923
+ var import_v4 = require("zod/v4");
924
+ var ReasoningDetailSummarySchema = import_v4.z.object({
925
+ type: import_v4.z.literal("reasoning.summary" /* Summary */),
926
+ summary: import_v4.z.string()
70
927
  });
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()
928
+ var ReasoningDetailEncryptedSchema = import_v4.z.object({
929
+ type: import_v4.z.literal("reasoning.encrypted" /* Encrypted */),
930
+ data: import_v4.z.string()
75
931
  });
76
- var ReasoningDetailUnionSchema = import_zod.z.union([
932
+ var ReasoningDetailTextSchema = import_v4.z.object({
933
+ type: import_v4.z.literal("reasoning.text" /* Text */),
934
+ text: import_v4.z.string().nullish(),
935
+ signature: import_v4.z.string().nullish()
936
+ });
937
+ var ReasoningDetailUnionSchema = import_v4.z.union([
77
938
  ReasoningDetailSummarySchema,
78
939
  ReasoningDetailEncryptedSchema,
79
940
  ReasoningDetailTextSchema
80
941
  ]);
81
- var ReasoningDetailsWithUnknownSchema = import_zod.z.union([
942
+ var ReasoningDetailsWithUnknownSchema = import_v4.z.union([
82
943
  ReasoningDetailUnionSchema,
83
- import_zod.z.unknown().transform(() => null)
944
+ import_v4.z.unknown().transform(() => null)
84
945
  ]);
85
- var ReasoningDetailArraySchema = import_zod.z.array(ReasoningDetailsWithUnknownSchema).transform((d) => d.filter((d2) => !!d2));
946
+ var ReasoningDetailArraySchema = import_v4.z.array(ReasoningDetailsWithUnknownSchema).transform((d) => d.filter((d2) => !!d2));
86
947
 
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");
948
+ // src/schemas/error-response.ts
949
+ var import_v42 = require("zod/v4");
950
+ var OpenRouterErrorResponseSchema = import_v42.z.object({
951
+ error: import_v42.z.object({
952
+ code: import_v42.z.union([import_v42.z.string(), import_v42.z.number()]).nullable(),
953
+ message: import_v42.z.string(),
954
+ type: import_v42.z.string().nullable(),
955
+ param: import_v42.z.any().nullable()
956
+ })
957
+ });
958
+ var openrouterFailedResponseHandler = createJsonErrorResponseHandler({
959
+ errorSchema: OpenRouterErrorResponseSchema,
960
+ errorToMessage: (data) => data.error.message
961
+ });
91
962
 
92
- // src/convert-to-openrouter-chat-messages.ts
93
- var import_provider_utils = require("@ai-sdk/provider-utils");
963
+ // src/utils/map-finish-reason.ts
964
+ function mapOpenRouterFinishReason(finishReason) {
965
+ switch (finishReason) {
966
+ case "stop":
967
+ return "stop";
968
+ case "length":
969
+ return "length";
970
+ case "content_filter":
971
+ return "content-filter";
972
+ case "function_call":
973
+ case "tool_calls":
974
+ return "tool-calls";
975
+ default:
976
+ return "unknown";
977
+ }
978
+ }
979
+
980
+ // src/chat/convert-to-openrouter-chat-messages.ts
94
981
  function getCacheControl(providerMetadata) {
95
- var _a, _b, _c;
982
+ var _a15, _b, _c;
96
983
  const anthropic = providerMetadata == null ? void 0 : providerMetadata.anthropic;
97
984
  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;
985
+ 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
986
  }
100
987
  function convertToOpenRouterChatMessages(prompt) {
101
- var _a, _b, _c;
988
+ var _a15, _b, _c;
102
989
  const messages = [];
103
- for (const { role, content, providerMetadata } of prompt) {
990
+ for (const { role, content, providerOptions } of prompt) {
104
991
  switch (role) {
105
992
  case "system": {
106
993
  messages.push({
107
994
  role: "system",
108
995
  content,
109
- cache_control: getCacheControl(providerMetadata)
996
+ cache_control: getCacheControl(providerOptions)
110
997
  });
111
998
  break;
112
999
  }
113
1000
  case "user": {
114
- if (content.length === 1 && ((_a = content[0]) == null ? void 0 : _a.type) === "text") {
1001
+ if (content.length === 1 && ((_a15 = content[0]) == null ? void 0 : _a15.type) === "text") {
1002
+ const cacheControl = (_b = getCacheControl(providerOptions)) != null ? _b : getCacheControl(content[0].providerOptions);
1003
+ const contentWithCacheControl = cacheControl ? [
1004
+ {
1005
+ type: "text",
1006
+ text: content[0].text,
1007
+ cache_control: cacheControl
1008
+ }
1009
+ ] : content[0].text;
115
1010
  messages.push({
116
1011
  role: "user",
117
- content: content[0].text,
118
- cache_control: (_b = getCacheControl(providerMetadata)) != null ? _b : getCacheControl(content[0].providerMetadata)
1012
+ content: contentWithCacheControl
119
1013
  });
120
1014
  break;
121
1015
  }
122
- const messageCacheControl = getCacheControl(providerMetadata);
1016
+ const messageCacheControl = getCacheControl(providerOptions);
123
1017
  const contentParts = content.map(
124
1018
  (part) => {
125
- var _a2, _b2, _c2, _d;
126
- const cacheControl = (_a2 = getCacheControl(part.providerMetadata)) != null ? _a2 : messageCacheControl;
1019
+ var _a16, _b2, _c2, _d, _e, _f, _g;
1020
+ const cacheControl = (_a16 = getCacheControl(part.providerOptions)) != null ? _a16 : messageCacheControl;
127
1021
  switch (part.type) {
128
1022
  case "text":
129
1023
  return {
@@ -132,33 +1026,35 @@ function convertToOpenRouterChatMessages(prompt) {
132
1026
  // For text parts, only use part-specific cache control
133
1027
  cache_control: cacheControl
134
1028
  };
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
1029
  case "file":
1030
+ if ((_b2 = part.mediaType) == null ? void 0 : _b2.startsWith("image/")) {
1031
+ return {
1032
+ type: "image_url",
1033
+ image_url: {
1034
+ url: part.data instanceof URL ? part.data.toString() : `data:${(_c2 = part.mediaType) != null ? _c2 : "image/jpeg"};base64,${convertUint8ArrayToBase64(
1035
+ part.data instanceof Uint8Array ? part.data : new Uint8Array()
1036
+ )}`
1037
+ },
1038
+ // For image parts, use part-specific or message-level cache control
1039
+ cache_control: cacheControl
1040
+ };
1041
+ }
147
1042
  return {
148
1043
  type: "file",
149
1044
  file: {
150
1045
  filename: String(
151
- (_d = (_c2 = part.providerMetadata) == null ? void 0 : _c2.openrouter) == null ? void 0 : _d.filename
1046
+ (_g = (_f = (_e = (_d = part.providerOptions) == null ? void 0 : _d.openrouter) == null ? void 0 : _e.filename) != null ? _f : part.filename) != null ? _g : ""
152
1047
  ),
153
- file_data: part.data instanceof Uint8Array ? `data:${part.mimeType};base64,${(0, import_provider_utils.convertUint8ArrayToBase64)(part.data)}` : `data:${part.mimeType};base64,${part.data}`
1048
+ file_data: part.data instanceof Uint8Array ? `data:${part.mediaType};base64,${convertUint8ArrayToBase64(part.data)}` : `data:${part.mediaType};base64,${part.data}`
154
1049
  },
155
1050
  cache_control: cacheControl
156
1051
  };
157
1052
  default: {
158
- const _exhaustiveCheck = part;
159
- throw new Error(
160
- `Unsupported content part type: ${_exhaustiveCheck}`
161
- );
1053
+ return {
1054
+ type: "text",
1055
+ text: "",
1056
+ cache_control: cacheControl
1057
+ };
162
1058
  }
163
1059
  }
164
1060
  }
@@ -186,7 +1082,7 @@ function convertToOpenRouterChatMessages(prompt) {
186
1082
  type: "function",
187
1083
  function: {
188
1084
  name: part.toolName,
189
- arguments: JSON.stringify(part.args)
1085
+ arguments: JSON.stringify(part.input)
190
1086
  }
191
1087
  });
192
1088
  break;
@@ -195,23 +1091,14 @@ function convertToOpenRouterChatMessages(prompt) {
195
1091
  reasoning += part.text;
196
1092
  reasoningDetails.push({
197
1093
  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
1094
+ text: part.text
207
1095
  });
208
1096
  break;
209
1097
  }
210
1098
  case "file":
211
1099
  break;
212
1100
  default: {
213
- const _exhaustiveCheck = part;
214
- throw new Error(`Unsupported part: ${_exhaustiveCheck}`);
1101
+ break;
215
1102
  }
216
1103
  }
217
1104
  }
@@ -221,95 +1108,185 @@ function convertToOpenRouterChatMessages(prompt) {
221
1108
  tool_calls: toolCalls.length > 0 ? toolCalls : void 0,
222
1109
  reasoning: reasoning || void 0,
223
1110
  reasoning_details: reasoningDetails.length > 0 ? reasoningDetails : void 0,
224
- cache_control: getCacheControl(providerMetadata)
1111
+ cache_control: getCacheControl(providerOptions)
225
1112
  });
226
1113
  break;
227
1114
  }
228
1115
  case "tool": {
229
1116
  for (const toolResponse of content) {
1117
+ const content2 = getToolResultContent(toolResponse);
230
1118
  messages.push({
231
1119
  role: "tool",
232
1120
  tool_call_id: toolResponse.toolCallId,
233
- content: JSON.stringify(toolResponse.result),
234
- cache_control: (_c = getCacheControl(providerMetadata)) != null ? _c : getCacheControl(toolResponse.providerMetadata)
1121
+ content: content2,
1122
+ cache_control: (_c = getCacheControl(providerOptions)) != null ? _c : getCacheControl(toolResponse.providerOptions)
235
1123
  });
236
1124
  }
237
1125
  break;
238
1126
  }
239
1127
  default: {
240
- const _exhaustiveCheck = role;
241
- throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
1128
+ break;
242
1129
  }
243
1130
  }
244
1131
  }
245
1132
  return messages;
246
1133
  }
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;
1134
+ function getToolResultContent(input) {
1135
+ return input.output.type === "text" ? input.output.value : JSON.stringify(input.output.value);
259
1136
  }
260
1137
 
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";
1138
+ // src/chat/get-tool-choice.ts
1139
+ var import_v43 = require("zod/v4");
1140
+ var ChatCompletionToolChoiceSchema = import_v43.z.union([
1141
+ import_v43.z.literal("auto"),
1142
+ import_v43.z.literal("none"),
1143
+ import_v43.z.literal("required"),
1144
+ import_v43.z.object({
1145
+ type: import_v43.z.literal("function"),
1146
+ function: import_v43.z.object({
1147
+ name: import_v43.z.string()
1148
+ })
1149
+ })
1150
+ ]);
1151
+ function getChatCompletionToolChoice(toolChoice) {
1152
+ switch (toolChoice.type) {
1153
+ case "auto":
1154
+ case "none":
1155
+ case "required":
1156
+ return toolChoice.type;
1157
+ case "tool": {
1158
+ return {
1159
+ type: "function",
1160
+ function: { name: toolChoice.toolName }
1161
+ };
1162
+ }
1163
+ default: {
1164
+ toolChoice;
1165
+ throw new Error(`Invalid tool choice type: ${toolChoice}`);
1166
+ }
275
1167
  }
276
1168
  }
277
1169
 
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
- code: import_zod2.z.union([import_zod2.z.string(), import_zod2.z.number()]).nullable(),
284
- message: import_zod2.z.string(),
285
- type: import_zod2.z.string().nullable(),
286
- param: import_zod2.z.any().nullable()
287
- })
1170
+ // src/chat/schemas.ts
1171
+ var import_v44 = require("zod/v4");
1172
+ var OpenRouterChatCompletionBaseResponseSchema = import_v44.z.object({
1173
+ id: import_v44.z.string().optional(),
1174
+ model: import_v44.z.string().optional(),
1175
+ usage: import_v44.z.object({
1176
+ prompt_tokens: import_v44.z.number(),
1177
+ prompt_tokens_details: import_v44.z.object({
1178
+ cached_tokens: import_v44.z.number()
1179
+ }).nullish(),
1180
+ completion_tokens: import_v44.z.number(),
1181
+ completion_tokens_details: import_v44.z.object({
1182
+ reasoning_tokens: import_v44.z.number()
1183
+ }).nullish(),
1184
+ total_tokens: import_v44.z.number(),
1185
+ cost: import_v44.z.number().optional()
1186
+ }).nullish()
288
1187
  });
289
- var openrouterFailedResponseHandler = (0, import_provider_utils2.createJsonErrorResponseHandler)({
290
- errorSchema: OpenRouterErrorResponseSchema,
291
- errorToMessage: (data) => data.error.message
1188
+ var OpenRouterNonStreamChatCompletionResponseSchema = OpenRouterChatCompletionBaseResponseSchema.extend({
1189
+ choices: import_v44.z.array(
1190
+ import_v44.z.object({
1191
+ message: import_v44.z.object({
1192
+ role: import_v44.z.literal("assistant"),
1193
+ content: import_v44.z.string().nullable().optional(),
1194
+ reasoning: import_v44.z.string().nullable().optional(),
1195
+ reasoning_details: ReasoningDetailArraySchema.nullish(),
1196
+ tool_calls: import_v44.z.array(
1197
+ import_v44.z.object({
1198
+ id: import_v44.z.string().optional().nullable(),
1199
+ type: import_v44.z.literal("function"),
1200
+ function: import_v44.z.object({
1201
+ name: import_v44.z.string(),
1202
+ arguments: import_v44.z.string()
1203
+ })
1204
+ })
1205
+ ).optional()
1206
+ }),
1207
+ index: import_v44.z.number().nullish(),
1208
+ logprobs: import_v44.z.object({
1209
+ content: import_v44.z.array(
1210
+ import_v44.z.object({
1211
+ token: import_v44.z.string(),
1212
+ logprob: import_v44.z.number(),
1213
+ top_logprobs: import_v44.z.array(
1214
+ import_v44.z.object({
1215
+ token: import_v44.z.string(),
1216
+ logprob: import_v44.z.number()
1217
+ })
1218
+ )
1219
+ })
1220
+ ).nullable()
1221
+ }).nullable().optional(),
1222
+ finish_reason: import_v44.z.string().optional().nullable()
1223
+ })
1224
+ )
292
1225
  });
1226
+ var OpenRouterStreamChatCompletionChunkSchema = import_v44.z.union([
1227
+ OpenRouterChatCompletionBaseResponseSchema.extend({
1228
+ choices: import_v44.z.array(
1229
+ import_v44.z.object({
1230
+ delta: import_v44.z.object({
1231
+ role: import_v44.z.enum(["assistant"]).optional(),
1232
+ content: import_v44.z.string().nullish(),
1233
+ reasoning: import_v44.z.string().nullish().optional(),
1234
+ reasoning_details: ReasoningDetailArraySchema.nullish(),
1235
+ tool_calls: import_v44.z.array(
1236
+ import_v44.z.object({
1237
+ index: import_v44.z.number().nullish(),
1238
+ id: import_v44.z.string().nullish(),
1239
+ type: import_v44.z.literal("function").optional(),
1240
+ function: import_v44.z.object({
1241
+ name: import_v44.z.string().nullish(),
1242
+ arguments: import_v44.z.string().nullish()
1243
+ })
1244
+ })
1245
+ ).nullish()
1246
+ }).nullish(),
1247
+ logprobs: import_v44.z.object({
1248
+ content: import_v44.z.array(
1249
+ import_v44.z.object({
1250
+ token: import_v44.z.string(),
1251
+ logprob: import_v44.z.number(),
1252
+ top_logprobs: import_v44.z.array(
1253
+ import_v44.z.object({
1254
+ token: import_v44.z.string(),
1255
+ logprob: import_v44.z.number()
1256
+ })
1257
+ )
1258
+ })
1259
+ ).nullable()
1260
+ }).nullish(),
1261
+ finish_reason: import_v44.z.string().nullable().optional(),
1262
+ index: import_v44.z.number().nullish()
1263
+ })
1264
+ )
1265
+ }),
1266
+ OpenRouterErrorResponseSchema
1267
+ ]);
293
1268
 
294
- // src/openrouter-chat-language-model.ts
295
- function isFunctionTool(tool) {
296
- return "parameters" in tool;
297
- }
1269
+ // src/chat/index.ts
298
1270
  var OpenRouterChatLanguageModel = class {
299
1271
  constructor(modelId, settings, config) {
300
- this.specificationVersion = "v1";
1272
+ this.specificationVersion = "v2";
1273
+ this.provider = "openrouter";
301
1274
  this.defaultObjectGenerationMode = "tool";
1275
+ this.supportedUrls = {
1276
+ "image/*": [
1277
+ /^data:image\/[a-zA-Z]+;base64,/,
1278
+ /^https?:\/\/.+\.(jpg|jpeg|png|gif|webp)$/i
1279
+ ],
1280
+ // 'text/*': [/^data:text\//, /^https?:\/\/.+$/],
1281
+ "application/*": [/^data:application\//, /^https?:\/\/.+$/]
1282
+ };
302
1283
  this.modelId = modelId;
303
1284
  this.settings = settings;
304
1285
  this.config = config;
305
1286
  }
306
- get provider() {
307
- return this.config.provider;
308
- }
309
1287
  getArgs({
310
- mode,
311
1288
  prompt,
312
- maxTokens,
1289
+ maxOutputTokens,
313
1290
  temperature,
314
1291
  topP,
315
1292
  frequencyPenalty,
@@ -318,12 +1295,10 @@ var OpenRouterChatLanguageModel = class {
318
1295
  stopSequences,
319
1296
  responseFormat,
320
1297
  topK,
321
- providerMetadata
1298
+ tools,
1299
+ toolChoice
322
1300
  }) {
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({
1301
+ const baseArgs = __spreadValues(__spreadValues({
327
1302
  // model id:
328
1303
  model: this.modelId,
329
1304
  models: this.settings.models,
@@ -334,7 +1309,7 @@ var OpenRouterChatLanguageModel = class {
334
1309
  user: this.settings.user,
335
1310
  parallel_tool_calls: this.settings.parallelToolCalls,
336
1311
  // standardized settings:
337
- max_tokens: maxTokens,
1312
+ max_tokens: maxOutputTokens,
338
1313
  temperature,
339
1314
  top_p: topP,
340
1315
  frequency_penalty: frequencyPenalty,
@@ -349,97 +1324,74 @@ var OpenRouterChatLanguageModel = class {
349
1324
  include_reasoning: this.settings.includeReasoning,
350
1325
  reasoning: this.settings.reasoning,
351
1326
  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
- }
1327
+ }, this.config.extraBody), this.settings.extraBody);
1328
+ if ((responseFormat == null ? void 0 : responseFormat.type) === "json") {
1329
+ return __spreadProps(__spreadValues({}, baseArgs), {
1330
+ response_format: { type: "json_object" }
1331
+ });
1332
+ }
1333
+ if (tools && tools.length > 0) {
1334
+ const mappedTools = tools.filter((tool) => tool.type === "function").map((tool) => ({
1335
+ type: "function",
1336
+ function: {
1337
+ name: tool.name,
1338
+ description: tool.type,
1339
+ parameters: tool.inputSchema
1340
+ }
1341
+ }));
1342
+ return __spreadProps(__spreadValues({}, baseArgs), {
1343
+ tools: mappedTools,
1344
+ tool_choice: toolChoice ? getChatCompletionToolChoice(toolChoice) : void 0
1345
+ });
384
1346
  }
1347
+ return baseArgs;
385
1348
  }
386
1349
  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)({
1350
+ var _a15, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t;
1351
+ const providerOptions = options.providerOptions || {};
1352
+ const openrouterOptions = providerOptions.openrouter || {};
1353
+ const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
1354
+ const { value: response, responseHeaders } = await postJsonToApi({
390
1355
  url: this.config.url({
391
1356
  path: "/chat/completions",
392
1357
  modelId: this.modelId
393
1358
  }),
394
- headers: (0, import_provider_utils3.combineHeaders)(this.config.headers(), options.headers),
1359
+ headers: combineHeaders(this.config.headers(), options.headers),
395
1360
  body: args,
396
1361
  failedResponseHandler: openrouterFailedResponseHandler,
397
- successfulResponseHandler: (0, import_provider_utils3.createJsonResponseHandler)(
1362
+ successfulResponseHandler: createJsonResponseHandler(
398
1363
  OpenRouterNonStreamChatCompletionResponseSchema
399
1364
  ),
400
1365
  abortSignal: options.abortSignal,
401
1366
  fetch: this.config.fetch
402
1367
  });
403
- const _a = args, { messages: rawPrompt } = _a, rawSettings = __objRest(_a, ["messages"]);
404
1368
  const choice = response.choices[0];
405
1369
  if (!choice) {
406
1370
  throw new Error("No choice in response");
407
1371
  }
408
1372
  const usageInfo = response.usage ? {
409
- promptTokens: (_b = response.usage.prompt_tokens) != null ? _b : 0,
410
- completionTokens: (_c = response.usage.completion_tokens) != null ? _c : 0
1373
+ inputTokens: (_a15 = response.usage.prompt_tokens) != null ? _a15 : 0,
1374
+ outputTokens: (_b = response.usage.completion_tokens) != null ? _b : 0,
1375
+ totalTokens: ((_c = response.usage.prompt_tokens) != null ? _c : 0) + ((_d = response.usage.completion_tokens) != null ? _d : 0),
1376
+ reasoningTokens: (_f = (_e = response.usage.completion_tokens_details) == null ? void 0 : _e.reasoning_tokens) != null ? _f : 0,
1377
+ cachedInputTokens: (_h = (_g = response.usage.prompt_tokens_details) == null ? void 0 : _g.cached_tokens) != null ? _h : 0
411
1378
  } : {
412
- promptTokens: 0,
413
- completionTokens: 0
1379
+ inputTokens: 0,
1380
+ outputTokens: 0,
1381
+ totalTokens: 0,
1382
+ reasoningTokens: 0,
1383
+ cachedInputTokens: 0
414
1384
  };
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;
1385
+ const reasoningDetails = (_i = choice.message.reasoning_details) != null ? _i : [];
1386
+ reasoningDetails.length > 0 ? reasoningDetails.map((detail) => {
1387
+ var _a16;
436
1388
  switch (detail.type) {
437
1389
  case "reasoning.text" /* Text */: {
438
1390
  if (detail.text) {
439
1391
  return {
440
1392
  type: "text",
441
1393
  text: detail.text,
442
- signature: (_a2 = detail.signature) != null ? _a2 : void 0
1394
+ signature: (_a16 = detail.signature) != null ? _a16 : void 0
443
1395
  };
444
1396
  }
445
1397
  break;
@@ -473,68 +1425,92 @@ var OpenRouterChatLanguageModel = class {
473
1425
  text: choice.message.reasoning
474
1426
  }
475
1427
  ] : [];
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)(),
1428
+ const content = [];
1429
+ if (choice.message.content) {
1430
+ content.push({
1431
+ type: "text",
1432
+ text: choice.message.content
1433
+ });
1434
+ }
1435
+ if (choice.message.tool_calls) {
1436
+ for (const toolCall of choice.message.tool_calls) {
1437
+ content.push({
1438
+ type: "tool-call",
1439
+ toolCallId: (_j = toolCall.id) != null ? _j : generateId(),
488
1440
  toolName: toolCall.function.name,
489
- args: toolCall.function.arguments
490
- };
491
- }),
1441
+ input: toolCall.function.arguments
1442
+ });
1443
+ }
1444
+ }
1445
+ return {
1446
+ content,
492
1447
  finishReason: mapOpenRouterFinishReason(choice.finish_reason),
493
1448
  usage: usageInfo,
494
- rawCall: { rawPrompt, rawSettings },
495
- rawResponse: { headers: responseHeaders },
496
1449
  warnings: [],
497
- logprobs: mapOpenRouterChatLogProbsOutput(choice.logprobs)
498
- }, hasProviderMetadata ? { providerMetadata } : {});
1450
+ providerMetadata: {
1451
+ openrouter: {
1452
+ usage: {
1453
+ promptTokens: (_k = usageInfo.inputTokens) != null ? _k : 0,
1454
+ completionTokens: (_l = usageInfo.outputTokens) != null ? _l : 0,
1455
+ totalTokens: (_m = usageInfo.totalTokens) != null ? _m : 0,
1456
+ cost: (_n = response.usage) == null ? void 0 : _n.cost,
1457
+ promptTokensDetails: {
1458
+ cachedTokens: (_q = (_p = (_o = response.usage) == null ? void 0 : _o.prompt_tokens_details) == null ? void 0 : _p.cached_tokens) != null ? _q : 0
1459
+ },
1460
+ completionTokensDetails: {
1461
+ reasoningTokens: (_t = (_s = (_r = response.usage) == null ? void 0 : _r.completion_tokens_details) == null ? void 0 : _s.reasoning_tokens) != null ? _t : 0
1462
+ }
1463
+ }
1464
+ }
1465
+ },
1466
+ request: { body: args },
1467
+ response: {
1468
+ id: response.id,
1469
+ modelId: response.model,
1470
+ headers: responseHeaders
1471
+ }
1472
+ };
499
1473
  }
500
1474
  async doStream(options) {
501
- var _a, _c;
502
- const args = this.getArgs(options);
503
- const { responseHeaders, value: response } = await (0, import_provider_utils3.postJsonToApi)({
1475
+ var _a15;
1476
+ const providerOptions = options.providerOptions || {};
1477
+ const openrouterOptions = providerOptions.openrouter || {};
1478
+ const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
1479
+ const { value: response, responseHeaders } = await postJsonToApi({
504
1480
  url: this.config.url({
505
1481
  path: "/chat/completions",
506
1482
  modelId: this.modelId
507
1483
  }),
508
- headers: (0, import_provider_utils3.combineHeaders)(this.config.headers(), options.headers),
1484
+ headers: combineHeaders(this.config.headers(), options.headers),
509
1485
  body: __spreadProps(__spreadValues({}, args), {
510
1486
  stream: true,
511
1487
  // only include stream_options when in strict compatibility mode:
512
1488
  stream_options: this.config.compatibility === "strict" ? __spreadValues({
513
1489
  include_usage: true
514
- }, ((_a = this.settings.usage) == null ? void 0 : _a.include) ? { include_usage: true } : {}) : void 0
1490
+ }, ((_a15 = this.settings.usage) == null ? void 0 : _a15.include) ? { include_usage: true } : {}) : void 0
515
1491
  }),
516
1492
  failedResponseHandler: openrouterFailedResponseHandler,
517
- successfulResponseHandler: (0, import_provider_utils3.createEventSourceResponseHandler)(
1493
+ successfulResponseHandler: createEventSourceResponseHandler(
518
1494
  OpenRouterStreamChatCompletionChunkSchema
519
1495
  ),
520
1496
  abortSignal: options.abortSignal,
521
1497
  fetch: this.config.fetch
522
1498
  });
523
- const _b = args, { messages: rawPrompt } = _b, rawSettings = __objRest(_b, ["messages"]);
524
1499
  const toolCalls = [];
525
1500
  let finishReason = "other";
526
- let usage = {
527
- promptTokens: Number.NaN,
528
- completionTokens: Number.NaN
1501
+ const usage = {
1502
+ inputTokens: Number.NaN,
1503
+ outputTokens: Number.NaN,
1504
+ totalTokens: Number.NaN,
1505
+ reasoningTokens: Number.NaN,
1506
+ cachedInputTokens: Number.NaN
529
1507
  };
530
- let logprobs;
531
1508
  const openrouterUsage = {};
532
- const shouldIncludeUsageAccounting = !!((_c = this.settings.usage) == null ? void 0 : _c.include);
533
1509
  return {
534
1510
  stream: response.pipeThrough(
535
1511
  new TransformStream({
536
1512
  transform(chunk, controller) {
537
- var _a2, _b2, _c2, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
1513
+ var _a16, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
538
1514
  if (!chunk.success) {
539
1515
  finishReason = "error";
540
1516
  controller.enqueue({ type: "error", error: chunk.error });
@@ -559,20 +1535,23 @@ var OpenRouterChatLanguageModel = class {
559
1535
  });
560
1536
  }
561
1537
  if (value.usage != null) {
562
- usage = {
563
- promptTokens: value.usage.prompt_tokens,
564
- completionTokens: value.usage.completion_tokens
565
- };
1538
+ usage.inputTokens = value.usage.prompt_tokens;
1539
+ usage.outputTokens = value.usage.completion_tokens;
1540
+ usage.totalTokens = value.usage.prompt_tokens + value.usage.completion_tokens;
566
1541
  openrouterUsage.promptTokens = value.usage.prompt_tokens;
567
1542
  if (value.usage.prompt_tokens_details) {
1543
+ const cachedInputTokens = (_a16 = value.usage.prompt_tokens_details.cached_tokens) != null ? _a16 : 0;
1544
+ usage.cachedInputTokens = cachedInputTokens;
568
1545
  openrouterUsage.promptTokensDetails = {
569
- cachedTokens: (_a2 = value.usage.prompt_tokens_details.cached_tokens) != null ? _a2 : 0
1546
+ cachedTokens: cachedInputTokens
570
1547
  };
571
1548
  }
572
1549
  openrouterUsage.completionTokens = value.usage.completion_tokens;
573
1550
  if (value.usage.completion_tokens_details) {
1551
+ const reasoningTokens = (_b = value.usage.completion_tokens_details.reasoning_tokens) != null ? _b : 0;
1552
+ usage.reasoningTokens = reasoningTokens;
574
1553
  openrouterUsage.completionTokensDetails = {
575
- reasoningTokens: (_b2 = value.usage.completion_tokens_details.reasoning_tokens) != null ? _b2 : 0
1554
+ reasoningTokens
576
1555
  };
577
1556
  }
578
1557
  openrouterUsage.cost = value.usage.cost;
@@ -589,13 +1568,15 @@ var OpenRouterChatLanguageModel = class {
589
1568
  if (delta.content != null) {
590
1569
  controller.enqueue({
591
1570
  type: "text-delta",
592
- textDelta: delta.content
1571
+ delta: delta.content,
1572
+ id: generateId()
593
1573
  });
594
1574
  }
595
1575
  if (delta.reasoning != null) {
596
1576
  controller.enqueue({
597
- type: "reasoning",
598
- textDelta: delta.reasoning
1577
+ type: "reasoning-delta",
1578
+ delta: delta.reasoning,
1579
+ id: generateId()
599
1580
  });
600
1581
  }
601
1582
  if (delta.reasoning_details && delta.reasoning_details.length > 0) {
@@ -604,14 +1585,15 @@ var OpenRouterChatLanguageModel = class {
604
1585
  case "reasoning.text" /* Text */: {
605
1586
  if (detail.text) {
606
1587
  controller.enqueue({
607
- type: "reasoning",
608
- textDelta: detail.text
1588
+ type: "reasoning-delta",
1589
+ delta: detail.text,
1590
+ id: generateId()
609
1591
  });
610
1592
  }
611
1593
  if (detail.signature) {
612
1594
  controller.enqueue({
613
- type: "reasoning-signature",
614
- signature: detail.signature
1595
+ type: "reasoning-end",
1596
+ id: generateId()
615
1597
  });
616
1598
  }
617
1599
  break;
@@ -619,8 +1601,9 @@ var OpenRouterChatLanguageModel = class {
619
1601
  case "reasoning.encrypted" /* Encrypted */: {
620
1602
  if (detail.data) {
621
1603
  controller.enqueue({
622
- type: "redacted-reasoning",
623
- data: detail.data
1604
+ type: "reasoning-delta",
1605
+ delta: "[REDACTED]",
1606
+ id: generateId()
624
1607
  });
625
1608
  }
626
1609
  break;
@@ -628,8 +1611,9 @@ var OpenRouterChatLanguageModel = class {
628
1611
  case "reasoning.summary" /* Summary */: {
629
1612
  if (detail.summary) {
630
1613
  controller.enqueue({
631
- type: "reasoning",
632
- textDelta: detail.summary
1614
+ type: "reasoning-delta",
1615
+ delta: detail.summary,
1616
+ id: generateId()
633
1617
  });
634
1618
  }
635
1619
  break;
@@ -641,33 +1625,24 @@ var OpenRouterChatLanguageModel = class {
641
1625
  }
642
1626
  }
643
1627
  }
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
1628
  if (delta.tool_calls != null) {
654
1629
  for (const toolCallDelta of delta.tool_calls) {
655
- const index = toolCallDelta.index;
1630
+ const index = (_c = toolCallDelta.index) != null ? _c : toolCalls.length - 1;
656
1631
  if (toolCalls[index] == null) {
657
1632
  if (toolCallDelta.type !== "function") {
658
- throw new import_provider.InvalidResponseDataError({
1633
+ throw new InvalidResponseDataError({
659
1634
  data: toolCallDelta,
660
1635
  message: `Expected 'function' type.`
661
1636
  });
662
1637
  }
663
1638
  if (toolCallDelta.id == null) {
664
- throw new import_provider.InvalidResponseDataError({
1639
+ throw new InvalidResponseDataError({
665
1640
  data: toolCallDelta,
666
1641
  message: `Expected 'id' to be a string.`
667
1642
  });
668
1643
  }
669
- if (((_c2 = toolCallDelta.function) == null ? void 0 : _c2.name) == null) {
670
- throw new import_provider.InvalidResponseDataError({
1644
+ if (((_d = toolCallDelta.function) == null ? void 0 : _d.name) == null) {
1645
+ throw new InvalidResponseDataError({
671
1646
  data: toolCallDelta,
672
1647
  message: `Expected 'function.name' to be a string.`
673
1648
  });
@@ -677,7 +1652,7 @@ var OpenRouterChatLanguageModel = class {
677
1652
  type: "function",
678
1653
  function: {
679
1654
  name: toolCallDelta.function.name,
680
- arguments: (_d = toolCallDelta.function.arguments) != null ? _d : ""
1655
+ arguments: (_e = toolCallDelta.function.arguments) != null ? _e : ""
681
1656
  },
682
1657
  sent: false
683
1658
  };
@@ -685,20 +1660,26 @@ var OpenRouterChatLanguageModel = class {
685
1660
  if (toolCall2 == null) {
686
1661
  throw new Error("Tool call is missing");
687
1662
  }
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)) {
1663
+ if (((_f = toolCall2.function) == null ? void 0 : _f.name) != null && ((_g = toolCall2.function) == null ? void 0 : _g.arguments) != null && isParsableJson(toolCall2.function.arguments)) {
689
1664
  controller.enqueue({
690
- type: "tool-call-delta",
691
- toolCallType: "function",
692
- toolCallId: toolCall2.id,
693
- toolName: toolCall2.function.name,
694
- argsTextDelta: toolCall2.function.arguments
1665
+ type: "tool-input-start",
1666
+ id: toolCall2.id,
1667
+ toolName: toolCall2.function.name
1668
+ });
1669
+ controller.enqueue({
1670
+ type: "tool-input-delta",
1671
+ id: toolCall2.id,
1672
+ delta: toolCall2.function.arguments
1673
+ });
1674
+ controller.enqueue({
1675
+ type: "tool-input-end",
1676
+ id: toolCall2.id
695
1677
  });
696
1678
  controller.enqueue({
697
1679
  type: "tool-call",
698
- toolCallType: "function",
699
- toolCallId: (_g = toolCall2.id) != null ? _g : (0, import_provider_utils3.generateId)(),
1680
+ toolCallId: toolCall2.id,
700
1681
  toolName: toolCall2.function.name,
701
- args: toolCall2.function.arguments
1682
+ input: toolCall2.function.arguments
702
1683
  });
703
1684
  toolCall2.sent = true;
704
1685
  }
@@ -708,23 +1689,27 @@ var OpenRouterChatLanguageModel = class {
708
1689
  if (toolCall == null) {
709
1690
  throw new Error("Tool call is missing");
710
1691
  }
711
- if (((_h = toolCallDelta.function) == null ? void 0 : _h.arguments) != null) {
712
- toolCall.function.arguments += (_j = (_i = toolCallDelta.function) == null ? void 0 : _i.arguments) != null ? _j : "";
1692
+ if (((_h = toolCallDelta.function) == null ? void 0 : _h.name) != null) {
1693
+ controller.enqueue({
1694
+ type: "tool-input-start",
1695
+ id: toolCall.id,
1696
+ toolName: toolCall.function.name
1697
+ });
1698
+ }
1699
+ if (((_i = toolCallDelta.function) == null ? void 0 : _i.arguments) != null) {
1700
+ toolCall.function.arguments += (_k = (_j = toolCallDelta.function) == null ? void 0 : _j.arguments) != null ? _k : "";
713
1701
  }
714
1702
  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 : ""
1703
+ type: "tool-input-delta",
1704
+ id: toolCall.id,
1705
+ delta: (_l = toolCallDelta.function.arguments) != null ? _l : ""
720
1706
  });
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)) {
1707
+ if (((_m = toolCall.function) == null ? void 0 : _m.name) != null && ((_n = toolCall.function) == null ? void 0 : _n.arguments) != null && isParsableJson(toolCall.function.arguments)) {
722
1708
  controller.enqueue({
723
1709
  type: "tool-call",
724
- toolCallType: "function",
725
- toolCallId: (_n = toolCall.id) != null ? _n : (0, import_provider_utils3.generateId)(),
1710
+ toolCallId: (_o = toolCall.id) != null ? _o : generateId(),
726
1711
  toolName: toolCall.function.name,
727
- args: toolCall.function.arguments
1712
+ input: toolCall.function.arguments
728
1713
  });
729
1714
  toolCall.sent = true;
730
1715
  }
@@ -732,198 +1717,42 @@ var OpenRouterChatLanguageModel = class {
732
1717
  }
733
1718
  },
734
1719
  flush(controller) {
735
- var _a2;
1720
+ var _a16;
736
1721
  if (finishReason === "tool-calls") {
737
1722
  for (const toolCall of toolCalls) {
738
1723
  if (!toolCall.sent) {
739
1724
  controller.enqueue({
740
1725
  type: "tool-call",
741
- toolCallType: "function",
742
- toolCallId: (_a2 = toolCall.id) != null ? _a2 : (0, import_provider_utils3.generateId)(),
1726
+ toolCallId: (_a16 = toolCall.id) != null ? _a16 : generateId(),
743
1727
  toolName: toolCall.function.name,
744
1728
  // Coerce invalid arguments to an empty JSON object
745
- args: (0, import_provider_utils3.isParsableJson)(toolCall.function.arguments) ? toolCall.function.arguments : "{}"
1729
+ input: isParsableJson(toolCall.function.arguments) ? toolCall.function.arguments : "{}"
746
1730
  });
747
1731
  toolCall.sent = true;
748
1732
  }
749
1733
  }
750
1734
  }
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({
1735
+ controller.enqueue({
759
1736
  type: "finish",
760
1737
  finishReason,
761
- logprobs,
762
- usage
763
- }, hasProviderMetadata ? { providerMetadata } : {}));
1738
+ usage,
1739
+ providerMetadata: {
1740
+ openrouter: {
1741
+ usage: openrouterUsage
1742
+ }
1743
+ }
1744
+ });
764
1745
  }
765
1746
  })
766
1747
  ),
767
- rawCall: { rawPrompt, rawSettings },
768
- rawResponse: { headers: responseHeaders },
769
- warnings: []
1748
+ warnings: [],
1749
+ request: { body: args },
1750
+ response: { headers: responseHeaders }
770
1751
  };
771
1752
  }
772
1753
  };
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()
780
- }).nullish(),
781
- completion_tokens: import_zod3.z.number(),
782
- completion_tokens_details: import_zod3.z.object({
783
- reasoning_tokens: import_zod3.z.number()
784
- }).nullish(),
785
- total_tokens: import_zod3.z.number(),
786
- cost: import_zod3.z.number().optional()
787
- }).nullish()
788
- });
789
- 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(),
796
- 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()
804
- })
805
- })
806
- ).optional()
807
- }),
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()
818
- })
819
- )
820
- })
821
- ).nullable()
822
- }).nullable().optional(),
823
- finish_reason: import_zod3.z.string().optional().nullable()
824
- })
825
- )
826
- });
827
- var OpenRouterStreamChatCompletionChunkSchema = import_zod3.z.union([
828
- 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(),
835
- 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()
844
- })
845
- })
846
- ).nullish()
847
- }).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()
857
- })
858
- )
859
- })
860
- ).nullable()
861
- }).nullish(),
862
- finish_reason: import_zod3.z.string().nullable().optional(),
863
- index: import_zod3.z.number()
864
- })
865
- )
866
- }),
867
- OpenRouterErrorResponseSchema
868
- ]);
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
-
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");
924
1754
 
925
- // src/convert-to-openrouter-completion-prompt.ts
926
- var import_provider2 = require("@ai-sdk/provider");
1755
+ // src/completion/convert-to-openrouter-completion-prompt.ts
927
1756
  function convertToOpenRouterCompletionPrompt({
928
1757
  prompt,
929
1758
  inputFormat,
@@ -943,8 +1772,8 @@ function convertToOpenRouterCompletionPrompt({
943
1772
  for (const { role, content } of prompt) {
944
1773
  switch (role) {
945
1774
  case "system": {
946
- throw new import_provider2.InvalidPromptError({
947
- message: "Unexpected system message in prompt: ${content}",
1775
+ throw new InvalidPromptError({
1776
+ message: `Unexpected system message in prompt: ${content}`,
948
1777
  prompt
949
1778
  });
950
1779
  }
@@ -954,21 +1783,13 @@ function convertToOpenRouterCompletionPrompt({
954
1783
  case "text": {
955
1784
  return part.text;
956
1785
  }
957
- case "image": {
958
- throw new import_provider2.UnsupportedFunctionalityError({
959
- functionality: "images"
960
- });
961
- }
962
1786
  case "file": {
963
- throw new import_provider2.UnsupportedFunctionalityError({
1787
+ throw new UnsupportedFunctionalityError({
964
1788
  functionality: "file attachments"
965
1789
  });
966
1790
  }
967
1791
  default: {
968
- const _exhaustiveCheck = part;
969
- throw new Error(
970
- `Unsupported content type: ${_exhaustiveCheck}`
971
- );
1792
+ return "";
972
1793
  }
973
1794
  }
974
1795
  }).join("");
@@ -979,39 +1800,38 @@ ${userMessage}
979
1800
  break;
980
1801
  }
981
1802
  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
- );
1803
+ const assistantMessage = content.map(
1804
+ (part) => {
1805
+ switch (part.type) {
1806
+ case "text": {
1807
+ return part.text;
1808
+ }
1809
+ case "tool-call": {
1810
+ throw new UnsupportedFunctionalityError({
1811
+ functionality: "tool-call messages"
1812
+ });
1813
+ }
1814
+ case "tool-result": {
1815
+ throw new UnsupportedFunctionalityError({
1816
+ functionality: "tool-result messages"
1817
+ });
1818
+ }
1819
+ case "reasoning": {
1820
+ throw new UnsupportedFunctionalityError({
1821
+ functionality: "reasoning messages"
1822
+ });
1823
+ }
1824
+ case "file": {
1825
+ throw new UnsupportedFunctionalityError({
1826
+ functionality: "file attachments"
1827
+ });
1828
+ }
1829
+ default: {
1830
+ return "";
1831
+ }
1012
1832
  }
1013
1833
  }
1014
- }).join("");
1834
+ ).join("");
1015
1835
  text += `${assistant}:
1016
1836
  ${assistantMessage}
1017
1837
 
@@ -1019,13 +1839,12 @@ ${assistantMessage}
1019
1839
  break;
1020
1840
  }
1021
1841
  case "tool": {
1022
- throw new import_provider2.UnsupportedFunctionalityError({
1842
+ throw new UnsupportedFunctionalityError({
1023
1843
  functionality: "tool messages"
1024
1844
  });
1025
1845
  }
1026
1846
  default: {
1027
- const _exhaustiveCheck = role;
1028
- throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
1847
+ break;
1029
1848
  }
1030
1849
  }
1031
1850
  }
@@ -1036,40 +1855,63 @@ ${assistantMessage}
1036
1855
  };
1037
1856
  }
1038
1857
 
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
- }
1858
+ // src/completion/schemas.ts
1859
+ var import_v45 = require("zod/v4");
1860
+ var OpenRouterCompletionChunkSchema = import_v45.z.union([
1861
+ import_v45.z.object({
1862
+ id: import_v45.z.string().optional(),
1863
+ model: import_v45.z.string().optional(),
1864
+ choices: import_v45.z.array(
1865
+ import_v45.z.object({
1866
+ text: import_v45.z.string(),
1867
+ reasoning: import_v45.z.string().nullish().optional(),
1868
+ reasoning_details: ReasoningDetailArraySchema.nullish(),
1869
+ finish_reason: import_v45.z.string().nullish(),
1870
+ index: import_v45.z.number().nullish(),
1871
+ logprobs: import_v45.z.object({
1872
+ tokens: import_v45.z.array(import_v45.z.string()),
1873
+ token_logprobs: import_v45.z.array(import_v45.z.number()),
1874
+ top_logprobs: import_v45.z.array(import_v45.z.record(import_v45.z.string(), import_v45.z.number())).nullable()
1875
+ }).nullable().optional()
1876
+ })
1877
+ ),
1878
+ usage: import_v45.z.object({
1879
+ prompt_tokens: import_v45.z.number(),
1880
+ prompt_tokens_details: import_v45.z.object({
1881
+ cached_tokens: import_v45.z.number()
1882
+ }).nullish(),
1883
+ completion_tokens: import_v45.z.number(),
1884
+ completion_tokens_details: import_v45.z.object({
1885
+ reasoning_tokens: import_v45.z.number()
1886
+ }).nullish(),
1887
+ total_tokens: import_v45.z.number(),
1888
+ cost: import_v45.z.number().optional()
1889
+ }).nullish()
1890
+ }),
1891
+ OpenRouterErrorResponseSchema
1892
+ ]);
1055
1893
 
1056
- // src/openrouter-completion-language-model.ts
1894
+ // src/completion/index.ts
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"