@mux/ai 0.50.0 → 0.51.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.
@@ -8196,6 +8196,52 @@ async function getSummaryAndTagsInternal(assetId, options, collectedUsage) {
8196
8196
  // src/workflows/translate-audio.ts
8197
8197
  import { sleep } from "workflow";
8198
8198
 
8199
+ // src/lib/elevenlabs-errors.ts
8200
+ var MAX_ERROR_BODY_CHARS = 500;
8201
+ async function elevenLabsResponseError(context, response) {
8202
+ const error = new Error(`${context}: ${await describeElevenLabsErrorResponse(response)}`);
8203
+ if (!isRetryableElevenLabsStatus(response.status)) {
8204
+ error.name = "FatalError";
8205
+ }
8206
+ return error;
8207
+ }
8208
+ function isRetryableElevenLabsStatus(status) {
8209
+ return status === 408 || status === 425 || status === 429 || status >= 500;
8210
+ }
8211
+ async function describeElevenLabsErrorResponse(response) {
8212
+ const statusLine = [response.status, response.statusText].filter(Boolean).join(" ");
8213
+ const body = await response.text().catch(() => "");
8214
+ const detail = formatElevenLabsErrorBody(body);
8215
+ return detail ? `${statusLine}: ${detail}` : statusLine;
8216
+ }
8217
+ function formatElevenLabsErrorBody(body) {
8218
+ const trimmed = body.trim();
8219
+ if (!trimmed) {
8220
+ return "";
8221
+ }
8222
+ let detail;
8223
+ try {
8224
+ detail = JSON.parse(trimmed).detail;
8225
+ } catch {
8226
+ return trimmed.slice(0, MAX_ERROR_BODY_CHARS);
8227
+ }
8228
+ if (typeof detail === "string" && detail) {
8229
+ return detail;
8230
+ }
8231
+ if (Array.isArray(detail) && detail.length > 0) {
8232
+ return detail.map((item) => [item.loc?.join("."), item.msg].filter(Boolean).join(": ")).join("; ");
8233
+ }
8234
+ if (detail && typeof detail === "object") {
8235
+ const { status, code, message, param, request_id: requestId } = detail;
8236
+ const reason = [status ?? code, message].filter(Boolean).join(": ");
8237
+ const context = [param && `param: ${param}`, requestId && `request_id: ${requestId}`].filter(Boolean).join(", ");
8238
+ if (reason) {
8239
+ return context ? `${reason} (${context})` : reason;
8240
+ }
8241
+ }
8242
+ return trimmed.slice(0, MAX_ERROR_BODY_CHARS);
8243
+ }
8244
+
8199
8245
  // src/lib/mux-static-renditions.ts
8200
8246
  var STATIC_RENDITIONS_GUIDE_URL = "https://www.mux.com/docs/guides/enable-static-mp4-renditions";
8201
8247
  var LEGACY_MP4_SUPPORT_FILE_PREFERENCE = {
@@ -8415,7 +8461,7 @@ async function createElevenLabsDubbingJob({
8415
8461
  body: formData
8416
8462
  });
8417
8463
  if (!dubbingResponse.ok) {
8418
- throw new Error(`ElevenLabs API error: ${dubbingResponse.statusText}`);
8464
+ throw await elevenLabsResponseError("ElevenLabs API error", dubbingResponse);
8419
8465
  }
8420
8466
  const dubbingData = await dubbingResponse.json();
8421
8467
  return dubbingData.dubbing_id;
@@ -8432,12 +8478,13 @@ async function checkElevenLabsDubbingStatus({
8432
8478
  }
8433
8479
  });
8434
8480
  if (!statusResponse.ok) {
8435
- throw new Error(`Status check failed: ${statusResponse.statusText}`);
8481
+ throw await elevenLabsResponseError("Status check failed", statusResponse);
8436
8482
  }
8437
8483
  const statusData = await statusResponse.json();
8438
8484
  return {
8439
8485
  status: statusData.status,
8440
- targetLanguages: statusData.target_languages ?? []
8486
+ targetLanguages: statusData.target_languages ?? [],
8487
+ error: typeof statusData.error === "string" && statusData.error ? statusData.error : void 0
8441
8488
  };
8442
8489
  }
8443
8490
  async function downloadAndUploadDubbedAudio({
@@ -8461,7 +8508,7 @@ async function downloadAndUploadDubbedAudio({
8461
8508
  }
8462
8509
  });
8463
8510
  if (!audioResponse.ok) {
8464
- throw new Error(`Failed to fetch dubbed audio: ${audioResponse.statusText}`);
8511
+ throw await elevenLabsResponseError("Failed to fetch dubbed audio", audioResponse);
8465
8512
  }
8466
8513
  const dubbedAudio = new Uint8Array(await audioResponse.arrayBuffer());
8467
8514
  const s3AccessKeyId = env_default.S3_ACCESS_KEY_ID;
@@ -8512,7 +8559,7 @@ async function downloadAndUploadDubTranscript({
8512
8559
  }
8513
8560
  });
8514
8561
  if (!transcriptResponse.ok) {
8515
- throw new Error(`Failed to fetch dub transcript: ${transcriptResponse.statusText}`);
8562
+ throw await elevenLabsResponseError("Failed to fetch dub transcript", transcriptResponse);
8516
8563
  }
8517
8564
  const transcriptBody = await transcriptResponse.json();
8518
8565
  const transcriptVtt = transcriptBody.webvtt;
@@ -8665,6 +8712,7 @@ async function translateAudio(assetId, toLanguageCode, options = {}) {
8665
8712
  let dubbingStatus = "dubbing";
8666
8713
  let pollAttempts = 0;
8667
8714
  let targetLanguages = [];
8715
+ let dubbingError;
8668
8716
  while (dubbingStatus !== "dubbed" && pollAttempts < maxPollAttempts) {
8669
8717
  await sleep(DUBBING_POLL_INTERVAL_MS);
8670
8718
  pollAttempts++;
@@ -8675,10 +8723,12 @@ async function translateAudio(assetId, toLanguageCode, options = {}) {
8675
8723
  });
8676
8724
  dubbingStatus = statusResult.status;
8677
8725
  targetLanguages = statusResult.targetLanguages;
8726
+ dubbingError = statusResult.error;
8678
8727
  } catch (error) {
8679
8728
  wrapError(error, "Failed to check dubbing status");
8680
8729
  }
8681
8730
  if (dubbingStatus === "failed") {
8731
+ console.warn(`\u274C ElevenLabs dubbing job ${dubbingId} failed: ${dubbingError ?? "no error reported"}`);
8682
8732
  throw new MuxAiError("ElevenLabs reported that the dubbing job failed.", { type: "processing_error" });
8683
8733
  }
8684
8734
  }