@mux/ai 0.2.0 → 0.3.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.
package/dist/index.js CHANGED
@@ -72,10 +72,9 @@ var env = parseEnv();
72
72
  var env_default = env;
73
73
 
74
74
  // src/lib/url-signing.ts
75
- async function resolveSigningContext(config) {
76
- "use step";
77
- const keyId = config.muxSigningKey ?? env_default.MUX_SIGNING_KEY;
78
- const keySecret = config.muxPrivateKey ?? env_default.MUX_PRIVATE_KEY;
75
+ function getMuxSigningContextFromEnv() {
76
+ const keyId = env_default.MUX_SIGNING_KEY;
77
+ const keySecret = env_default.MUX_PRIVATE_KEY;
79
78
  if (!keyId || !keySecret) {
80
79
  return void 0;
81
80
  }
@@ -112,10 +111,11 @@ async function signUrl(url, playbackId, context, type = "video", params) {
112
111
 
113
112
  // src/primitives/storyboards.ts
114
113
  var DEFAULT_STORYBOARD_WIDTH = 640;
115
- async function getStoryboardUrl(playbackId, width = DEFAULT_STORYBOARD_WIDTH, signingContext) {
114
+ async function getStoryboardUrl(playbackId, width = DEFAULT_STORYBOARD_WIDTH, shouldSign = false) {
116
115
  "use step";
117
116
  const baseUrl = `https://image.mux.com/${playbackId}/storyboard.png`;
118
- if (signingContext) {
117
+ if (shouldSign) {
118
+ const signingContext = getMuxSigningContextFromEnv();
119
119
  return signUrl(baseUrl, playbackId, signingContext, "storyboard", { width });
120
120
  }
121
121
  return `${baseUrl}?width=${width}`;
@@ -209,7 +209,7 @@ function chunkText(text, strategy) {
209
209
  // src/primitives/thumbnails.ts
210
210
  async function getThumbnailUrls(playbackId, duration, options = {}) {
211
211
  "use step";
212
- const { interval = 10, width = 640, signingContext } = options;
212
+ const { interval = 10, width = 640, shouldSign = false } = options;
213
213
  const timestamps = [];
214
214
  if (duration <= 50) {
215
215
  const spacing = duration / 6;
@@ -223,7 +223,8 @@ async function getThumbnailUrls(playbackId, duration, options = {}) {
223
223
  }
224
224
  const baseUrl = `https://image.mux.com/${playbackId}/thumbnail.png`;
225
225
  const urlPromises = timestamps.map(async (time) => {
226
- if (signingContext) {
226
+ if (shouldSign) {
227
+ const signingContext = getMuxSigningContextFromEnv();
227
228
  return signUrl(baseUrl, playbackId, signingContext, "thumbnail", { time, width });
228
229
  }
229
230
  return `${baseUrl}?time=${time}&width=${width}`;
@@ -339,17 +340,18 @@ function parseVTTCues(vttContent) {
339
340
  }
340
341
  return cues;
341
342
  }
342
- async function buildTranscriptUrl(playbackId, trackId, signingContext) {
343
+ async function buildTranscriptUrl(playbackId, trackId, shouldSign = false) {
343
344
  "use step";
344
345
  const baseUrl = `https://stream.mux.com/${playbackId}/text/${trackId}.vtt`;
345
- if (signingContext) {
346
+ if (shouldSign) {
347
+ const signingContext = getMuxSigningContextFromEnv();
346
348
  return signUrl(baseUrl, playbackId, signingContext, "video");
347
349
  }
348
350
  return baseUrl;
349
351
  }
350
352
  async function fetchTranscriptForAsset(asset, playbackId, options = {}) {
351
353
  "use step";
352
- const { languageCode, cleanTranscript = true, signingContext } = options;
354
+ const { languageCode, cleanTranscript = true, shouldSign } = options;
353
355
  const track = findCaptionTrack(asset, languageCode);
354
356
  if (!track) {
355
357
  return { transcriptText: "" };
@@ -357,7 +359,7 @@ async function fetchTranscriptForAsset(asset, playbackId, options = {}) {
357
359
  if (!track.id) {
358
360
  return { transcriptText: "", track };
359
361
  }
360
- const transcriptUrl = await buildTranscriptUrl(playbackId, track.id, signingContext);
362
+ const transcriptUrl = await buildTranscriptUrl(playbackId, track.id, shouldSign);
361
363
  try {
362
364
  const response = await fetch(transcriptUrl);
363
365
  if (!response.ok) {
@@ -414,22 +416,22 @@ function requireEnv(value, name) {
414
416
  }
415
417
  return value;
416
418
  }
417
- function createLanguageModelFromConfig(provider, modelId, credentials) {
419
+ function createLanguageModelFromConfig(provider, modelId) {
418
420
  switch (provider) {
419
421
  case "openai": {
420
- const apiKey = credentials.openaiApiKey;
422
+ const apiKey = env_default.OPENAI_API_KEY;
421
423
  requireEnv(apiKey, "OPENAI_API_KEY");
422
424
  const openai = createOpenAI({ apiKey });
423
425
  return openai(modelId);
424
426
  }
425
427
  case "anthropic": {
426
- const apiKey = credentials.anthropicApiKey;
428
+ const apiKey = env_default.ANTHROPIC_API_KEY;
427
429
  requireEnv(apiKey, "ANTHROPIC_API_KEY");
428
430
  const anthropic = createAnthropic({ apiKey });
429
431
  return anthropic(modelId);
430
432
  }
431
433
  case "google": {
432
- const apiKey = credentials.googleApiKey;
434
+ const apiKey = env_default.GOOGLE_GENERATIVE_AI_API_KEY;
433
435
  requireEnv(apiKey, "GOOGLE_GENERATIVE_AI_API_KEY");
434
436
  const google = createGoogleGenerativeAI({ apiKey });
435
437
  return google(modelId);
@@ -440,16 +442,16 @@ function createLanguageModelFromConfig(provider, modelId, credentials) {
440
442
  }
441
443
  }
442
444
  }
443
- function createEmbeddingModelFromConfig(provider, modelId, credentials) {
445
+ function createEmbeddingModelFromConfig(provider, modelId) {
444
446
  switch (provider) {
445
447
  case "openai": {
446
- const apiKey = credentials.openaiApiKey;
448
+ const apiKey = env_default.OPENAI_API_KEY;
447
449
  requireEnv(apiKey, "OPENAI_API_KEY");
448
450
  const openai = createOpenAI({ apiKey });
449
451
  return openai.embedding(modelId);
450
452
  }
451
453
  case "google": {
452
- const apiKey = credentials.googleApiKey;
454
+ const apiKey = env_default.GOOGLE_GENERATIVE_AI_API_KEY;
453
455
  requireEnv(apiKey, "GOOGLE_GENERATIVE_AI_API_KEY");
454
456
  const google = createGoogleGenerativeAI({ apiKey });
455
457
  return google.textEmbeddingModel(modelId);
@@ -465,7 +467,7 @@ function resolveLanguageModel(options = {}) {
465
467
  const modelId = options.model || DEFAULT_LANGUAGE_MODELS[provider];
466
468
  switch (provider) {
467
469
  case "openai": {
468
- const apiKey = options.openaiApiKey ?? env_default.OPENAI_API_KEY;
470
+ const apiKey = env_default.OPENAI_API_KEY;
469
471
  requireEnv(apiKey, "OPENAI_API_KEY");
470
472
  const openai = createOpenAI({
471
473
  apiKey
@@ -477,7 +479,7 @@ function resolveLanguageModel(options = {}) {
477
479
  };
478
480
  }
479
481
  case "anthropic": {
480
- const apiKey = options.anthropicApiKey ?? env_default.ANTHROPIC_API_KEY;
482
+ const apiKey = env_default.ANTHROPIC_API_KEY;
481
483
  requireEnv(apiKey, "ANTHROPIC_API_KEY");
482
484
  const anthropic = createAnthropic({
483
485
  apiKey
@@ -489,7 +491,7 @@ function resolveLanguageModel(options = {}) {
489
491
  };
490
492
  }
491
493
  case "google": {
492
- const apiKey = options.googleApiKey ?? env_default.GOOGLE_GENERATIVE_AI_API_KEY;
494
+ const apiKey = env_default.GOOGLE_GENERATIVE_AI_API_KEY;
493
495
  requireEnv(apiKey, "GOOGLE_GENERATIVE_AI_API_KEY");
494
496
  const google = createGoogleGenerativeAI({
495
497
  apiKey
@@ -511,7 +513,7 @@ function resolveEmbeddingModel(options = {}) {
511
513
  const modelId = options.model || DEFAULT_EMBEDDING_MODELS[provider];
512
514
  switch (provider) {
513
515
  case "openai": {
514
- const apiKey = options.openaiApiKey ?? env_default.OPENAI_API_KEY;
516
+ const apiKey = env_default.OPENAI_API_KEY;
515
517
  requireEnv(apiKey, "OPENAI_API_KEY");
516
518
  const openai = createOpenAI({
517
519
  apiKey
@@ -523,7 +525,7 @@ function resolveEmbeddingModel(options = {}) {
523
525
  };
524
526
  }
525
527
  case "google": {
526
- const apiKey = options.googleApiKey ?? env_default.GOOGLE_GENERATIVE_AI_API_KEY;
528
+ const apiKey = env_default.GOOGLE_GENERATIVE_AI_API_KEY;
527
529
  requireEnv(apiKey, "GOOGLE_GENERATIVE_AI_API_KEY");
528
530
  const google = createGoogleGenerativeAI({
529
531
  apiKey
@@ -542,13 +544,45 @@ function resolveEmbeddingModel(options = {}) {
542
544
  }
543
545
 
544
546
  // src/lib/client-factory.ts
545
- async function validateCredentials(options, requiredProvider) {
546
- "use step";
547
- const muxTokenId = options.muxTokenId ?? env_default.MUX_TOKEN_ID;
548
- const muxTokenSecret = options.muxTokenSecret ?? env_default.MUX_TOKEN_SECRET;
549
- const openaiApiKey = options.openaiApiKey ?? env_default.OPENAI_API_KEY;
550
- const anthropicApiKey = options.anthropicApiKey ?? env_default.ANTHROPIC_API_KEY;
551
- const googleApiKey = options.googleApiKey ?? env_default.GOOGLE_GENERATIVE_AI_API_KEY;
547
+ function getMuxCredentialsFromEnv() {
548
+ const muxTokenId = env_default.MUX_TOKEN_ID;
549
+ const muxTokenSecret = env_default.MUX_TOKEN_SECRET;
550
+ if (!muxTokenId || !muxTokenSecret) {
551
+ throw new Error(
552
+ "Mux credentials are required. Set MUX_TOKEN_ID and MUX_TOKEN_SECRET environment variables."
553
+ );
554
+ }
555
+ return { muxTokenId, muxTokenSecret };
556
+ }
557
+ function getApiKeyFromEnv(provider) {
558
+ const envVarMap = {
559
+ openai: env_default.OPENAI_API_KEY,
560
+ anthropic: env_default.ANTHROPIC_API_KEY,
561
+ google: env_default.GOOGLE_GENERATIVE_AI_API_KEY,
562
+ hive: env_default.HIVE_API_KEY,
563
+ elevenlabs: env_default.ELEVENLABS_API_KEY
564
+ };
565
+ const apiKey = envVarMap[provider];
566
+ if (!apiKey) {
567
+ const envVarNames = {
568
+ openai: "OPENAI_API_KEY",
569
+ anthropic: "ANTHROPIC_API_KEY",
570
+ google: "GOOGLE_GENERATIVE_AI_API_KEY",
571
+ hive: "HIVE_API_KEY",
572
+ elevenlabs: "ELEVENLABS_API_KEY"
573
+ };
574
+ throw new Error(
575
+ `${provider} API key is required. Set ${envVarNames[provider]} environment variable.`
576
+ );
577
+ }
578
+ return apiKey;
579
+ }
580
+ async function validateCredentials(requiredProvider) {
581
+ const muxTokenId = env_default.MUX_TOKEN_ID;
582
+ const muxTokenSecret = env_default.MUX_TOKEN_SECRET;
583
+ const openaiApiKey = env_default.OPENAI_API_KEY;
584
+ const anthropicApiKey = env_default.ANTHROPIC_API_KEY;
585
+ const googleApiKey = env_default.GOOGLE_GENERATIVE_AI_API_KEY;
552
586
  if (!muxTokenId || !muxTokenSecret) {
553
587
  throw new Error(
554
588
  "Mux credentials are required. Provide muxTokenId and muxTokenSecret in options or set MUX_TOKEN_ID and MUX_TOKEN_SECRET environment variables."
@@ -578,9 +612,8 @@ async function validateCredentials(options, requiredProvider) {
578
612
  };
579
613
  }
580
614
  async function createWorkflowConfig(options, provider) {
581
- "use step";
582
615
  const providerToUse = provider || options.provider || "openai";
583
- const credentials = await validateCredentials(options, providerToUse);
616
+ const credentials = await validateCredentials(providerToUse);
584
617
  const resolved = resolveLanguageModel({
585
618
  ...options,
586
619
  provider: providerToUse
@@ -701,11 +734,12 @@ function getPlaybackId(asset) {
701
734
  "No public or signed playback ID found for this asset. A public or signed playback ID is required. DRM playback IDs are not currently supported."
702
735
  );
703
736
  }
704
- async function getPlaybackIdForAsset(credentials, assetId) {
737
+ async function getPlaybackIdForAsset(assetId) {
705
738
  "use step";
739
+ const { muxTokenId, muxTokenSecret } = getMuxCredentialsFromEnv();
706
740
  const mux = new Mux2({
707
- tokenId: credentials.muxTokenId,
708
- tokenSecret: credentials.muxTokenSecret
741
+ tokenId: muxTokenId,
742
+ tokenSecret: muxTokenSecret
709
743
  });
710
744
  const asset = await mux.video.assets.retrieve(assetId);
711
745
  const { id: playbackId, policy } = getPlaybackId(asset);
@@ -884,16 +918,11 @@ async function analyzeStoryboard({
884
918
  imageDataUrl,
885
919
  provider,
886
920
  modelId,
887
- credentials,
888
921
  userPrompt,
889
922
  systemPrompt
890
923
  }) {
891
924
  "use step";
892
- const model = createLanguageModelFromConfig(
893
- provider,
894
- modelId,
895
- credentials
896
- );
925
+ const model = createLanguageModelFromConfig(provider, modelId);
897
926
  const response = await generateObject({
898
927
  model,
899
928
  schema: burnedInCaptionsSchema,
@@ -938,14 +967,14 @@ async function hasBurnedInCaptions(assetId, options = {}) {
938
967
  { ...config, model },
939
968
  provider
940
969
  );
941
- const { playbackId, policy } = await getPlaybackIdForAsset(workflowConfig.credentials, assetId);
942
- const signingContext = await resolveSigningContext(options);
970
+ const { playbackId, policy } = await getPlaybackIdForAsset(assetId);
971
+ const signingContext = getMuxSigningContextFromEnv();
943
972
  if (policy === "signed" && !signingContext) {
944
973
  throw new Error(
945
974
  "Signed playback ID requires signing credentials. Provide muxSigningKey and muxPrivateKey in options or set MUX_SIGNING_KEY and MUX_PRIVATE_KEY environment variables."
946
975
  );
947
976
  }
948
- const imageUrl = await getStoryboardUrl(playbackId, 640, policy === "signed" ? signingContext : void 0);
977
+ const imageUrl = await getStoryboardUrl(playbackId, 640, policy === "signed");
949
978
  let analysisResponse;
950
979
  if (imageSubmissionMode === "base64") {
951
980
  const base64Data = await fetchImageAsBase64(imageUrl, imageDownloadOptions);
@@ -953,7 +982,6 @@ async function hasBurnedInCaptions(assetId, options = {}) {
953
982
  imageDataUrl: base64Data,
954
983
  provider: workflowConfig.provider,
955
984
  modelId: workflowConfig.modelId,
956
- credentials: workflowConfig.credentials,
957
985
  userPrompt,
958
986
  systemPrompt: SYSTEM_PROMPT
959
987
  });
@@ -962,7 +990,6 @@ async function hasBurnedInCaptions(assetId, options = {}) {
962
990
  imageDataUrl: imageUrl,
963
991
  provider: workflowConfig.provider,
964
992
  modelId: workflowConfig.modelId,
965
- credentials: workflowConfig.credentials,
966
993
  userPrompt,
967
994
  systemPrompt: SYSTEM_PROMPT
968
995
  });
@@ -1035,16 +1062,11 @@ var chaptersSchema = z3.object({
1035
1062
  async function generateChaptersWithAI({
1036
1063
  provider,
1037
1064
  modelId,
1038
- credentials,
1039
1065
  timestampedTranscript,
1040
1066
  systemPrompt
1041
1067
  }) {
1042
1068
  "use step";
1043
- const model = createLanguageModelFromConfig(
1044
- provider,
1045
- modelId,
1046
- credentials
1047
- );
1069
+ const model = createLanguageModelFromConfig(provider, modelId);
1048
1070
  const response = await withRetry(
1049
1071
  () => generateObject2({
1050
1072
  model,
@@ -1087,8 +1109,8 @@ async function generateChapters(assetId, languageCode, options = {}) {
1087
1109
  "use workflow";
1088
1110
  const { provider = "openai", model } = options;
1089
1111
  const config = await createWorkflowConfig({ ...options, model }, provider);
1090
- const { asset: assetData, playbackId, policy } = await getPlaybackIdForAsset(config.credentials, assetId);
1091
- const signingContext = await resolveSigningContext(options);
1112
+ const { asset: assetData, playbackId, policy } = await getPlaybackIdForAsset(assetId);
1113
+ const signingContext = getMuxSigningContextFromEnv();
1092
1114
  if (policy === "signed" && !signingContext) {
1093
1115
  throw new Error(
1094
1116
  "Signed playback ID requires signing credentials. Provide muxSigningKey and muxPrivateKey in options or set MUX_SIGNING_KEY and MUX_PRIVATE_KEY environment variables."
@@ -1098,7 +1120,7 @@ async function generateChapters(assetId, languageCode, options = {}) {
1098
1120
  languageCode,
1099
1121
  cleanTranscript: false,
1100
1122
  // keep timestamps for chapter segmentation
1101
- signingContext: policy === "signed" ? signingContext : void 0
1123
+ shouldSign: policy === "signed"
1102
1124
  });
1103
1125
  if (!transcriptResult.track || !transcriptResult.transcriptText) {
1104
1126
  const availableLanguages = getReadyTextTracks(assetData).map((t) => t.language_code).filter(Boolean).join(", ");
@@ -1115,7 +1137,6 @@ async function generateChapters(assetId, languageCode, options = {}) {
1115
1137
  chaptersData = await generateChaptersWithAI({
1116
1138
  provider: config.provider,
1117
1139
  modelId: config.modelId,
1118
- credentials: config.credentials,
1119
1140
  timestampedTranscript,
1120
1141
  systemPrompt: SYSTEM_PROMPT2
1121
1142
  });
@@ -1162,11 +1183,10 @@ function averageEmbeddings(embeddings) {
1162
1183
  async function generateSingleChunkEmbedding({
1163
1184
  chunk,
1164
1185
  provider,
1165
- modelId,
1166
- credentials
1186
+ modelId
1167
1187
  }) {
1168
1188
  "use step";
1169
- const model = createEmbeddingModelFromConfig(provider, modelId, credentials);
1189
+ const model = createEmbeddingModelFromConfig(provider, modelId);
1170
1190
  const response = await withRetry(
1171
1191
  () => embed({
1172
1192
  model,
@@ -1192,13 +1212,9 @@ async function generateVideoEmbeddings(assetId, options = {}) {
1192
1212
  chunkingStrategy = { type: "token", maxTokens: 500, overlap: 100 },
1193
1213
  batchSize = 5
1194
1214
  } = options;
1195
- const credentials = await validateCredentials(options, provider === "google" ? "google" : "openai");
1196
1215
  const embeddingModel = resolveEmbeddingModel({ ...options, provider, model });
1197
- const { asset: assetData, playbackId, policy } = await getPlaybackIdForAsset(
1198
- credentials,
1199
- assetId
1200
- );
1201
- const signingContext = await resolveSigningContext(options);
1216
+ const { asset: assetData, playbackId, policy } = await getPlaybackIdForAsset(assetId);
1217
+ const signingContext = getMuxSigningContextFromEnv();
1202
1218
  if (policy === "signed" && !signingContext) {
1203
1219
  throw new Error(
1204
1220
  "Signed playback ID requires signing credentials. Provide muxSigningKey and muxPrivateKey in options or set MUX_SIGNING_KEY and MUX_PRIVATE_KEY environment variables."
@@ -1208,7 +1224,7 @@ async function generateVideoEmbeddings(assetId, options = {}) {
1208
1224
  const transcriptResult = await fetchTranscriptForAsset(assetData, playbackId, {
1209
1225
  languageCode,
1210
1226
  cleanTranscript: !useVttChunking,
1211
- signingContext: policy === "signed" ? signingContext : void 0
1227
+ shouldSign: policy === "signed"
1212
1228
  });
1213
1229
  if (!transcriptResult.track || !transcriptResult.transcriptText) {
1214
1230
  const availableLanguages = getReadyTextTracks(assetData).map((t) => t.language_code).filter(Boolean).join(", ");
@@ -1237,8 +1253,7 @@ async function generateVideoEmbeddings(assetId, options = {}) {
1237
1253
  (chunk) => generateSingleChunkEmbedding({
1238
1254
  chunk,
1239
1255
  provider: embeddingModel.provider,
1240
- modelId: embeddingModel.modelId,
1241
- credentials
1256
+ modelId: embeddingModel.modelId
1242
1257
  })
1243
1258
  )
1244
1259
  );
@@ -1323,19 +1338,20 @@ async function processConcurrently(items, processor, maxConcurrent = 5) {
1323
1338
  }
1324
1339
  return results;
1325
1340
  }
1326
- async function requestOpenAIModeration(imageUrls, apiKey, model, maxConcurrent = 5, submissionMode = "url", downloadOptions) {
1341
+ async function requestOpenAIModeration(imageUrls, model, maxConcurrent = 5, submissionMode = "url", downloadOptions) {
1327
1342
  "use step";
1328
1343
  const targetUrls = submissionMode === "base64" ? (await downloadImagesAsBase64(imageUrls, downloadOptions, maxConcurrent)).map(
1329
- (img) => ({ url: img.url, image: img.base64Data, apiKey, model })
1330
- ) : imageUrls.map((url) => ({ url, image: url, apiKey, model }));
1344
+ (img) => ({ url: img.url, image: img.base64Data, model })
1345
+ ) : imageUrls.map((url) => ({ url, image: url, model }));
1331
1346
  const moderate = async (entry) => {
1332
1347
  "use step";
1348
+ const apiKey = getApiKeyFromEnv("openai");
1333
1349
  try {
1334
1350
  const res = await fetch("https://api.openai.com/v1/moderations", {
1335
1351
  method: "POST",
1336
1352
  headers: {
1337
1353
  "Content-Type": "application/json",
1338
- "Authorization": `Bearer ${entry.apiKey}`
1354
+ "Authorization": `Bearer ${apiKey}`
1339
1355
  },
1340
1356
  body: JSON.stringify({
1341
1357
  model: entry.model,
@@ -1381,7 +1397,7 @@ function getHiveCategoryScores(classes, categoryNames) {
1381
1397
  const scores = categoryNames.map((category) => scoreMap[category] || 0);
1382
1398
  return Math.max(...scores, 0);
1383
1399
  }
1384
- async function requestHiveModeration(imageUrls, apiKey, maxConcurrent = 5, submissionMode = "url", downloadOptions) {
1400
+ async function requestHiveModeration(imageUrls, maxConcurrent = 5, submissionMode = "url", downloadOptions) {
1385
1401
  "use step";
1386
1402
  const targets = submissionMode === "base64" ? (await downloadImagesAsBase64(imageUrls, downloadOptions, maxConcurrent)).map((img) => ({
1387
1403
  url: img.url,
@@ -1396,6 +1412,7 @@ async function requestHiveModeration(imageUrls, apiKey, maxConcurrent = 5, submi
1396
1412
  }));
1397
1413
  const moderate = async (entry) => {
1398
1414
  "use step";
1415
+ const apiKey = getApiKeyFromEnv("hive");
1399
1416
  try {
1400
1417
  const formData = new FormData();
1401
1418
  if (entry.source.kind === "url") {
@@ -1452,10 +1469,9 @@ async function getModerationScores(assetId, options = {}) {
1452
1469
  imageSubmissionMode = "url",
1453
1470
  imageDownloadOptions
1454
1471
  } = options;
1455
- const credentials = await validateCredentials(options, provider === "openai" ? "openai" : void 0);
1456
- const { asset, playbackId, policy } = await getPlaybackIdForAsset(credentials, assetId);
1472
+ const { asset, playbackId, policy } = await getPlaybackIdForAsset(assetId);
1457
1473
  const duration = asset.duration || 0;
1458
- const signingContext = await resolveSigningContext(options);
1474
+ const signingContext = getMuxSigningContextFromEnv();
1459
1475
  if (policy === "signed" && !signingContext) {
1460
1476
  throw new Error(
1461
1477
  "Signed playback ID requires signing credentials. Provide muxSigningKey and muxPrivateKey in options or set MUX_SIGNING_KEY and MUX_PRIVATE_KEY environment variables."
@@ -1464,30 +1480,20 @@ async function getModerationScores(assetId, options = {}) {
1464
1480
  const thumbnailUrls = await getThumbnailUrls(playbackId, duration, {
1465
1481
  interval: thumbnailInterval,
1466
1482
  width: thumbnailWidth,
1467
- signingContext: policy === "signed" ? signingContext : void 0
1483
+ shouldSign: policy === "signed"
1468
1484
  });
1469
1485
  let thumbnailScores;
1470
1486
  if (provider === "openai") {
1471
- const apiKey = credentials.openaiApiKey;
1472
- if (!apiKey) {
1473
- throw new Error("OpenAI API key is required for moderation. Set OPENAI_API_KEY or pass openaiApiKey.");
1474
- }
1475
1487
  thumbnailScores = await requestOpenAIModeration(
1476
1488
  thumbnailUrls,
1477
- apiKey,
1478
1489
  model || "omni-moderation-latest",
1479
1490
  maxConcurrent,
1480
1491
  imageSubmissionMode,
1481
1492
  imageDownloadOptions
1482
1493
  );
1483
1494
  } else if (provider === "hive") {
1484
- const hiveApiKey = options.hiveApiKey || env_default.HIVE_API_KEY;
1485
- if (!hiveApiKey) {
1486
- throw new Error("Hive API key is required for moderation. Set HIVE_API_KEY or pass hiveApiKey.");
1487
- }
1488
1495
  thumbnailScores = await requestHiveModeration(
1489
1496
  thumbnailUrls,
1490
- hiveApiKey,
1491
1497
  maxConcurrent,
1492
1498
  imageSubmissionMode,
1493
1499
  imageDownloadOptions
@@ -1520,9 +1526,10 @@ var summarySchema = z4.object({
1520
1526
  title: z4.string(),
1521
1527
  description: z4.string()
1522
1528
  });
1529
+ var VALID_TONES = ["neutral", "playful", "professional"];
1523
1530
  var TONE_INSTRUCTIONS = {
1524
- normal: "Provide a clear, straightforward analysis.",
1525
- sassy: "Channel your inner diva! Answer with maximum sass, wit, and playful attitude. Don't hold back - be cheeky, clever, and delightfully snarky. Make it pop!",
1531
+ neutral: "Provide a clear, straightforward analysis.",
1532
+ playful: "Channel your inner diva! Answer with maximum sass, wit, and playful attitude. Don't hold back - be cheeky, clever, and delightfully snarky. Make it pop!",
1526
1533
  professional: "Provide a professional, executive-level analysis suitable for business reporting."
1527
1534
  };
1528
1535
  var summarizationPromptBuilder = createPromptBuilder({
@@ -1638,13 +1645,9 @@ function buildUserPrompt2({
1638
1645
  }
1639
1646
  return summarizationPromptBuilder.buildWithContext(promptOverrides, contextSections);
1640
1647
  }
1641
- async function analyzeStoryboard2(imageDataUrl, workflowConfig, userPrompt, systemPrompt) {
1648
+ async function analyzeStoryboard2(imageDataUrl, provider, modelId, userPrompt, systemPrompt) {
1642
1649
  "use step";
1643
- const model = createLanguageModelFromConfig(
1644
- workflowConfig.provider,
1645
- workflowConfig.modelId,
1646
- workflowConfig.credentials
1647
- );
1650
+ const model = createLanguageModelFromConfig(provider, modelId);
1648
1651
  const response = await generateObject3({
1649
1652
  model,
1650
1653
  schema: summarySchema,
@@ -1701,7 +1704,7 @@ async function getSummaryAndTags(assetId, options) {
1701
1704
  const {
1702
1705
  provider = "openai",
1703
1706
  model,
1704
- tone = "normal",
1707
+ tone = "neutral",
1705
1708
  includeTranscript = true,
1706
1709
  cleanTranscript = true,
1707
1710
  imageSubmissionMode = "url",
@@ -1709,12 +1712,17 @@ async function getSummaryAndTags(assetId, options) {
1709
1712
  abortSignal: _abortSignal,
1710
1713
  promptOverrides
1711
1714
  } = options ?? {};
1715
+ if (!VALID_TONES.includes(tone)) {
1716
+ throw new Error(
1717
+ `Invalid tone "${tone}". Valid tones are: ${VALID_TONES.join(", ")}`
1718
+ );
1719
+ }
1712
1720
  const config = await createWorkflowConfig(
1713
1721
  { ...options, model },
1714
1722
  provider
1715
1723
  );
1716
- const { asset: assetData, playbackId, policy } = await getPlaybackIdForAsset(config.credentials, assetId);
1717
- const signingContext = await resolveSigningContext(options ?? {});
1724
+ const { asset: assetData, playbackId, policy } = await getPlaybackIdForAsset(assetId);
1725
+ const signingContext = getMuxSigningContextFromEnv();
1718
1726
  if (policy === "signed" && !signingContext) {
1719
1727
  throw new Error(
1720
1728
  "Signed playback ID requires signing credentials. Provide muxSigningKey and muxPrivateKey in options or set MUX_SIGNING_KEY and MUX_PRIVATE_KEY environment variables."
@@ -1722,7 +1730,7 @@ async function getSummaryAndTags(assetId, options) {
1722
1730
  }
1723
1731
  const transcriptText = includeTranscript ? (await fetchTranscriptForAsset(assetData, playbackId, {
1724
1732
  cleanTranscript,
1725
- signingContext: policy === "signed" ? signingContext : void 0
1733
+ shouldSign: policy === "signed"
1726
1734
  })).transcriptText : "";
1727
1735
  const userPrompt = buildUserPrompt2({
1728
1736
  tone,
@@ -1730,19 +1738,20 @@ async function getSummaryAndTags(assetId, options) {
1730
1738
  isCleanTranscript: cleanTranscript,
1731
1739
  promptOverrides
1732
1740
  });
1733
- const imageUrl = await getStoryboardUrl(playbackId, 640, policy === "signed" ? signingContext : void 0);
1741
+ const imageUrl = await getStoryboardUrl(playbackId, 640, policy === "signed");
1734
1742
  let analysisResponse;
1735
1743
  try {
1736
1744
  if (imageSubmissionMode === "base64") {
1737
1745
  const downloadResult = await downloadImageAsBase64(imageUrl, imageDownloadOptions);
1738
1746
  analysisResponse = await analyzeStoryboard2(
1739
1747
  downloadResult.base64Data,
1740
- config,
1748
+ config.provider,
1749
+ config.modelId,
1741
1750
  userPrompt,
1742
1751
  SYSTEM_PROMPT3
1743
1752
  );
1744
1753
  } else {
1745
- analysisResponse = await withRetry(() => analyzeStoryboard2(imageUrl, config, userPrompt, SYSTEM_PROMPT3));
1754
+ analysisResponse = await withRetry(() => analyzeStoryboard2(imageUrl, config.provider, config.modelId, userPrompt, SYSTEM_PROMPT3));
1746
1755
  }
1747
1756
  } catch (error) {
1748
1757
  throw new Error(
@@ -1947,11 +1956,12 @@ function getReadyAudioStaticRendition(asset) {
1947
1956
  );
1948
1957
  }
1949
1958
  var hasReadyAudioStaticRendition = (asset) => Boolean(getReadyAudioStaticRendition(asset));
1950
- async function requestStaticRenditionCreation(credentials, assetId) {
1959
+ async function requestStaticRenditionCreation(assetId) {
1951
1960
  "use step";
1961
+ const { muxTokenId, muxTokenSecret } = getMuxCredentialsFromEnv();
1952
1962
  const mux = new Mux3({
1953
- tokenId: credentials.muxTokenId,
1954
- tokenSecret: credentials.muxTokenSecret
1963
+ tokenId: muxTokenId,
1964
+ tokenSecret: muxTokenSecret
1955
1965
  });
1956
1966
  try {
1957
1967
  await mux.video.assets.createStaticRendition(assetId, {
@@ -1970,13 +1980,13 @@ async function requestStaticRenditionCreation(credentials, assetId) {
1970
1980
  }
1971
1981
  async function waitForAudioStaticRendition({
1972
1982
  assetId,
1973
- credentials,
1974
1983
  initialAsset
1975
1984
  }) {
1976
1985
  "use step";
1986
+ const { muxTokenId, muxTokenSecret } = getMuxCredentialsFromEnv();
1977
1987
  const mux = new Mux3({
1978
- tokenId: credentials.muxTokenId,
1979
- tokenSecret: credentials.muxTokenSecret
1988
+ tokenId: muxTokenId,
1989
+ tokenSecret: muxTokenSecret
1980
1990
  });
1981
1991
  let currentAsset = initialAsset;
1982
1992
  if (hasReadyAudioStaticRendition(currentAsset)) {
@@ -1984,9 +1994,9 @@ async function waitForAudioStaticRendition({
1984
1994
  }
1985
1995
  const status = currentAsset.static_renditions?.status ?? "not_requested";
1986
1996
  if (status === "not_requested" || status === void 0) {
1987
- await requestStaticRenditionCreation(credentials, assetId);
1997
+ await requestStaticRenditionCreation(assetId);
1988
1998
  } else if (status === "errored") {
1989
- await requestStaticRenditionCreation(credentials, assetId);
1999
+ await requestStaticRenditionCreation(assetId);
1990
2000
  } else {
1991
2001
  console.warn(`\u2139\uFE0F Static rendition already ${status}. Waiting for it to finish...`);
1992
2002
  }
@@ -2022,10 +2032,10 @@ async function createElevenLabsDubbingJob({
2022
2032
  audioBuffer,
2023
2033
  assetId,
2024
2034
  elevenLabsLangCode,
2025
- elevenLabsApiKey,
2026
2035
  numSpeakers
2027
2036
  }) {
2028
2037
  "use step";
2038
+ const elevenLabsApiKey = getApiKeyFromEnv("elevenlabs");
2029
2039
  const audioBlob = new Blob([audioBuffer], { type: "audio/mp4" });
2030
2040
  const formData = new FormData();
2031
2041
  formData.append("file", audioBlob);
@@ -2046,10 +2056,10 @@ async function createElevenLabsDubbingJob({
2046
2056
  return dubbingData.dubbing_id;
2047
2057
  }
2048
2058
  async function checkElevenLabsDubbingStatus({
2049
- dubbingId,
2050
- elevenLabsApiKey
2059
+ dubbingId
2051
2060
  }) {
2052
2061
  "use step";
2062
+ const elevenLabsApiKey = getApiKeyFromEnv("elevenlabs");
2053
2063
  const statusResponse = await fetch(`https://api.elevenlabs.io/v1/dubbing/${dubbingId}`, {
2054
2064
  headers: {
2055
2065
  "xi-api-key": elevenLabsApiKey
@@ -2066,10 +2076,10 @@ async function checkElevenLabsDubbingStatus({
2066
2076
  }
2067
2077
  async function downloadDubbedAudioFromElevenLabs({
2068
2078
  dubbingId,
2069
- languageCode,
2070
- elevenLabsApiKey
2079
+ languageCode
2071
2080
  }) {
2072
2081
  "use step";
2082
+ const elevenLabsApiKey = getApiKeyFromEnv("elevenlabs");
2073
2083
  const audioUrl = `https://api.elevenlabs.io/v1/dubbing/${dubbingId}/audio/${languageCode}`;
2074
2084
  const audioResponse = await fetch(audioUrl, {
2075
2085
  headers: {
@@ -2087,14 +2097,14 @@ async function uploadDubbedAudioToS3({
2087
2097
  toLanguageCode,
2088
2098
  s3Endpoint,
2089
2099
  s3Region,
2090
- s3Bucket,
2091
- s3AccessKeyId,
2092
- s3SecretAccessKey
2100
+ s3Bucket
2093
2101
  }) {
2094
2102
  "use step";
2095
2103
  const { S3Client, GetObjectCommand } = await import("@aws-sdk/client-s3");
2096
2104
  const { Upload } = await import("@aws-sdk/lib-storage");
2097
2105
  const { getSignedUrl } = await import("@aws-sdk/s3-request-presigner");
2106
+ const s3AccessKeyId = env_default.S3_ACCESS_KEY_ID;
2107
+ const s3SecretAccessKey = env_default.S3_SECRET_ACCESS_KEY;
2098
2108
  const s3Client = new S3Client({
2099
2109
  region: s3Region,
2100
2110
  endpoint: s3Endpoint,
@@ -2127,11 +2137,12 @@ async function uploadDubbedAudioToS3({
2127
2137
  console.warn(`\u{1F517} Generated presigned URL (expires in 1 hour)`);
2128
2138
  return presignedUrl;
2129
2139
  }
2130
- async function createAudioTrackOnMux(credentials, assetId, languageCode, presignedUrl) {
2140
+ async function createAudioTrackOnMux(assetId, languageCode, presignedUrl) {
2131
2141
  "use step";
2142
+ const { muxTokenId, muxTokenSecret } = getMuxCredentialsFromEnv();
2132
2143
  const mux = new Mux3({
2133
- tokenId: credentials.muxTokenId,
2134
- tokenSecret: credentials.muxTokenSecret
2144
+ tokenId: muxTokenId,
2145
+ tokenSecret: muxTokenSecret
2135
2146
  });
2136
2147
  const languageName = new Intl.DisplayNames(["en"], { type: "language" }).of(languageCode) || languageCode.toUpperCase();
2137
2148
  const trackName = `${languageName} (auto-dubbed)`;
@@ -2158,21 +2169,20 @@ async function translateAudio(assetId, toLanguageCode, options = {}) {
2158
2169
  if (provider !== "elevenlabs") {
2159
2170
  throw new Error("Only ElevenLabs provider is currently supported for audio translation");
2160
2171
  }
2161
- const credentials = await validateCredentials(options);
2162
2172
  const elevenLabsKey = elevenLabsApiKey ?? env_default.ELEVENLABS_API_KEY;
2163
2173
  const s3Endpoint = options.s3Endpoint ?? env_default.S3_ENDPOINT;
2164
2174
  const s3Region = options.s3Region ?? env_default.S3_REGION ?? "auto";
2165
2175
  const s3Bucket = options.s3Bucket ?? env_default.S3_BUCKET;
2166
- const s3AccessKeyId = options.s3AccessKeyId ?? env_default.S3_ACCESS_KEY_ID;
2167
- const s3SecretAccessKey = options.s3SecretAccessKey ?? env_default.S3_SECRET_ACCESS_KEY;
2176
+ const s3AccessKeyId = env_default.S3_ACCESS_KEY_ID;
2177
+ const s3SecretAccessKey = env_default.S3_SECRET_ACCESS_KEY;
2168
2178
  if (!elevenLabsKey) {
2169
2179
  throw new Error("ElevenLabs API key is required. Provide elevenLabsApiKey in options or set ELEVENLABS_API_KEY environment variable.");
2170
2180
  }
2171
2181
  if (uploadToMux && (!s3Endpoint || !s3Bucket || !s3AccessKeyId || !s3SecretAccessKey)) {
2172
2182
  throw new Error("S3 configuration is required for uploading to Mux. Provide s3Endpoint, s3Bucket, s3AccessKeyId, and s3SecretAccessKey in options or set S3_ENDPOINT, S3_BUCKET, S3_ACCESS_KEY_ID, and S3_SECRET_ACCESS_KEY environment variables.");
2173
2183
  }
2174
- const { asset: initialAsset, playbackId, policy } = await getPlaybackIdForAsset(credentials, assetId);
2175
- const signingContext = await resolveSigningContext(options);
2184
+ const { asset: initialAsset, playbackId, policy } = await getPlaybackIdForAsset(assetId);
2185
+ const signingContext = getMuxSigningContextFromEnv();
2176
2186
  if (policy === "signed" && !signingContext) {
2177
2187
  throw new Error(
2178
2188
  "Signed playback ID requires signing credentials. Provide muxSigningKey and muxPrivateKey in options or set MUX_SIGNING_KEY and MUX_PRIVATE_KEY environment variables."
@@ -2183,7 +2193,6 @@ async function translateAudio(assetId, toLanguageCode, options = {}) {
2183
2193
  console.warn("\u274C No ready audio static rendition found. Requesting one now...");
2184
2194
  currentAsset = await waitForAudioStaticRendition({
2185
2195
  assetId,
2186
- credentials,
2187
2196
  initialAsset: currentAsset
2188
2197
  });
2189
2198
  }
@@ -2213,7 +2222,6 @@ async function translateAudio(assetId, toLanguageCode, options = {}) {
2213
2222
  audioBuffer,
2214
2223
  assetId,
2215
2224
  elevenLabsLangCode,
2216
- elevenLabsApiKey: elevenLabsKey,
2217
2225
  numSpeakers
2218
2226
  });
2219
2227
  console.warn(`\u2705 Dubbing job created with ID: ${dubbingId}`);
@@ -2230,8 +2238,7 @@ async function translateAudio(assetId, toLanguageCode, options = {}) {
2230
2238
  pollAttempts++;
2231
2239
  try {
2232
2240
  const statusResult = await checkElevenLabsDubbingStatus({
2233
- dubbingId,
2234
- elevenLabsApiKey: elevenLabsKey
2241
+ dubbingId
2235
2242
  });
2236
2243
  dubbingStatus = statusResult.status;
2237
2244
  targetLanguages = statusResult.targetLanguages;
@@ -2274,8 +2281,7 @@ async function translateAudio(assetId, toLanguageCode, options = {}) {
2274
2281
  }
2275
2282
  dubbedAudioBuffer = await downloadDubbedAudioFromElevenLabs({
2276
2283
  dubbingId,
2277
- languageCode: downloadLangCode,
2278
- elevenLabsApiKey: elevenLabsKey
2284
+ languageCode: downloadLangCode
2279
2285
  });
2280
2286
  console.warn("\u2705 Dubbed audio downloaded successfully!");
2281
2287
  } catch (error) {
@@ -2290,9 +2296,7 @@ async function translateAudio(assetId, toLanguageCode, options = {}) {
2290
2296
  toLanguageCode,
2291
2297
  s3Endpoint,
2292
2298
  s3Region,
2293
- s3Bucket,
2294
- s3AccessKeyId,
2295
- s3SecretAccessKey
2299
+ s3Bucket
2296
2300
  });
2297
2301
  } catch (error) {
2298
2302
  throw new Error(`Failed to upload audio to S3: ${error instanceof Error ? error.message : "Unknown error"}`);
@@ -2301,7 +2305,7 @@ async function translateAudio(assetId, toLanguageCode, options = {}) {
2301
2305
  let uploadedTrackId;
2302
2306
  const muxLangCode = toISO639_1(toLanguageCode);
2303
2307
  try {
2304
- uploadedTrackId = await createAudioTrackOnMux(credentials, assetId, muxLangCode, presignedUrl);
2308
+ uploadedTrackId = await createAudioTrackOnMux(assetId, muxLangCode, presignedUrl);
2305
2309
  const languageName = new Intl.DisplayNames(["en"], { type: "language" }).of(muxLangCode) || muxLangCode.toUpperCase();
2306
2310
  const trackName = `${languageName} (auto-dubbed)`;
2307
2311
  console.warn(`\u2705 Track added to Mux asset with ID: ${uploadedTrackId}`);
@@ -2343,15 +2347,10 @@ async function translateVttWithAI({
2343
2347
  toLanguageCode,
2344
2348
  provider,
2345
2349
  modelId,
2346
- credentials,
2347
2350
  abortSignal
2348
2351
  }) {
2349
2352
  "use step";
2350
- const languageModel = createLanguageModelFromConfig(
2351
- provider,
2352
- modelId,
2353
- credentials
2354
- );
2353
+ const languageModel = createLanguageModelFromConfig(provider, modelId);
2355
2354
  const response = await generateObject4({
2356
2355
  model: languageModel,
2357
2356
  schema: translationSchema,
@@ -2383,14 +2382,14 @@ async function uploadVttToS3({
2383
2382
  toLanguageCode,
2384
2383
  s3Endpoint,
2385
2384
  s3Region,
2386
- s3Bucket,
2387
- s3AccessKeyId,
2388
- s3SecretAccessKey
2385
+ s3Bucket
2389
2386
  }) {
2390
2387
  "use step";
2391
2388
  const { S3Client, GetObjectCommand } = await import("@aws-sdk/client-s3");
2392
2389
  const { Upload } = await import("@aws-sdk/lib-storage");
2393
2390
  const { getSignedUrl } = await import("@aws-sdk/s3-request-presigner");
2391
+ const s3AccessKeyId = env_default.S3_ACCESS_KEY_ID;
2392
+ const s3SecretAccessKey = env_default.S3_SECRET_ACCESS_KEY;
2394
2393
  const s3Client = new S3Client({
2395
2394
  region: s3Region,
2396
2395
  endpoint: s3Endpoint,
@@ -2421,11 +2420,12 @@ async function uploadVttToS3({
2421
2420
  });
2422
2421
  return presignedUrl;
2423
2422
  }
2424
- async function createTextTrackOnMux(credentials, assetId, languageCode, trackName, presignedUrl) {
2423
+ async function createTextTrackOnMux(assetId, languageCode, trackName, presignedUrl) {
2425
2424
  "use step";
2425
+ const { muxTokenId, muxTokenSecret } = getMuxCredentialsFromEnv();
2426
2426
  const mux = new Mux4({
2427
- tokenId: credentials.muxTokenId,
2428
- tokenSecret: credentials.muxTokenSecret
2427
+ tokenId: muxTokenId,
2428
+ tokenSecret: muxTokenSecret
2429
2429
  });
2430
2430
  const trackResponse = await mux.video.assets.createTrack(assetId, {
2431
2431
  type: "text",
@@ -2447,15 +2447,13 @@ async function translateCaptions(assetId, fromLanguageCode, toLanguageCode, opti
2447
2447
  s3Endpoint: providedS3Endpoint,
2448
2448
  s3Region: providedS3Region,
2449
2449
  s3Bucket: providedS3Bucket,
2450
- s3AccessKeyId: providedS3AccessKeyId,
2451
- s3SecretAccessKey: providedS3SecretAccessKey,
2452
2450
  uploadToMux: uploadToMuxOption
2453
2451
  } = options;
2454
2452
  const s3Endpoint = providedS3Endpoint ?? env_default.S3_ENDPOINT;
2455
2453
  const s3Region = providedS3Region ?? env_default.S3_REGION ?? "auto";
2456
2454
  const s3Bucket = providedS3Bucket ?? env_default.S3_BUCKET;
2457
- const s3AccessKeyId = providedS3AccessKeyId ?? env_default.S3_ACCESS_KEY_ID;
2458
- const s3SecretAccessKey = providedS3SecretAccessKey ?? env_default.S3_SECRET_ACCESS_KEY;
2455
+ const s3AccessKeyId = env_default.S3_ACCESS_KEY_ID;
2456
+ const s3SecretAccessKey = env_default.S3_SECRET_ACCESS_KEY;
2459
2457
  const uploadToMux = uploadToMuxOption !== false;
2460
2458
  const config = await createWorkflowConfig(
2461
2459
  { ...options, model },
@@ -2464,8 +2462,8 @@ async function translateCaptions(assetId, fromLanguageCode, toLanguageCode, opti
2464
2462
  if (uploadToMux && (!s3Endpoint || !s3Bucket || !s3AccessKeyId || !s3SecretAccessKey)) {
2465
2463
  throw new Error("S3 configuration is required for uploading to Mux. Provide s3Endpoint, s3Bucket, s3AccessKeyId, and s3SecretAccessKey in options or set S3_ENDPOINT, S3_BUCKET, S3_ACCESS_KEY_ID, and S3_SECRET_ACCESS_KEY environment variables.");
2466
2464
  }
2467
- const { asset: assetData, playbackId, policy } = await getPlaybackIdForAsset(config.credentials, assetId);
2468
- const signingContext = await resolveSigningContext(options);
2465
+ const { asset: assetData, playbackId, policy } = await getPlaybackIdForAsset(assetId);
2466
+ const signingContext = getMuxSigningContextFromEnv();
2469
2467
  if (policy === "signed" && !signingContext) {
2470
2468
  throw new Error(
2471
2469
  "Signed playback ID requires signing credentials. Provide muxSigningKey and muxPrivateKey in options or set MUX_SIGNING_KEY and MUX_PRIVATE_KEY environment variables."
@@ -2499,7 +2497,6 @@ async function translateCaptions(assetId, fromLanguageCode, toLanguageCode, opti
2499
2497
  toLanguageCode,
2500
2498
  provider: config.provider,
2501
2499
  modelId: config.modelId,
2502
- credentials: config.credentials,
2503
2500
  abortSignal: options.abortSignal
2504
2501
  });
2505
2502
  translatedVtt = result.translatedVtt;
@@ -2530,9 +2527,7 @@ async function translateCaptions(assetId, fromLanguageCode, toLanguageCode, opti
2530
2527
  toLanguageCode,
2531
2528
  s3Endpoint,
2532
2529
  s3Region,
2533
- s3Bucket,
2534
- s3AccessKeyId,
2535
- s3SecretAccessKey
2530
+ s3Bucket
2536
2531
  });
2537
2532
  } catch (error) {
2538
2533
  throw new Error(`Failed to upload VTT to S3: ${error instanceof Error ? error.message : "Unknown error"}`);
@@ -2541,7 +2536,7 @@ async function translateCaptions(assetId, fromLanguageCode, toLanguageCode, opti
2541
2536
  try {
2542
2537
  const languageName = getLanguageName(toLanguageCode);
2543
2538
  const trackName = `${languageName} (auto-translated)`;
2544
- uploadedTrackId = await createTextTrackOnMux(config.credentials, assetId, toLanguageCode, trackName, presignedUrl);
2539
+ uploadedTrackId = await createTextTrackOnMux(assetId, toLanguageCode, trackName, presignedUrl);
2545
2540
  } catch (error) {
2546
2541
  console.warn(`Failed to add track to Mux asset: ${error instanceof Error ? error.message : "Unknown error"}`);
2547
2542
  }