@openrouter/ai-sdk-provider 2.0.4 → 2.1.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/README.md +28 -0
- package/dist/index.d.mts +147 -12
- package/dist/index.d.ts +147 -12
- package/dist/index.js +356 -61
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +356 -61
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.d.mts +181 -12
- package/dist/internal/index.d.ts +181 -12
- package/dist/internal/index.js +390 -47
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +387 -46
- package/dist/internal/index.mjs.map +1 -1
- package/package.json +1 -4
package/dist/index.mjs
CHANGED
|
@@ -4,6 +4,9 @@ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
|
4
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
6
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __typeError = (msg) => {
|
|
8
|
+
throw TypeError(msg);
|
|
9
|
+
};
|
|
7
10
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
11
|
var __spreadValues = (a, b) => {
|
|
9
12
|
for (var prop in b || (b = {}))
|
|
@@ -29,6 +32,9 @@ var __objRest = (source, exclude) => {
|
|
|
29
32
|
}
|
|
30
33
|
return target;
|
|
31
34
|
};
|
|
35
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
36
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
37
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
32
38
|
|
|
33
39
|
// node_modules/.pnpm/@ai-sdk+provider@3.0.0/node_modules/@ai-sdk/provider/dist/index.mjs
|
|
34
40
|
var marker = "vercel.ai.error";
|
|
@@ -2316,6 +2322,54 @@ function createFinishReason(unified, raw) {
|
|
|
2316
2322
|
return { unified, raw };
|
|
2317
2323
|
}
|
|
2318
2324
|
|
|
2325
|
+
// src/utils/reasoning-details-duplicate-tracker.ts
|
|
2326
|
+
var _seenKeys;
|
|
2327
|
+
var ReasoningDetailsDuplicateTracker = class {
|
|
2328
|
+
constructor() {
|
|
2329
|
+
__privateAdd(this, _seenKeys, /* @__PURE__ */ new Set());
|
|
2330
|
+
}
|
|
2331
|
+
/**
|
|
2332
|
+
* Attempts to track a detail.
|
|
2333
|
+
* Returns true if this is a NEW detail (not seen before and has valid key),
|
|
2334
|
+
* false if it was skipped (no valid key) or already seen (duplicate).
|
|
2335
|
+
*/
|
|
2336
|
+
upsert(detail) {
|
|
2337
|
+
const key = this.getCanonicalKey(detail);
|
|
2338
|
+
if (key === null) {
|
|
2339
|
+
return false;
|
|
2340
|
+
}
|
|
2341
|
+
if (__privateGet(this, _seenKeys).has(key)) {
|
|
2342
|
+
return false;
|
|
2343
|
+
}
|
|
2344
|
+
__privateGet(this, _seenKeys).add(key);
|
|
2345
|
+
return true;
|
|
2346
|
+
}
|
|
2347
|
+
getCanonicalKey(detail) {
|
|
2348
|
+
switch (detail.type) {
|
|
2349
|
+
case "reasoning.summary" /* Summary */:
|
|
2350
|
+
return detail.summary;
|
|
2351
|
+
case "reasoning.encrypted" /* Encrypted */:
|
|
2352
|
+
if (detail.id) {
|
|
2353
|
+
return detail.id;
|
|
2354
|
+
}
|
|
2355
|
+
return detail.data;
|
|
2356
|
+
case "reasoning.text" /* Text */: {
|
|
2357
|
+
if (detail.text) {
|
|
2358
|
+
return detail.text;
|
|
2359
|
+
}
|
|
2360
|
+
if (detail.signature) {
|
|
2361
|
+
return detail.signature;
|
|
2362
|
+
}
|
|
2363
|
+
return null;
|
|
2364
|
+
}
|
|
2365
|
+
default: {
|
|
2366
|
+
return null;
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
};
|
|
2371
|
+
_seenKeys = new WeakMap();
|
|
2372
|
+
|
|
2319
2373
|
// src/types/openrouter-chat-completions-input.ts
|
|
2320
2374
|
var OPENROUTER_AUDIO_FORMATS = [
|
|
2321
2375
|
"wav",
|
|
@@ -2447,6 +2501,7 @@ function getCacheControl(providerMetadata) {
|
|
|
2447
2501
|
function convertToOpenRouterChatMessages(prompt) {
|
|
2448
2502
|
var _a16, _b16, _c, _d, _e, _f, _g, _h;
|
|
2449
2503
|
const messages = [];
|
|
2504
|
+
const reasoningDetailsTracker = new ReasoningDetailsDuplicateTracker();
|
|
2450
2505
|
for (const { role, content, providerOptions } of prompt) {
|
|
2451
2506
|
switch (role) {
|
|
2452
2507
|
case "system": {
|
|
@@ -2589,7 +2644,17 @@ function convertToOpenRouterChatMessages(prompt) {
|
|
|
2589
2644
|
const parsedProviderOptions = OpenRouterProviderOptionsSchema.safeParse(providerOptions);
|
|
2590
2645
|
const messageReasoningDetails = parsedProviderOptions.success ? (_e = (_d = parsedProviderOptions.data) == null ? void 0 : _d.openrouter) == null ? void 0 : _e.reasoning_details : void 0;
|
|
2591
2646
|
const messageAnnotations = parsedProviderOptions.success ? (_g = (_f = parsedProviderOptions.data) == null ? void 0 : _f.openrouter) == null ? void 0 : _g.annotations : void 0;
|
|
2592
|
-
const
|
|
2647
|
+
const candidateReasoningDetails = messageReasoningDetails && Array.isArray(messageReasoningDetails) && messageReasoningDetails.length > 0 ? messageReasoningDetails : findFirstReasoningDetails(content);
|
|
2648
|
+
let finalReasoningDetails;
|
|
2649
|
+
if (candidateReasoningDetails && candidateReasoningDetails.length > 0) {
|
|
2650
|
+
const uniqueDetails = [];
|
|
2651
|
+
for (const detail of candidateReasoningDetails) {
|
|
2652
|
+
if (reasoningDetailsTracker.upsert(detail)) {
|
|
2653
|
+
uniqueDetails.push(detail);
|
|
2654
|
+
}
|
|
2655
|
+
}
|
|
2656
|
+
finalReasoningDetails = uniqueDetails.length > 0 ? uniqueDetails : void 0;
|
|
2657
|
+
}
|
|
2593
2658
|
messages.push({
|
|
2594
2659
|
role: "assistant",
|
|
2595
2660
|
content: text,
|
|
@@ -2758,13 +2823,14 @@ var OpenRouterNonStreamChatCompletionResponseSchema = z7.union([
|
|
|
2758
2823
|
annotations: z7.array(
|
|
2759
2824
|
z7.union([
|
|
2760
2825
|
// URL citation from web search
|
|
2826
|
+
// title, start_index, end_index are optional as some upstream providers may omit them
|
|
2761
2827
|
z7.object({
|
|
2762
2828
|
type: z7.literal("url_citation"),
|
|
2763
2829
|
url_citation: z7.object({
|
|
2764
|
-
end_index: z7.number(),
|
|
2765
|
-
start_index: z7.number(),
|
|
2766
|
-
title: z7.string(),
|
|
2767
2830
|
url: z7.string(),
|
|
2831
|
+
title: z7.string().optional(),
|
|
2832
|
+
start_index: z7.number().optional(),
|
|
2833
|
+
end_index: z7.number().optional(),
|
|
2768
2834
|
content: z7.string().optional()
|
|
2769
2835
|
}).passthrough()
|
|
2770
2836
|
}).passthrough(),
|
|
@@ -2841,13 +2907,14 @@ var OpenRouterStreamChatCompletionChunkSchema = z7.union([
|
|
|
2841
2907
|
annotations: z7.array(
|
|
2842
2908
|
z7.union([
|
|
2843
2909
|
// URL citation from web search
|
|
2910
|
+
// title, start_index, end_index are optional as some upstream providers may omit them
|
|
2844
2911
|
z7.object({
|
|
2845
2912
|
type: z7.literal("url_citation"),
|
|
2846
2913
|
url_citation: z7.object({
|
|
2847
|
-
end_index: z7.number(),
|
|
2848
|
-
start_index: z7.number(),
|
|
2849
|
-
title: z7.string(),
|
|
2850
2914
|
url: z7.string(),
|
|
2915
|
+
title: z7.string().optional(),
|
|
2916
|
+
start_index: z7.number().optional(),
|
|
2917
|
+
end_index: z7.number().optional(),
|
|
2851
2918
|
content: z7.string().optional()
|
|
2852
2919
|
}).passthrough()
|
|
2853
2920
|
}).passthrough(),
|
|
@@ -2994,7 +3061,7 @@ var OpenRouterChatLanguageModel = class {
|
|
|
2994
3061
|
return baseArgs;
|
|
2995
3062
|
}
|
|
2996
3063
|
async doGenerate(options) {
|
|
2997
|
-
var _a16, _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
|
|
3064
|
+
var _a16, _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B;
|
|
2998
3065
|
const providerOptions = options.providerOptions || {};
|
|
2999
3066
|
const openrouterOptions = providerOptions.openrouter || {};
|
|
3000
3067
|
const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
|
|
@@ -3044,7 +3111,8 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3044
3111
|
total: (_d = response.usage.completion_tokens) != null ? _d : 0,
|
|
3045
3112
|
text: void 0,
|
|
3046
3113
|
reasoning: (_f = (_e = response.usage.completion_tokens_details) == null ? void 0 : _e.reasoning_tokens) != null ? _f : void 0
|
|
3047
|
-
}
|
|
3114
|
+
},
|
|
3115
|
+
raw: response.usage
|
|
3048
3116
|
} : {
|
|
3049
3117
|
inputTokens: {
|
|
3050
3118
|
total: 0,
|
|
@@ -3056,7 +3124,8 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3056
3124
|
total: 0,
|
|
3057
3125
|
text: void 0,
|
|
3058
3126
|
reasoning: void 0
|
|
3059
|
-
}
|
|
3127
|
+
},
|
|
3128
|
+
raw: void 0
|
|
3060
3129
|
};
|
|
3061
3130
|
const reasoningDetails = (_g = choice.message.reasoning_details) != null ? _g : [];
|
|
3062
3131
|
const reasoning = reasoningDetails.length > 0 ? reasoningDetails.map((detail) => {
|
|
@@ -3156,17 +3225,19 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3156
3225
|
sourceType: "url",
|
|
3157
3226
|
id: annotation.url_citation.url,
|
|
3158
3227
|
url: annotation.url_citation.url,
|
|
3159
|
-
title: annotation.url_citation.title,
|
|
3228
|
+
title: (_j = annotation.url_citation.title) != null ? _j : "",
|
|
3160
3229
|
providerMetadata: {
|
|
3161
3230
|
openrouter: {
|
|
3162
|
-
content: annotation.url_citation.content
|
|
3231
|
+
content: (_k = annotation.url_citation.content) != null ? _k : "",
|
|
3232
|
+
startIndex: (_l = annotation.url_citation.start_index) != null ? _l : 0,
|
|
3233
|
+
endIndex: (_m = annotation.url_citation.end_index) != null ? _m : 0
|
|
3163
3234
|
}
|
|
3164
3235
|
}
|
|
3165
3236
|
});
|
|
3166
3237
|
}
|
|
3167
3238
|
}
|
|
3168
3239
|
}
|
|
3169
|
-
const fileAnnotations = (
|
|
3240
|
+
const fileAnnotations = (_n = choice.message.annotations) == null ? void 0 : _n.filter(
|
|
3170
3241
|
(a) => a.type === "file"
|
|
3171
3242
|
);
|
|
3172
3243
|
const hasToolCalls = choice.message.tool_calls && choice.message.tool_calls.length > 0;
|
|
@@ -3174,7 +3245,7 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3174
3245
|
(d) => d.type === "reasoning.encrypted" /* Encrypted */ && d.data
|
|
3175
3246
|
);
|
|
3176
3247
|
const shouldOverrideFinishReason = hasToolCalls && hasEncryptedReasoning && choice.finish_reason === "stop";
|
|
3177
|
-
const effectiveFinishReason = shouldOverrideFinishReason ? createFinishReason("tool-calls", (
|
|
3248
|
+
const effectiveFinishReason = shouldOverrideFinishReason ? createFinishReason("tool-calls", (_o = choice.finish_reason) != null ? _o : void 0) : mapOpenRouterFinishReason(choice.finish_reason);
|
|
3178
3249
|
return {
|
|
3179
3250
|
content,
|
|
3180
3251
|
finishReason: effectiveFinishReason,
|
|
@@ -3182,23 +3253,22 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3182
3253
|
warnings: [],
|
|
3183
3254
|
providerMetadata: {
|
|
3184
3255
|
openrouter: OpenRouterProviderMetadataSchema.parse({
|
|
3185
|
-
provider: (
|
|
3186
|
-
reasoning_details: (
|
|
3256
|
+
provider: (_p = response.provider) != null ? _p : "",
|
|
3257
|
+
reasoning_details: (_q = choice.message.reasoning_details) != null ? _q : [],
|
|
3187
3258
|
annotations: fileAnnotations && fileAnnotations.length > 0 ? fileAnnotations : void 0,
|
|
3188
|
-
usage: __spreadValues(__spreadValues(__spreadValues({
|
|
3189
|
-
promptTokens: (
|
|
3190
|
-
completionTokens: (
|
|
3191
|
-
totalTokens: ((
|
|
3192
|
-
|
|
3193
|
-
}, ((_t = (_s = response.usage) == null ? void 0 : _s.prompt_tokens_details) == null ? void 0 : _t.cached_tokens) != null ? {
|
|
3259
|
+
usage: __spreadValues(__spreadValues(__spreadValues(__spreadValues({
|
|
3260
|
+
promptTokens: (_r = usageInfo.inputTokens.total) != null ? _r : 0,
|
|
3261
|
+
completionTokens: (_s = usageInfo.outputTokens.total) != null ? _s : 0,
|
|
3262
|
+
totalTokens: ((_t = usageInfo.inputTokens.total) != null ? _t : 0) + ((_u = usageInfo.outputTokens.total) != null ? _u : 0)
|
|
3263
|
+
}, ((_v = response.usage) == null ? void 0 : _v.cost) != null ? { cost: response.usage.cost } : {}), ((_x = (_w = response.usage) == null ? void 0 : _w.prompt_tokens_details) == null ? void 0 : _x.cached_tokens) != null ? {
|
|
3194
3264
|
promptTokensDetails: {
|
|
3195
3265
|
cachedTokens: response.usage.prompt_tokens_details.cached_tokens
|
|
3196
3266
|
}
|
|
3197
|
-
} : {}), ((
|
|
3267
|
+
} : {}), ((_z = (_y = response.usage) == null ? void 0 : _y.completion_tokens_details) == null ? void 0 : _z.reasoning_tokens) != null ? {
|
|
3198
3268
|
completionTokensDetails: {
|
|
3199
3269
|
reasoningTokens: response.usage.completion_tokens_details.reasoning_tokens
|
|
3200
3270
|
}
|
|
3201
|
-
} : {}), ((
|
|
3271
|
+
} : {}), ((_B = (_A = response.usage) == null ? void 0 : _A.cost_details) == null ? void 0 : _B.upstream_inference_cost) != null ? {
|
|
3202
3272
|
costDetails: {
|
|
3203
3273
|
upstreamInferenceCost: response.usage.cost_details.upstream_inference_cost
|
|
3204
3274
|
}
|
|
@@ -3251,9 +3321,11 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3251
3321
|
total: void 0,
|
|
3252
3322
|
text: void 0,
|
|
3253
3323
|
reasoning: void 0
|
|
3254
|
-
}
|
|
3324
|
+
},
|
|
3325
|
+
raw: void 0
|
|
3255
3326
|
};
|
|
3256
3327
|
const openrouterUsage = {};
|
|
3328
|
+
let rawUsage;
|
|
3257
3329
|
const accumulatedReasoningDetails = [];
|
|
3258
3330
|
let reasoningDetailsAttachedToToolCall = false;
|
|
3259
3331
|
const accumulatedFileAnnotations = [];
|
|
@@ -3267,7 +3339,10 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3267
3339
|
stream: response.pipeThrough(
|
|
3268
3340
|
new TransformStream({
|
|
3269
3341
|
transform(chunk, controller) {
|
|
3270
|
-
var _a17, _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
|
|
3342
|
+
var _a17, _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
|
|
3343
|
+
if (options.includeRawChunks) {
|
|
3344
|
+
controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
|
|
3345
|
+
}
|
|
3271
3346
|
if (!chunk.success) {
|
|
3272
3347
|
finishReason = createFinishReason("error");
|
|
3273
3348
|
controller.enqueue({ type: "error", error: chunk.error });
|
|
@@ -3298,6 +3373,7 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3298
3373
|
if (value.usage != null) {
|
|
3299
3374
|
usage.inputTokens.total = value.usage.prompt_tokens;
|
|
3300
3375
|
usage.outputTokens.total = value.usage.completion_tokens;
|
|
3376
|
+
rawUsage = value.usage;
|
|
3301
3377
|
openrouterUsage.promptTokens = value.usage.prompt_tokens;
|
|
3302
3378
|
if (value.usage.prompt_tokens_details) {
|
|
3303
3379
|
const cachedInputTokens = (_a17 = value.usage.prompt_tokens_details.cached_tokens) != null ? _a17 : 0;
|
|
@@ -3314,7 +3390,9 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3314
3390
|
reasoningTokens
|
|
3315
3391
|
};
|
|
3316
3392
|
}
|
|
3317
|
-
|
|
3393
|
+
if (value.usage.cost != null) {
|
|
3394
|
+
openrouterUsage.cost = value.usage.cost;
|
|
3395
|
+
}
|
|
3318
3396
|
openrouterUsage.totalTokens = value.usage.total_tokens;
|
|
3319
3397
|
const upstreamInferenceCost = (_c = value.usage.cost_details) == null ? void 0 : _c.upstream_inference_cost;
|
|
3320
3398
|
if (upstreamInferenceCost != null) {
|
|
@@ -3427,10 +3505,12 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3427
3505
|
sourceType: "url",
|
|
3428
3506
|
id: annotation.url_citation.url,
|
|
3429
3507
|
url: annotation.url_citation.url,
|
|
3430
|
-
title: annotation.url_citation.title,
|
|
3508
|
+
title: (_d = annotation.url_citation.title) != null ? _d : "",
|
|
3431
3509
|
providerMetadata: {
|
|
3432
3510
|
openrouter: {
|
|
3433
|
-
content: annotation.url_citation.content
|
|
3511
|
+
content: (_e = annotation.url_citation.content) != null ? _e : "",
|
|
3512
|
+
startIndex: (_f = annotation.url_citation.start_index) != null ? _f : 0,
|
|
3513
|
+
endIndex: (_g = annotation.url_citation.end_index) != null ? _g : 0
|
|
3434
3514
|
}
|
|
3435
3515
|
}
|
|
3436
3516
|
});
|
|
@@ -3446,7 +3526,7 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3446
3526
|
}
|
|
3447
3527
|
if (delta.tool_calls != null) {
|
|
3448
3528
|
for (const toolCallDelta of delta.tool_calls) {
|
|
3449
|
-
const index = (
|
|
3529
|
+
const index = (_h = toolCallDelta.index) != null ? _h : toolCalls.length - 1;
|
|
3450
3530
|
if (toolCalls[index] == null) {
|
|
3451
3531
|
if (toolCallDelta.type !== "function") {
|
|
3452
3532
|
throw new InvalidResponseDataError({
|
|
@@ -3460,7 +3540,7 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3460
3540
|
message: `Expected 'id' to be a string.`
|
|
3461
3541
|
});
|
|
3462
3542
|
}
|
|
3463
|
-
if (((
|
|
3543
|
+
if (((_i = toolCallDelta.function) == null ? void 0 : _i.name) == null) {
|
|
3464
3544
|
throw new InvalidResponseDataError({
|
|
3465
3545
|
data: toolCallDelta,
|
|
3466
3546
|
message: `Expected 'function.name' to be a string.`
|
|
@@ -3471,7 +3551,7 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3471
3551
|
type: "function",
|
|
3472
3552
|
function: {
|
|
3473
3553
|
name: toolCallDelta.function.name,
|
|
3474
|
-
arguments: (
|
|
3554
|
+
arguments: (_j = toolCallDelta.function.arguments) != null ? _j : ""
|
|
3475
3555
|
},
|
|
3476
3556
|
inputStarted: false,
|
|
3477
3557
|
sent: false
|
|
@@ -3483,7 +3563,7 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3483
3563
|
message: `Tool call at index ${index} is missing after creation.`
|
|
3484
3564
|
});
|
|
3485
3565
|
}
|
|
3486
|
-
if (((
|
|
3566
|
+
if (((_k = toolCall2.function) == null ? void 0 : _k.name) != null && ((_l = toolCall2.function) == null ? void 0 : _l.arguments) != null && isParsableJson(toolCall2.function.arguments)) {
|
|
3487
3567
|
toolCall2.inputStarted = true;
|
|
3488
3568
|
controller.enqueue({
|
|
3489
3569
|
type: "tool-input-start",
|
|
@@ -3534,18 +3614,18 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3534
3614
|
toolName: toolCall.function.name
|
|
3535
3615
|
});
|
|
3536
3616
|
}
|
|
3537
|
-
if (((
|
|
3538
|
-
toolCall.function.arguments += (
|
|
3617
|
+
if (((_m = toolCallDelta.function) == null ? void 0 : _m.arguments) != null) {
|
|
3618
|
+
toolCall.function.arguments += (_o = (_n = toolCallDelta.function) == null ? void 0 : _n.arguments) != null ? _o : "";
|
|
3539
3619
|
}
|
|
3540
3620
|
controller.enqueue({
|
|
3541
3621
|
type: "tool-input-delta",
|
|
3542
3622
|
id: toolCall.id,
|
|
3543
|
-
delta: (
|
|
3623
|
+
delta: (_p = toolCallDelta.function.arguments) != null ? _p : ""
|
|
3544
3624
|
});
|
|
3545
|
-
if (((
|
|
3625
|
+
if (((_q = toolCall.function) == null ? void 0 : _q.name) != null && ((_r = toolCall.function) == null ? void 0 : _r.arguments) != null && isParsableJson(toolCall.function.arguments)) {
|
|
3546
3626
|
controller.enqueue({
|
|
3547
3627
|
type: "tool-call",
|
|
3548
|
-
toolCallId: (
|
|
3628
|
+
toolCallId: (_s = toolCall.id) != null ? _s : generateId(),
|
|
3549
3629
|
toolName: toolCall.function.name,
|
|
3550
3630
|
input: toolCall.function.arguments,
|
|
3551
3631
|
providerMetadata: !reasoningDetailsAttachedToToolCall ? {
|
|
@@ -3622,6 +3702,7 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3622
3702
|
if (accumulatedFileAnnotations.length > 0) {
|
|
3623
3703
|
openrouterMetadata.annotations = accumulatedFileAnnotations;
|
|
3624
3704
|
}
|
|
3705
|
+
usage.raw = rawUsage;
|
|
3625
3706
|
controller.enqueue({
|
|
3626
3707
|
type: "finish",
|
|
3627
3708
|
finishReason,
|
|
@@ -3749,6 +3830,7 @@ var OpenRouterCompletionChunkSchema = z8.union([
|
|
|
3749
3830
|
z8.object({
|
|
3750
3831
|
id: z8.string().optional(),
|
|
3751
3832
|
model: z8.string().optional(),
|
|
3833
|
+
provider: z8.string().optional(),
|
|
3752
3834
|
choices: z8.array(
|
|
3753
3835
|
z8.object({
|
|
3754
3836
|
text: z8.string(),
|
|
@@ -3856,7 +3938,7 @@ var OpenRouterCompletionLanguageModel = class {
|
|
|
3856
3938
|
}, this.config.extraBody), this.settings.extraBody);
|
|
3857
3939
|
}
|
|
3858
3940
|
async doGenerate(options) {
|
|
3859
|
-
var _a16, _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
3941
|
+
var _a16, _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B;
|
|
3860
3942
|
const providerOptions = options.providerOptions || {};
|
|
3861
3943
|
const openrouterOptions = providerOptions.openrouter || {};
|
|
3862
3944
|
const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
|
|
@@ -3913,9 +3995,32 @@ var OpenRouterCompletionLanguageModel = class {
|
|
|
3913
3995
|
total: (_h = (_g = response.usage) == null ? void 0 : _g.completion_tokens) != null ? _h : 0,
|
|
3914
3996
|
text: void 0,
|
|
3915
3997
|
reasoning: (_k = (_j = (_i = response.usage) == null ? void 0 : _i.completion_tokens_details) == null ? void 0 : _j.reasoning_tokens) != null ? _k : void 0
|
|
3916
|
-
}
|
|
3998
|
+
},
|
|
3999
|
+
raw: (_l = response.usage) != null ? _l : void 0
|
|
3917
4000
|
},
|
|
3918
4001
|
warnings: [],
|
|
4002
|
+
providerMetadata: {
|
|
4003
|
+
openrouter: OpenRouterProviderMetadataSchema.parse({
|
|
4004
|
+
provider: (_m = response.provider) != null ? _m : "",
|
|
4005
|
+
usage: __spreadValues(__spreadValues(__spreadValues(__spreadValues({
|
|
4006
|
+
promptTokens: (_o = (_n = response.usage) == null ? void 0 : _n.prompt_tokens) != null ? _o : 0,
|
|
4007
|
+
completionTokens: (_q = (_p = response.usage) == null ? void 0 : _p.completion_tokens) != null ? _q : 0,
|
|
4008
|
+
totalTokens: ((_s = (_r = response.usage) == null ? void 0 : _r.prompt_tokens) != null ? _s : 0) + ((_u = (_t = response.usage) == null ? void 0 : _t.completion_tokens) != null ? _u : 0)
|
|
4009
|
+
}, ((_v = response.usage) == null ? void 0 : _v.cost) != null ? { cost: response.usage.cost } : {}), ((_x = (_w = response.usage) == null ? void 0 : _w.prompt_tokens_details) == null ? void 0 : _x.cached_tokens) != null ? {
|
|
4010
|
+
promptTokensDetails: {
|
|
4011
|
+
cachedTokens: response.usage.prompt_tokens_details.cached_tokens
|
|
4012
|
+
}
|
|
4013
|
+
} : {}), ((_z = (_y = response.usage) == null ? void 0 : _y.completion_tokens_details) == null ? void 0 : _z.reasoning_tokens) != null ? {
|
|
4014
|
+
completionTokensDetails: {
|
|
4015
|
+
reasoningTokens: response.usage.completion_tokens_details.reasoning_tokens
|
|
4016
|
+
}
|
|
4017
|
+
} : {}), ((_B = (_A = response.usage) == null ? void 0 : _A.cost_details) == null ? void 0 : _B.upstream_inference_cost) != null ? {
|
|
4018
|
+
costDetails: {
|
|
4019
|
+
upstreamInferenceCost: response.usage.cost_details.upstream_inference_cost
|
|
4020
|
+
}
|
|
4021
|
+
} : {})
|
|
4022
|
+
})
|
|
4023
|
+
},
|
|
3919
4024
|
response: {
|
|
3920
4025
|
headers: responseHeaders
|
|
3921
4026
|
}
|
|
@@ -3955,14 +4060,20 @@ var OpenRouterCompletionLanguageModel = class {
|
|
|
3955
4060
|
total: void 0,
|
|
3956
4061
|
text: void 0,
|
|
3957
4062
|
reasoning: void 0
|
|
3958
|
-
}
|
|
4063
|
+
},
|
|
4064
|
+
raw: void 0
|
|
3959
4065
|
};
|
|
3960
4066
|
const openrouterUsage = {};
|
|
4067
|
+
let provider;
|
|
4068
|
+
let rawUsage;
|
|
3961
4069
|
return {
|
|
3962
4070
|
stream: response.pipeThrough(
|
|
3963
4071
|
new TransformStream({
|
|
3964
4072
|
transform(chunk, controller) {
|
|
3965
4073
|
var _a16, _b16, _c;
|
|
4074
|
+
if (options.includeRawChunks) {
|
|
4075
|
+
controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
|
|
4076
|
+
}
|
|
3966
4077
|
if (!chunk.success) {
|
|
3967
4078
|
finishReason = createFinishReason("error");
|
|
3968
4079
|
controller.enqueue({ type: "error", error: chunk.error });
|
|
@@ -3974,9 +4085,13 @@ var OpenRouterCompletionLanguageModel = class {
|
|
|
3974
4085
|
controller.enqueue({ type: "error", error: value.error });
|
|
3975
4086
|
return;
|
|
3976
4087
|
}
|
|
4088
|
+
if (value.provider) {
|
|
4089
|
+
provider = value.provider;
|
|
4090
|
+
}
|
|
3977
4091
|
if (value.usage != null) {
|
|
3978
4092
|
usage.inputTokens.total = value.usage.prompt_tokens;
|
|
3979
4093
|
usage.outputTokens.total = value.usage.completion_tokens;
|
|
4094
|
+
rawUsage = value.usage;
|
|
3980
4095
|
openrouterUsage.promptTokens = value.usage.prompt_tokens;
|
|
3981
4096
|
if (value.usage.prompt_tokens_details) {
|
|
3982
4097
|
const cachedInputTokens = (_a16 = value.usage.prompt_tokens_details.cached_tokens) != null ? _a16 : 0;
|
|
@@ -3993,7 +4108,9 @@ var OpenRouterCompletionLanguageModel = class {
|
|
|
3993
4108
|
reasoningTokens
|
|
3994
4109
|
};
|
|
3995
4110
|
}
|
|
3996
|
-
|
|
4111
|
+
if (value.usage.cost != null) {
|
|
4112
|
+
openrouterUsage.cost = value.usage.cost;
|
|
4113
|
+
}
|
|
3997
4114
|
openrouterUsage.totalTokens = value.usage.total_tokens;
|
|
3998
4115
|
const upstreamInferenceCost = (_c = value.usage.cost_details) == null ? void 0 : _c.upstream_inference_cost;
|
|
3999
4116
|
if (upstreamInferenceCost != null) {
|
|
@@ -4015,14 +4132,19 @@ var OpenRouterCompletionLanguageModel = class {
|
|
|
4015
4132
|
}
|
|
4016
4133
|
},
|
|
4017
4134
|
flush(controller) {
|
|
4135
|
+
usage.raw = rawUsage;
|
|
4136
|
+
const openrouterMetadata = {
|
|
4137
|
+
usage: openrouterUsage
|
|
4138
|
+
};
|
|
4139
|
+
if (provider !== void 0) {
|
|
4140
|
+
openrouterMetadata.provider = provider;
|
|
4141
|
+
}
|
|
4018
4142
|
controller.enqueue({
|
|
4019
4143
|
type: "finish",
|
|
4020
4144
|
finishReason,
|
|
4021
4145
|
usage,
|
|
4022
4146
|
providerMetadata: {
|
|
4023
|
-
openrouter:
|
|
4024
|
-
usage: openrouterUsage
|
|
4025
|
-
}
|
|
4147
|
+
openrouter: openrouterMetadata
|
|
4026
4148
|
}
|
|
4027
4149
|
});
|
|
4028
4150
|
}
|
|
@@ -4052,6 +4174,7 @@ var OpenRouterEmbeddingResponseSchema = z9.object({
|
|
|
4052
4174
|
object: z9.literal("list"),
|
|
4053
4175
|
data: z9.array(openrouterEmbeddingDataSchema),
|
|
4054
4176
|
model: z9.string(),
|
|
4177
|
+
provider: z9.string().optional(),
|
|
4055
4178
|
usage: openrouterEmbeddingUsageSchema.optional()
|
|
4056
4179
|
});
|
|
4057
4180
|
|
|
@@ -4067,7 +4190,7 @@ var OpenRouterEmbeddingModel = class {
|
|
|
4067
4190
|
this.config = config;
|
|
4068
4191
|
}
|
|
4069
4192
|
async doEmbed(options) {
|
|
4070
|
-
var _a16;
|
|
4193
|
+
var _a16, _b16, _c, _d, _e, _f;
|
|
4071
4194
|
const { values, abortSignal, headers } = options;
|
|
4072
4195
|
const args = __spreadValues(__spreadValues({
|
|
4073
4196
|
model: this.modelId,
|
|
@@ -4092,13 +4215,16 @@ var OpenRouterEmbeddingModel = class {
|
|
|
4092
4215
|
return {
|
|
4093
4216
|
embeddings: responseValue.data.map((item) => item.embedding),
|
|
4094
4217
|
usage: responseValue.usage ? { tokens: responseValue.usage.prompt_tokens } : void 0,
|
|
4095
|
-
providerMetadata:
|
|
4096
|
-
openrouter: {
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4218
|
+
providerMetadata: {
|
|
4219
|
+
openrouter: OpenRouterProviderMetadataSchema.parse({
|
|
4220
|
+
provider: (_a16 = responseValue.provider) != null ? _a16 : "",
|
|
4221
|
+
usage: __spreadValues({
|
|
4222
|
+
promptTokens: (_c = (_b16 = responseValue.usage) == null ? void 0 : _b16.prompt_tokens) != null ? _c : 0,
|
|
4223
|
+
completionTokens: 0,
|
|
4224
|
+
totalTokens: (_e = (_d = responseValue.usage) == null ? void 0 : _d.total_tokens) != null ? _e : 0
|
|
4225
|
+
}, ((_f = responseValue.usage) == null ? void 0 : _f.cost) != null ? { cost: responseValue.usage.cost } : {})
|
|
4226
|
+
})
|
|
4227
|
+
},
|
|
4102
4228
|
response: {
|
|
4103
4229
|
headers: responseHeaders,
|
|
4104
4230
|
body: responseValue
|
|
@@ -4165,27 +4291,188 @@ var OpenRouter = class {
|
|
|
4165
4291
|
}
|
|
4166
4292
|
};
|
|
4167
4293
|
|
|
4294
|
+
// src/image/schemas.ts
|
|
4295
|
+
import { z as z10 } from "zod/v4";
|
|
4296
|
+
var OpenRouterImageResponseSchema = z10.object({
|
|
4297
|
+
id: z10.string().optional(),
|
|
4298
|
+
object: z10.string().optional(),
|
|
4299
|
+
created: z10.number().optional(),
|
|
4300
|
+
model: z10.string(),
|
|
4301
|
+
choices: z10.array(
|
|
4302
|
+
z10.object({
|
|
4303
|
+
index: z10.number(),
|
|
4304
|
+
message: z10.object({
|
|
4305
|
+
role: z10.string(),
|
|
4306
|
+
content: z10.string().nullable().optional(),
|
|
4307
|
+
images: z10.array(
|
|
4308
|
+
z10.object({
|
|
4309
|
+
type: z10.literal("image_url"),
|
|
4310
|
+
image_url: z10.object({
|
|
4311
|
+
url: z10.string()
|
|
4312
|
+
})
|
|
4313
|
+
}).passthrough()
|
|
4314
|
+
).optional()
|
|
4315
|
+
}).passthrough(),
|
|
4316
|
+
finish_reason: z10.string().nullable().optional()
|
|
4317
|
+
}).passthrough()
|
|
4318
|
+
),
|
|
4319
|
+
usage: z10.object({
|
|
4320
|
+
prompt_tokens: z10.number(),
|
|
4321
|
+
completion_tokens: z10.number(),
|
|
4322
|
+
total_tokens: z10.number()
|
|
4323
|
+
}).passthrough().optional()
|
|
4324
|
+
}).passthrough();
|
|
4325
|
+
|
|
4326
|
+
// src/image/index.ts
|
|
4327
|
+
var OpenRouterImageModel = class {
|
|
4328
|
+
constructor(modelId, settings, config) {
|
|
4329
|
+
this.specificationVersion = "v3";
|
|
4330
|
+
this.provider = "openrouter";
|
|
4331
|
+
this.maxImagesPerCall = 1;
|
|
4332
|
+
this.modelId = modelId;
|
|
4333
|
+
this.settings = settings;
|
|
4334
|
+
this.config = config;
|
|
4335
|
+
}
|
|
4336
|
+
async doGenerate(options) {
|
|
4337
|
+
var _a16;
|
|
4338
|
+
const {
|
|
4339
|
+
prompt,
|
|
4340
|
+
n,
|
|
4341
|
+
size,
|
|
4342
|
+
aspectRatio,
|
|
4343
|
+
seed,
|
|
4344
|
+
files,
|
|
4345
|
+
mask,
|
|
4346
|
+
abortSignal,
|
|
4347
|
+
headers,
|
|
4348
|
+
providerOptions
|
|
4349
|
+
} = options;
|
|
4350
|
+
const openrouterOptions = (providerOptions == null ? void 0 : providerOptions.openrouter) || {};
|
|
4351
|
+
const warnings = [];
|
|
4352
|
+
if (files !== void 0 && files.length > 0) {
|
|
4353
|
+
throw new UnsupportedFunctionalityError({
|
|
4354
|
+
functionality: "image editing (files parameter)"
|
|
4355
|
+
});
|
|
4356
|
+
}
|
|
4357
|
+
if (mask !== void 0) {
|
|
4358
|
+
throw new UnsupportedFunctionalityError({
|
|
4359
|
+
functionality: "image inpainting (mask parameter)"
|
|
4360
|
+
});
|
|
4361
|
+
}
|
|
4362
|
+
if (n > 1) {
|
|
4363
|
+
warnings.push({
|
|
4364
|
+
type: "unsupported",
|
|
4365
|
+
feature: "n > 1",
|
|
4366
|
+
details: `OpenRouter image generation returns 1 image per call. Requested ${n} images.`
|
|
4367
|
+
});
|
|
4368
|
+
}
|
|
4369
|
+
if (size !== void 0) {
|
|
4370
|
+
warnings.push({
|
|
4371
|
+
type: "unsupported",
|
|
4372
|
+
feature: "size",
|
|
4373
|
+
details: "Use aspectRatio instead. Size parameter is not supported by OpenRouter image generation."
|
|
4374
|
+
});
|
|
4375
|
+
}
|
|
4376
|
+
const imageConfig = aspectRatio !== void 0 ? { aspect_ratio: aspectRatio } : void 0;
|
|
4377
|
+
const body = __spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({
|
|
4378
|
+
model: this.modelId,
|
|
4379
|
+
messages: [
|
|
4380
|
+
{
|
|
4381
|
+
role: "user",
|
|
4382
|
+
content: prompt != null ? prompt : ""
|
|
4383
|
+
}
|
|
4384
|
+
],
|
|
4385
|
+
modalities: ["image", "text"]
|
|
4386
|
+
}, imageConfig !== void 0 && { image_config: imageConfig }), seed !== void 0 && { seed }), this.settings.user !== void 0 && { user: this.settings.user }), this.settings.provider !== void 0 && {
|
|
4387
|
+
provider: this.settings.provider
|
|
4388
|
+
}), this.config.extraBody), this.settings.extraBody), openrouterOptions);
|
|
4389
|
+
const { value: responseValue, responseHeaders } = await postJsonToApi({
|
|
4390
|
+
url: this.config.url({
|
|
4391
|
+
path: "/chat/completions",
|
|
4392
|
+
modelId: this.modelId
|
|
4393
|
+
}),
|
|
4394
|
+
headers: combineHeaders(this.config.headers(), headers),
|
|
4395
|
+
body,
|
|
4396
|
+
failedResponseHandler: openrouterFailedResponseHandler,
|
|
4397
|
+
successfulResponseHandler: createJsonResponseHandler(
|
|
4398
|
+
OpenRouterImageResponseSchema
|
|
4399
|
+
),
|
|
4400
|
+
abortSignal,
|
|
4401
|
+
fetch: this.config.fetch
|
|
4402
|
+
});
|
|
4403
|
+
const choice = responseValue.choices[0];
|
|
4404
|
+
if (!choice) {
|
|
4405
|
+
throw new NoContentGeneratedError({
|
|
4406
|
+
message: "No choice in response"
|
|
4407
|
+
});
|
|
4408
|
+
}
|
|
4409
|
+
const images = [];
|
|
4410
|
+
if ((_a16 = choice.message) == null ? void 0 : _a16.images) {
|
|
4411
|
+
for (const image of choice.message.images) {
|
|
4412
|
+
const dataUrl = image.image_url.url;
|
|
4413
|
+
images.push(getBase64FromDataUrl(dataUrl));
|
|
4414
|
+
}
|
|
4415
|
+
}
|
|
4416
|
+
const usage = responseValue.usage ? {
|
|
4417
|
+
inputTokens: responseValue.usage.prompt_tokens,
|
|
4418
|
+
outputTokens: responseValue.usage.completion_tokens,
|
|
4419
|
+
totalTokens: responseValue.usage.total_tokens
|
|
4420
|
+
} : void 0;
|
|
4421
|
+
return {
|
|
4422
|
+
images,
|
|
4423
|
+
warnings,
|
|
4424
|
+
response: {
|
|
4425
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
4426
|
+
modelId: responseValue.model,
|
|
4427
|
+
headers: responseHeaders
|
|
4428
|
+
},
|
|
4429
|
+
usage
|
|
4430
|
+
};
|
|
4431
|
+
}
|
|
4432
|
+
};
|
|
4433
|
+
|
|
4168
4434
|
// src/utils/remove-undefined.ts
|
|
4169
4435
|
function removeUndefinedEntries(record) {
|
|
4170
4436
|
return Object.fromEntries(
|
|
4171
|
-
Object.entries(record).filter(([, value]) => value
|
|
4437
|
+
Object.entries(record).filter(([, value]) => value != null)
|
|
4172
4438
|
);
|
|
4173
4439
|
}
|
|
4174
4440
|
|
|
4175
4441
|
// src/utils/with-user-agent-suffix.ts
|
|
4442
|
+
function normalizeHeaders2(headers) {
|
|
4443
|
+
if (!headers) {
|
|
4444
|
+
return {};
|
|
4445
|
+
}
|
|
4446
|
+
if (headers instanceof Headers) {
|
|
4447
|
+
return Object.fromEntries(headers.entries());
|
|
4448
|
+
}
|
|
4449
|
+
if (Array.isArray(headers)) {
|
|
4450
|
+
return Object.fromEntries(headers);
|
|
4451
|
+
}
|
|
4452
|
+
return headers;
|
|
4453
|
+
}
|
|
4454
|
+
function findHeaderKey(headers, targetKey) {
|
|
4455
|
+
const lowerTarget = targetKey.toLowerCase();
|
|
4456
|
+
return Object.keys(headers).find((key) => key.toLowerCase() === lowerTarget);
|
|
4457
|
+
}
|
|
4176
4458
|
function withUserAgentSuffix2(headers, ...userAgentSuffixParts) {
|
|
4177
|
-
const
|
|
4178
|
-
|
|
4459
|
+
const normalizedHeaders = normalizeHeaders2(headers);
|
|
4460
|
+
const cleanedHeaders = removeUndefinedEntries(normalizedHeaders);
|
|
4461
|
+
const existingUserAgentKey = findHeaderKey(cleanedHeaders, "user-agent");
|
|
4462
|
+
const existingUserAgentValue = existingUserAgentKey ? cleanedHeaders[existingUserAgentKey] : void 0;
|
|
4463
|
+
const userAgent = (existingUserAgentValue == null ? void 0 : existingUserAgentValue.trim()) ? existingUserAgentValue : userAgentSuffixParts.filter(Boolean).join(" ");
|
|
4464
|
+
const headersWithoutUserAgent = Object.fromEntries(
|
|
4465
|
+
Object.entries(cleanedHeaders).filter(
|
|
4466
|
+
([key]) => key.toLowerCase() !== "user-agent"
|
|
4467
|
+
)
|
|
4179
4468
|
);
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
return __spreadProps(__spreadValues({}, cleanedHeaders), {
|
|
4183
|
-
"user-agent": newUserAgent
|
|
4469
|
+
return __spreadProps(__spreadValues({}, headersWithoutUserAgent), {
|
|
4470
|
+
"user-agent": userAgent
|
|
4184
4471
|
});
|
|
4185
4472
|
}
|
|
4186
4473
|
|
|
4187
4474
|
// src/version.ts
|
|
4188
|
-
var VERSION2 = false ? "0.0.0-test" : "2.
|
|
4475
|
+
var VERSION2 = false ? "0.0.0-test" : "2.1.1";
|
|
4189
4476
|
|
|
4190
4477
|
// src/provider.ts
|
|
4191
4478
|
function createOpenRouter(options = {}) {
|
|
@@ -4227,6 +4514,13 @@ function createOpenRouter(options = {}) {
|
|
|
4227
4514
|
fetch: options.fetch,
|
|
4228
4515
|
extraBody: options.extraBody
|
|
4229
4516
|
});
|
|
4517
|
+
const createImageModel = (modelId, settings = {}) => new OpenRouterImageModel(modelId, settings, {
|
|
4518
|
+
provider: "openrouter.image",
|
|
4519
|
+
url: ({ path }) => `${baseURL}${path}`,
|
|
4520
|
+
headers: getHeaders,
|
|
4521
|
+
fetch: options.fetch,
|
|
4522
|
+
extraBody: options.extraBody
|
|
4523
|
+
});
|
|
4230
4524
|
const createLanguageModel = (modelId, settings) => {
|
|
4231
4525
|
if (new.target) {
|
|
4232
4526
|
throw new Error(
|
|
@@ -4247,6 +4541,7 @@ function createOpenRouter(options = {}) {
|
|
|
4247
4541
|
provider.completion = createCompletionModel;
|
|
4248
4542
|
provider.textEmbeddingModel = createEmbeddingModel;
|
|
4249
4543
|
provider.embedding = createEmbeddingModel;
|
|
4544
|
+
provider.imageModel = createImageModel;
|
|
4250
4545
|
return provider;
|
|
4251
4546
|
}
|
|
4252
4547
|
var openrouter = createOpenRouter({
|