@openrouter/ai-sdk-provider 2.5.1 → 2.7.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.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: JSON.stringify(part.input)
2839
+ arguments: deterministicStringify(part.input)
2777
2840
  }
2778
2841
  });
2779
2842
  break;
@@ -3289,7 +3352,7 @@ var OpenRouterChatLanguageModel = class {
3289
3352
  tools,
3290
3353
  toolChoice
3291
3354
  }) {
3292
- var _a16;
3355
+ var _a16, _b16;
3293
3356
  const baseArgs = __spreadValues(__spreadValues({
3294
3357
  // model id:
3295
3358
  model: this.modelId,
@@ -3300,12 +3363,12 @@ var OpenRouterChatLanguageModel = class {
3300
3363
  top_logprobs: typeof this.settings.logprobs === "number" ? this.settings.logprobs : typeof this.settings.logprobs === "boolean" ? this.settings.logprobs ? 0 : void 0 : void 0,
3301
3364
  user: this.settings.user,
3302
3365
  parallel_tool_calls: this.settings.parallelToolCalls,
3303
- // standardized settings:
3304
- max_tokens: maxOutputTokens,
3305
- temperature,
3306
- top_p: topP,
3307
- frequency_penalty: frequencyPenalty,
3308
- presence_penalty: presencePenalty,
3366
+ // standardized settings (call-level options override model-level settings):
3367
+ max_tokens: maxOutputTokens != null ? maxOutputTokens : this.settings.maxTokens,
3368
+ temperature: temperature != null ? temperature : this.settings.temperature,
3369
+ top_p: topP != null ? topP : this.settings.topP,
3370
+ frequency_penalty: frequencyPenalty != null ? frequencyPenalty : this.settings.frequencyPenalty,
3371
+ presence_penalty: presencePenalty != null ? presencePenalty : this.settings.presencePenalty,
3309
3372
  seed,
3310
3373
  stop: stopSequences,
3311
3374
  response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? responseFormat.schema != null ? {
@@ -3318,7 +3381,7 @@ var OpenRouterChatLanguageModel = class {
3318
3381
  description: responseFormat.description
3319
3382
  })
3320
3383
  } : { type: "json_object" } : void 0,
3321
- top_k: topK,
3384
+ top_k: topK != null ? topK : this.settings.topK,
3322
3385
  // messages:
3323
3386
  messages: convertToOpenRouterChatMessages(prompt),
3324
3387
  // OpenRouter specific settings:
@@ -3336,16 +3399,25 @@ 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 = tools.filter(
3340
- (tool) => tool.type === "function"
3341
- ).map((tool) => ({
3342
- type: "function",
3343
- function: {
3344
- name: tool.name,
3345
- description: tool.description,
3346
- parameters: tool.inputSchema
3402
+ const mappedTools = [];
3403
+ for (const tool2 of tools) {
3404
+ if (tool2.type === "function") {
3405
+ const openrouterOptions = (_b16 = tool2.providerOptions) == null ? void 0 : _b16.openrouter;
3406
+ const eagerInputStreaming = openrouterOptions == null ? void 0 : openrouterOptions.eager_input_streaming;
3407
+ mappedTools.push(__spreadValues({
3408
+ type: "function",
3409
+ function: {
3410
+ name: tool2.name,
3411
+ description: tool2.description,
3412
+ parameters: tool2.inputSchema
3413
+ }
3414
+ }, eagerInputStreaming != null && {
3415
+ eager_input_streaming: eagerInputStreaming
3416
+ }));
3417
+ } else if (tool2.type === "provider") {
3418
+ mappedTools.push(mapProviderTool(tool2));
3347
3419
  }
3348
- }));
3420
+ }
3349
3421
  return __spreadProps(__spreadValues({}, baseArgs), {
3350
3422
  tools: mappedTools,
3351
3423
  tool_choice: toolChoice ? getChatCompletionToolChoice(toolChoice) : void 0
@@ -3354,7 +3426,7 @@ var OpenRouterChatLanguageModel = class {
3354
3426
  return baseArgs;
3355
3427
  }
3356
3428
  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, _w;
3429
+ var _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v;
3358
3430
  const providerOptions = options.providerOptions || {};
3359
3431
  const openrouterOptions = providerOptions.openrouter || {};
3360
3432
  const _a16 = openrouterOptions, { cacheControl } = _a16, restOpenrouterOptions = __objRest(_a16, ["cacheControl"]);
@@ -3450,12 +3522,18 @@ var OpenRouterChatLanguageModel = class {
3450
3522
  }
3451
3523
  if (choice.message.tool_calls) {
3452
3524
  let reasoningDetailsAttachedToToolCall = false;
3525
+ const seenToolCallIds = /* @__PURE__ */ new Set();
3453
3526
  for (const toolCall of choice.message.tool_calls) {
3527
+ let toolCallId = toolCall.id;
3528
+ if (!toolCallId || seenToolCallIds.has(toolCallId)) {
3529
+ toolCallId = generateId();
3530
+ }
3531
+ seenToolCallIds.add(toolCallId);
3454
3532
  content.push({
3455
3533
  type: "tool-call",
3456
- toolCallId: (_c = toolCall.id) != null ? _c : generateId(),
3534
+ toolCallId,
3457
3535
  toolName: toolCall.function.name,
3458
- input: (_d = toolCall.function.arguments) != null ? _d : "{}",
3536
+ input: (_c = toolCall.function.arguments) != null ? _c : "{}",
3459
3537
  providerMetadata: !reasoningDetailsAttachedToToolCall ? {
3460
3538
  openrouter: {
3461
3539
  reasoning_details: reasoningDetails
@@ -3482,19 +3560,19 @@ var OpenRouterChatLanguageModel = class {
3482
3560
  sourceType: "url",
3483
3561
  id: annotation.url_citation.url,
3484
3562
  url: annotation.url_citation.url,
3485
- title: (_e = annotation.url_citation.title) != null ? _e : "",
3563
+ title: (_d = annotation.url_citation.title) != null ? _d : "",
3486
3564
  providerMetadata: {
3487
3565
  openrouter: {
3488
- content: (_f = annotation.url_citation.content) != null ? _f : "",
3489
- startIndex: (_g = annotation.url_citation.start_index) != null ? _g : 0,
3490
- endIndex: (_h = annotation.url_citation.end_index) != null ? _h : 0
3566
+ content: (_e = annotation.url_citation.content) != null ? _e : "",
3567
+ startIndex: (_f = annotation.url_citation.start_index) != null ? _f : 0,
3568
+ endIndex: (_g = annotation.url_citation.end_index) != null ? _g : 0
3491
3569
  }
3492
3570
  }
3493
3571
  });
3494
3572
  }
3495
3573
  }
3496
3574
  }
3497
- const fileAnnotations = (_i = choice.message.annotations) == null ? void 0 : _i.filter(
3575
+ const fileAnnotations = (_h = choice.message.annotations) == null ? void 0 : _h.filter(
3498
3576
  (a) => a.type === "file"
3499
3577
  );
3500
3578
  const hasToolCalls = choice.message.tool_calls && choice.message.tool_calls.length > 0;
@@ -3502,7 +3580,7 @@ var OpenRouterChatLanguageModel = class {
3502
3580
  (d) => d.type === "reasoning.encrypted" /* Encrypted */ && d.data
3503
3581
  );
3504
3582
  const shouldOverrideFinishReason = hasToolCalls && hasEncryptedReasoning && choice.finish_reason === "stop";
3505
- const mappedFinishReason = shouldOverrideFinishReason ? createFinishReason("tool-calls", (_j = choice.finish_reason) != null ? _j : void 0) : mapOpenRouterFinishReason(choice.finish_reason);
3583
+ const mappedFinishReason = shouldOverrideFinishReason ? createFinishReason("tool-calls", (_i = choice.finish_reason) != null ? _i : void 0) : mapOpenRouterFinishReason(choice.finish_reason);
3506
3584
  const effectiveFinishReason = hasToolCalls && mappedFinishReason.unified === "other" ? createFinishReason("tool-calls", mappedFinishReason.raw) : mappedFinishReason;
3507
3585
  return {
3508
3586
  content,
@@ -3511,22 +3589,22 @@ var OpenRouterChatLanguageModel = class {
3511
3589
  warnings: [],
3512
3590
  providerMetadata: {
3513
3591
  openrouter: OpenRouterProviderMetadataSchema.parse({
3514
- provider: (_k = response.provider) != null ? _k : "",
3515
- reasoning_details: (_l = choice.message.reasoning_details) != null ? _l : [],
3592
+ provider: (_j = response.provider) != null ? _j : "",
3593
+ reasoning_details: (_k = choice.message.reasoning_details) != null ? _k : [],
3516
3594
  annotations: fileAnnotations && fileAnnotations.length > 0 ? fileAnnotations : void 0,
3517
3595
  usage: __spreadValues(__spreadValues(__spreadValues(__spreadValues({
3518
- promptTokens: (_m = usageInfo.inputTokens.total) != null ? _m : 0,
3519
- completionTokens: (_n = usageInfo.outputTokens.total) != null ? _n : 0,
3520
- totalTokens: ((_o = usageInfo.inputTokens.total) != null ? _o : 0) + ((_p = usageInfo.outputTokens.total) != null ? _p : 0)
3521
- }, ((_q = response.usage) == null ? void 0 : _q.cost) != null ? { cost: response.usage.cost } : {}), ((_s = (_r = response.usage) == null ? void 0 : _r.prompt_tokens_details) == null ? void 0 : _s.cached_tokens) != null ? {
3596
+ promptTokens: (_l = usageInfo.inputTokens.total) != null ? _l : 0,
3597
+ completionTokens: (_m = usageInfo.outputTokens.total) != null ? _m : 0,
3598
+ totalTokens: ((_n = usageInfo.inputTokens.total) != null ? _n : 0) + ((_o = usageInfo.outputTokens.total) != null ? _o : 0)
3599
+ }, ((_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
3600
  promptTokensDetails: {
3523
3601
  cachedTokens: response.usage.prompt_tokens_details.cached_tokens
3524
3602
  }
3525
- } : {}), ((_u = (_t = response.usage) == null ? void 0 : _t.completion_tokens_details) == null ? void 0 : _u.reasoning_tokens) != null ? {
3603
+ } : {}), ((_t = (_s = response.usage) == null ? void 0 : _s.completion_tokens_details) == null ? void 0 : _t.reasoning_tokens) != null ? {
3526
3604
  completionTokensDetails: {
3527
3605
  reasoningTokens: response.usage.completion_tokens_details.reasoning_tokens
3528
3606
  }
3529
- } : {}), ((_w = (_v = response.usage) == null ? void 0 : _v.cost_details) == null ? void 0 : _w.upstream_inference_cost) != null ? {
3607
+ } : {}), ((_v = (_u = response.usage) == null ? void 0 : _u.cost_details) == null ? void 0 : _v.upstream_inference_cost) != null ? {
3530
3608
  costDetails: {
3531
3609
  upstreamInferenceCost: response.usage.cost_details.upstream_inference_cost
3532
3610
  }
@@ -3573,6 +3651,7 @@ var OpenRouterChatLanguageModel = class {
3573
3651
  streamError = err;
3574
3652
  });
3575
3653
  const toolCalls = [];
3654
+ const seenToolCallIds = /* @__PURE__ */ new Set();
3576
3655
  let finishReason = createFinishReason("other");
3577
3656
  const usage = {
3578
3657
  inputTokens: {
@@ -3672,18 +3751,16 @@ var OpenRouterChatLanguageModel = class {
3672
3751
  return;
3673
3752
  }
3674
3753
  const delta = choice.delta;
3675
- const emitReasoningChunk = (chunkText, providerMetadata) => {
3754
+ const emitReasoningChunk = (chunkText) => {
3676
3755
  if (!reasoningStarted) {
3677
3756
  reasoningId = generateId();
3678
3757
  controller.enqueue({
3679
- providerMetadata,
3680
3758
  type: "reasoning-start",
3681
3759
  id: reasoningId
3682
3760
  });
3683
3761
  reasoningStarted = true;
3684
3762
  }
3685
3763
  controller.enqueue({
3686
- providerMetadata,
3687
3764
  type: "reasoning-delta",
3688
3765
  delta: chunkText,
3689
3766
  id: reasoningId || generateId()
@@ -3705,15 +3782,10 @@ var OpenRouterChatLanguageModel = class {
3705
3782
  }
3706
3783
  }
3707
3784
  if (!textStarted) {
3708
- const reasoningMetadata = {
3709
- openrouter: {
3710
- reasoning_details: accumulatedReasoningDetails.map((d) => __spreadValues({}, d))
3711
- }
3712
- };
3713
3785
  for (const detail of delta.reasoning_details) {
3714
3786
  switch (detail.type) {
3715
3787
  case "reasoning.text" /* Text */: {
3716
- emitReasoningChunk(detail.text || "", reasoningMetadata);
3788
+ emitReasoningChunk(detail.text || "");
3717
3789
  break;
3718
3790
  }
3719
3791
  case "reasoning.encrypted" /* Encrypted */: {
@@ -3721,7 +3793,7 @@ var OpenRouterChatLanguageModel = class {
3721
3793
  }
3722
3794
  case "reasoning.summary" /* Summary */: {
3723
3795
  if (detail.summary) {
3724
- emitReasoningChunk(detail.summary, reasoningMetadata);
3796
+ emitReasoningChunk(detail.summary);
3725
3797
  }
3726
3798
  break;
3727
3799
  }
@@ -3803,24 +3875,23 @@ var OpenRouterChatLanguageModel = class {
3803
3875
  message: `Expected 'function' type.`
3804
3876
  });
3805
3877
  }
3806
- if (toolCallDelta.id == null) {
3807
- throw new InvalidResponseDataError({
3808
- data: toolCallDelta,
3809
- message: `Expected 'id' to be a string.`
3810
- });
3811
- }
3812
3878
  if (((_k = toolCallDelta.function) == null ? void 0 : _k.name) == null) {
3813
3879
  throw new InvalidResponseDataError({
3814
3880
  data: toolCallDelta,
3815
3881
  message: `Expected 'function.name' to be a string.`
3816
3882
  });
3817
3883
  }
3884
+ let toolCallId = (_l = toolCallDelta.id) != null ? _l : "";
3885
+ if (!toolCallId || seenToolCallIds.has(toolCallId)) {
3886
+ toolCallId = generateId();
3887
+ }
3888
+ seenToolCallIds.add(toolCallId);
3818
3889
  toolCalls[index] = {
3819
- id: toolCallDelta.id,
3890
+ id: toolCallId,
3820
3891
  type: "function",
3821
3892
  function: {
3822
3893
  name: toolCallDelta.function.name,
3823
- arguments: (_l = toolCallDelta.function.arguments) != null ? _l : ""
3894
+ arguments: (_m = toolCallDelta.function.arguments) != null ? _m : ""
3824
3895
  },
3825
3896
  inputStarted: false,
3826
3897
  sent: false
@@ -3832,7 +3903,7 @@ var OpenRouterChatLanguageModel = class {
3832
3903
  message: `Tool call at index ${index} is missing after creation.`
3833
3904
  });
3834
3905
  }
3835
- if (((_m = toolCall2.function) == null ? void 0 : _m.name) != null && ((_n = toolCall2.function) == null ? void 0 : _n.arguments) != null && isParsableJson(toolCall2.function.arguments)) {
3906
+ if (((_n = toolCall2.function) == null ? void 0 : _n.name) != null && ((_o = toolCall2.function) == null ? void 0 : _o.arguments) != null && isParsableJson(toolCall2.function.arguments)) {
3836
3907
  toolCall2.inputStarted = true;
3837
3908
  controller.enqueue({
3838
3909
  type: "tool-input-start",
@@ -3890,22 +3961,22 @@ var OpenRouterChatLanguageModel = class {
3890
3961
  });
3891
3962
  }
3892
3963
  }
3893
- if (((_o = toolCallDelta.function) == null ? void 0 : _o.arguments) != null) {
3894
- toolCall.function.arguments += (_q = (_p = toolCallDelta.function) == null ? void 0 : _p.arguments) != null ? _q : "";
3964
+ if (((_p = toolCallDelta.function) == null ? void 0 : _p.arguments) != null) {
3965
+ toolCall.function.arguments += (_r = (_q = toolCallDelta.function) == null ? void 0 : _q.arguments) != null ? _r : "";
3895
3966
  }
3896
3967
  controller.enqueue({
3897
3968
  type: "tool-input-delta",
3898
3969
  id: toolCall.id,
3899
- delta: (_r = toolCallDelta.function.arguments) != null ? _r : ""
3970
+ delta: (_s = toolCallDelta.function.arguments) != null ? _s : ""
3900
3971
  });
3901
- if (((_s = toolCall.function) == null ? void 0 : _s.name) != null && ((_t = toolCall.function) == null ? void 0 : _t.arguments) != null && isParsableJson(toolCall.function.arguments)) {
3972
+ if (((_t = toolCall.function) == null ? void 0 : _t.name) != null && ((_u = toolCall.function) == null ? void 0 : _u.arguments) != null && isParsableJson(toolCall.function.arguments)) {
3902
3973
  controller.enqueue({
3903
3974
  type: "tool-input-end",
3904
3975
  id: toolCall.id
3905
3976
  });
3906
3977
  controller.enqueue({
3907
3978
  type: "tool-call",
3908
- toolCallId: (_u = toolCall.id) != null ? _u : generateId(),
3979
+ toolCallId: toolCall.id,
3909
3980
  toolName: toolCall.function.name,
3910
3981
  input: toolCall.function.arguments,
3911
3982
  providerMetadata: !reasoningDetailsAttachedToToolCall ? {
@@ -3930,7 +4001,6 @@ var OpenRouterChatLanguageModel = class {
3930
4001
  }
3931
4002
  },
3932
4003
  flush(controller) {
3933
- var _a17;
3934
4004
  const hasToolCalls = toolCalls.length > 0;
3935
4005
  if (streamError != null) {
3936
4006
  finishReason = createFinishReason("error");
@@ -3967,7 +4037,7 @@ var OpenRouterChatLanguageModel = class {
3967
4037
  });
3968
4038
  controller.enqueue({
3969
4039
  type: "tool-call",
3970
- toolCallId: (_a17 = toolCall.id) != null ? _a17 : generateId(),
4040
+ toolCallId: toolCall.id,
3971
4041
  toolName: toolCall.function.name,
3972
4042
  input,
3973
4043
  providerMetadata: !reasoningDetailsAttachedToToolCall ? {
@@ -4012,6 +4082,12 @@ var OpenRouterChatLanguageModel = class {
4012
4082
  if (accumulatedFileAnnotations.length > 0) {
4013
4083
  openrouterMetadata.annotations = accumulatedFileAnnotations;
4014
4084
  }
4085
+ if (usage.inputTokens.total === void 0 && openrouterUsage.promptTokens !== void 0) {
4086
+ usage.inputTokens.total = openrouterUsage.promptTokens;
4087
+ }
4088
+ if (usage.outputTokens.total === void 0 && openrouterUsage.completionTokens !== void 0) {
4089
+ usage.outputTokens.total = openrouterUsage.completionTokens;
4090
+ }
4015
4091
  usage.raw = rawUsage;
4016
4092
  controller.enqueue({
4017
4093
  type: "finish",
@@ -4030,6 +4106,22 @@ var OpenRouterChatLanguageModel = class {
4030
4106
  };
4031
4107
  }
4032
4108
  };
4109
+ function mapProviderTool(tool2) {
4110
+ const [provider, toolName] = tool2.id.split(".");
4111
+ const apiToolType = `${provider}:${toolName}`;
4112
+ const mappedArgs = {};
4113
+ for (const [key, value] of Object.entries(tool2.args)) {
4114
+ if (value !== void 0) {
4115
+ mappedArgs[camelToSnake(key)] = value;
4116
+ }
4117
+ }
4118
+ return __spreadValues({
4119
+ type: apiToolType
4120
+ }, mappedArgs);
4121
+ }
4122
+ function camelToSnake(str) {
4123
+ return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
4124
+ }
4033
4125
 
4034
4126
  // src/completion/convert-to-openrouter-completion-prompt.ts
4035
4127
  function convertToOpenRouterCompletionPrompt({
@@ -4231,16 +4323,16 @@ var OpenRouterCompletionLanguageModel = class {
4231
4323
  logprobs: typeof this.settings.logprobs === "number" ? this.settings.logprobs : typeof this.settings.logprobs === "boolean" ? this.settings.logprobs ? 0 : void 0 : void 0,
4232
4324
  suffix: this.settings.suffix,
4233
4325
  user: this.settings.user,
4234
- // standardized settings:
4235
- max_tokens: maxOutputTokens,
4236
- temperature,
4237
- top_p: topP,
4238
- frequency_penalty: frequencyPenalty,
4239
- presence_penalty: presencePenalty,
4326
+ // standardized settings (call-level options override model-level settings):
4327
+ max_tokens: maxOutputTokens != null ? maxOutputTokens : this.settings.maxTokens,
4328
+ temperature: temperature != null ? temperature : this.settings.temperature,
4329
+ top_p: topP != null ? topP : this.settings.topP,
4330
+ frequency_penalty: frequencyPenalty != null ? frequencyPenalty : this.settings.frequencyPenalty,
4331
+ presence_penalty: presencePenalty != null ? presencePenalty : this.settings.presencePenalty,
4240
4332
  seed,
4241
4333
  stop: stopSequences,
4242
4334
  response_format: responseFormat,
4243
- top_k: topK,
4335
+ top_k: topK != null ? topK : this.settings.topK,
4244
4336
  // prompt:
4245
4337
  prompt: completionPrompt,
4246
4338
  // OpenRouter specific settings:
@@ -4758,6 +4850,17 @@ function convertImageFileToContentPart(file) {
4758
4850
  };
4759
4851
  }
4760
4852
 
4853
+ // src/tool/web-search.ts
4854
+ import { z as z11 } from "zod/v4";
4855
+ var webSearchInputSchema = z11.object({
4856
+ /** Search results returned by the server tool */
4857
+ results: z11.array(z11.unknown()).optional()
4858
+ });
4859
+ var webSearch = createProviderToolFactory({
4860
+ id: "openrouter.web_search",
4861
+ inputSchema: webSearchInputSchema
4862
+ });
4863
+
4761
4864
  // src/utils/remove-undefined.ts
4762
4865
  function removeUndefinedEntries(record) {
4763
4866
  return Object.fromEntries(
@@ -4799,7 +4902,7 @@ function withUserAgentSuffix2(headers, ...userAgentSuffixParts) {
4799
4902
  }
4800
4903
 
4801
4904
  // src/version.ts
4802
- var VERSION2 = false ? "0.0.0-test" : "2.5.1";
4905
+ var VERSION2 = false ? "0.0.0-test" : "2.7.0";
4803
4906
 
4804
4907
  // src/provider.ts
4805
4908
  function createOpenRouter(options = {}) {
@@ -4869,6 +4972,9 @@ function createOpenRouter(options = {}) {
4869
4972
  provider.textEmbeddingModel = createEmbeddingModel;
4870
4973
  provider.embedding = createEmbeddingModel;
4871
4974
  provider.imageModel = createImageModel;
4975
+ provider.tools = {
4976
+ webSearch
4977
+ };
4872
4978
  return provider;
4873
4979
  }
4874
4980
  var openrouter = createOpenRouter({