@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.
- package/README.md +113 -390
- package/dist/{index-BMqnP1RV.d.ts → index-Bavk1Y8-.d.ts} +6 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +107 -4
- package/dist/index.js.map +1 -1
- package/dist/primitives/index.js +85 -0
- package/dist/primitives/index.js.map +1 -1
- package/dist/workflows/index.d.ts +1 -1
- package/dist/workflows/index.js +106 -3
- package/dist/workflows/index.js.map +1 -1
- package/package.json +11 -3
package/dist/workflows/index.js
CHANGED
|
@@ -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
|
|
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(
|
|
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
|
-
|
|
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
|
});
|