@openrouter/ai-sdk-provider 2.6.0 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -71,7 +71,7 @@ __export(index_exports, {
71
71
  });
72
72
  module.exports = __toCommonJS(index_exports);
73
73
 
74
- // node_modules/.pnpm/@ai-sdk+provider@3.0.0/node_modules/@ai-sdk/provider/dist/index.mjs
74
+ // node_modules/.pnpm/@ai-sdk+provider@3.0.8/node_modules/@ai-sdk/provider/dist/index.mjs
75
75
  var marker = "vercel.ai.error";
76
76
  var symbol = Symbol.for(marker);
77
77
  var _a;
@@ -341,34 +341,61 @@ var symbol13 = Symbol.for(marker13);
341
341
  var _a13;
342
342
  var _b13;
343
343
  var TypeValidationError = class _TypeValidationError extends (_b13 = AISDKError, _a13 = symbol13, _b13) {
344
- constructor({ value, cause }) {
344
+ constructor({
345
+ value,
346
+ cause,
347
+ context
348
+ }) {
349
+ let contextPrefix = "Type validation failed";
350
+ if (context == null ? void 0 : context.field) {
351
+ contextPrefix += ` for ${context.field}`;
352
+ }
353
+ if ((context == null ? void 0 : context.entityName) || (context == null ? void 0 : context.entityId)) {
354
+ contextPrefix += " (";
355
+ const parts = [];
356
+ if (context.entityName) {
357
+ parts.push(context.entityName);
358
+ }
359
+ if (context.entityId) {
360
+ parts.push(`id: "${context.entityId}"`);
361
+ }
362
+ contextPrefix += parts.join(", ");
363
+ contextPrefix += ")";
364
+ }
345
365
  super({
346
366
  name: name12,
347
- message: `Type validation failed: Value: ${JSON.stringify(value)}.
367
+ message: `${contextPrefix}: Value: ${JSON.stringify(value)}.
348
368
  Error message: ${getErrorMessage(cause)}`,
349
369
  cause
350
370
  });
351
371
  this[_a13] = true;
352
372
  this.value = value;
373
+ this.context = context;
353
374
  }
354
375
  static isInstance(error) {
355
376
  return AISDKError.hasMarker(error, marker13);
356
377
  }
357
378
  /**
358
379
  * Wraps an error into a TypeValidationError.
359
- * If the cause is already a TypeValidationError with the same value, it returns the cause.
380
+ * If the cause is already a TypeValidationError with the same value and context, it returns the cause.
360
381
  * Otherwise, it creates a new TypeValidationError.
361
382
  *
362
383
  * @param {Object} params - The parameters for wrapping the error.
363
384
  * @param {unknown} params.value - The value that failed validation.
364
385
  * @param {unknown} params.cause - The original error or cause of the validation failure.
386
+ * @param {TypeValidationContext} params.context - Optional context about what is being validated.
365
387
  * @returns {TypeValidationError} A TypeValidationError instance.
366
388
  */
367
389
  static wrap({
368
390
  value,
369
- cause
391
+ cause,
392
+ context
370
393
  }) {
371
- return _TypeValidationError.isInstance(cause) && cause.value === value ? cause : new _TypeValidationError({ value, cause });
394
+ var _a152, _b152, _c;
395
+ if (_TypeValidationError.isInstance(cause) && cause.value === value && ((_a152 = cause.context) == null ? void 0 : _a152.field) === (context == null ? void 0 : context.field) && ((_b152 = cause.context) == null ? void 0 : _b152.entityName) === (context == null ? void 0 : context.entityName) && ((_c = cause.context) == null ? void 0 : _c.entityId) === (context == null ? void 0 : context.entityId)) {
396
+ return cause;
397
+ }
398
+ return new _TypeValidationError({ value, cause, context });
372
399
  }
373
400
  };
374
401
  var name13 = "AI_UnsupportedFunctionalityError";
@@ -390,7 +417,7 @@ var UnsupportedFunctionalityError = class extends (_b14 = AISDKError, _a14 = sym
390
417
  }
391
418
  };
392
419
 
393
- // node_modules/.pnpm/@ai-sdk+provider-utils@4.0.1_zod@4.3.5/node_modules/@ai-sdk/provider-utils/dist/index.mjs
420
+ // node_modules/.pnpm/@ai-sdk+provider-utils@4.0.23_zod@4.3.5/node_modules/@ai-sdk/provider-utils/dist/index.mjs
394
421
  var z4 = __toESM(require("zod/v4"), 1);
395
422
  var import_v3 = require("zod/v3");
396
423
  var import_v32 = require("zod/v3");
@@ -523,13 +550,41 @@ var EventSourceParserStream = class extends TransformStream {
523
550
  }
524
551
  };
525
552
 
526
- // node_modules/.pnpm/@ai-sdk+provider-utils@4.0.1_zod@4.3.5/node_modules/@ai-sdk/provider-utils/dist/index.mjs
553
+ // node_modules/.pnpm/@ai-sdk+provider-utils@4.0.23_zod@4.3.5/node_modules/@ai-sdk/provider-utils/dist/index.mjs
527
554
  function combineHeaders(...headers) {
528
555
  return headers.reduce(
529
556
  (combinedHeaders, currentHeaders) => __spreadValues(__spreadValues({}, combinedHeaders), currentHeaders != null ? currentHeaders : {}),
530
557
  {}
531
558
  );
532
559
  }
560
+ async function delay(delayInMs, options) {
561
+ if (delayInMs == null) {
562
+ return Promise.resolve();
563
+ }
564
+ const signal = options == null ? void 0 : options.abortSignal;
565
+ return new Promise((resolve2, reject) => {
566
+ if (signal == null ? void 0 : signal.aborted) {
567
+ reject(createAbortError());
568
+ return;
569
+ }
570
+ const timeoutId = setTimeout(() => {
571
+ cleanup();
572
+ resolve2();
573
+ }, delayInMs);
574
+ const cleanup = () => {
575
+ clearTimeout(timeoutId);
576
+ signal == null ? void 0 : signal.removeEventListener("abort", onAbort);
577
+ };
578
+ const onAbort = () => {
579
+ cleanup();
580
+ reject(createAbortError());
581
+ };
582
+ signal == null ? void 0 : signal.addEventListener("abort", onAbort);
583
+ });
584
+ }
585
+ function createAbortError() {
586
+ return new DOMException("Delay was aborted", "AbortError");
587
+ }
533
588
  function extractResponseHeaders(response) {
534
589
  return Object.fromEntries([...response.headers]);
535
590
  }
@@ -564,6 +619,7 @@ var DownloadError = class extends (_b15 = AISDKError, _a15 = symbol15, _b15) {
564
619
  return AISDKError.hasMarker(error, marker15);
565
620
  }
566
621
  };
622
+ var DEFAULT_MAX_DOWNLOAD_SIZE = 2 * 1024 * 1024 * 1024;
567
623
  var createIdGenerator = ({
568
624
  prefix,
569
625
  size = 16,
@@ -595,6 +651,25 @@ function isAbortError(error) {
595
651
  error.name === "TimeoutError");
596
652
  }
597
653
  var FETCH_FAILED_ERROR_MESSAGES = ["fetch failed", "failed to fetch"];
654
+ var BUN_ERROR_CODES = [
655
+ "ConnectionRefused",
656
+ "ConnectionClosed",
657
+ "FailedToOpenSocket",
658
+ "ECONNRESET",
659
+ "ECONNREFUSED",
660
+ "ETIMEDOUT",
661
+ "EPIPE"
662
+ ];
663
+ function isBunNetworkError(error) {
664
+ if (!(error instanceof Error)) {
665
+ return false;
666
+ }
667
+ const code = error.code;
668
+ if (typeof code === "string" && BUN_ERROR_CODES.includes(code)) {
669
+ return true;
670
+ }
671
+ return false;
672
+ }
598
673
  function handleFetchError({
599
674
  error,
600
675
  url,
@@ -616,6 +691,15 @@ function handleFetchError({
616
691
  });
617
692
  }
618
693
  }
694
+ if (isBunNetworkError(error)) {
695
+ return new APICallError({
696
+ message: `Cannot connect to API: ${error.message}`,
697
+ cause: error,
698
+ url,
699
+ requestBodyValues,
700
+ isRetryable: true
701
+ });
702
+ }
619
703
  return error;
620
704
  }
621
705
  function getRuntimeEnvironmentUserAgent(globalThisAny = globalThis) {
@@ -664,7 +748,75 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
664
748
  );
665
749
  return Object.fromEntries(normalizedHeaders.entries());
666
750
  }
667
- var VERSION = true ? "4.0.1" : "0.0.0-test";
751
+ var VERSION = true ? "4.0.23" : "0.0.0-test";
752
+ var getOriginalFetch = () => globalThis.fetch;
753
+ var getFromApi = async ({
754
+ url,
755
+ headers = {},
756
+ successfulResponseHandler,
757
+ failedResponseHandler,
758
+ abortSignal,
759
+ fetch: fetch2 = getOriginalFetch()
760
+ }) => {
761
+ try {
762
+ const response = await fetch2(url, {
763
+ method: "GET",
764
+ headers: withUserAgentSuffix(
765
+ headers,
766
+ `ai-sdk/provider-utils/${VERSION}`,
767
+ getRuntimeEnvironmentUserAgent()
768
+ ),
769
+ signal: abortSignal
770
+ });
771
+ const responseHeaders = extractResponseHeaders(response);
772
+ if (!response.ok) {
773
+ let errorInformation;
774
+ try {
775
+ errorInformation = await failedResponseHandler({
776
+ response,
777
+ url,
778
+ requestBodyValues: {}
779
+ });
780
+ } catch (error) {
781
+ if (isAbortError(error) || APICallError.isInstance(error)) {
782
+ throw error;
783
+ }
784
+ throw new APICallError({
785
+ message: "Failed to process error response",
786
+ cause: error,
787
+ statusCode: response.status,
788
+ url,
789
+ responseHeaders,
790
+ requestBodyValues: {}
791
+ });
792
+ }
793
+ throw errorInformation.value;
794
+ }
795
+ try {
796
+ return await successfulResponseHandler({
797
+ response,
798
+ url,
799
+ requestBodyValues: {}
800
+ });
801
+ } catch (error) {
802
+ if (error instanceof Error) {
803
+ if (isAbortError(error) || APICallError.isInstance(error)) {
804
+ throw error;
805
+ }
806
+ }
807
+ throw new APICallError({
808
+ message: "Failed to process successful response",
809
+ cause: error,
810
+ statusCode: response.status,
811
+ url,
812
+ responseHeaders,
813
+ requestBodyValues: {}
814
+ });
815
+ }
816
+ } catch (error) {
817
+ throw handleFetchError({ error, url, requestBodyValues: {} });
818
+ }
819
+ };
668
820
  function loadApiKey({
669
821
  apiKey,
670
822
  environmentVariableName,
@@ -681,7 +833,7 @@ function loadApiKey({
681
833
  }
682
834
  if (typeof process === "undefined") {
683
835
  throw new LoadAPIKeyError({
684
- message: `${description} API key is missing. Pass it using the '${apiKeyParameterName}' parameter. Environment variables is not supported in this environment.`
836
+ message: `${description} API key is missing. Pass it using the '${apiKeyParameterName}' parameter. Environment variables are not supported in this environment.`
685
837
  });
686
838
  }
687
839
  apiKey = process.env[environmentVariableName];
@@ -697,8 +849,8 @@ function loadApiKey({
697
849
  }
698
850
  return apiKey;
699
851
  }
700
- var suspectProtoRx = /"__proto__"\s*:/;
701
- var suspectConstructorRx = /"constructor"\s*:/;
852
+ var suspectProtoRx = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/;
853
+ var suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
702
854
  function _parse(text) {
703
855
  const obj = JSON.parse(text);
704
856
  if (obj === null || typeof obj !== "object") {
@@ -718,7 +870,7 @@ function filter(obj) {
718
870
  if (Object.prototype.hasOwnProperty.call(node, "__proto__")) {
719
871
  throw new SyntaxError("Object contains forbidden prototype property");
720
872
  }
721
- if (Object.prototype.hasOwnProperty.call(node, "constructor") && Object.prototype.hasOwnProperty.call(node.constructor, "prototype")) {
873
+ if (Object.prototype.hasOwnProperty.call(node, "constructor") && node.constructor !== null && typeof node.constructor === "object" && Object.prototype.hasOwnProperty.call(node.constructor, "prototype")) {
722
874
  throw new SyntaxError("Object contains forbidden prototype property");
723
875
  }
724
876
  for (const key in node) {
@@ -745,31 +897,40 @@ function secureJsonParse(text) {
745
897
  }
746
898
  }
747
899
  function addAdditionalPropertiesToJsonSchema(jsonSchema2) {
748
- if (jsonSchema2.type === "object") {
900
+ if (jsonSchema2.type === "object" || Array.isArray(jsonSchema2.type) && jsonSchema2.type.includes("object")) {
749
901
  jsonSchema2.additionalProperties = false;
750
- const properties = jsonSchema2.properties;
902
+ const { properties } = jsonSchema2;
751
903
  if (properties != null) {
752
- for (const property in properties) {
753
- properties[property] = addAdditionalPropertiesToJsonSchema(
754
- properties[property]
755
- );
904
+ for (const key of Object.keys(properties)) {
905
+ properties[key] = visit(properties[key]);
756
906
  }
757
907
  }
758
908
  }
759
- if (jsonSchema2.type === "array" && jsonSchema2.items != null) {
760
- if (Array.isArray(jsonSchema2.items)) {
761
- jsonSchema2.items = jsonSchema2.items.map(
762
- (item) => addAdditionalPropertiesToJsonSchema(item)
763
- );
764
- } else {
765
- jsonSchema2.items = addAdditionalPropertiesToJsonSchema(
766
- jsonSchema2.items
767
- );
909
+ if (jsonSchema2.items != null) {
910
+ jsonSchema2.items = Array.isArray(jsonSchema2.items) ? jsonSchema2.items.map(visit) : visit(jsonSchema2.items);
911
+ }
912
+ if (jsonSchema2.anyOf != null) {
913
+ jsonSchema2.anyOf = jsonSchema2.anyOf.map(visit);
914
+ }
915
+ if (jsonSchema2.allOf != null) {
916
+ jsonSchema2.allOf = jsonSchema2.allOf.map(visit);
917
+ }
918
+ if (jsonSchema2.oneOf != null) {
919
+ jsonSchema2.oneOf = jsonSchema2.oneOf.map(visit);
920
+ }
921
+ const { definitions } = jsonSchema2;
922
+ if (definitions != null) {
923
+ for (const key of Object.keys(definitions)) {
924
+ definitions[key] = visit(definitions[key]);
768
925
  }
769
926
  }
770
927
  return jsonSchema2;
771
928
  }
772
- var ignoreOverride = Symbol(
929
+ function visit(def) {
930
+ if (typeof def === "boolean") return def;
931
+ return addAdditionalPropertiesToJsonSchema(def);
932
+ }
933
+ var ignoreOverride = /* @__PURE__ */ Symbol(
773
934
  "Let zodToJsonSchema decide on which parser to use"
774
935
  );
775
936
  var defaultOptions = {
@@ -1835,7 +1996,7 @@ var zod3ToJsonSchema = (schema, options) => {
1835
1996
  combined.$schema = "http://json-schema.org/draft-07/schema#";
1836
1997
  return combined;
1837
1998
  };
1838
- var schemaSymbol = Symbol.for("vercel.ai.schema");
1999
+ var schemaSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.schema");
1839
2000
  function jsonSchema(jsonSchema2, {
1840
2001
  validate
1841
2002
  } = {}) {
@@ -1860,9 +2021,11 @@ function asSchema(schema) {
1860
2021
  }
1861
2022
  function standardSchema(standardSchema2) {
1862
2023
  return jsonSchema(
1863
- () => standardSchema2["~standard"].jsonSchema.input({
1864
- target: "draft-07"
1865
- }),
2024
+ () => addAdditionalPropertiesToJsonSchema(
2025
+ standardSchema2["~standard"].jsonSchema.input({
2026
+ target: "draft-07"
2027
+ })
2028
+ ),
1866
2029
  {
1867
2030
  validate: async (value) => {
1868
2031
  const result = await standardSchema2["~standard"].validate(value);
@@ -1925,17 +2088,19 @@ function zodSchema(zodSchema2, options) {
1925
2088
  }
1926
2089
  async function validateTypes({
1927
2090
  value,
1928
- schema
2091
+ schema,
2092
+ context
1929
2093
  }) {
1930
- const result = await safeValidateTypes({ value, schema });
2094
+ const result = await safeValidateTypes({ value, schema, context });
1931
2095
  if (!result.success) {
1932
- throw TypeValidationError.wrap({ value, cause: result.error });
2096
+ throw TypeValidationError.wrap({ value, cause: result.error, context });
1933
2097
  }
1934
2098
  return result.value;
1935
2099
  }
1936
2100
  async function safeValidateTypes({
1937
2101
  value,
1938
- schema
2102
+ schema,
2103
+ context
1939
2104
  }) {
1940
2105
  const actualSchema = asSchema(schema);
1941
2106
  try {
@@ -1948,13 +2113,13 @@ async function safeValidateTypes({
1948
2113
  }
1949
2114
  return {
1950
2115
  success: false,
1951
- error: TypeValidationError.wrap({ value, cause: result.error }),
2116
+ error: TypeValidationError.wrap({ value, cause: result.error, context }),
1952
2117
  rawValue: value
1953
2118
  };
1954
2119
  } catch (error) {
1955
2120
  return {
1956
2121
  success: false,
1957
- error: TypeValidationError.wrap({ value, cause: error }),
2122
+ error: TypeValidationError.wrap({ value, cause: error, context }),
1958
2123
  rawValue: value
1959
2124
  };
1960
2125
  }
@@ -3385,7 +3550,7 @@ var OpenRouterChatLanguageModel = class {
3385
3550
  tools,
3386
3551
  toolChoice
3387
3552
  }) {
3388
- var _a16;
3553
+ var _a16, _b16;
3389
3554
  const baseArgs = __spreadValues(__spreadValues({
3390
3555
  // model id:
3391
3556
  model: this.modelId,
@@ -3396,12 +3561,12 @@ var OpenRouterChatLanguageModel = class {
3396
3561
  top_logprobs: typeof this.settings.logprobs === "number" ? this.settings.logprobs : typeof this.settings.logprobs === "boolean" ? this.settings.logprobs ? 0 : void 0 : void 0,
3397
3562
  user: this.settings.user,
3398
3563
  parallel_tool_calls: this.settings.parallelToolCalls,
3399
- // standardized settings:
3400
- max_tokens: maxOutputTokens,
3401
- temperature,
3402
- top_p: topP,
3403
- frequency_penalty: frequencyPenalty,
3404
- presence_penalty: presencePenalty,
3564
+ // standardized settings (call-level options override model-level settings):
3565
+ max_tokens: maxOutputTokens != null ? maxOutputTokens : this.settings.maxTokens,
3566
+ temperature: temperature != null ? temperature : this.settings.temperature,
3567
+ top_p: topP != null ? topP : this.settings.topP,
3568
+ frequency_penalty: frequencyPenalty != null ? frequencyPenalty : this.settings.frequencyPenalty,
3569
+ presence_penalty: presencePenalty != null ? presencePenalty : this.settings.presencePenalty,
3405
3570
  seed,
3406
3571
  stop: stopSequences,
3407
3572
  response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? responseFormat.schema != null ? {
@@ -3414,7 +3579,7 @@ var OpenRouterChatLanguageModel = class {
3414
3579
  description: responseFormat.description
3415
3580
  })
3416
3581
  } : { type: "json_object" } : void 0,
3417
- top_k: topK,
3582
+ top_k: topK != null ? topK : this.settings.topK,
3418
3583
  // messages:
3419
3584
  messages: convertToOpenRouterChatMessages(prompt),
3420
3585
  // OpenRouter specific settings:
@@ -3435,14 +3600,18 @@ var OpenRouterChatLanguageModel = class {
3435
3600
  const mappedTools = [];
3436
3601
  for (const tool2 of tools) {
3437
3602
  if (tool2.type === "function") {
3438
- mappedTools.push({
3603
+ const openrouterOptions = (_b16 = tool2.providerOptions) == null ? void 0 : _b16.openrouter;
3604
+ const eagerInputStreaming = openrouterOptions == null ? void 0 : openrouterOptions.eager_input_streaming;
3605
+ mappedTools.push(__spreadValues({
3439
3606
  type: "function",
3440
3607
  function: {
3441
3608
  name: tool2.name,
3442
3609
  description: tool2.description,
3443
3610
  parameters: tool2.inputSchema
3444
3611
  }
3445
- });
3612
+ }, eagerInputStreaming != null && {
3613
+ eager_input_streaming: eagerInputStreaming
3614
+ }));
3446
3615
  } else if (tool2.type === "provider") {
3447
3616
  mappedTools.push(mapProviderTool(tool2));
3448
3617
  }
@@ -3780,18 +3949,16 @@ var OpenRouterChatLanguageModel = class {
3780
3949
  return;
3781
3950
  }
3782
3951
  const delta = choice.delta;
3783
- const emitReasoningChunk = (chunkText, providerMetadata) => {
3952
+ const emitReasoningChunk = (chunkText) => {
3784
3953
  if (!reasoningStarted) {
3785
3954
  reasoningId = generateId();
3786
3955
  controller.enqueue({
3787
- providerMetadata,
3788
3956
  type: "reasoning-start",
3789
3957
  id: reasoningId
3790
3958
  });
3791
3959
  reasoningStarted = true;
3792
3960
  }
3793
3961
  controller.enqueue({
3794
- providerMetadata,
3795
3962
  type: "reasoning-delta",
3796
3963
  delta: chunkText,
3797
3964
  id: reasoningId || generateId()
@@ -3813,15 +3980,10 @@ var OpenRouterChatLanguageModel = class {
3813
3980
  }
3814
3981
  }
3815
3982
  if (!textStarted) {
3816
- const reasoningMetadata = {
3817
- openrouter: {
3818
- reasoning_details: accumulatedReasoningDetails.map((d) => __spreadValues({}, d))
3819
- }
3820
- };
3821
3983
  for (const detail of delta.reasoning_details) {
3822
3984
  switch (detail.type) {
3823
3985
  case "reasoning.text" /* Text */: {
3824
- emitReasoningChunk(detail.text || "", reasoningMetadata);
3986
+ emitReasoningChunk(detail.text || "");
3825
3987
  break;
3826
3988
  }
3827
3989
  case "reasoning.encrypted" /* Encrypted */: {
@@ -3829,7 +3991,7 @@ var OpenRouterChatLanguageModel = class {
3829
3991
  }
3830
3992
  case "reasoning.summary" /* Summary */: {
3831
3993
  if (detail.summary) {
3832
- emitReasoningChunk(detail.summary, reasoningMetadata);
3994
+ emitReasoningChunk(detail.summary);
3833
3995
  }
3834
3996
  break;
3835
3997
  }
@@ -4118,6 +4280,12 @@ var OpenRouterChatLanguageModel = class {
4118
4280
  if (accumulatedFileAnnotations.length > 0) {
4119
4281
  openrouterMetadata.annotations = accumulatedFileAnnotations;
4120
4282
  }
4283
+ if (usage.inputTokens.total === void 0 && openrouterUsage.promptTokens !== void 0) {
4284
+ usage.inputTokens.total = openrouterUsage.promptTokens;
4285
+ }
4286
+ if (usage.outputTokens.total === void 0 && openrouterUsage.completionTokens !== void 0) {
4287
+ usage.outputTokens.total = openrouterUsage.completionTokens;
4288
+ }
4121
4289
  usage.raw = rawUsage;
4122
4290
  controller.enqueue({
4123
4291
  type: "finish",
@@ -4353,16 +4521,16 @@ var OpenRouterCompletionLanguageModel = class {
4353
4521
  logprobs: typeof this.settings.logprobs === "number" ? this.settings.logprobs : typeof this.settings.logprobs === "boolean" ? this.settings.logprobs ? 0 : void 0 : void 0,
4354
4522
  suffix: this.settings.suffix,
4355
4523
  user: this.settings.user,
4356
- // standardized settings:
4357
- max_tokens: maxOutputTokens,
4358
- temperature,
4359
- top_p: topP,
4360
- frequency_penalty: frequencyPenalty,
4361
- presence_penalty: presencePenalty,
4524
+ // standardized settings (call-level options override model-level settings):
4525
+ max_tokens: maxOutputTokens != null ? maxOutputTokens : this.settings.maxTokens,
4526
+ temperature: temperature != null ? temperature : this.settings.temperature,
4527
+ top_p: topP != null ? topP : this.settings.topP,
4528
+ frequency_penalty: frequencyPenalty != null ? frequencyPenalty : this.settings.frequencyPenalty,
4529
+ presence_penalty: presencePenalty != null ? presencePenalty : this.settings.presencePenalty,
4362
4530
  seed,
4363
4531
  stop: stopSequences,
4364
4532
  response_format: responseFormat,
4365
- top_k: topK,
4533
+ top_k: topK != null ? topK : this.settings.topK,
4366
4534
  // prompt:
4367
4535
  prompt: completionPrompt,
4368
4536
  // OpenRouter specific settings:
@@ -4932,7 +5100,199 @@ function withUserAgentSuffix2(headers, ...userAgentSuffixParts) {
4932
5100
  }
4933
5101
 
4934
5102
  // src/version.ts
4935
- var VERSION2 = false ? "0.0.0-test" : "2.6.0";
5103
+ var VERSION2 = false ? "0.0.0-test" : "2.8.0";
5104
+
5105
+ // src/video/schemas.ts
5106
+ var import_v411 = require("zod/v4");
5107
+ var VideoGenerationSubmitResponseSchema = import_v411.z.object({
5108
+ id: import_v411.z.string(),
5109
+ generation_id: import_v411.z.string().optional(),
5110
+ polling_url: import_v411.z.string(),
5111
+ status: import_v411.z.string()
5112
+ }).passthrough();
5113
+ var VideoGenerationPollResponseSchema = import_v411.z.object({
5114
+ id: import_v411.z.string(),
5115
+ generation_id: import_v411.z.string().optional(),
5116
+ polling_url: import_v411.z.string(),
5117
+ status: import_v411.z.string(),
5118
+ unsigned_urls: import_v411.z.array(import_v411.z.string()).optional(),
5119
+ usage: import_v411.z.object({
5120
+ cost: import_v411.z.number().optional(),
5121
+ is_byok: import_v411.z.boolean().optional()
5122
+ }).passthrough().optional(),
5123
+ error: import_v411.z.string().optional()
5124
+ }).passthrough();
5125
+
5126
+ // src/video/index.ts
5127
+ var DEFAULT_POLL_INTERVAL_MS = 2e3;
5128
+ var DEFAULT_MAX_POLL_TIME_MS = 6e5;
5129
+ var OpenRouterVideoModel = class {
5130
+ constructor(modelId, settings, config) {
5131
+ this.specificationVersion = "v3";
5132
+ this.provider = "openrouter";
5133
+ this.maxVideosPerCall = 1;
5134
+ this.modelId = modelId;
5135
+ this.settings = settings;
5136
+ this.config = config;
5137
+ }
5138
+ async doGenerate(options) {
5139
+ var _a16, _b16, _c, _d, _e;
5140
+ const {
5141
+ prompt,
5142
+ n,
5143
+ aspectRatio,
5144
+ resolution,
5145
+ duration,
5146
+ seed,
5147
+ image,
5148
+ abortSignal,
5149
+ headers,
5150
+ providerOptions
5151
+ } = options;
5152
+ const warnings = [];
5153
+ if (n > 1) {
5154
+ warnings.push({
5155
+ type: "unsupported",
5156
+ feature: "n > 1",
5157
+ details: `OpenRouter video generation returns 1 video per call. Requested ${n} videos.`
5158
+ });
5159
+ }
5160
+ const body = __spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({
5161
+ model: this.modelId,
5162
+ prompt: prompt != null ? prompt : ""
5163
+ }, aspectRatio !== void 0 && { aspect_ratio: aspectRatio }), resolution !== void 0 && { size: resolution }), duration !== void 0 && { duration }), seed !== void 0 && { seed }), this.settings.generateAudio !== void 0 && {
5164
+ generate_audio: this.settings.generateAudio
5165
+ }), image !== void 0 && {
5166
+ frame_images: [convertImageToFrameImage(image)]
5167
+ }), this.config.extraBody), this.settings.extraBody), providerOptions.openrouter);
5168
+ const mergedHeaders = combineHeaders(this.config.headers(), headers);
5169
+ const { value: submitResponse, responseHeaders } = await postJsonToApi({
5170
+ url: this.config.url({
5171
+ path: "/videos",
5172
+ modelId: this.modelId
5173
+ }),
5174
+ headers: mergedHeaders,
5175
+ body,
5176
+ failedResponseHandler: openrouterFailedResponseHandler,
5177
+ successfulResponseHandler: createJsonResponseHandler(
5178
+ VideoGenerationSubmitResponseSchema
5179
+ ),
5180
+ abortSignal,
5181
+ fetch: this.config.fetch
5182
+ });
5183
+ const pollIntervalMs = (_a16 = this.settings.pollIntervalMs) != null ? _a16 : DEFAULT_POLL_INTERVAL_MS;
5184
+ const maxPollTimeMs = (_b16 = this.settings.maxPollTimeMs) != null ? _b16 : DEFAULT_MAX_POLL_TIME_MS;
5185
+ const pollResult = await this.pollUntilComplete({
5186
+ jobId: submitResponse.id,
5187
+ headers: mergedHeaders,
5188
+ abortSignal,
5189
+ pollIntervalMs,
5190
+ maxPollTimeMs
5191
+ });
5192
+ const videos = [];
5193
+ if (pollResult.unsigned_urls) {
5194
+ for (const url of pollResult.unsigned_urls) {
5195
+ videos.push({
5196
+ type: "url",
5197
+ url,
5198
+ mediaType: "video/mp4"
5199
+ });
5200
+ }
5201
+ }
5202
+ const providerMetadata = {
5203
+ openrouter: {
5204
+ generationId: (_c = pollResult.generation_id) != null ? _c : null,
5205
+ cost: (_e = (_d = pollResult.usage) == null ? void 0 : _d.cost) != null ? _e : null
5206
+ }
5207
+ };
5208
+ return {
5209
+ videos,
5210
+ warnings,
5211
+ providerMetadata,
5212
+ response: {
5213
+ timestamp: /* @__PURE__ */ new Date(),
5214
+ modelId: this.modelId,
5215
+ headers: responseHeaders
5216
+ }
5217
+ };
5218
+ }
5219
+ async pollUntilComplete({
5220
+ jobId,
5221
+ headers,
5222
+ abortSignal,
5223
+ pollIntervalMs,
5224
+ maxPollTimeMs
5225
+ }) {
5226
+ var _a16;
5227
+ const startTime = Date.now();
5228
+ while (Date.now() - startTime < maxPollTimeMs) {
5229
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
5230
+ await delay(pollIntervalMs);
5231
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
5232
+ const { value: pollResponse } = await getFromApi({
5233
+ url: this.config.url({
5234
+ path: `/videos/${jobId}`,
5235
+ modelId: this.modelId
5236
+ }),
5237
+ headers,
5238
+ failedResponseHandler: openrouterFailedResponseHandler,
5239
+ successfulResponseHandler: createJsonResponseHandler(
5240
+ VideoGenerationPollResponseSchema
5241
+ ),
5242
+ abortSignal,
5243
+ fetch: this.config.fetch
5244
+ });
5245
+ if (pollResponse.status === "completed") {
5246
+ return {
5247
+ generation_id: pollResponse.generation_id,
5248
+ unsigned_urls: pollResponse.unsigned_urls,
5249
+ usage: pollResponse.usage
5250
+ };
5251
+ }
5252
+ if (pollResponse.status === "failed" || pollResponse.status === "dead" || pollResponse.status === "cancelled" || pollResponse.status === "expired") {
5253
+ throw new APICallError({
5254
+ message: (_a16 = pollResponse.error) != null ? _a16 : `Video generation failed with status: ${pollResponse.status}`,
5255
+ url: this.config.url({
5256
+ path: `/videos/${jobId}`,
5257
+ modelId: this.modelId
5258
+ }),
5259
+ requestBodyValues: {},
5260
+ statusCode: 500,
5261
+ isRetryable: false
5262
+ });
5263
+ }
5264
+ }
5265
+ throw new APICallError({
5266
+ message: `Video generation timed out after ${maxPollTimeMs}ms`,
5267
+ url: this.config.url({
5268
+ path: `/videos/${jobId}`,
5269
+ modelId: this.modelId
5270
+ }),
5271
+ requestBodyValues: {},
5272
+ statusCode: 408,
5273
+ isRetryable: true
5274
+ });
5275
+ }
5276
+ };
5277
+ function convertImageToFrameImage(file) {
5278
+ if (file.type === "url") {
5279
+ return {
5280
+ type: "image_url",
5281
+ image_url: { url: file.url },
5282
+ frame_type: "first_frame"
5283
+ };
5284
+ }
5285
+ const url = buildFileDataUrl({
5286
+ data: file.data,
5287
+ mediaType: file.mediaType,
5288
+ defaultMediaType: "image/png"
5289
+ });
5290
+ return {
5291
+ type: "image_url",
5292
+ image_url: { url },
5293
+ frame_type: "first_frame"
5294
+ };
5295
+ }
4936
5296
 
4937
5297
  // src/provider.ts
4938
5298
  function createOpenRouter(options = {}) {
@@ -4981,6 +5341,13 @@ function createOpenRouter(options = {}) {
4981
5341
  fetch: options.fetch,
4982
5342
  extraBody: options.extraBody
4983
5343
  });
5344
+ const createVideoModel = (modelId, settings = {}) => new OpenRouterVideoModel(modelId, settings, {
5345
+ provider: "openrouter.video",
5346
+ url: ({ path }) => `${baseURL}${path}`,
5347
+ headers: getHeaders,
5348
+ fetch: options.fetch,
5349
+ extraBody: options.extraBody
5350
+ });
4984
5351
  const createLanguageModel = (modelId, settings) => {
4985
5352
  if (new.target) {
4986
5353
  throw new Error(
@@ -5002,6 +5369,7 @@ function createOpenRouter(options = {}) {
5002
5369
  provider.textEmbeddingModel = createEmbeddingModel;
5003
5370
  provider.embedding = createEmbeddingModel;
5004
5371
  provider.imageModel = createImageModel;
5372
+ provider.videoModel = createVideoModel;
5005
5373
  provider.tools = {
5006
5374
  webSearch
5007
5375
  };