@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.
@@ -68,11 +68,12 @@ __export(index_exports, {
68
68
  OpenRouterChatLanguageModel: () => OpenRouterChatLanguageModel,
69
69
  OpenRouterCompletionLanguageModel: () => OpenRouterCompletionLanguageModel,
70
70
  OpenRouterEmbeddingModel: () => OpenRouterEmbeddingModel,
71
- OpenRouterImageModel: () => OpenRouterImageModel
71
+ OpenRouterImageModel: () => OpenRouterImageModel,
72
+ OpenRouterVideoModel: () => OpenRouterVideoModel
72
73
  });
73
74
  module.exports = __toCommonJS(index_exports);
74
75
 
75
- // node_modules/.pnpm/@ai-sdk+provider@3.0.0/node_modules/@ai-sdk/provider/dist/index.mjs
76
+ // node_modules/.pnpm/@ai-sdk+provider@3.0.8/node_modules/@ai-sdk/provider/dist/index.mjs
76
77
  var marker = "vercel.ai.error";
77
78
  var symbol = Symbol.for(marker);
78
79
  var _a;
@@ -342,34 +343,61 @@ var symbol13 = Symbol.for(marker13);
342
343
  var _a13;
343
344
  var _b13;
344
345
  var TypeValidationError = class _TypeValidationError extends (_b13 = AISDKError, _a13 = symbol13, _b13) {
345
- constructor({ value, cause }) {
346
+ constructor({
347
+ value,
348
+ cause,
349
+ context
350
+ }) {
351
+ let contextPrefix = "Type validation failed";
352
+ if (context == null ? void 0 : context.field) {
353
+ contextPrefix += ` for ${context.field}`;
354
+ }
355
+ if ((context == null ? void 0 : context.entityName) || (context == null ? void 0 : context.entityId)) {
356
+ contextPrefix += " (";
357
+ const parts = [];
358
+ if (context.entityName) {
359
+ parts.push(context.entityName);
360
+ }
361
+ if (context.entityId) {
362
+ parts.push(`id: "${context.entityId}"`);
363
+ }
364
+ contextPrefix += parts.join(", ");
365
+ contextPrefix += ")";
366
+ }
346
367
  super({
347
368
  name: name12,
348
- message: `Type validation failed: Value: ${JSON.stringify(value)}.
369
+ message: `${contextPrefix}: Value: ${JSON.stringify(value)}.
349
370
  Error message: ${getErrorMessage(cause)}`,
350
371
  cause
351
372
  });
352
373
  this[_a13] = true;
353
374
  this.value = value;
375
+ this.context = context;
354
376
  }
355
377
  static isInstance(error) {
356
378
  return AISDKError.hasMarker(error, marker13);
357
379
  }
358
380
  /**
359
381
  * Wraps an error into a TypeValidationError.
360
- * If the cause is already a TypeValidationError with the same value, it returns the cause.
382
+ * If the cause is already a TypeValidationError with the same value and context, it returns the cause.
361
383
  * Otherwise, it creates a new TypeValidationError.
362
384
  *
363
385
  * @param {Object} params - The parameters for wrapping the error.
364
386
  * @param {unknown} params.value - The value that failed validation.
365
387
  * @param {unknown} params.cause - The original error or cause of the validation failure.
388
+ * @param {TypeValidationContext} params.context - Optional context about what is being validated.
366
389
  * @returns {TypeValidationError} A TypeValidationError instance.
367
390
  */
368
391
  static wrap({
369
392
  value,
370
- cause
393
+ cause,
394
+ context
371
395
  }) {
372
- return _TypeValidationError.isInstance(cause) && cause.value === value ? cause : new _TypeValidationError({ value, cause });
396
+ var _a152, _b152, _c;
397
+ 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)) {
398
+ return cause;
399
+ }
400
+ return new _TypeValidationError({ value, cause, context });
373
401
  }
374
402
  };
375
403
  var name13 = "AI_UnsupportedFunctionalityError";
@@ -391,7 +419,7 @@ var UnsupportedFunctionalityError = class extends (_b14 = AISDKError, _a14 = sym
391
419
  }
392
420
  };
393
421
 
394
- // node_modules/.pnpm/@ai-sdk+provider-utils@4.0.1_zod@4.3.5/node_modules/@ai-sdk/provider-utils/dist/index.mjs
422
+ // node_modules/.pnpm/@ai-sdk+provider-utils@4.0.23_zod@4.3.5/node_modules/@ai-sdk/provider-utils/dist/index.mjs
395
423
  var z4 = __toESM(require("zod/v4"), 1);
396
424
  var import_v3 = require("zod/v3");
397
425
  var import_v32 = require("zod/v3");
@@ -524,13 +552,41 @@ var EventSourceParserStream = class extends TransformStream {
524
552
  }
525
553
  };
526
554
 
527
- // node_modules/.pnpm/@ai-sdk+provider-utils@4.0.1_zod@4.3.5/node_modules/@ai-sdk/provider-utils/dist/index.mjs
555
+ // node_modules/.pnpm/@ai-sdk+provider-utils@4.0.23_zod@4.3.5/node_modules/@ai-sdk/provider-utils/dist/index.mjs
528
556
  function combineHeaders(...headers) {
529
557
  return headers.reduce(
530
558
  (combinedHeaders, currentHeaders) => __spreadValues(__spreadValues({}, combinedHeaders), currentHeaders != null ? currentHeaders : {}),
531
559
  {}
532
560
  );
533
561
  }
562
+ async function delay(delayInMs, options) {
563
+ if (delayInMs == null) {
564
+ return Promise.resolve();
565
+ }
566
+ const signal = options == null ? void 0 : options.abortSignal;
567
+ return new Promise((resolve2, reject) => {
568
+ if (signal == null ? void 0 : signal.aborted) {
569
+ reject(createAbortError());
570
+ return;
571
+ }
572
+ const timeoutId = setTimeout(() => {
573
+ cleanup();
574
+ resolve2();
575
+ }, delayInMs);
576
+ const cleanup = () => {
577
+ clearTimeout(timeoutId);
578
+ signal == null ? void 0 : signal.removeEventListener("abort", onAbort);
579
+ };
580
+ const onAbort = () => {
581
+ cleanup();
582
+ reject(createAbortError());
583
+ };
584
+ signal == null ? void 0 : signal.addEventListener("abort", onAbort);
585
+ });
586
+ }
587
+ function createAbortError() {
588
+ return new DOMException("Delay was aborted", "AbortError");
589
+ }
534
590
  function extractResponseHeaders(response) {
535
591
  return Object.fromEntries([...response.headers]);
536
592
  }
@@ -565,6 +621,7 @@ var DownloadError = class extends (_b15 = AISDKError, _a15 = symbol15, _b15) {
565
621
  return AISDKError.hasMarker(error, marker15);
566
622
  }
567
623
  };
624
+ var DEFAULT_MAX_DOWNLOAD_SIZE = 2 * 1024 * 1024 * 1024;
568
625
  var createIdGenerator = ({
569
626
  prefix,
570
627
  size = 16,
@@ -596,6 +653,25 @@ function isAbortError(error) {
596
653
  error.name === "TimeoutError");
597
654
  }
598
655
  var FETCH_FAILED_ERROR_MESSAGES = ["fetch failed", "failed to fetch"];
656
+ var BUN_ERROR_CODES = [
657
+ "ConnectionRefused",
658
+ "ConnectionClosed",
659
+ "FailedToOpenSocket",
660
+ "ECONNRESET",
661
+ "ECONNREFUSED",
662
+ "ETIMEDOUT",
663
+ "EPIPE"
664
+ ];
665
+ function isBunNetworkError(error) {
666
+ if (!(error instanceof Error)) {
667
+ return false;
668
+ }
669
+ const code = error.code;
670
+ if (typeof code === "string" && BUN_ERROR_CODES.includes(code)) {
671
+ return true;
672
+ }
673
+ return false;
674
+ }
599
675
  function handleFetchError({
600
676
  error,
601
677
  url,
@@ -617,6 +693,15 @@ function handleFetchError({
617
693
  });
618
694
  }
619
695
  }
696
+ if (isBunNetworkError(error)) {
697
+ return new APICallError({
698
+ message: `Cannot connect to API: ${error.message}`,
699
+ cause: error,
700
+ url,
701
+ requestBodyValues,
702
+ isRetryable: true
703
+ });
704
+ }
620
705
  return error;
621
706
  }
622
707
  function getRuntimeEnvironmentUserAgent(globalThisAny = globalThis) {
@@ -665,9 +750,77 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
665
750
  );
666
751
  return Object.fromEntries(normalizedHeaders.entries());
667
752
  }
668
- var VERSION = true ? "4.0.1" : "0.0.0-test";
669
- var suspectProtoRx = /"__proto__"\s*:/;
670
- var suspectConstructorRx = /"constructor"\s*:/;
753
+ var VERSION = true ? "4.0.23" : "0.0.0-test";
754
+ var getOriginalFetch = () => globalThis.fetch;
755
+ var getFromApi = async ({
756
+ url,
757
+ headers = {},
758
+ successfulResponseHandler,
759
+ failedResponseHandler,
760
+ abortSignal,
761
+ fetch: fetch2 = getOriginalFetch()
762
+ }) => {
763
+ try {
764
+ const response = await fetch2(url, {
765
+ method: "GET",
766
+ headers: withUserAgentSuffix(
767
+ headers,
768
+ `ai-sdk/provider-utils/${VERSION}`,
769
+ getRuntimeEnvironmentUserAgent()
770
+ ),
771
+ signal: abortSignal
772
+ });
773
+ const responseHeaders = extractResponseHeaders(response);
774
+ if (!response.ok) {
775
+ let errorInformation;
776
+ try {
777
+ errorInformation = await failedResponseHandler({
778
+ response,
779
+ url,
780
+ requestBodyValues: {}
781
+ });
782
+ } catch (error) {
783
+ if (isAbortError(error) || APICallError.isInstance(error)) {
784
+ throw error;
785
+ }
786
+ throw new APICallError({
787
+ message: "Failed to process error response",
788
+ cause: error,
789
+ statusCode: response.status,
790
+ url,
791
+ responseHeaders,
792
+ requestBodyValues: {}
793
+ });
794
+ }
795
+ throw errorInformation.value;
796
+ }
797
+ try {
798
+ return await successfulResponseHandler({
799
+ response,
800
+ url,
801
+ requestBodyValues: {}
802
+ });
803
+ } catch (error) {
804
+ if (error instanceof Error) {
805
+ if (isAbortError(error) || APICallError.isInstance(error)) {
806
+ throw error;
807
+ }
808
+ }
809
+ throw new APICallError({
810
+ message: "Failed to process successful response",
811
+ cause: error,
812
+ statusCode: response.status,
813
+ url,
814
+ responseHeaders,
815
+ requestBodyValues: {}
816
+ });
817
+ }
818
+ } catch (error) {
819
+ throw handleFetchError({ error, url, requestBodyValues: {} });
820
+ }
821
+ };
822
+ var suspectProtoRx = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/;
823
+ 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*:/;
671
824
  function _parse(text) {
672
825
  const obj = JSON.parse(text);
673
826
  if (obj === null || typeof obj !== "object") {
@@ -687,7 +840,7 @@ function filter(obj) {
687
840
  if (Object.prototype.hasOwnProperty.call(node, "__proto__")) {
688
841
  throw new SyntaxError("Object contains forbidden prototype property");
689
842
  }
690
- if (Object.prototype.hasOwnProperty.call(node, "constructor") && Object.prototype.hasOwnProperty.call(node.constructor, "prototype")) {
843
+ if (Object.prototype.hasOwnProperty.call(node, "constructor") && node.constructor !== null && typeof node.constructor === "object" && Object.prototype.hasOwnProperty.call(node.constructor, "prototype")) {
691
844
  throw new SyntaxError("Object contains forbidden prototype property");
692
845
  }
693
846
  for (const key in node) {
@@ -714,31 +867,40 @@ function secureJsonParse(text) {
714
867
  }
715
868
  }
716
869
  function addAdditionalPropertiesToJsonSchema(jsonSchema2) {
717
- if (jsonSchema2.type === "object") {
870
+ if (jsonSchema2.type === "object" || Array.isArray(jsonSchema2.type) && jsonSchema2.type.includes("object")) {
718
871
  jsonSchema2.additionalProperties = false;
719
- const properties = jsonSchema2.properties;
872
+ const { properties } = jsonSchema2;
720
873
  if (properties != null) {
721
- for (const property in properties) {
722
- properties[property] = addAdditionalPropertiesToJsonSchema(
723
- properties[property]
724
- );
874
+ for (const key of Object.keys(properties)) {
875
+ properties[key] = visit(properties[key]);
725
876
  }
726
877
  }
727
878
  }
728
- if (jsonSchema2.type === "array" && jsonSchema2.items != null) {
729
- if (Array.isArray(jsonSchema2.items)) {
730
- jsonSchema2.items = jsonSchema2.items.map(
731
- (item) => addAdditionalPropertiesToJsonSchema(item)
732
- );
733
- } else {
734
- jsonSchema2.items = addAdditionalPropertiesToJsonSchema(
735
- jsonSchema2.items
736
- );
879
+ if (jsonSchema2.items != null) {
880
+ jsonSchema2.items = Array.isArray(jsonSchema2.items) ? jsonSchema2.items.map(visit) : visit(jsonSchema2.items);
881
+ }
882
+ if (jsonSchema2.anyOf != null) {
883
+ jsonSchema2.anyOf = jsonSchema2.anyOf.map(visit);
884
+ }
885
+ if (jsonSchema2.allOf != null) {
886
+ jsonSchema2.allOf = jsonSchema2.allOf.map(visit);
887
+ }
888
+ if (jsonSchema2.oneOf != null) {
889
+ jsonSchema2.oneOf = jsonSchema2.oneOf.map(visit);
890
+ }
891
+ const { definitions } = jsonSchema2;
892
+ if (definitions != null) {
893
+ for (const key of Object.keys(definitions)) {
894
+ definitions[key] = visit(definitions[key]);
737
895
  }
738
896
  }
739
897
  return jsonSchema2;
740
898
  }
741
- var ignoreOverride = Symbol(
899
+ function visit(def) {
900
+ if (typeof def === "boolean") return def;
901
+ return addAdditionalPropertiesToJsonSchema(def);
902
+ }
903
+ var ignoreOverride = /* @__PURE__ */ Symbol(
742
904
  "Let zodToJsonSchema decide on which parser to use"
743
905
  );
744
906
  var defaultOptions = {
@@ -1804,7 +1966,7 @@ var zod3ToJsonSchema = (schema, options) => {
1804
1966
  combined.$schema = "http://json-schema.org/draft-07/schema#";
1805
1967
  return combined;
1806
1968
  };
1807
- var schemaSymbol = Symbol.for("vercel.ai.schema");
1969
+ var schemaSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.schema");
1808
1970
  function jsonSchema(jsonSchema2, {
1809
1971
  validate
1810
1972
  } = {}) {
@@ -1829,9 +1991,11 @@ function asSchema(schema) {
1829
1991
  }
1830
1992
  function standardSchema(standardSchema2) {
1831
1993
  return jsonSchema(
1832
- () => standardSchema2["~standard"].jsonSchema.input({
1833
- target: "draft-07"
1834
- }),
1994
+ () => addAdditionalPropertiesToJsonSchema(
1995
+ standardSchema2["~standard"].jsonSchema.input({
1996
+ target: "draft-07"
1997
+ })
1998
+ ),
1835
1999
  {
1836
2000
  validate: async (value) => {
1837
2001
  const result = await standardSchema2["~standard"].validate(value);
@@ -1894,17 +2058,19 @@ function zodSchema(zodSchema2, options) {
1894
2058
  }
1895
2059
  async function validateTypes({
1896
2060
  value,
1897
- schema
2061
+ schema,
2062
+ context
1898
2063
  }) {
1899
- const result = await safeValidateTypes({ value, schema });
2064
+ const result = await safeValidateTypes({ value, schema, context });
1900
2065
  if (!result.success) {
1901
- throw TypeValidationError.wrap({ value, cause: result.error });
2066
+ throw TypeValidationError.wrap({ value, cause: result.error, context });
1902
2067
  }
1903
2068
  return result.value;
1904
2069
  }
1905
2070
  async function safeValidateTypes({
1906
2071
  value,
1907
- schema
2072
+ schema,
2073
+ context
1908
2074
  }) {
1909
2075
  const actualSchema = asSchema(schema);
1910
2076
  try {
@@ -1917,13 +2083,13 @@ async function safeValidateTypes({
1917
2083
  }
1918
2084
  return {
1919
2085
  success: false,
1920
- error: TypeValidationError.wrap({ value, cause: result.error }),
2086
+ error: TypeValidationError.wrap({ value, cause: result.error, context }),
1921
2087
  rawValue: value
1922
2088
  };
1923
2089
  } catch (error) {
1924
2090
  return {
1925
2091
  success: false,
1926
- error: TypeValidationError.wrap({ value, cause: error }),
2092
+ error: TypeValidationError.wrap({ value, cause: error, context }),
1927
2093
  rawValue: value
1928
2094
  };
1929
2095
  }
@@ -3311,7 +3477,7 @@ var OpenRouterChatLanguageModel = class {
3311
3477
  tools,
3312
3478
  toolChoice
3313
3479
  }) {
3314
- var _a16;
3480
+ var _a16, _b16;
3315
3481
  const baseArgs = __spreadValues(__spreadValues({
3316
3482
  // model id:
3317
3483
  model: this.modelId,
@@ -3322,12 +3488,12 @@ var OpenRouterChatLanguageModel = class {
3322
3488
  top_logprobs: typeof this.settings.logprobs === "number" ? this.settings.logprobs : typeof this.settings.logprobs === "boolean" ? this.settings.logprobs ? 0 : void 0 : void 0,
3323
3489
  user: this.settings.user,
3324
3490
  parallel_tool_calls: this.settings.parallelToolCalls,
3325
- // standardized settings:
3326
- max_tokens: maxOutputTokens,
3327
- temperature,
3328
- top_p: topP,
3329
- frequency_penalty: frequencyPenalty,
3330
- presence_penalty: presencePenalty,
3491
+ // standardized settings (call-level options override model-level settings):
3492
+ max_tokens: maxOutputTokens != null ? maxOutputTokens : this.settings.maxTokens,
3493
+ temperature: temperature != null ? temperature : this.settings.temperature,
3494
+ top_p: topP != null ? topP : this.settings.topP,
3495
+ frequency_penalty: frequencyPenalty != null ? frequencyPenalty : this.settings.frequencyPenalty,
3496
+ presence_penalty: presencePenalty != null ? presencePenalty : this.settings.presencePenalty,
3331
3497
  seed,
3332
3498
  stop: stopSequences,
3333
3499
  response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? responseFormat.schema != null ? {
@@ -3340,7 +3506,7 @@ var OpenRouterChatLanguageModel = class {
3340
3506
  description: responseFormat.description
3341
3507
  })
3342
3508
  } : { type: "json_object" } : void 0,
3343
- top_k: topK,
3509
+ top_k: topK != null ? topK : this.settings.topK,
3344
3510
  // messages:
3345
3511
  messages: convertToOpenRouterChatMessages(prompt),
3346
3512
  // OpenRouter specific settings:
@@ -3361,14 +3527,18 @@ var OpenRouterChatLanguageModel = class {
3361
3527
  const mappedTools = [];
3362
3528
  for (const tool of tools) {
3363
3529
  if (tool.type === "function") {
3364
- mappedTools.push({
3530
+ const openrouterOptions = (_b16 = tool.providerOptions) == null ? void 0 : _b16.openrouter;
3531
+ const eagerInputStreaming = openrouterOptions == null ? void 0 : openrouterOptions.eager_input_streaming;
3532
+ mappedTools.push(__spreadValues({
3365
3533
  type: "function",
3366
3534
  function: {
3367
3535
  name: tool.name,
3368
3536
  description: tool.description,
3369
3537
  parameters: tool.inputSchema
3370
3538
  }
3371
- });
3539
+ }, eagerInputStreaming != null && {
3540
+ eager_input_streaming: eagerInputStreaming
3541
+ }));
3372
3542
  } else if (tool.type === "provider") {
3373
3543
  mappedTools.push(mapProviderTool(tool));
3374
3544
  }
@@ -3706,18 +3876,16 @@ var OpenRouterChatLanguageModel = class {
3706
3876
  return;
3707
3877
  }
3708
3878
  const delta = choice.delta;
3709
- const emitReasoningChunk = (chunkText, providerMetadata) => {
3879
+ const emitReasoningChunk = (chunkText) => {
3710
3880
  if (!reasoningStarted) {
3711
3881
  reasoningId = generateId();
3712
3882
  controller.enqueue({
3713
- providerMetadata,
3714
3883
  type: "reasoning-start",
3715
3884
  id: reasoningId
3716
3885
  });
3717
3886
  reasoningStarted = true;
3718
3887
  }
3719
3888
  controller.enqueue({
3720
- providerMetadata,
3721
3889
  type: "reasoning-delta",
3722
3890
  delta: chunkText,
3723
3891
  id: reasoningId || generateId()
@@ -3739,15 +3907,10 @@ var OpenRouterChatLanguageModel = class {
3739
3907
  }
3740
3908
  }
3741
3909
  if (!textStarted) {
3742
- const reasoningMetadata = {
3743
- openrouter: {
3744
- reasoning_details: accumulatedReasoningDetails.map((d) => __spreadValues({}, d))
3745
- }
3746
- };
3747
3910
  for (const detail of delta.reasoning_details) {
3748
3911
  switch (detail.type) {
3749
3912
  case "reasoning.text" /* Text */: {
3750
- emitReasoningChunk(detail.text || "", reasoningMetadata);
3913
+ emitReasoningChunk(detail.text || "");
3751
3914
  break;
3752
3915
  }
3753
3916
  case "reasoning.encrypted" /* Encrypted */: {
@@ -3755,7 +3918,7 @@ var OpenRouterChatLanguageModel = class {
3755
3918
  }
3756
3919
  case "reasoning.summary" /* Summary */: {
3757
3920
  if (detail.summary) {
3758
- emitReasoningChunk(detail.summary, reasoningMetadata);
3921
+ emitReasoningChunk(detail.summary);
3759
3922
  }
3760
3923
  break;
3761
3924
  }
@@ -4044,6 +4207,12 @@ var OpenRouterChatLanguageModel = class {
4044
4207
  if (accumulatedFileAnnotations.length > 0) {
4045
4208
  openrouterMetadata.annotations = accumulatedFileAnnotations;
4046
4209
  }
4210
+ if (usage.inputTokens.total === void 0 && openrouterUsage.promptTokens !== void 0) {
4211
+ usage.inputTokens.total = openrouterUsage.promptTokens;
4212
+ }
4213
+ if (usage.outputTokens.total === void 0 && openrouterUsage.completionTokens !== void 0) {
4214
+ usage.outputTokens.total = openrouterUsage.completionTokens;
4215
+ }
4047
4216
  usage.raw = rawUsage;
4048
4217
  controller.enqueue({
4049
4218
  type: "finish",
@@ -4279,16 +4448,16 @@ var OpenRouterCompletionLanguageModel = class {
4279
4448
  logprobs: typeof this.settings.logprobs === "number" ? this.settings.logprobs : typeof this.settings.logprobs === "boolean" ? this.settings.logprobs ? 0 : void 0 : void 0,
4280
4449
  suffix: this.settings.suffix,
4281
4450
  user: this.settings.user,
4282
- // standardized settings:
4283
- max_tokens: maxOutputTokens,
4284
- temperature,
4285
- top_p: topP,
4286
- frequency_penalty: frequencyPenalty,
4287
- presence_penalty: presencePenalty,
4451
+ // standardized settings (call-level options override model-level settings):
4452
+ max_tokens: maxOutputTokens != null ? maxOutputTokens : this.settings.maxTokens,
4453
+ temperature: temperature != null ? temperature : this.settings.temperature,
4454
+ top_p: topP != null ? topP : this.settings.topP,
4455
+ frequency_penalty: frequencyPenalty != null ? frequencyPenalty : this.settings.frequencyPenalty,
4456
+ presence_penalty: presencePenalty != null ? presencePenalty : this.settings.presencePenalty,
4288
4457
  seed,
4289
4458
  stop: stopSequences,
4290
4459
  response_format: responseFormat,
4291
- top_k: topK,
4460
+ top_k: topK != null ? topK : this.settings.topK,
4292
4461
  // prompt:
4293
4462
  prompt: completionPrompt,
4294
4463
  // OpenRouter specific settings:
@@ -4746,11 +4915,204 @@ function convertImageFileToContentPart(file) {
4746
4915
  image_url: { url }
4747
4916
  };
4748
4917
  }
4918
+
4919
+ // src/video/schemas.ts
4920
+ var import_v410 = require("zod/v4");
4921
+ var VideoGenerationSubmitResponseSchema = import_v410.z.object({
4922
+ id: import_v410.z.string(),
4923
+ generation_id: import_v410.z.string().optional(),
4924
+ polling_url: import_v410.z.string(),
4925
+ status: import_v410.z.string()
4926
+ }).passthrough();
4927
+ var VideoGenerationPollResponseSchema = import_v410.z.object({
4928
+ id: import_v410.z.string(),
4929
+ generation_id: import_v410.z.string().optional(),
4930
+ polling_url: import_v410.z.string(),
4931
+ status: import_v410.z.string(),
4932
+ unsigned_urls: import_v410.z.array(import_v410.z.string()).optional(),
4933
+ usage: import_v410.z.object({
4934
+ cost: import_v410.z.number().optional(),
4935
+ is_byok: import_v410.z.boolean().optional()
4936
+ }).passthrough().optional(),
4937
+ error: import_v410.z.string().optional()
4938
+ }).passthrough();
4939
+
4940
+ // src/video/index.ts
4941
+ var DEFAULT_POLL_INTERVAL_MS = 2e3;
4942
+ var DEFAULT_MAX_POLL_TIME_MS = 6e5;
4943
+ var OpenRouterVideoModel = class {
4944
+ constructor(modelId, settings, config) {
4945
+ this.specificationVersion = "v3";
4946
+ this.provider = "openrouter";
4947
+ this.maxVideosPerCall = 1;
4948
+ this.modelId = modelId;
4949
+ this.settings = settings;
4950
+ this.config = config;
4951
+ }
4952
+ async doGenerate(options) {
4953
+ var _a16, _b16, _c, _d, _e;
4954
+ const {
4955
+ prompt,
4956
+ n,
4957
+ aspectRatio,
4958
+ resolution,
4959
+ duration,
4960
+ seed,
4961
+ image,
4962
+ abortSignal,
4963
+ headers,
4964
+ providerOptions
4965
+ } = options;
4966
+ const warnings = [];
4967
+ if (n > 1) {
4968
+ warnings.push({
4969
+ type: "unsupported",
4970
+ feature: "n > 1",
4971
+ details: `OpenRouter video generation returns 1 video per call. Requested ${n} videos.`
4972
+ });
4973
+ }
4974
+ const body = __spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({
4975
+ model: this.modelId,
4976
+ prompt: prompt != null ? prompt : ""
4977
+ }, aspectRatio !== void 0 && { aspect_ratio: aspectRatio }), resolution !== void 0 && { size: resolution }), duration !== void 0 && { duration }), seed !== void 0 && { seed }), this.settings.generateAudio !== void 0 && {
4978
+ generate_audio: this.settings.generateAudio
4979
+ }), image !== void 0 && {
4980
+ frame_images: [convertImageToFrameImage(image)]
4981
+ }), this.config.extraBody), this.settings.extraBody), providerOptions.openrouter);
4982
+ const mergedHeaders = combineHeaders(this.config.headers(), headers);
4983
+ const { value: submitResponse, responseHeaders } = await postJsonToApi({
4984
+ url: this.config.url({
4985
+ path: "/videos",
4986
+ modelId: this.modelId
4987
+ }),
4988
+ headers: mergedHeaders,
4989
+ body,
4990
+ failedResponseHandler: openrouterFailedResponseHandler,
4991
+ successfulResponseHandler: createJsonResponseHandler(
4992
+ VideoGenerationSubmitResponseSchema
4993
+ ),
4994
+ abortSignal,
4995
+ fetch: this.config.fetch
4996
+ });
4997
+ const pollIntervalMs = (_a16 = this.settings.pollIntervalMs) != null ? _a16 : DEFAULT_POLL_INTERVAL_MS;
4998
+ const maxPollTimeMs = (_b16 = this.settings.maxPollTimeMs) != null ? _b16 : DEFAULT_MAX_POLL_TIME_MS;
4999
+ const pollResult = await this.pollUntilComplete({
5000
+ jobId: submitResponse.id,
5001
+ headers: mergedHeaders,
5002
+ abortSignal,
5003
+ pollIntervalMs,
5004
+ maxPollTimeMs
5005
+ });
5006
+ const videos = [];
5007
+ if (pollResult.unsigned_urls) {
5008
+ for (const url of pollResult.unsigned_urls) {
5009
+ videos.push({
5010
+ type: "url",
5011
+ url,
5012
+ mediaType: "video/mp4"
5013
+ });
5014
+ }
5015
+ }
5016
+ const providerMetadata = {
5017
+ openrouter: {
5018
+ generationId: (_c = pollResult.generation_id) != null ? _c : null,
5019
+ cost: (_e = (_d = pollResult.usage) == null ? void 0 : _d.cost) != null ? _e : null
5020
+ }
5021
+ };
5022
+ return {
5023
+ videos,
5024
+ warnings,
5025
+ providerMetadata,
5026
+ response: {
5027
+ timestamp: /* @__PURE__ */ new Date(),
5028
+ modelId: this.modelId,
5029
+ headers: responseHeaders
5030
+ }
5031
+ };
5032
+ }
5033
+ async pollUntilComplete({
5034
+ jobId,
5035
+ headers,
5036
+ abortSignal,
5037
+ pollIntervalMs,
5038
+ maxPollTimeMs
5039
+ }) {
5040
+ var _a16;
5041
+ const startTime = Date.now();
5042
+ while (Date.now() - startTime < maxPollTimeMs) {
5043
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
5044
+ await delay(pollIntervalMs);
5045
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
5046
+ const { value: pollResponse } = await getFromApi({
5047
+ url: this.config.url({
5048
+ path: `/videos/${jobId}`,
5049
+ modelId: this.modelId
5050
+ }),
5051
+ headers,
5052
+ failedResponseHandler: openrouterFailedResponseHandler,
5053
+ successfulResponseHandler: createJsonResponseHandler(
5054
+ VideoGenerationPollResponseSchema
5055
+ ),
5056
+ abortSignal,
5057
+ fetch: this.config.fetch
5058
+ });
5059
+ if (pollResponse.status === "completed") {
5060
+ return {
5061
+ generation_id: pollResponse.generation_id,
5062
+ unsigned_urls: pollResponse.unsigned_urls,
5063
+ usage: pollResponse.usage
5064
+ };
5065
+ }
5066
+ if (pollResponse.status === "failed" || pollResponse.status === "dead" || pollResponse.status === "cancelled" || pollResponse.status === "expired") {
5067
+ throw new APICallError({
5068
+ message: (_a16 = pollResponse.error) != null ? _a16 : `Video generation failed with status: ${pollResponse.status}`,
5069
+ url: this.config.url({
5070
+ path: `/videos/${jobId}`,
5071
+ modelId: this.modelId
5072
+ }),
5073
+ requestBodyValues: {},
5074
+ statusCode: 500,
5075
+ isRetryable: false
5076
+ });
5077
+ }
5078
+ }
5079
+ throw new APICallError({
5080
+ message: `Video generation timed out after ${maxPollTimeMs}ms`,
5081
+ url: this.config.url({
5082
+ path: `/videos/${jobId}`,
5083
+ modelId: this.modelId
5084
+ }),
5085
+ requestBodyValues: {},
5086
+ statusCode: 408,
5087
+ isRetryable: true
5088
+ });
5089
+ }
5090
+ };
5091
+ function convertImageToFrameImage(file) {
5092
+ if (file.type === "url") {
5093
+ return {
5094
+ type: "image_url",
5095
+ image_url: { url: file.url },
5096
+ frame_type: "first_frame"
5097
+ };
5098
+ }
5099
+ const url = buildFileDataUrl({
5100
+ data: file.data,
5101
+ mediaType: file.mediaType,
5102
+ defaultMediaType: "image/png"
5103
+ });
5104
+ return {
5105
+ type: "image_url",
5106
+ image_url: { url },
5107
+ frame_type: "first_frame"
5108
+ };
5109
+ }
4749
5110
  // Annotate the CommonJS export names for ESM import in node:
4750
5111
  0 && (module.exports = {
4751
5112
  OpenRouterChatLanguageModel,
4752
5113
  OpenRouterCompletionLanguageModel,
4753
5114
  OpenRouterEmbeddingModel,
4754
- OpenRouterImageModel
5115
+ OpenRouterImageModel,
5116
+ OpenRouterVideoModel
4755
5117
  });
4756
5118
  //# sourceMappingURL=index.js.map