@openrouter/ai-sdk-provider 2.5.0 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +25 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +149 -46
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +149 -46
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.js +94 -45
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +94 -45
- package/dist/internal/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2076,6 +2076,46 @@ var postToApi = async ({
|
|
|
2076
2076
|
throw handleFetchError({ error, url, requestBodyValues: body.values });
|
|
2077
2077
|
}
|
|
2078
2078
|
};
|
|
2079
|
+
function tool(tool2) {
|
|
2080
|
+
return tool2;
|
|
2081
|
+
}
|
|
2082
|
+
function createProviderToolFactory({
|
|
2083
|
+
id,
|
|
2084
|
+
inputSchema
|
|
2085
|
+
}) {
|
|
2086
|
+
return (_a16) => {
|
|
2087
|
+
var _b16 = _a16, {
|
|
2088
|
+
execute,
|
|
2089
|
+
outputSchema,
|
|
2090
|
+
needsApproval,
|
|
2091
|
+
toModelOutput,
|
|
2092
|
+
onInputStart,
|
|
2093
|
+
onInputDelta,
|
|
2094
|
+
onInputAvailable
|
|
2095
|
+
} = _b16, args = __objRest(_b16, [
|
|
2096
|
+
"execute",
|
|
2097
|
+
"outputSchema",
|
|
2098
|
+
"needsApproval",
|
|
2099
|
+
"toModelOutput",
|
|
2100
|
+
"onInputStart",
|
|
2101
|
+
"onInputDelta",
|
|
2102
|
+
"onInputAvailable"
|
|
2103
|
+
]);
|
|
2104
|
+
return tool({
|
|
2105
|
+
type: "provider",
|
|
2106
|
+
id,
|
|
2107
|
+
args,
|
|
2108
|
+
inputSchema,
|
|
2109
|
+
outputSchema,
|
|
2110
|
+
execute,
|
|
2111
|
+
needsApproval,
|
|
2112
|
+
toModelOutput,
|
|
2113
|
+
onInputStart,
|
|
2114
|
+
onInputDelta,
|
|
2115
|
+
onInputAvailable
|
|
2116
|
+
});
|
|
2117
|
+
};
|
|
2118
|
+
}
|
|
2079
2119
|
var createJsonErrorResponseHandler = ({
|
|
2080
2120
|
errorSchema,
|
|
2081
2121
|
errorToMessage,
|
|
@@ -2442,6 +2482,29 @@ function withStreamErrorHandling(source, onError) {
|
|
|
2442
2482
|
});
|
|
2443
2483
|
}
|
|
2444
2484
|
|
|
2485
|
+
// src/utils/deterministic-stringify.ts
|
|
2486
|
+
function deterministicStringify(value) {
|
|
2487
|
+
return JSON.stringify(sortKeys(value));
|
|
2488
|
+
}
|
|
2489
|
+
function sortKeys(value) {
|
|
2490
|
+
if (value === null || value === void 0) {
|
|
2491
|
+
return value;
|
|
2492
|
+
}
|
|
2493
|
+
if (Array.isArray(value)) {
|
|
2494
|
+
return value.map(sortKeys);
|
|
2495
|
+
}
|
|
2496
|
+
if (typeof value === "object") {
|
|
2497
|
+
const sorted = {};
|
|
2498
|
+
const entries = Object.entries(value);
|
|
2499
|
+
entries.sort(([a], [b]) => a.localeCompare(b));
|
|
2500
|
+
for (const [key, val] of entries) {
|
|
2501
|
+
sorted[key] = sortKeys(val);
|
|
2502
|
+
}
|
|
2503
|
+
return sorted;
|
|
2504
|
+
}
|
|
2505
|
+
return value;
|
|
2506
|
+
}
|
|
2507
|
+
|
|
2445
2508
|
// src/utils/reasoning-details-duplicate-tracker.ts
|
|
2446
2509
|
var _seenKeys;
|
|
2447
2510
|
var ReasoningDetailsDuplicateTracker = class {
|
|
@@ -2773,7 +2836,7 @@ function convertToOpenRouterChatMessages(prompt) {
|
|
|
2773
2836
|
type: "function",
|
|
2774
2837
|
function: {
|
|
2775
2838
|
name: part.toolName,
|
|
2776
|
-
arguments:
|
|
2839
|
+
arguments: deterministicStringify(part.input)
|
|
2777
2840
|
}
|
|
2778
2841
|
});
|
|
2779
2842
|
break;
|
|
@@ -2801,7 +2864,7 @@ function convertToOpenRouterChatMessages(prompt) {
|
|
|
2801
2864
|
return true;
|
|
2802
2865
|
}
|
|
2803
2866
|
const format = (_a17 = detail.format) != null ? _a17 : DEFAULT_REASONING_FORMAT;
|
|
2804
|
-
if (format !== "anthropic-claude-v1" /* AnthropicClaudeV1 */) {
|
|
2867
|
+
if (format !== "anthropic-claude-v1" /* AnthropicClaudeV1 */ && format !== "google-gemini-v1" /* GoogleGeminiV1 */) {
|
|
2805
2868
|
return true;
|
|
2806
2869
|
}
|
|
2807
2870
|
return !!detail.signature;
|
|
@@ -2810,7 +2873,7 @@ function convertToOpenRouterChatMessages(prompt) {
|
|
|
2810
2873
|
const logger = globalThis.AI_SDK_LOG_WARNINGS;
|
|
2811
2874
|
if (logger !== false && typeof logger !== "function") {
|
|
2812
2875
|
console.warn(
|
|
2813
|
-
"[openrouter] Some reasoning_details entries were removed because they were missing signatures. See https://github.com/OpenRouterTeam/ai-sdk-provider/issues/423 for more details."
|
|
2876
|
+
"[openrouter] Some reasoning_details entries were removed because they were missing signatures. See https://github.com/OpenRouterTeam/ai-sdk-provider/issues/423 and https://github.com/OpenRouterTeam/ai-sdk-provider/issues/418 for more details."
|
|
2814
2877
|
);
|
|
2815
2878
|
}
|
|
2816
2879
|
}
|
|
@@ -3336,16 +3399,21 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3336
3399
|
cache_control: this.settings.cache_control
|
|
3337
3400
|
}, this.config.extraBody), this.settings.extraBody);
|
|
3338
3401
|
if (tools && tools.length > 0) {
|
|
3339
|
-
const mappedTools =
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3402
|
+
const mappedTools = [];
|
|
3403
|
+
for (const tool2 of tools) {
|
|
3404
|
+
if (tool2.type === "function") {
|
|
3405
|
+
mappedTools.push({
|
|
3406
|
+
type: "function",
|
|
3407
|
+
function: {
|
|
3408
|
+
name: tool2.name,
|
|
3409
|
+
description: tool2.description,
|
|
3410
|
+
parameters: tool2.inputSchema
|
|
3411
|
+
}
|
|
3412
|
+
});
|
|
3413
|
+
} else if (tool2.type === "provider") {
|
|
3414
|
+
mappedTools.push(mapProviderTool(tool2));
|
|
3347
3415
|
}
|
|
3348
|
-
}
|
|
3416
|
+
}
|
|
3349
3417
|
return __spreadProps(__spreadValues({}, baseArgs), {
|
|
3350
3418
|
tools: mappedTools,
|
|
3351
3419
|
tool_choice: toolChoice ? getChatCompletionToolChoice(toolChoice) : void 0
|
|
@@ -3354,7 +3422,7 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3354
3422
|
return baseArgs;
|
|
3355
3423
|
}
|
|
3356
3424
|
async doGenerate(options) {
|
|
3357
|
-
var _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v
|
|
3425
|
+
var _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
3358
3426
|
const providerOptions = options.providerOptions || {};
|
|
3359
3427
|
const openrouterOptions = providerOptions.openrouter || {};
|
|
3360
3428
|
const _a16 = openrouterOptions, { cacheControl } = _a16, restOpenrouterOptions = __objRest(_a16, ["cacheControl"]);
|
|
@@ -3450,12 +3518,18 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3450
3518
|
}
|
|
3451
3519
|
if (choice.message.tool_calls) {
|
|
3452
3520
|
let reasoningDetailsAttachedToToolCall = false;
|
|
3521
|
+
const seenToolCallIds = /* @__PURE__ */ new Set();
|
|
3453
3522
|
for (const toolCall of choice.message.tool_calls) {
|
|
3523
|
+
let toolCallId = toolCall.id;
|
|
3524
|
+
if (!toolCallId || seenToolCallIds.has(toolCallId)) {
|
|
3525
|
+
toolCallId = generateId();
|
|
3526
|
+
}
|
|
3527
|
+
seenToolCallIds.add(toolCallId);
|
|
3454
3528
|
content.push({
|
|
3455
3529
|
type: "tool-call",
|
|
3456
|
-
toolCallId
|
|
3530
|
+
toolCallId,
|
|
3457
3531
|
toolName: toolCall.function.name,
|
|
3458
|
-
input: (
|
|
3532
|
+
input: (_c = toolCall.function.arguments) != null ? _c : "{}",
|
|
3459
3533
|
providerMetadata: !reasoningDetailsAttachedToToolCall ? {
|
|
3460
3534
|
openrouter: {
|
|
3461
3535
|
reasoning_details: reasoningDetails
|
|
@@ -3482,19 +3556,19 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3482
3556
|
sourceType: "url",
|
|
3483
3557
|
id: annotation.url_citation.url,
|
|
3484
3558
|
url: annotation.url_citation.url,
|
|
3485
|
-
title: (
|
|
3559
|
+
title: (_d = annotation.url_citation.title) != null ? _d : "",
|
|
3486
3560
|
providerMetadata: {
|
|
3487
3561
|
openrouter: {
|
|
3488
|
-
content: (
|
|
3489
|
-
startIndex: (
|
|
3490
|
-
endIndex: (
|
|
3562
|
+
content: (_e = annotation.url_citation.content) != null ? _e : "",
|
|
3563
|
+
startIndex: (_f = annotation.url_citation.start_index) != null ? _f : 0,
|
|
3564
|
+
endIndex: (_g = annotation.url_citation.end_index) != null ? _g : 0
|
|
3491
3565
|
}
|
|
3492
3566
|
}
|
|
3493
3567
|
});
|
|
3494
3568
|
}
|
|
3495
3569
|
}
|
|
3496
3570
|
}
|
|
3497
|
-
const fileAnnotations = (
|
|
3571
|
+
const fileAnnotations = (_h = choice.message.annotations) == null ? void 0 : _h.filter(
|
|
3498
3572
|
(a) => a.type === "file"
|
|
3499
3573
|
);
|
|
3500
3574
|
const hasToolCalls = choice.message.tool_calls && choice.message.tool_calls.length > 0;
|
|
@@ -3502,7 +3576,7 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3502
3576
|
(d) => d.type === "reasoning.encrypted" /* Encrypted */ && d.data
|
|
3503
3577
|
);
|
|
3504
3578
|
const shouldOverrideFinishReason = hasToolCalls && hasEncryptedReasoning && choice.finish_reason === "stop";
|
|
3505
|
-
const mappedFinishReason = shouldOverrideFinishReason ? createFinishReason("tool-calls", (
|
|
3579
|
+
const mappedFinishReason = shouldOverrideFinishReason ? createFinishReason("tool-calls", (_i = choice.finish_reason) != null ? _i : void 0) : mapOpenRouterFinishReason(choice.finish_reason);
|
|
3506
3580
|
const effectiveFinishReason = hasToolCalls && mappedFinishReason.unified === "other" ? createFinishReason("tool-calls", mappedFinishReason.raw) : mappedFinishReason;
|
|
3507
3581
|
return {
|
|
3508
3582
|
content,
|
|
@@ -3511,22 +3585,22 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3511
3585
|
warnings: [],
|
|
3512
3586
|
providerMetadata: {
|
|
3513
3587
|
openrouter: OpenRouterProviderMetadataSchema.parse({
|
|
3514
|
-
provider: (
|
|
3515
|
-
reasoning_details: (
|
|
3588
|
+
provider: (_j = response.provider) != null ? _j : "",
|
|
3589
|
+
reasoning_details: (_k = choice.message.reasoning_details) != null ? _k : [],
|
|
3516
3590
|
annotations: fileAnnotations && fileAnnotations.length > 0 ? fileAnnotations : void 0,
|
|
3517
3591
|
usage: __spreadValues(__spreadValues(__spreadValues(__spreadValues({
|
|
3518
|
-
promptTokens: (
|
|
3519
|
-
completionTokens: (
|
|
3520
|
-
totalTokens: ((
|
|
3521
|
-
}, ((
|
|
3592
|
+
promptTokens: (_l = usageInfo.inputTokens.total) != null ? _l : 0,
|
|
3593
|
+
completionTokens: (_m = usageInfo.outputTokens.total) != null ? _m : 0,
|
|
3594
|
+
totalTokens: ((_n = usageInfo.inputTokens.total) != null ? _n : 0) + ((_o = usageInfo.outputTokens.total) != null ? _o : 0)
|
|
3595
|
+
}, ((_p = response.usage) == null ? void 0 : _p.cost) != null ? { cost: response.usage.cost } : {}), ((_r = (_q = response.usage) == null ? void 0 : _q.prompt_tokens_details) == null ? void 0 : _r.cached_tokens) != null ? {
|
|
3522
3596
|
promptTokensDetails: {
|
|
3523
3597
|
cachedTokens: response.usage.prompt_tokens_details.cached_tokens
|
|
3524
3598
|
}
|
|
3525
|
-
} : {}), ((
|
|
3599
|
+
} : {}), ((_t = (_s = response.usage) == null ? void 0 : _s.completion_tokens_details) == null ? void 0 : _t.reasoning_tokens) != null ? {
|
|
3526
3600
|
completionTokensDetails: {
|
|
3527
3601
|
reasoningTokens: response.usage.completion_tokens_details.reasoning_tokens
|
|
3528
3602
|
}
|
|
3529
|
-
} : {}), ((
|
|
3603
|
+
} : {}), ((_v = (_u = response.usage) == null ? void 0 : _u.cost_details) == null ? void 0 : _v.upstream_inference_cost) != null ? {
|
|
3530
3604
|
costDetails: {
|
|
3531
3605
|
upstreamInferenceCost: response.usage.cost_details.upstream_inference_cost
|
|
3532
3606
|
}
|
|
@@ -3573,6 +3647,7 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3573
3647
|
streamError = err;
|
|
3574
3648
|
});
|
|
3575
3649
|
const toolCalls = [];
|
|
3650
|
+
const seenToolCallIds = /* @__PURE__ */ new Set();
|
|
3576
3651
|
let finishReason = createFinishReason("other");
|
|
3577
3652
|
const usage = {
|
|
3578
3653
|
inputTokens: {
|
|
@@ -3803,24 +3878,23 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3803
3878
|
message: `Expected 'function' type.`
|
|
3804
3879
|
});
|
|
3805
3880
|
}
|
|
3806
|
-
if (toolCallDelta.id == null) {
|
|
3807
|
-
throw new InvalidResponseDataError({
|
|
3808
|
-
data: toolCallDelta,
|
|
3809
|
-
message: `Expected 'id' to be a string.`
|
|
3810
|
-
});
|
|
3811
|
-
}
|
|
3812
3881
|
if (((_k = toolCallDelta.function) == null ? void 0 : _k.name) == null) {
|
|
3813
3882
|
throw new InvalidResponseDataError({
|
|
3814
3883
|
data: toolCallDelta,
|
|
3815
3884
|
message: `Expected 'function.name' to be a string.`
|
|
3816
3885
|
});
|
|
3817
3886
|
}
|
|
3887
|
+
let toolCallId = (_l = toolCallDelta.id) != null ? _l : "";
|
|
3888
|
+
if (!toolCallId || seenToolCallIds.has(toolCallId)) {
|
|
3889
|
+
toolCallId = generateId();
|
|
3890
|
+
}
|
|
3891
|
+
seenToolCallIds.add(toolCallId);
|
|
3818
3892
|
toolCalls[index] = {
|
|
3819
|
-
id:
|
|
3893
|
+
id: toolCallId,
|
|
3820
3894
|
type: "function",
|
|
3821
3895
|
function: {
|
|
3822
3896
|
name: toolCallDelta.function.name,
|
|
3823
|
-
arguments: (
|
|
3897
|
+
arguments: (_m = toolCallDelta.function.arguments) != null ? _m : ""
|
|
3824
3898
|
},
|
|
3825
3899
|
inputStarted: false,
|
|
3826
3900
|
sent: false
|
|
@@ -3832,7 +3906,7 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3832
3906
|
message: `Tool call at index ${index} is missing after creation.`
|
|
3833
3907
|
});
|
|
3834
3908
|
}
|
|
3835
|
-
if (((
|
|
3909
|
+
if (((_n = toolCall2.function) == null ? void 0 : _n.name) != null && ((_o = toolCall2.function) == null ? void 0 : _o.arguments) != null && isParsableJson(toolCall2.function.arguments)) {
|
|
3836
3910
|
toolCall2.inputStarted = true;
|
|
3837
3911
|
controller.enqueue({
|
|
3838
3912
|
type: "tool-input-start",
|
|
@@ -3890,22 +3964,22 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3890
3964
|
});
|
|
3891
3965
|
}
|
|
3892
3966
|
}
|
|
3893
|
-
if (((
|
|
3894
|
-
toolCall.function.arguments += (
|
|
3967
|
+
if (((_p = toolCallDelta.function) == null ? void 0 : _p.arguments) != null) {
|
|
3968
|
+
toolCall.function.arguments += (_r = (_q = toolCallDelta.function) == null ? void 0 : _q.arguments) != null ? _r : "";
|
|
3895
3969
|
}
|
|
3896
3970
|
controller.enqueue({
|
|
3897
3971
|
type: "tool-input-delta",
|
|
3898
3972
|
id: toolCall.id,
|
|
3899
|
-
delta: (
|
|
3973
|
+
delta: (_s = toolCallDelta.function.arguments) != null ? _s : ""
|
|
3900
3974
|
});
|
|
3901
|
-
if (((
|
|
3975
|
+
if (((_t = toolCall.function) == null ? void 0 : _t.name) != null && ((_u = toolCall.function) == null ? void 0 : _u.arguments) != null && isParsableJson(toolCall.function.arguments)) {
|
|
3902
3976
|
controller.enqueue({
|
|
3903
3977
|
type: "tool-input-end",
|
|
3904
3978
|
id: toolCall.id
|
|
3905
3979
|
});
|
|
3906
3980
|
controller.enqueue({
|
|
3907
3981
|
type: "tool-call",
|
|
3908
|
-
toolCallId:
|
|
3982
|
+
toolCallId: toolCall.id,
|
|
3909
3983
|
toolName: toolCall.function.name,
|
|
3910
3984
|
input: toolCall.function.arguments,
|
|
3911
3985
|
providerMetadata: !reasoningDetailsAttachedToToolCall ? {
|
|
@@ -3930,7 +4004,6 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3930
4004
|
}
|
|
3931
4005
|
},
|
|
3932
4006
|
flush(controller) {
|
|
3933
|
-
var _a17;
|
|
3934
4007
|
const hasToolCalls = toolCalls.length > 0;
|
|
3935
4008
|
if (streamError != null) {
|
|
3936
4009
|
finishReason = createFinishReason("error");
|
|
@@ -3967,7 +4040,7 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3967
4040
|
});
|
|
3968
4041
|
controller.enqueue({
|
|
3969
4042
|
type: "tool-call",
|
|
3970
|
-
toolCallId:
|
|
4043
|
+
toolCallId: toolCall.id,
|
|
3971
4044
|
toolName: toolCall.function.name,
|
|
3972
4045
|
input,
|
|
3973
4046
|
providerMetadata: !reasoningDetailsAttachedToToolCall ? {
|
|
@@ -4030,6 +4103,22 @@ var OpenRouterChatLanguageModel = class {
|
|
|
4030
4103
|
};
|
|
4031
4104
|
}
|
|
4032
4105
|
};
|
|
4106
|
+
function mapProviderTool(tool2) {
|
|
4107
|
+
const [provider, toolName] = tool2.id.split(".");
|
|
4108
|
+
const apiToolType = `${provider}:${toolName}`;
|
|
4109
|
+
const mappedArgs = {};
|
|
4110
|
+
for (const [key, value] of Object.entries(tool2.args)) {
|
|
4111
|
+
if (value !== void 0) {
|
|
4112
|
+
mappedArgs[camelToSnake(key)] = value;
|
|
4113
|
+
}
|
|
4114
|
+
}
|
|
4115
|
+
return __spreadValues({
|
|
4116
|
+
type: apiToolType
|
|
4117
|
+
}, mappedArgs);
|
|
4118
|
+
}
|
|
4119
|
+
function camelToSnake(str) {
|
|
4120
|
+
return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
4121
|
+
}
|
|
4033
4122
|
|
|
4034
4123
|
// src/completion/convert-to-openrouter-completion-prompt.ts
|
|
4035
4124
|
function convertToOpenRouterCompletionPrompt({
|
|
@@ -4758,6 +4847,17 @@ function convertImageFileToContentPart(file) {
|
|
|
4758
4847
|
};
|
|
4759
4848
|
}
|
|
4760
4849
|
|
|
4850
|
+
// src/tool/web-search.ts
|
|
4851
|
+
import { z as z11 } from "zod/v4";
|
|
4852
|
+
var webSearchInputSchema = z11.object({
|
|
4853
|
+
/** Search results returned by the server tool */
|
|
4854
|
+
results: z11.array(z11.unknown()).optional()
|
|
4855
|
+
});
|
|
4856
|
+
var webSearch = createProviderToolFactory({
|
|
4857
|
+
id: "openrouter.web_search",
|
|
4858
|
+
inputSchema: webSearchInputSchema
|
|
4859
|
+
});
|
|
4860
|
+
|
|
4761
4861
|
// src/utils/remove-undefined.ts
|
|
4762
4862
|
function removeUndefinedEntries(record) {
|
|
4763
4863
|
return Object.fromEntries(
|
|
@@ -4799,7 +4899,7 @@ function withUserAgentSuffix2(headers, ...userAgentSuffixParts) {
|
|
|
4799
4899
|
}
|
|
4800
4900
|
|
|
4801
4901
|
// src/version.ts
|
|
4802
|
-
var VERSION2 = false ? "0.0.0-test" : "2.
|
|
4902
|
+
var VERSION2 = false ? "0.0.0-test" : "2.6.0";
|
|
4803
4903
|
|
|
4804
4904
|
// src/provider.ts
|
|
4805
4905
|
function createOpenRouter(options = {}) {
|
|
@@ -4869,6 +4969,9 @@ function createOpenRouter(options = {}) {
|
|
|
4869
4969
|
provider.textEmbeddingModel = createEmbeddingModel;
|
|
4870
4970
|
provider.embedding = createEmbeddingModel;
|
|
4871
4971
|
provider.imageModel = createImageModel;
|
|
4972
|
+
provider.tools = {
|
|
4973
|
+
webSearch
|
|
4974
|
+
};
|
|
4872
4975
|
return provider;
|
|
4873
4976
|
}
|
|
4874
4977
|
var openrouter = createOpenRouter({
|