@openrouter/ai-sdk-provider 2.7.0 → 2.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
  }
@@ -2814,9 +2980,9 @@ function convertToOpenRouterChatMessages(prompt) {
2814
2980
  const parsedProviderOptions = OpenRouterProviderOptionsSchema.safeParse(providerOptions);
2815
2981
  const messageReasoningDetails = parsedProviderOptions.success ? (_e = (_d = parsedProviderOptions.data) == null ? void 0 : _d.openrouter) == null ? void 0 : _e.reasoning_details : void 0;
2816
2982
  const messageAnnotations = parsedProviderOptions.success ? (_g = (_f = parsedProviderOptions.data) == null ? void 0 : _f.openrouter) == null ? void 0 : _g.annotations : void 0;
2817
- const candidateReasoningDetails = messageReasoningDetails && Array.isArray(messageReasoningDetails) && messageReasoningDetails.length > 0 ? messageReasoningDetails : findFirstReasoningDetails(content);
2983
+ const candidateReasoningDetails = messageReasoningDetails && Array.isArray(messageReasoningDetails) ? messageReasoningDetails : findFirstReasoningDetails(content);
2818
2984
  let finalReasoningDetails;
2819
- if (candidateReasoningDetails && candidateReasoningDetails.length > 0) {
2985
+ if (candidateReasoningDetails) {
2820
2986
  const validDetails = candidateReasoningDetails.filter((detail) => {
2821
2987
  var _a17;
2822
2988
  if (detail.type !== "reasoning.text" /* Text */) {
@@ -2842,9 +3008,9 @@ function convertToOpenRouterChatMessages(prompt) {
2842
3008
  uniqueDetails.push(detail);
2843
3009
  }
2844
3010
  }
2845
- finalReasoningDetails = uniqueDetails.length > 0 ? uniqueDetails : void 0;
3011
+ finalReasoningDetails = uniqueDetails;
2846
3012
  }
2847
- const effectiveReasoning = reasoning && finalReasoningDetails ? reasoning : void 0;
3013
+ const effectiveReasoning = reasoning && finalReasoningDetails && finalReasoningDetails.length > 0 ? reasoning : void 0;
2848
3014
  messages.push({
2849
3015
  role: "assistant",
2850
3016
  content: text,
@@ -3771,15 +3937,17 @@ var OpenRouterChatLanguageModel = class {
3771
3937
  controller.enqueue({
3772
3938
  type: "reasoning-end",
3773
3939
  id: reasoningId || generateId(),
3774
- // Include accumulated reasoning_details so the AI SDK can update
3775
- // the reasoning part's providerMetadata with the correct signature.
3776
- // The signature typically arrives in the last reasoning delta,
3940
+ // Always include accumulated reasoning_details so the AI SDK can
3941
+ // update the reasoning part's providerMetadata with the correct
3942
+ // signature. The signature typically arrives in the last delta,
3777
3943
  // but reasoning-start only carries the first delta's metadata.
3778
- providerMetadata: accumulatedReasoningDetails.length > 0 ? {
3944
+ // An empty array is intentional — it signals the provider produced
3945
+ // no reasoning tokens this turn (e.g. DeepSeek V4).
3946
+ providerMetadata: {
3779
3947
  openrouter: {
3780
3948
  reasoning_details: accumulatedReasoningDetails
3781
3949
  }
3782
- } : void 0
3950
+ }
3783
3951
  });
3784
3952
  reasoningStarted = false;
3785
3953
  }
@@ -4014,13 +4182,14 @@ var OpenRouterChatLanguageModel = class {
4014
4182
  controller.enqueue({
4015
4183
  type: "reasoning-end",
4016
4184
  id: reasoningId || generateId(),
4017
- // Include accumulated reasoning_details so the AI SDK can update
4018
- // the reasoning part's providerMetadata with the correct signature.
4019
- providerMetadata: accumulatedReasoningDetails.length > 0 ? {
4185
+ // Always include accumulated reasoning_details so the AI SDK can
4186
+ // update the reasoning part's providerMetadata. An empty array is
4187
+ // intentional it signals the provider produced no reasoning tokens.
4188
+ providerMetadata: {
4020
4189
  openrouter: {
4021
4190
  reasoning_details: accumulatedReasoningDetails
4022
4191
  }
4023
- } : void 0
4192
+ }
4024
4193
  });
4025
4194
  }
4026
4195
  if (textStarted) {
@@ -4035,9 +4204,7 @@ var OpenRouterChatLanguageModel = class {
4035
4204
  if (provider !== void 0) {
4036
4205
  openrouterMetadata.provider = provider;
4037
4206
  }
4038
- if (accumulatedReasoningDetails.length > 0) {
4039
- openrouterMetadata.reasoning_details = accumulatedReasoningDetails;
4040
- }
4207
+ openrouterMetadata.reasoning_details = accumulatedReasoningDetails;
4041
4208
  if (accumulatedFileAnnotations.length > 0) {
4042
4209
  openrouterMetadata.annotations = accumulatedFileAnnotations;
4043
4210
  }
@@ -4749,11 +4916,204 @@ function convertImageFileToContentPart(file) {
4749
4916
  image_url: { url }
4750
4917
  };
4751
4918
  }
4919
+
4920
+ // src/video/schemas.ts
4921
+ var import_v410 = require("zod/v4");
4922
+ var VideoGenerationSubmitResponseSchema = import_v410.z.object({
4923
+ id: import_v410.z.string(),
4924
+ generation_id: import_v410.z.string().optional(),
4925
+ polling_url: import_v410.z.string(),
4926
+ status: import_v410.z.string()
4927
+ }).passthrough();
4928
+ var VideoGenerationPollResponseSchema = import_v410.z.object({
4929
+ id: import_v410.z.string(),
4930
+ generation_id: import_v410.z.string().optional(),
4931
+ polling_url: import_v410.z.string(),
4932
+ status: import_v410.z.string(),
4933
+ unsigned_urls: import_v410.z.array(import_v410.z.string()).optional(),
4934
+ usage: import_v410.z.object({
4935
+ cost: import_v410.z.number().optional(),
4936
+ is_byok: import_v410.z.boolean().optional()
4937
+ }).passthrough().optional(),
4938
+ error: import_v410.z.string().optional()
4939
+ }).passthrough();
4940
+
4941
+ // src/video/index.ts
4942
+ var DEFAULT_POLL_INTERVAL_MS = 2e3;
4943
+ var DEFAULT_MAX_POLL_TIME_MS = 6e5;
4944
+ var OpenRouterVideoModel = class {
4945
+ constructor(modelId, settings, config) {
4946
+ this.specificationVersion = "v3";
4947
+ this.provider = "openrouter";
4948
+ this.maxVideosPerCall = 1;
4949
+ this.modelId = modelId;
4950
+ this.settings = settings;
4951
+ this.config = config;
4952
+ }
4953
+ async doGenerate(options) {
4954
+ var _a16, _b16, _c, _d, _e;
4955
+ const {
4956
+ prompt,
4957
+ n,
4958
+ aspectRatio,
4959
+ resolution,
4960
+ duration,
4961
+ seed,
4962
+ image,
4963
+ abortSignal,
4964
+ headers,
4965
+ providerOptions
4966
+ } = options;
4967
+ const warnings = [];
4968
+ if (n > 1) {
4969
+ warnings.push({
4970
+ type: "unsupported",
4971
+ feature: "n > 1",
4972
+ details: `OpenRouter video generation returns 1 video per call. Requested ${n} videos.`
4973
+ });
4974
+ }
4975
+ const body = __spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({
4976
+ model: this.modelId,
4977
+ prompt: prompt != null ? prompt : ""
4978
+ }, aspectRatio !== void 0 && { aspect_ratio: aspectRatio }), resolution !== void 0 && { size: resolution }), duration !== void 0 && { duration }), seed !== void 0 && { seed }), this.settings.generateAudio !== void 0 && {
4979
+ generate_audio: this.settings.generateAudio
4980
+ }), image !== void 0 && {
4981
+ frame_images: [convertImageToFrameImage(image)]
4982
+ }), this.config.extraBody), this.settings.extraBody), providerOptions.openrouter);
4983
+ const mergedHeaders = combineHeaders(this.config.headers(), headers);
4984
+ const { value: submitResponse, responseHeaders } = await postJsonToApi({
4985
+ url: this.config.url({
4986
+ path: "/videos",
4987
+ modelId: this.modelId
4988
+ }),
4989
+ headers: mergedHeaders,
4990
+ body,
4991
+ failedResponseHandler: openrouterFailedResponseHandler,
4992
+ successfulResponseHandler: createJsonResponseHandler(
4993
+ VideoGenerationSubmitResponseSchema
4994
+ ),
4995
+ abortSignal,
4996
+ fetch: this.config.fetch
4997
+ });
4998
+ const pollIntervalMs = (_a16 = this.settings.pollIntervalMs) != null ? _a16 : DEFAULT_POLL_INTERVAL_MS;
4999
+ const maxPollTimeMs = (_b16 = this.settings.maxPollTimeMs) != null ? _b16 : DEFAULT_MAX_POLL_TIME_MS;
5000
+ const pollResult = await this.pollUntilComplete({
5001
+ jobId: submitResponse.id,
5002
+ headers: mergedHeaders,
5003
+ abortSignal,
5004
+ pollIntervalMs,
5005
+ maxPollTimeMs
5006
+ });
5007
+ const videos = [];
5008
+ if (pollResult.unsigned_urls) {
5009
+ for (const url of pollResult.unsigned_urls) {
5010
+ videos.push({
5011
+ type: "url",
5012
+ url,
5013
+ mediaType: "video/mp4"
5014
+ });
5015
+ }
5016
+ }
5017
+ const providerMetadata = {
5018
+ openrouter: {
5019
+ generationId: (_c = pollResult.generation_id) != null ? _c : null,
5020
+ cost: (_e = (_d = pollResult.usage) == null ? void 0 : _d.cost) != null ? _e : null
5021
+ }
5022
+ };
5023
+ return {
5024
+ videos,
5025
+ warnings,
5026
+ providerMetadata,
5027
+ response: {
5028
+ timestamp: /* @__PURE__ */ new Date(),
5029
+ modelId: this.modelId,
5030
+ headers: responseHeaders
5031
+ }
5032
+ };
5033
+ }
5034
+ async pollUntilComplete({
5035
+ jobId,
5036
+ headers,
5037
+ abortSignal,
5038
+ pollIntervalMs,
5039
+ maxPollTimeMs
5040
+ }) {
5041
+ var _a16;
5042
+ const startTime = Date.now();
5043
+ while (Date.now() - startTime < maxPollTimeMs) {
5044
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
5045
+ await delay(pollIntervalMs);
5046
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
5047
+ const { value: pollResponse } = await getFromApi({
5048
+ url: this.config.url({
5049
+ path: `/videos/${jobId}`,
5050
+ modelId: this.modelId
5051
+ }),
5052
+ headers,
5053
+ failedResponseHandler: openrouterFailedResponseHandler,
5054
+ successfulResponseHandler: createJsonResponseHandler(
5055
+ VideoGenerationPollResponseSchema
5056
+ ),
5057
+ abortSignal,
5058
+ fetch: this.config.fetch
5059
+ });
5060
+ if (pollResponse.status === "completed") {
5061
+ return {
5062
+ generation_id: pollResponse.generation_id,
5063
+ unsigned_urls: pollResponse.unsigned_urls,
5064
+ usage: pollResponse.usage
5065
+ };
5066
+ }
5067
+ if (pollResponse.status === "failed" || pollResponse.status === "dead" || pollResponse.status === "cancelled" || pollResponse.status === "expired") {
5068
+ throw new APICallError({
5069
+ message: (_a16 = pollResponse.error) != null ? _a16 : `Video generation failed with status: ${pollResponse.status}`,
5070
+ url: this.config.url({
5071
+ path: `/videos/${jobId}`,
5072
+ modelId: this.modelId
5073
+ }),
5074
+ requestBodyValues: {},
5075
+ statusCode: 500,
5076
+ isRetryable: false
5077
+ });
5078
+ }
5079
+ }
5080
+ throw new APICallError({
5081
+ message: `Video generation timed out after ${maxPollTimeMs}ms`,
5082
+ url: this.config.url({
5083
+ path: `/videos/${jobId}`,
5084
+ modelId: this.modelId
5085
+ }),
5086
+ requestBodyValues: {},
5087
+ statusCode: 408,
5088
+ isRetryable: true
5089
+ });
5090
+ }
5091
+ };
5092
+ function convertImageToFrameImage(file) {
5093
+ if (file.type === "url") {
5094
+ return {
5095
+ type: "image_url",
5096
+ image_url: { url: file.url },
5097
+ frame_type: "first_frame"
5098
+ };
5099
+ }
5100
+ const url = buildFileDataUrl({
5101
+ data: file.data,
5102
+ mediaType: file.mediaType,
5103
+ defaultMediaType: "image/png"
5104
+ });
5105
+ return {
5106
+ type: "image_url",
5107
+ image_url: { url },
5108
+ frame_type: "first_frame"
5109
+ };
5110
+ }
4752
5111
  // Annotate the CommonJS export names for ESM import in node:
4753
5112
  0 && (module.exports = {
4754
5113
  OpenRouterChatLanguageModel,
4755
5114
  OpenRouterCompletionLanguageModel,
4756
5115
  OpenRouterEmbeddingModel,
4757
- OpenRouterImageModel
5116
+ OpenRouterImageModel,
5117
+ OpenRouterVideoModel
4758
5118
  });
4759
5119
  //# sourceMappingURL=index.js.map