@runpod/ai-sdk-provider 1.2.0 → 1.4.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
@@ -27,7 +27,7 @@ module.exports = __toCommonJS(index_exports);
27
27
 
28
28
  // src/runpod-provider.ts
29
29
  var import_openai_compatible = require("@ai-sdk/openai-compatible");
30
- var import_provider_utils5 = require("@ai-sdk/provider-utils");
30
+ var import_provider_utils6 = require("@ai-sdk/provider-utils");
31
31
 
32
32
  // src/runpod-image-model.ts
33
33
  var import_provider_utils2 = require("@ai-sdk/provider-utils");
@@ -69,6 +69,10 @@ var runpodTranscriptionFailedResponseHandler = (0, import_provider_utils.createJ
69
69
  errorSchema: runpodImageErrorSchema,
70
70
  errorToMessage: extractErrorMessage
71
71
  });
72
+ var runpodVideoFailedResponseHandler = (0, import_provider_utils.createJsonErrorResponseHandler)({
73
+ errorSchema: runpodImageErrorSchema,
74
+ errorToMessage: extractErrorMessage
75
+ });
72
76
 
73
77
  // src/runpod-image-model.ts
74
78
  var SUPPORTED_ASPECT_RATIOS = {
@@ -101,6 +105,50 @@ var SUPPORTED_SIZES = /* @__PURE__ */ new Set([
101
105
  "1024*768",
102
106
  "768*1024"
103
107
  ]);
108
+ var Z_IMAGE_TURBO_SUPPORTED_SIZES = /* @__PURE__ */ new Set([
109
+ "1328*1328",
110
+ // 1:1
111
+ "1472*1140",
112
+ // 4:3
113
+ "1140*1472",
114
+ // 3:4
115
+ "512*512",
116
+ "768*768",
117
+ "1024*1024",
118
+ "1280*1280",
119
+ "1536*1536",
120
+ "512*768",
121
+ "768*512",
122
+ "1024*768",
123
+ "768*1024",
124
+ "768*432",
125
+ "1024*576",
126
+ "1280*720",
127
+ "1536*864",
128
+ "432*768",
129
+ "576*1024",
130
+ "720*1280",
131
+ "864*1536"
132
+ ]);
133
+ var Z_IMAGE_TURBO_ASPECT_RATIOS = {
134
+ "1:1": "1328*1328",
135
+ "4:3": "1472*1140",
136
+ "3:4": "1140*1472",
137
+ "3:2": "768*512",
138
+ "2:3": "512*768",
139
+ "16:9": "1280*720",
140
+ "9:16": "720*1280"
141
+ };
142
+ var MODEL_SUPPORTED_SIZES = {
143
+ "tongyi-mai/z-image-turbo": Z_IMAGE_TURBO_SUPPORTED_SIZES,
144
+ "z-image-turbo": Z_IMAGE_TURBO_SUPPORTED_SIZES
145
+ // alias, not advertised
146
+ };
147
+ var MODEL_SUPPORTED_ASPECT_RATIOS = {
148
+ "tongyi-mai/z-image-turbo": Z_IMAGE_TURBO_ASPECT_RATIOS,
149
+ "z-image-turbo": Z_IMAGE_TURBO_ASPECT_RATIOS
150
+ // alias, not advertised
151
+ };
104
152
  var WAN_ASPECT_RATIOS = {
105
153
  "1:1": "1280*1280",
106
154
  // 1,638,400 pixels
@@ -184,9 +232,10 @@ var RunpodImageModel = class {
184
232
  }
185
233
  const isPrunaModel = this.modelId.includes("pruna") || this.modelId.includes("p-image");
186
234
  const isNanoBananaProModel = this.modelId.includes("nano-banana-pro");
235
+ const isNanoBanana2Model = this.modelId.includes("nano-banana-2");
187
236
  const isWanModel = this.modelId.includes("wan-2");
188
237
  let runpodSize;
189
- if (isPrunaModel || isNanoBananaProModel) {
238
+ if (isPrunaModel || isNanoBananaProModel || isNanoBanana2Model) {
190
239
  runpodSize = aspectRatio || "1:1";
191
240
  } else if (isWanModel) {
192
241
  if (size) {
@@ -206,23 +255,27 @@ var RunpodImageModel = class {
206
255
  }
207
256
  } else if (size) {
208
257
  const runpodSizeCandidate = size.replace("x", "*");
209
- if (!SUPPORTED_SIZES.has(runpodSizeCandidate)) {
258
+ const supportedSizes = MODEL_SUPPORTED_SIZES[this.modelId] ?? SUPPORTED_SIZES;
259
+ if (!supportedSizes.has(runpodSizeCandidate)) {
210
260
  throw new import_provider.InvalidArgumentError({
211
261
  argument: "size",
212
262
  message: `Size ${size} is not supported by Runpod. Supported sizes: ${Array.from(
213
- SUPPORTED_SIZES
263
+ supportedSizes
214
264
  ).map((s) => s.replace("*", "x")).join(", ")}`
215
265
  });
216
266
  }
217
267
  runpodSize = runpodSizeCandidate;
218
268
  } else if (aspectRatio) {
219
- if (!SUPPORTED_ASPECT_RATIOS[aspectRatio]) {
269
+ const supportedAspectRatios = MODEL_SUPPORTED_ASPECT_RATIOS[this.modelId] ?? SUPPORTED_ASPECT_RATIOS;
270
+ if (!supportedAspectRatios[aspectRatio]) {
220
271
  throw new import_provider.InvalidArgumentError({
221
272
  argument: "aspectRatio",
222
- message: `Aspect ratio ${aspectRatio} is not supported by Runpod. Supported aspect ratios: ${Object.keys(SUPPORTED_ASPECT_RATIOS).join(", ")}`
273
+ message: `Aspect ratio ${aspectRatio} is not supported by Runpod. Supported aspect ratios: ${Object.keys(
274
+ supportedAspectRatios
275
+ ).join(", ")}`
223
276
  });
224
277
  }
225
- runpodSize = SUPPORTED_ASPECT_RATIOS[aspectRatio];
278
+ runpodSize = supportedAspectRatios[aspectRatio];
226
279
  } else {
227
280
  runpodSize = "1328*1328";
228
281
  }
@@ -477,6 +530,22 @@ var RunpodImageModel = class {
477
530
  return t2iPayload;
478
531
  }
479
532
  }
533
+ const isNanoBanana2Model = this.modelId.includes("nano-banana-2");
534
+ if (isNanoBanana2Model) {
535
+ const nanoBanana2Payload = {
536
+ prompt,
537
+ aspect_ratio: runpodOptions?.aspect_ratio ?? aspectRatio ?? "1:1",
538
+ resolution: runpodOptions?.resolution ?? "1k",
539
+ output_format: runpodOptions?.output_format ?? "jpeg",
540
+ enable_safety_checker: runpodOptions?.enable_safety_checker ?? true
541
+ };
542
+ if (standardizedImages && standardizedImages.length > 0) {
543
+ nanoBanana2Payload.images = standardizedImages;
544
+ } else if (runpodOptions?.images) {
545
+ nanoBanana2Payload.images = runpodOptions.images;
546
+ }
547
+ return nanoBanana2Payload;
548
+ }
480
549
  const isNanaBananaProModel = this.modelId.includes("nano-banana-pro");
481
550
  if (isNanaBananaProModel) {
482
551
  const nanoBananaPayload = {
@@ -525,6 +594,25 @@ var RunpodImageModel = class {
525
594
  }
526
595
  return qwenEdit2511Payload;
527
596
  }
597
+ const isZImageTurbo = this.modelId === "tongyi-mai/z-image-turbo" || this.modelId === "z-image-turbo";
598
+ if (isZImageTurbo) {
599
+ const zImageTurboPayload = {
600
+ prompt,
601
+ size: runpodSize,
602
+ seed: seed ?? -1,
603
+ output_format: runpodOptions?.output_format ?? "png",
604
+ enable_safety_checker: runpodOptions?.enable_safety_checker ?? true,
605
+ ...runpodOptions
606
+ };
607
+ if (standardizedImages && standardizedImages.length > 0) {
608
+ if (standardizedImages.length === 1) {
609
+ zImageTurboPayload.image = standardizedImages[0];
610
+ } else {
611
+ zImageTurboPayload.images = standardizedImages;
612
+ }
613
+ }
614
+ return zImageTurboPayload;
615
+ }
528
616
  const isWanModel = this.modelId.includes("wan-2");
529
617
  if (isWanModel) {
530
618
  return {
@@ -938,6 +1026,210 @@ var RunpodTranscriptionModel = class {
938
1026
  }
939
1027
  };
940
1028
 
1029
+ // src/runpod-video-model.ts
1030
+ var import_provider_utils5 = require("@ai-sdk/provider-utils");
1031
+ var import_zod4 = require("zod");
1032
+ function isRecord3(value) {
1033
+ return typeof value === "object" && value !== null;
1034
+ }
1035
+ var runpodVideoJobResponseSchema = import_zod4.z.object({
1036
+ id: import_zod4.z.string(),
1037
+ status: import_zod4.z.string().optional()
1038
+ });
1039
+ var runpodVideoStatusSchema = import_zod4.z.object({
1040
+ id: import_zod4.z.string().optional(),
1041
+ status: import_zod4.z.string(),
1042
+ output: import_zod4.z.unknown().optional(),
1043
+ error: import_zod4.z.string().optional()
1044
+ });
1045
+ var RunpodVideoModel = class {
1046
+ constructor(modelId, config) {
1047
+ this.modelId = modelId;
1048
+ this.config = config;
1049
+ this.specificationVersion = "v3";
1050
+ this.maxVideosPerCall = 1;
1051
+ }
1052
+ get provider() {
1053
+ return this.config.provider;
1054
+ }
1055
+ getRunpodRunUrl() {
1056
+ const baseURL = (0, import_provider_utils5.withoutTrailingSlash)(this.config.baseURL) ?? this.config.baseURL;
1057
+ if (baseURL.endsWith("/run") || baseURL.endsWith("/runsync")) {
1058
+ return baseURL;
1059
+ }
1060
+ return `${baseURL}/run`;
1061
+ }
1062
+ async doGenerate(options) {
1063
+ const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
1064
+ const warnings = [];
1065
+ if (options.n > 1) {
1066
+ warnings.push({
1067
+ type: "unsupported",
1068
+ feature: "n > 1",
1069
+ details: "Runpod video models only support generating 1 video per call. Only 1 video will be generated."
1070
+ });
1071
+ }
1072
+ const { providerOptions, abortSignal, headers } = options;
1073
+ const runpodOptions = this.extractRunpodOptions(providerOptions);
1074
+ const input = this.buildInputPayload(options, runpodOptions);
1075
+ const requestBody = { input };
1076
+ const url = this.getRunpodRunUrl();
1077
+ const effectiveBaseURL = (0, import_provider_utils5.withoutTrailingSlash)(this.config.baseURL) ?? this.config.baseURL;
1078
+ const { value: response, responseHeaders } = await (0, import_provider_utils5.postJsonToApi)({
1079
+ url,
1080
+ headers: {
1081
+ ...this.config.headers(),
1082
+ ...headers
1083
+ },
1084
+ body: requestBody,
1085
+ failedResponseHandler: runpodVideoFailedResponseHandler,
1086
+ successfulResponseHandler: (0, import_provider_utils5.createJsonResponseHandler)(
1087
+ runpodVideoJobResponseSchema
1088
+ ),
1089
+ abortSignal,
1090
+ fetch: this.config.fetch
1091
+ });
1092
+ const typedResponse = response;
1093
+ const jobId = typedResponse.id;
1094
+ if (!jobId) {
1095
+ throw new Error("Runpod video response did not include a job id.");
1096
+ }
1097
+ const pollOptions = {
1098
+ maxAttempts: runpodOptions.maxPollAttempts ?? 120,
1099
+ pollIntervalMillis: runpodOptions.pollIntervalMillis ?? 5e3
1100
+ };
1101
+ const result = await this.pollForCompletion(
1102
+ jobId,
1103
+ abortSignal,
1104
+ pollOptions,
1105
+ effectiveBaseURL
1106
+ );
1107
+ const videoUrl = this.extractVideoUrl(result.output);
1108
+ const providerMetadata = {
1109
+ runpod: {
1110
+ jobId
1111
+ }
1112
+ };
1113
+ return {
1114
+ videos: [{ type: "url", url: videoUrl, mediaType: "video/mp4" }],
1115
+ warnings,
1116
+ response: {
1117
+ timestamp: currentDate,
1118
+ modelId: this.modelId,
1119
+ headers: responseHeaders
1120
+ },
1121
+ providerMetadata
1122
+ };
1123
+ }
1124
+ buildInputPayload(options, runpodOptions) {
1125
+ const apiOptions = Object.fromEntries(
1126
+ Object.entries(runpodOptions).filter(
1127
+ ([key]) => key !== "maxPollAttempts" && key !== "pollIntervalMillis"
1128
+ )
1129
+ );
1130
+ const input = {
1131
+ ...apiOptions
1132
+ };
1133
+ if (options.prompt) {
1134
+ input.prompt = options.prompt;
1135
+ }
1136
+ if (options.duration !== void 0) {
1137
+ input.duration = options.duration;
1138
+ }
1139
+ if (options.fps !== void 0) {
1140
+ input.fps = options.fps;
1141
+ }
1142
+ if (options.seed !== void 0) {
1143
+ input.seed = options.seed;
1144
+ }
1145
+ if (options.resolution) {
1146
+ input.size = options.resolution.replace("x", "*");
1147
+ } else if (options.aspectRatio) {
1148
+ input.aspect_ratio = options.aspectRatio;
1149
+ }
1150
+ if (options.image) {
1151
+ input.image = this.convertFileToRunpodFormat(options.image);
1152
+ }
1153
+ return input;
1154
+ }
1155
+ convertFileToRunpodFormat(file) {
1156
+ if (file.type === "url") {
1157
+ return file.url;
1158
+ }
1159
+ const mediaType = file.mediaType;
1160
+ const data = file.data;
1161
+ if (typeof data === "string") {
1162
+ return `data:${mediaType};base64,${data}`;
1163
+ }
1164
+ const base64 = this.uint8ArrayToBase64(data);
1165
+ return `data:${mediaType};base64,${base64}`;
1166
+ }
1167
+ uint8ArrayToBase64(data) {
1168
+ if (typeof Buffer !== "undefined") {
1169
+ return Buffer.from(data).toString("base64");
1170
+ }
1171
+ let binary = "";
1172
+ for (let i = 0; i < data.length; i++) {
1173
+ binary += String.fromCharCode(data[i]);
1174
+ }
1175
+ return btoa(binary);
1176
+ }
1177
+ extractRunpodOptions(providerOptions) {
1178
+ if (!providerOptions) return {};
1179
+ const runpod2 = providerOptions.runpod;
1180
+ if (isRecord3(runpod2)) {
1181
+ return runpod2;
1182
+ }
1183
+ return {};
1184
+ }
1185
+ extractVideoUrl(output) {
1186
+ if (isRecord3(output)) {
1187
+ if (typeof output.video_url === "string") return output.video_url;
1188
+ if (typeof output.result === "string") return output.result;
1189
+ if (typeof output.url === "string") return output.url;
1190
+ }
1191
+ if (typeof output === "string") {
1192
+ return output;
1193
+ }
1194
+ throw new Error(
1195
+ `Runpod video generation completed but no video URL was found in the output: ${JSON.stringify(output)}`
1196
+ );
1197
+ }
1198
+ async pollForCompletion(jobId, abortSignal, pollOptions, effectiveBaseURL) {
1199
+ const maxAttempts = pollOptions?.maxAttempts ?? 120;
1200
+ const pollInterval = pollOptions?.pollIntervalMillis ?? 5e3;
1201
+ const baseURL = effectiveBaseURL ?? this.config.baseURL;
1202
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
1203
+ if (abortSignal?.aborted) {
1204
+ throw new Error("Video generation was aborted");
1205
+ }
1206
+ const { value: statusResponse } = await (0, import_provider_utils5.getFromApi)({
1207
+ url: `${baseURL}/status/${jobId}`,
1208
+ headers: this.config.headers(),
1209
+ successfulResponseHandler: (0, import_provider_utils5.createJsonResponseHandler)(
1210
+ runpodVideoStatusSchema
1211
+ ),
1212
+ failedResponseHandler: runpodVideoFailedResponseHandler,
1213
+ abortSignal,
1214
+ fetch: this.config.fetch
1215
+ });
1216
+ const typedStatusResponse = statusResponse;
1217
+ if (typedStatusResponse.status === "COMPLETED") {
1218
+ return typedStatusResponse;
1219
+ }
1220
+ if (typedStatusResponse.status === "FAILED") {
1221
+ throw new Error(
1222
+ `Video generation failed: ${typedStatusResponse.error || "Unknown error"}`
1223
+ );
1224
+ }
1225
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
1226
+ }
1227
+ throw new Error(
1228
+ `Video generation timed out after ${maxAttempts} attempts (${maxAttempts * pollInterval / 1e3}s)`
1229
+ );
1230
+ }
1231
+ };
1232
+
941
1233
  // src/runpod-provider.ts
942
1234
  var MODEL_ID_TO_ENDPOINT_URL = {
943
1235
  "qwen/qwen3-32b-awq": "https://api.runpod.ai/v2/qwen3-32b-awq/openai/v1",
@@ -961,10 +1253,16 @@ var IMAGE_MODEL_ID_TO_ENDPOINT_URL = {
961
1253
  "black-forest-labs/flux-1-dev": "https://api.runpod.ai/v2/black-forest-labs-flux-1-dev",
962
1254
  // Alibaba Wan 2.6 (t2i)
963
1255
  "alibaba/wan-2.6": "https://api.runpod.ai/v2/wan-2-6-t2i",
1256
+ // Tongyi Z-Image Turbo (t2i)
1257
+ "tongyi-mai/z-image-turbo": "https://api.runpod.ai/v2/z-image-turbo",
1258
+ "z-image-turbo": "https://api.runpod.ai/v2/z-image-turbo",
1259
+ // alias, not advertised
964
1260
  // Nano Banana (edit only)
965
1261
  "google/nano-banana-edit": "https://api.runpod.ai/v2/nano-banana-edit",
966
1262
  "nano-banana-edit": "https://api.runpod.ai/v2/nano-banana-edit",
967
1263
  // backwards compatibility
1264
+ // Nano Banana 2 (edit only)
1265
+ "google/nano-banana-2-edit": "https://api.runpod.ai/v2/google-nano-banana-2-edit",
968
1266
  // Nano Banana Pro (edit only)
969
1267
  "google/nano-banana-pro-edit": "https://api.runpod.ai/v2/nano-banana-pro-edit",
970
1268
  // Pruna (t2i and edit)
@@ -977,6 +1275,23 @@ var SPEECH_MODEL_ID_TO_ENDPOINT_URL = {
977
1275
  var TRANSCRIPTION_MODEL_ID_TO_ENDPOINT_URL = {
978
1276
  "pruna/whisper-v3-large": "https://api.runpod.ai/v2/whisper-v3-large"
979
1277
  };
1278
+ var VIDEO_MODEL_ID_TO_ENDPOINT_URL = {
1279
+ "pruna/p-video": "https://api.runpod.ai/v2/p-video",
1280
+ "vidu/q3-t2v": "https://api.runpod.ai/v2/vidu-q3-t2v",
1281
+ "vidu/q3-i2v": "https://api.runpod.ai/v2/vidu-q3-i2v",
1282
+ "kwaivgi/kling-v2.6-std-motion-control": "https://api.runpod.ai/v2/kling-v2-6-std-motion-control",
1283
+ "kwaivgi/kling-video-o1-r2v": "https://api.runpod.ai/v2/kling-video-o1-r2v",
1284
+ "kwaivgi/kling-v2.1-i2v-pro": "https://api.runpod.ai/v2/kling-v2-1-i2v-pro",
1285
+ "alibaba/wan-2.6-t2v": "https://api.runpod.ai/v2/wan-2-6-t2v",
1286
+ "alibaba/wan-2.6-i2v": "https://api.runpod.ai/v2/wan-2-6-i2v",
1287
+ "alibaba/wan-2.5": "https://api.runpod.ai/v2/wan-2-5",
1288
+ "alibaba/wan-2.2-t2v-720-lora": "https://api.runpod.ai/v2/wan-2-2-t2v-720-lora",
1289
+ "alibaba/wan-2.2-i2v-720": "https://api.runpod.ai/v2/wan-2-2-i2v-720",
1290
+ "alibaba/wan-2.1-i2v-720": "https://api.runpod.ai/v2/wan-2-1-i2v-720",
1291
+ "bytedance/seedance-v1.5-pro-i2v": "https://api.runpod.ai/v2/seedance-v1-5-pro-i2v",
1292
+ "openai/sora-2-pro-i2v": "https://api.runpod.ai/v2/sora-2-pro-i2v",
1293
+ "openai/sora-2-i2v": "https://api.runpod.ai/v2/sora-2-i2v"
1294
+ };
980
1295
  var MODEL_ID_TO_OPENAI_NAME = {
981
1296
  "qwen/qwen3-32b-awq": "Qwen/Qwen3-32B-AWQ",
982
1297
  "deepcogito/cogito-671b-v2.1-fp8": "deepcogito/cogito-671b-v2.1-FP8",
@@ -1005,7 +1320,7 @@ function parseRunpodConsoleEndpointId(modelIdOrUrl) {
1005
1320
  }
1006
1321
  function createRunpod(options = {}) {
1007
1322
  const getHeaders = () => ({
1008
- Authorization: `Bearer ${(0, import_provider_utils5.loadApiKey)({
1323
+ Authorization: `Bearer ${(0, import_provider_utils6.loadApiKey)({
1009
1324
  apiKey: options.apiKey,
1010
1325
  environmentVariableName: "RUNPOD_API_KEY",
1011
1326
  description: "Runpod"
@@ -1035,7 +1350,7 @@ function createRunpod(options = {}) {
1035
1350
  }
1036
1351
  return {
1037
1352
  provider: `runpod.${modelType}`,
1038
- url: ({ path }) => `${(0, import_provider_utils5.withoutTrailingSlash)(baseURL)}${path}`,
1353
+ url: ({ path }) => `${(0, import_provider_utils6.withoutTrailingSlash)(baseURL)}${path}`,
1039
1354
  headers: getHeaders,
1040
1355
  fetch: runpodFetch
1041
1356
  };
@@ -1055,13 +1370,11 @@ function createRunpod(options = {}) {
1055
1370
  });
1056
1371
  };
1057
1372
  const createImageModel = (modelId) => {
1058
- let baseURL;
1059
- if (options.baseURL) {
1060
- baseURL = options.baseURL;
1061
- } else {
1062
- baseURL = IMAGE_MODEL_ID_TO_ENDPOINT_URL[modelId] || deriveEndpointURL(modelId);
1063
- }
1064
- return new RunpodImageModel(modelId, {
1373
+ const endpointIdFromConsole = parseRunpodConsoleEndpointId(modelId);
1374
+ const normalizedModelId = endpointIdFromConsole ?? modelId;
1375
+ const mappedBaseURL = IMAGE_MODEL_ID_TO_ENDPOINT_URL[normalizedModelId];
1376
+ const baseURL = options.baseURL ?? mappedBaseURL ?? (normalizedModelId.startsWith("http") ? normalizedModelId : `https://api.runpod.ai/v2/${normalizedModelId}`);
1377
+ return new RunpodImageModel(normalizedModelId, {
1065
1378
  provider: "runpod.image",
1066
1379
  baseURL,
1067
1380
  headers: getHeaders,
@@ -1092,6 +1405,18 @@ function createRunpod(options = {}) {
1092
1405
  fetch: runpodFetch
1093
1406
  });
1094
1407
  };
1408
+ const createVideoModel = (modelId) => {
1409
+ const endpointIdFromConsole = parseRunpodConsoleEndpointId(modelId);
1410
+ const normalizedModelId = endpointIdFromConsole ?? modelId;
1411
+ const mappedBaseURL = VIDEO_MODEL_ID_TO_ENDPOINT_URL[normalizedModelId];
1412
+ const baseURL = mappedBaseURL ?? (normalizedModelId.startsWith("http") ? normalizedModelId : `https://api.runpod.ai/v2/${normalizedModelId}`);
1413
+ return new RunpodVideoModel(normalizedModelId, {
1414
+ provider: "runpod.video",
1415
+ baseURL,
1416
+ headers: getHeaders,
1417
+ fetch: options.fetch
1418
+ });
1419
+ };
1095
1420
  const provider = (modelId) => createChatModel(modelId);
1096
1421
  provider.completionModel = createCompletionModel;
1097
1422
  provider.languageModel = createChatModel;
@@ -1102,6 +1427,8 @@ function createRunpod(options = {}) {
1102
1427
  provider.speech = createSpeechModel;
1103
1428
  provider.transcriptionModel = createTranscriptionModel;
1104
1429
  provider.transcription = createTranscriptionModel;
1430
+ provider.videoModel = createVideoModel;
1431
+ provider.video = createVideoModel;
1105
1432
  return provider;
1106
1433
  }
1107
1434
  var runpod = createRunpod();