@mux/ai 0.7.2 → 0.7.4

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.
@@ -156,6 +156,9 @@ var EnvSchema = z.object({
156
156
  ),
157
157
  MUX_TEST_ASSET_ID_AUDIO_ONLY: optionalString("Mux test asset ID for audio-only assets.", "Mux test asset id for audio-only assets for testing"),
158
158
  MUX_TEST_ASSET_ID_VIOLENT_AUDIO_ONLY: optionalString("Mux test asset ID for audio-only assets with violent content.", "Mux test asset id for audio-only assets with violent content for testing"),
159
+ // Eval config
160
+ MUX_AI_EVAL_MODEL_SET: optionalString("Eval model selection mode.", "Choose between 'default' (provider defaults only) or 'all' (all configured models)"),
161
+ MUX_AI_EVAL_MODELS: optionalString("Comma-separated eval model pairs.", "Comma-separated provider:model pairs (e.g. 'openai:gpt-5.1,anthropic:claude-sonnet-4-5,google:gemini-3-flash-preview')"),
159
162
  // AI Providers
160
163
  OPENAI_API_KEY: optionalString("OpenAI API key for OpenAI-backed workflows.", "OpenAI API key"),
161
164
  ANTHROPIC_API_KEY: optionalString("Anthropic API key for Claude-backed workflows.", "Anthropic API key"),
@@ -530,6 +533,81 @@ var DEFAULT_EMBEDDING_MODELS = {
530
533
  openai: "text-embedding-3-small",
531
534
  google: "gemini-embedding-001"
532
535
  };
536
+ var LANGUAGE_MODELS = {
537
+ openai: ["gpt-5.1", "gpt-5-mini"],
538
+ anthropic: ["claude-sonnet-4-5"],
539
+ google: ["gemini-3-flash-preview", "gemini-2.5-flash"]
540
+ };
541
+ function getDefaultEvalModelConfigs() {
542
+ return Object.entries(DEFAULT_LANGUAGE_MODELS).map(([provider, modelId]) => ({ provider, modelId }));
543
+ }
544
+ function getAllEvalModelConfigs() {
545
+ return Object.entries(LANGUAGE_MODELS).flatMap(([provider, models]) => models.map((modelId) => ({ provider, modelId })));
546
+ }
547
+ function isSupportedProvider(value) {
548
+ return value === "openai" || value === "anthropic" || value === "google";
549
+ }
550
+ function parseEvalModelPair(value) {
551
+ const trimmed = value.trim();
552
+ const [providerRaw, modelIdRaw] = trimmed.split(":", 2);
553
+ const provider = providerRaw?.trim();
554
+ const modelId = modelIdRaw?.trim();
555
+ if (!provider || !modelId) {
556
+ throw new Error(
557
+ `Invalid eval model pair "${value}". Use "provider:model" (example: "openai:gpt-5.1").`
558
+ );
559
+ }
560
+ if (!isSupportedProvider(provider)) {
561
+ throw new Error(
562
+ `Unsupported eval provider "${provider}" in "${value}". Supported providers: ${Object.keys(LANGUAGE_MODELS).join(", ")}.`
563
+ );
564
+ }
565
+ const supportedModels = LANGUAGE_MODELS[provider];
566
+ if (!supportedModels.includes(modelId)) {
567
+ throw new Error(
568
+ `Unsupported eval model "${modelId}" for provider "${provider}". Supported models: ${supportedModels.join(", ")}.`
569
+ );
570
+ }
571
+ return {
572
+ provider,
573
+ modelId
574
+ };
575
+ }
576
+ function resolveEvalModelConfigs(options = {}) {
577
+ const explicitPairs = options.modelPairs?.map((value) => value.trim()).filter(Boolean) ?? [];
578
+ if (explicitPairs.length > 0) {
579
+ const dedupedPairs = Array.from(new Set(explicitPairs));
580
+ return dedupedPairs.map(parseEvalModelPair);
581
+ }
582
+ const selection = options.selection ?? "default";
583
+ if (selection === "all") {
584
+ return getAllEvalModelConfigs();
585
+ }
586
+ return getDefaultEvalModelConfigs();
587
+ }
588
+ function resolveEvalModelConfigsFromEnv(environment = env_default) {
589
+ const rawSelection = environment.MUX_AI_EVAL_MODEL_SET?.trim();
590
+ const rawModelPairs = environment.MUX_AI_EVAL_MODELS?.trim();
591
+ let selection;
592
+ if (!rawSelection || rawSelection === "default") {
593
+ selection = "default";
594
+ } else if (rawSelection === "all") {
595
+ selection = "all";
596
+ } else {
597
+ throw new Error(
598
+ `Invalid MUX_AI_EVAL_MODEL_SET="${rawSelection}". Expected "default" or "all".`
599
+ );
600
+ }
601
+ let modelPairs;
602
+ if (rawModelPairs) {
603
+ modelPairs = rawModelPairs.split(",").map((value) => value.trim()).filter(Boolean);
604
+ }
605
+ return resolveEvalModelConfigs({
606
+ selection,
607
+ modelPairs
608
+ });
609
+ }
610
+ var EVAL_MODEL_CONFIGS = resolveEvalModelConfigsFromEnv();
533
611
  function resolveLanguageModelConfig(options = {}) {
534
612
  const provider = options.provider || "openai";
535
613
  const modelId = options.model || DEFAULT_LANGUAGE_MODELS[provider];
@@ -3307,6 +3385,18 @@ function getReadyAudioStaticRendition(asset) {
3307
3385
  );
3308
3386
  }
3309
3387
  var hasReadyAudioStaticRendition = (asset) => Boolean(getReadyAudioStaticRendition(asset));
3388
+ function getAudioStaticRenditionStatus(asset) {
3389
+ const files = asset.static_renditions?.files;
3390
+ const audioRendition = files?.find((rendition) => rendition.name === "audio.m4a");
3391
+ if (typeof audioRendition?.status === "string" && audioRendition.status.length > 0) {
3392
+ return audioRendition.status;
3393
+ }
3394
+ const aggregateStatus = asset.static_renditions?.status;
3395
+ if (typeof aggregateStatus === "string" && aggregateStatus.length > 0) {
3396
+ return aggregateStatus;
3397
+ }
3398
+ return asset.static_renditions ? "requested" : "not_requested";
3399
+ }
3310
3400
  async function requestStaticRenditionCreation(assetId, credentials) {
3311
3401
  "use step";
3312
3402
  const muxClient = await resolveMuxClient(credentials);
@@ -3352,7 +3442,7 @@ async function waitForAudioStaticRendition({
3352
3442
  if (hasReadyAudioStaticRendition(currentAsset)) {
3353
3443
  return currentAsset;
3354
3444
  }
3355
- const currentStatus = currentAsset.static_renditions?.status || "unknown";
3445
+ const currentStatus = getAudioStaticRenditionStatus(currentAsset);
3356
3446
  console.warn(
3357
3447
  `\u231B Waiting for static rendition (attempt ${attempt}/${STATIC_RENDITION_MAX_ATTEMPTS}) \u2192 ${currentStatus}`
3358
3448
  );
@@ -3378,6 +3468,7 @@ async function createElevenLabsDubbingJob({
3378
3468
  audioBuffer,
3379
3469
  assetId,
3380
3470
  elevenLabsLangCode,
3471
+ elevenLabsSourceLangCode,
3381
3472
  numSpeakers,
3382
3473
  credentials
3383
3474
  }) {
@@ -3387,8 +3478,14 @@ async function createElevenLabsDubbingJob({
3387
3478
  const formData = new FormData();
3388
3479
  formData.append("file", audioBlob);
3389
3480
  formData.append("target_lang", elevenLabsLangCode);
3481
+ if (elevenLabsSourceLangCode) {
3482
+ formData.append("source_lang", elevenLabsSourceLangCode);
3483
+ }
3390
3484
  formData.append("num_speakers", numSpeakers.toString());
3391
- formData.append("name", `Mux Asset ${assetId} - auto to ${elevenLabsLangCode}`);
3485
+ formData.append(
3486
+ "name",
3487
+ `Mux Asset ${assetId} - ${elevenLabsSourceLangCode ?? "auto"} to ${elevenLabsLangCode}`
3488
+ );
3392
3489
  const dubbingResponse = await fetch("https://api.elevenlabs.io/v1/dubbing", {
3393
3490
  method: "POST",
3394
3491
  headers: {
@@ -3497,6 +3594,7 @@ async function translateAudio(assetId, toLanguageCode, options = {}) {
3497
3594
  "use workflow";
3498
3595
  const {
3499
3596
  provider = "elevenlabs",
3597
+ fromLanguageCode,
3500
3598
  numSpeakers = 0,
3501
3599
  // 0 = auto-detect
3502
3600
  uploadToMux = true,
@@ -3546,13 +3644,18 @@ async function translateAudio(assetId, toLanguageCode, options = {}) {
3546
3644
  }
3547
3645
  console.warn("\u{1F399}\uFE0F Creating dubbing job in ElevenLabs...");
3548
3646
  const elevenLabsLangCode = toISO639_3(toLanguageCode);
3549
- console.warn(`\u{1F50D} Creating dubbing job for asset ${assetId} with language code: ${elevenLabsLangCode}`);
3647
+ const normalizedFromLanguageCode = fromLanguageCode?.trim();
3648
+ const elevenLabsSourceLangCode = normalizedFromLanguageCode ? toISO639_3(normalizedFromLanguageCode) : void 0;
3649
+ console.warn(
3650
+ `\u{1F50D} Creating dubbing job for asset ${assetId}: ${elevenLabsSourceLangCode ?? "auto"} -> ${elevenLabsLangCode}`
3651
+ );
3550
3652
  let dubbingId;
3551
3653
  try {
3552
3654
  dubbingId = await createElevenLabsDubbingJob({
3553
3655
  audioBuffer,
3554
3656
  assetId,
3555
3657
  elevenLabsLangCode,
3658
+ elevenLabsSourceLangCode,
3556
3659
  numSpeakers,
3557
3660
  credentials
3558
3661
  });