@mux/ai 0.33.0 → 0.35.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.
@@ -1246,6 +1246,8 @@ interface SummarizationOptions extends ScopedMuxAIOptions {
1246
1246
  }
1247
1247
  declare function getSummaryAndTags(assetId: string, options?: SummarizationOptions): Promise<SummaryAndTagsResult>;
1248
1248
 
1249
+ /** What happened to the audio-only static rendition `translateAudio` created as dubbing input. */
1250
+ type StaticRenditionCleanupOutcome = "deleted" | "delete_failed" | "kept" | "not_created";
1249
1251
  /** Output returned from `translateAudio`. */
1250
1252
  interface AudioTranslationResult {
1251
1253
  assetId: string;
@@ -1263,6 +1265,10 @@ interface AudioTranslationResult {
1263
1265
  captionsTrackId?: string;
1264
1266
  /** Presigned URL for the dub's translated transcript (WebVTT) staged to S3. */
1265
1267
  captionsPresignedUrl?: string;
1268
+ /** ID of the audio-only static rendition this run created, `undefined` when a usable rendition already existed. */
1269
+ createdStaticRenditionId?: string;
1270
+ /** Outcome of cleaning up the static rendition this run created (`not_created` when it reused an existing one). */
1271
+ staticRenditionCleanup: StaticRenditionCleanupOutcome;
1266
1272
  /** Workflow usage metadata (asset duration, thumbnails, etc.). */
1267
1273
  usage?: TokenUsage;
1268
1274
  }
@@ -1305,6 +1311,14 @@ interface AudioTranslationOptions extends MuxAIOptions {
1305
1311
  * text tracks — callers decide conflict semantics before enabling this.
1306
1312
  */
1307
1313
  uploadCaptionsToMux?: boolean;
1314
+ /**
1315
+ * Cleanup for the audio-only static rendition this run created as dubbing
1316
+ * input: `"delete"` (default) removes it when the workflow finishes, success
1317
+ * or failure; `"keep"` leaves it. A pre-existing rendition is never deleted.
1318
+ * Concurrent dubs of one asset share a rendition, so create it up front or
1319
+ * pass `"keep"` — one run's delete can race a peer's source fetch.
1320
+ */
1321
+ staticRenditionCleanup?: "delete" | "keep";
1308
1322
  /** Optional storage adapter override for upload + presign operations. */
1309
1323
  storageAdapter?: StorageAdapter;
1310
1324
  /** Expiry duration in seconds for S3 presigned GET URLs. Defaults to 86400 (24 hours). */
@@ -1402,7 +1416,10 @@ interface TranslationOptions<P extends SupportedProvider = SupportedProvider> ex
1402
1416
  interface TranslationChunkingOptions {
1403
1417
  /** Set to false to translate all cues in a single structured request. Defaults to true. */
1404
1418
  enabled?: boolean;
1405
- /** Prefer a single request until the asset is at least this long. Defaults to 30 minutes. */
1419
+ /**
1420
+ * Skip duration-based chunking until the asset is at least this long. Defaults to 30 minutes.
1421
+ * Shorter assets are still split by `maxCuesPerChunk` and `maxCueTextTokensPerChunk`.
1422
+ */
1406
1423
  minimumAssetDurationSeconds?: number;
1407
1424
  /** Soft target for chunk duration once chunking starts. Defaults to 30 minutes. */
1408
1425
  targetChunkDurationSeconds?: number;
@@ -1528,6 +1545,7 @@ type index_Question = Question;
1528
1545
  type index_QuestionAnswer = QuestionAnswer;
1529
1546
  type index_QuestionAnswerType = QuestionAnswerType;
1530
1547
  type index_ReplacementRecord = ReplacementRecord;
1548
+ type index_StaticRenditionCleanupOutcome = StaticRenditionCleanupOutcome;
1531
1549
  type index_SummarizationOptions = SummarizationOptions;
1532
1550
  type index_SummarizationPromptOverrides = SummarizationPromptOverrides;
1533
1551
  type index_SummarizationPromptSections = SummarizationPromptSections;
@@ -1570,7 +1588,7 @@ declare const index_translationSchema: typeof translationSchema;
1570
1588
  declare const index_validateNeverTranslateTerms: typeof validateNeverTranslateTerms;
1571
1589
  declare const index_verifyNeverTranslateTerms: typeof verifyNeverTranslateTerms;
1572
1590
  declare namespace index {
1573
- export { index_ASK_QUESTIONS_DEFAULT_MAX_ANSWER_OPTION_LENGTH as ASK_QUESTIONS_DEFAULT_MAX_ANSWER_OPTION_LENGTH, index_ASK_QUESTIONS_DEFAULT_MAX_FREE_FORM_ANSWER_LENGTH as ASK_QUESTIONS_DEFAULT_MAX_FREE_FORM_ANSWER_LENGTH, index_ASK_QUESTIONS_MAX_QUESTION_LENGTH as ASK_QUESTIONS_MAX_QUESTION_LENGTH, type index_AskQuestionsOptions as AskQuestionsOptions, type index_AskQuestionsResult as AskQuestionsResult, type index_AskQuestionsType as AskQuestionsType, type index_AudioTranslationOptions as AudioTranslationOptions, type index_AudioTranslationResult as AudioTranslationResult, type index_AutoCensorProfanityOptions as AutoCensorProfanityOptions, type index_BurnedInCaptionsAnalysis as BurnedInCaptionsAnalysis, type index_BurnedInCaptionsOptions as BurnedInCaptionsOptions, type index_BurnedInCaptionsPromptOverrides as BurnedInCaptionsPromptOverrides, type index_BurnedInCaptionsPromptSections as BurnedInCaptionsPromptSections, type index_BurnedInCaptionsResult as BurnedInCaptionsResult, type index_CaptionReplacement as CaptionReplacement, type index_CensorMode as CensorMode, type index_Chapter as Chapter, type index_ChapterSystemPromptSections as ChapterSystemPromptSections, type index_ChaptersOptions as ChaptersOptions, type index_ChaptersPromptOverrides as ChaptersPromptOverrides, type index_ChaptersPromptSections as ChaptersPromptSections, type index_ChaptersResult as ChaptersResult, type index_ChaptersType as ChaptersType, index_DEFAULT_DESCRIPTION_LENGTH as DEFAULT_DESCRIPTION_LENGTH, index_DEFAULT_SUMMARY_KEYWORD_LIMIT as DEFAULT_SUMMARY_KEYWORD_LIMIT, index_DEFAULT_TITLE_LENGTH as DEFAULT_TITLE_LENGTH, type index_EditCaptionsOptions as EditCaptionsOptions, type index_EditCaptionsResult as EditCaptionsResult, type index_EmbeddingsOptions as EmbeddingsOptions, type index_EmbeddingsResult as EmbeddingsResult, type index_EngagementInsightsOptions as EngagementInsightsOptions, type index_EngagementInsightsResult as EngagementInsightsResult, index_GOOGLE_VISION_LIKELIHOOD_TO_SCORE as GOOGLE_VISION_LIKELIHOOD_TO_SCORE, index_HIVE_SEXUAL_CATEGORIES as HIVE_SEXUAL_CATEGORIES, index_HIVE_VIOLENCE_CATEGORIES as HIVE_VIOLENCE_CATEGORIES, type index_HiveModerationOutput as HiveModerationOutput, type index_HiveModerationSource as HiveModerationSource, type index_ModerationOptions as ModerationOptions, type index_ModerationProvider as ModerationProvider, type index_ModerationResult as ModerationResult, type index_MomentInsight as MomentInsight, type index_OverallInsight as OverallInsight, type index_ProfanityDetectionPayload as ProfanityDetectionPayload, type index_Question as Question, type index_QuestionAnswer as QuestionAnswer, type index_QuestionAnswerType as QuestionAnswerType, type index_ReplacementRecord as ReplacementRecord, type index_SummarizationOptions as SummarizationOptions, type index_SummarizationPromptOverrides as SummarizationPromptOverrides, type index_SummarizationPromptSections as SummarizationPromptSections, type index_SummaryAndTagsResult as SummaryAndTagsResult, type index_SummaryType as SummaryType, type index_ThumbnailModerationScore as ThumbnailModerationScore, type index_TranslationChunkingOptions as TranslationChunkingOptions, type index_TranslationOptions as TranslationOptions, type index_TranslationPayload as TranslationPayload, type index_TranslationResult as TranslationResult, index_aggregateTokenUsage as aggregateTokenUsage, index_applyOverrideLists as applyOverrideLists, index_applyReplacements as applyReplacements, index_askQuestions as askQuestions, index_buildReplacementRegex as buildReplacementRegex, index_burnedInCaptionsSchema as burnedInCaptionsSchema, index_censorVttContent as censorVttContent, index_chapterSchema as chapterSchema, index_chaptersSchema as chaptersSchema, index_createReplacer as createReplacer, index_editCaptions as editCaptions, index_extractTranscriptSegmentsForHotspots as extractTranscriptSegmentsForHotspots, index_generateChapters as generateChapters, index_generateEmbeddings as generateEmbeddings, index_generateEngagementInsights as generateEngagementInsights, index_generateVideoEmbeddings as generateVideoEmbeddings, index_getModerationScores as getModerationScores, index_getSummaryAndTags as getSummaryAndTags, index_hasBurnedInCaptions as hasBurnedInCaptions, index_mapShotsToHotspots as mapShotsToHotspots, index_normalizeTranslatedVtt as normalizeTranslatedVtt, index_profanityDetectionSchema as profanityDetectionSchema, index_questionAnswerSchema as questionAnswerSchema, index_shouldSplitChunkTranslationError as shouldSplitChunkTranslationError, index_summarySchema as summarySchema, index_transformCueText as transformCueText, index_translateAudio as translateAudio, index_translateCaptions as translateCaptions, index_translationSchema as translationSchema, index_validateNeverTranslateTerms as validateNeverTranslateTerms, index_verifyNeverTranslateTerms as verifyNeverTranslateTerms };
1591
+ export { index_ASK_QUESTIONS_DEFAULT_MAX_ANSWER_OPTION_LENGTH as ASK_QUESTIONS_DEFAULT_MAX_ANSWER_OPTION_LENGTH, index_ASK_QUESTIONS_DEFAULT_MAX_FREE_FORM_ANSWER_LENGTH as ASK_QUESTIONS_DEFAULT_MAX_FREE_FORM_ANSWER_LENGTH, index_ASK_QUESTIONS_MAX_QUESTION_LENGTH as ASK_QUESTIONS_MAX_QUESTION_LENGTH, type index_AskQuestionsOptions as AskQuestionsOptions, type index_AskQuestionsResult as AskQuestionsResult, type index_AskQuestionsType as AskQuestionsType, type index_AudioTranslationOptions as AudioTranslationOptions, type index_AudioTranslationResult as AudioTranslationResult, type index_AutoCensorProfanityOptions as AutoCensorProfanityOptions, type index_BurnedInCaptionsAnalysis as BurnedInCaptionsAnalysis, type index_BurnedInCaptionsOptions as BurnedInCaptionsOptions, type index_BurnedInCaptionsPromptOverrides as BurnedInCaptionsPromptOverrides, type index_BurnedInCaptionsPromptSections as BurnedInCaptionsPromptSections, type index_BurnedInCaptionsResult as BurnedInCaptionsResult, type index_CaptionReplacement as CaptionReplacement, type index_CensorMode as CensorMode, type index_Chapter as Chapter, type index_ChapterSystemPromptSections as ChapterSystemPromptSections, type index_ChaptersOptions as ChaptersOptions, type index_ChaptersPromptOverrides as ChaptersPromptOverrides, type index_ChaptersPromptSections as ChaptersPromptSections, type index_ChaptersResult as ChaptersResult, type index_ChaptersType as ChaptersType, index_DEFAULT_DESCRIPTION_LENGTH as DEFAULT_DESCRIPTION_LENGTH, index_DEFAULT_SUMMARY_KEYWORD_LIMIT as DEFAULT_SUMMARY_KEYWORD_LIMIT, index_DEFAULT_TITLE_LENGTH as DEFAULT_TITLE_LENGTH, type index_EditCaptionsOptions as EditCaptionsOptions, type index_EditCaptionsResult as EditCaptionsResult, type index_EmbeddingsOptions as EmbeddingsOptions, type index_EmbeddingsResult as EmbeddingsResult, type index_EngagementInsightsOptions as EngagementInsightsOptions, type index_EngagementInsightsResult as EngagementInsightsResult, index_GOOGLE_VISION_LIKELIHOOD_TO_SCORE as GOOGLE_VISION_LIKELIHOOD_TO_SCORE, index_HIVE_SEXUAL_CATEGORIES as HIVE_SEXUAL_CATEGORIES, index_HIVE_VIOLENCE_CATEGORIES as HIVE_VIOLENCE_CATEGORIES, type index_HiveModerationOutput as HiveModerationOutput, type index_HiveModerationSource as HiveModerationSource, type index_ModerationOptions as ModerationOptions, type index_ModerationProvider as ModerationProvider, type index_ModerationResult as ModerationResult, type index_MomentInsight as MomentInsight, type index_OverallInsight as OverallInsight, type index_ProfanityDetectionPayload as ProfanityDetectionPayload, type index_Question as Question, type index_QuestionAnswer as QuestionAnswer, type index_QuestionAnswerType as QuestionAnswerType, type index_ReplacementRecord as ReplacementRecord, type index_StaticRenditionCleanupOutcome as StaticRenditionCleanupOutcome, type index_SummarizationOptions as SummarizationOptions, type index_SummarizationPromptOverrides as SummarizationPromptOverrides, type index_SummarizationPromptSections as SummarizationPromptSections, type index_SummaryAndTagsResult as SummaryAndTagsResult, type index_SummaryType as SummaryType, type index_ThumbnailModerationScore as ThumbnailModerationScore, type index_TranslationChunkingOptions as TranslationChunkingOptions, type index_TranslationOptions as TranslationOptions, type index_TranslationPayload as TranslationPayload, type index_TranslationResult as TranslationResult, index_aggregateTokenUsage as aggregateTokenUsage, index_applyOverrideLists as applyOverrideLists, index_applyReplacements as applyReplacements, index_askQuestions as askQuestions, index_buildReplacementRegex as buildReplacementRegex, index_burnedInCaptionsSchema as burnedInCaptionsSchema, index_censorVttContent as censorVttContent, index_chapterSchema as chapterSchema, index_chaptersSchema as chaptersSchema, index_createReplacer as createReplacer, index_editCaptions as editCaptions, index_extractTranscriptSegmentsForHotspots as extractTranscriptSegmentsForHotspots, index_generateChapters as generateChapters, index_generateEmbeddings as generateEmbeddings, index_generateEngagementInsights as generateEngagementInsights, index_generateVideoEmbeddings as generateVideoEmbeddings, index_getModerationScores as getModerationScores, index_getSummaryAndTags as getSummaryAndTags, index_hasBurnedInCaptions as hasBurnedInCaptions, index_mapShotsToHotspots as mapShotsToHotspots, index_normalizeTranslatedVtt as normalizeTranslatedVtt, index_profanityDetectionSchema as profanityDetectionSchema, index_questionAnswerSchema as questionAnswerSchema, index_shouldSplitChunkTranslationError as shouldSplitChunkTranslationError, index_summarySchema as summarySchema, index_transformCueText as transformCueText, index_translateAudio as translateAudio, index_translateCaptions as translateCaptions, index_translationSchema as translationSchema, index_validateNeverTranslateTerms as validateNeverTranslateTerms, index_verifyNeverTranslateTerms as verifyNeverTranslateTerms };
1574
1592
  }
1575
1593
 
1576
- export { type MomentInsight as $, ASK_QUESTIONS_DEFAULT_MAX_ANSWER_OPTION_LENGTH as A, type BurnedInCaptionsAnalysis as B, type CaptionReplacement as C, type ChaptersPromptOverrides as D, type ChaptersPromptSections as E, type ChaptersResult as F, type ChaptersType as G, DEFAULT_DESCRIPTION_LENGTH as H, type ISO639_1 as I, DEFAULT_SUMMARY_KEYWORD_LIMIT as J, DEFAULT_TITLE_LENGTH as K, type LanguageCodePair as L, type EditCaptionsOptions as M, type EditCaptionsResult as N, type EmbeddingsOptions as O, type EmbeddingsResult as P, type EngagementInsightsOptions as Q, type EngagementInsightsResult as R, type SupportedISO639_1 as S, GOOGLE_VISION_LIKELIHOOD_TO_SCORE as T, HIVE_SEXUAL_CATEGORIES as U, HIVE_VIOLENCE_CATEGORIES as V, type HiveModerationOutput as W, type HiveModerationSource as X, type ModerationOptions as Y, type ModerationProvider as Z, type ModerationResult as _, type ISO639_3 as a, type OverallInsight as a0, type ProfanityDetectionPayload as a1, type Question as a2, type QuestionAnswer as a3, type QuestionAnswerType as a4, type ReplacementRecord as a5, type SummarizationOptions as a6, type SummarizationPromptOverrides as a7, type SummarizationPromptSections as a8, type SummaryAndTagsResult as a9, normalizeTranslatedVtt as aA, profanityDetectionSchema as aB, questionAnswerSchema as aC, shouldSplitChunkTranslationError as aD, summarySchema as aE, transformCueText as aF, translateAudio as aG, translateCaptions as aH, translationSchema as aI, validateNeverTranslateTerms as aJ, verifyNeverTranslateTerms as aK, type SummaryType as aa, type ThumbnailModerationScore as ab, type TranslationChunkingOptions as ac, type TranslationOptions as ad, type TranslationPayload as ae, type TranslationResult as af, aggregateTokenUsage as ag, applyOverrideLists as ah, applyReplacements as ai, askQuestions as aj, buildReplacementRegex as ak, burnedInCaptionsSchema as al, censorVttContent as am, chapterSchema as an, chaptersSchema as ao, createReplacer as ap, editCaptions as aq, extractTranscriptSegmentsForHotspots as ar, generateChapters as as, generateEmbeddings as at, generateEngagementInsights as au, generateVideoEmbeddings as av, getModerationScores as aw, getSummaryAndTags as ax, hasBurnedInCaptions as ay, mapShotsToHotspots as az, type SupportedISO639_3 as b, getLanguageName as c, isValidISO639_1 as d, isValidISO639_3 as e, toISO639_3 as f, getLanguageCodePair as g, index as h, isUndeterminedLanguageCode as i, ASK_QUESTIONS_DEFAULT_MAX_FREE_FORM_ANSWER_LENGTH as j, ASK_QUESTIONS_MAX_QUESTION_LENGTH as k, type AskQuestionsOptions as l, type AskQuestionsResult as m, type AskQuestionsType as n, type AudioTranslationOptions as o, type AudioTranslationResult as p, type AutoCensorProfanityOptions as q, type BurnedInCaptionsOptions as r, type BurnedInCaptionsPromptOverrides as s, toISO639_1 as t, type BurnedInCaptionsPromptSections as u, type BurnedInCaptionsResult as v, type CensorMode as w, type Chapter as x, type ChapterSystemPromptSections as y, type ChaptersOptions as z };
1594
+ export { type MomentInsight as $, ASK_QUESTIONS_DEFAULT_MAX_ANSWER_OPTION_LENGTH as A, type BurnedInCaptionsAnalysis as B, type CaptionReplacement as C, type ChaptersPromptOverrides as D, type ChaptersPromptSections as E, type ChaptersResult as F, type ChaptersType as G, DEFAULT_DESCRIPTION_LENGTH as H, type ISO639_1 as I, DEFAULT_SUMMARY_KEYWORD_LIMIT as J, DEFAULT_TITLE_LENGTH as K, type LanguageCodePair as L, type EditCaptionsOptions as M, type EditCaptionsResult as N, type EmbeddingsOptions as O, type EmbeddingsResult as P, type EngagementInsightsOptions as Q, type EngagementInsightsResult as R, type SupportedISO639_1 as S, GOOGLE_VISION_LIKELIHOOD_TO_SCORE as T, HIVE_SEXUAL_CATEGORIES as U, HIVE_VIOLENCE_CATEGORIES as V, type HiveModerationOutput as W, type HiveModerationSource as X, type ModerationOptions as Y, type ModerationProvider as Z, type ModerationResult as _, type ISO639_3 as a, type OverallInsight as a0, type ProfanityDetectionPayload as a1, type Question as a2, type QuestionAnswer as a3, type QuestionAnswerType as a4, type ReplacementRecord as a5, type StaticRenditionCleanupOutcome as a6, type SummarizationOptions as a7, type SummarizationPromptOverrides as a8, type SummarizationPromptSections as a9, mapShotsToHotspots as aA, normalizeTranslatedVtt as aB, profanityDetectionSchema as aC, questionAnswerSchema as aD, shouldSplitChunkTranslationError as aE, summarySchema as aF, transformCueText as aG, translateAudio as aH, translateCaptions as aI, translationSchema as aJ, validateNeverTranslateTerms as aK, verifyNeverTranslateTerms as aL, type SummaryAndTagsResult as aa, type SummaryType as ab, type ThumbnailModerationScore as ac, type TranslationChunkingOptions as ad, type TranslationOptions as ae, type TranslationPayload as af, type TranslationResult as ag, aggregateTokenUsage as ah, applyOverrideLists as ai, applyReplacements as aj, askQuestions as ak, buildReplacementRegex as al, burnedInCaptionsSchema as am, censorVttContent as an, chapterSchema as ao, chaptersSchema as ap, createReplacer as aq, editCaptions as ar, extractTranscriptSegmentsForHotspots as as, generateChapters as at, generateEmbeddings as au, generateEngagementInsights as av, generateVideoEmbeddings as aw, getModerationScores as ax, getSummaryAndTags as ay, hasBurnedInCaptions as az, type SupportedISO639_3 as b, getLanguageName as c, isValidISO639_1 as d, isValidISO639_3 as e, toISO639_3 as f, getLanguageCodePair as g, index as h, isUndeterminedLanguageCode as i, ASK_QUESTIONS_DEFAULT_MAX_FREE_FORM_ANSWER_LENGTH as j, ASK_QUESTIONS_MAX_QUESTION_LENGTH as k, type AskQuestionsOptions as l, type AskQuestionsResult as m, type AskQuestionsType as n, type AudioTranslationOptions as o, type AudioTranslationResult as p, type AutoCensorProfanityOptions as q, type BurnedInCaptionsOptions as r, type BurnedInCaptionsPromptOverrides as s, toISO639_1 as t, type BurnedInCaptionsPromptSections as u, type BurnedInCaptionsResult as v, type CensorMode as w, type Chapter as x, type ChapterSystemPromptSections as y, type ChaptersOptions as z };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { I as ISO639_1, a as ISO639_3, L as LanguageCodePair, S as SupportedISO639_1, b as SupportedISO639_3, g as getLanguageCodePair, c as getLanguageName, i as isUndeterminedLanguageCode, d as isValidISO639_1, e as isValidISO639_3, t as toISO639_1, f as toISO639_3, h as workflows } from './index-Chccb380.js';
1
+ export { I as ISO639_1, a as ISO639_3, L as LanguageCodePair, S as SupportedISO639_1, b as SupportedISO639_3, g as getLanguageCodePair, c as getLanguageName, i as isUndeterminedLanguageCode, d as isValidISO639_1, e as isValidISO639_3, t as toISO639_1, f as toISO639_3, h as workflows } from './index-fU3hmKZu.js';
2
2
  import { W as WorkflowCredentials, S as StoragePutObjectInput, a as StoragePresignGetObjectInput } from './shots-BMbViFbZ.js';
3
3
  export { A as AssetTextTrack, C as ChunkEmbedding, b as ChunkingStrategy, E as Encrypted, c as EncryptedPayload, I as ImageSubmissionMode, M as MuxAIOptions, d as MuxAsset, P as PlaybackAsset, e as PlaybackPolicy, f as ScopedMuxAIOptions, g as StorageAdapter, T as TextChunk, h as TokenChunkingConfig, i as TokenUsage, j as ToneType, U as UsageMetadata, V as VTTChunkingConfig, k as VideoEmbeddingsResult, l as WorkflowCredentialsInput, m as WorkflowMuxClient, n as WorkflowScope, o as decryptFromWorkflow, p as encryptForWorkflow } from './shots-BMbViFbZ.js';
4
4
  import { WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from '@workflow/serde';
@@ -9,7 +9,7 @@ import '@ai-sdk/google';
9
9
  import '@ai-sdk/openai';
10
10
  import '@mux/mux-node';
11
11
 
12
- var version = "0.33.0";
12
+ var version = "0.35.0";
13
13
 
14
14
  type MuxAiErrorType = "validation_error" | "processing_error" | "timeout_error" | "content_policy_error";
15
15
  /**
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ var __export = (target, all) => {
5
5
  };
6
6
 
7
7
  // package.json
8
- var version = "0.33.0";
8
+ var version = "0.35.0";
9
9
 
10
10
  // src/lib/language-codes.ts
11
11
  var ISO639_1_TO_3 = {
@@ -3157,6 +3157,22 @@ var CONTENT_POLICY_REASONS = /* @__PURE__ */ new Set([
3157
3157
  "SAFETY",
3158
3158
  "SPII"
3159
3159
  ]);
3160
+ var IncompleteGenerationError = class extends MuxAiError {
3161
+ constructor(finishReason, rawFinishReason, usage) {
3162
+ const reason = rawFinishReason ?? finishReason;
3163
+ const message = finishReason === "length" ? `The model reached its output limit before producing a complete response (finish reason: ${reason}).` : `The model stopped before producing a complete response (finish reason: ${reason}).`;
3164
+ super(message, {
3165
+ type: "processing_error",
3166
+ retryable: finishReason !== "length"
3167
+ });
3168
+ this.finishReason = finishReason;
3169
+ this.rawFinishReason = rawFinishReason;
3170
+ this.usage = usage;
3171
+ }
3172
+ };
3173
+ function isIncompleteGenerationError(error) {
3174
+ return MuxAiError.is(error) && typeof error.finishReason === "string";
3175
+ }
3160
3176
  async function withContentPolicyErrorHandling(operation) {
3161
3177
  try {
3162
3178
  return await operation();
@@ -3183,6 +3199,14 @@ function getGeneratedOutputWithContentPolicyHandling(response) {
3183
3199
  const reason = rawReason.success && isContentPolicyReason(rawReason.data) ? rawReason.data : "CONTENT_FILTER";
3184
3200
  throwContentPolicyError({ reason }, getErrorTokenUsage(response));
3185
3201
  }
3202
+ if (response.finishReason !== "stop") {
3203
+ const rawReason = PolicyTokenSchema.safeParse(response.rawFinishReason);
3204
+ throw new IncompleteGenerationError(
3205
+ response.finishReason,
3206
+ rawReason.success ? rawReason.data : void 0,
3207
+ getErrorTokenUsage(response)
3208
+ );
3209
+ }
3186
3210
  return response.output;
3187
3211
  }
3188
3212
  function throwContentPolicyError(block, usage) {
@@ -7242,19 +7266,41 @@ async function requestStaticRenditionCreation(assetId, credentials) {
7242
7266
  const muxClient = await resolveMuxClient(credentials);
7243
7267
  const mux = await muxClient.createClient();
7244
7268
  try {
7245
- await mux.video.assets.createStaticRendition(assetId, {
7269
+ const rendition = await mux.video.assets.createStaticRendition(assetId, {
7246
7270
  resolution: "audio-only"
7247
7271
  });
7272
+ return rendition.id;
7248
7273
  } catch (error) {
7249
7274
  const statusCode = error?.status ?? error?.statusCode;
7250
7275
  const messages = error?.error?.messages;
7251
7276
  const alreadyDefined = messages?.some((message) => message.toLowerCase().includes("already defined")) ?? error?.message?.toLowerCase().includes("already defined");
7252
7277
  if (statusCode === 409 || alreadyDefined) {
7253
- return;
7278
+ return void 0;
7254
7279
  }
7255
7280
  wrapError(error, "Failed to request static rendition from Mux");
7256
7281
  }
7257
7282
  }
7283
+ async function deleteCreatedStaticRendition(assetId, staticRenditionId, credentials) {
7284
+ "use step";
7285
+ try {
7286
+ const muxClient = await resolveMuxClient(credentials);
7287
+ const mux = await muxClient.createClient();
7288
+ await mux.video.assets.deleteStaticRendition(assetId, staticRenditionId);
7289
+ console.warn(`\u{1F9F9} Deleted static rendition ${staticRenditionId} created on asset ${assetId}`);
7290
+ return "deleted";
7291
+ } catch (error) {
7292
+ const statusCode = error?.status ?? error?.statusCode;
7293
+ if (statusCode === 404) {
7294
+ console.warn(`\u{1F9F9} Static rendition ${staticRenditionId} on asset ${assetId} was already deleted`);
7295
+ return "deleted";
7296
+ }
7297
+ const message = error instanceof Error ? error.message : String(error);
7298
+ console.warn(
7299
+ `\u26A0\uFE0F Failed to delete static rendition ${staticRenditionId} on asset ${assetId} (status: ${statusCode ?? "unknown"}): ${message}`
7300
+ );
7301
+ return "delete_failed";
7302
+ }
7303
+ }
7258
7304
  async function retrieveAsset(assetId, credentials) {
7259
7305
  "use step";
7260
7306
  const muxClient = await resolveMuxClient(credentials);
@@ -7270,14 +7316,6 @@ async function waitForAudioStaticRendition({
7270
7316
  if (hasReadyAudioStaticRendition(currentAsset)) {
7271
7317
  return currentAsset;
7272
7318
  }
7273
- const status = currentAsset.static_renditions?.status ?? "not_requested";
7274
- if (status === "not_requested" || status === void 0) {
7275
- await requestStaticRenditionCreation(assetId, credentials);
7276
- } else if (status === "errored") {
7277
- await requestStaticRenditionCreation(assetId, credentials);
7278
- } else {
7279
- console.warn(`\u2139\uFE0F Static rendition already ${status}. Waiting for it to finish...`);
7280
- }
7281
7319
  for (let attempt = 1; attempt <= STATIC_RENDITION_MAX_ATTEMPTS; attempt++) {
7282
7320
  await sleep2(STATIC_RENDITION_POLL_INTERVAL_MS);
7283
7321
  currentAsset = await retrieveAsset(assetId, credentials);
@@ -7484,6 +7522,7 @@ async function translateAudio(assetId, toLanguageCode, options = {}) {
7484
7522
  uploadToS3: uploadToS3Option,
7485
7523
  uploadToMux: uploadToMuxOption,
7486
7524
  uploadCaptionsToMux = false,
7525
+ staticRenditionCleanup: staticRenditionCleanupOption = "delete",
7487
7526
  storageAdapter,
7488
7527
  credentials: providedCredentials
7489
7528
  } = options;
@@ -7505,144 +7544,167 @@ async function translateAudio(assetId, toLanguageCode, options = {}) {
7505
7544
  const { asset: initialAsset, playbackId, policy } = await getPlaybackIdForAsset(assetId, credentials);
7506
7545
  const assetDurationSeconds = getAssetDurationSecondsFromAsset(initialAsset);
7507
7546
  let currentAsset = initialAsset;
7547
+ let createdStaticRenditionId;
7508
7548
  if (!hasReadyAudioStaticRendition(currentAsset)) {
7509
7549
  console.warn("\u274C No ready audio static rendition found. Requesting one now...");
7510
- currentAsset = await waitForAudioStaticRendition({
7511
- assetId,
7512
- initialAsset: currentAsset,
7513
- credentials
7514
- });
7515
- }
7516
- const audioRendition = getReadyAudioStaticRendition(currentAsset);
7517
- if (!audioRendition) {
7518
- throw new MuxAiError(
7519
- "Unable to obtain an audio-only static rendition for this asset. Please verify static renditions are enabled in Mux.",
7520
- { type: "validation_error" }
7521
- );
7522
- }
7523
- let audioUrl = `${getMuxStreamOrigin()}/${playbackId}/audio.m4a`;
7524
- if (policy === "signed") {
7525
- audioUrl = await signUrl(audioUrl, playbackId, "video", void 0, credentials);
7550
+ const renditionStatus = currentAsset.static_renditions?.status ?? "not_requested";
7551
+ if (renditionStatus === "not_requested" || renditionStatus === "errored") {
7552
+ createdStaticRenditionId = await requestStaticRenditionCreation(assetId, credentials);
7553
+ } else {
7554
+ console.warn(`\u2139\uFE0F Static rendition already ${renditionStatus}. Waiting for it to finish...`);
7555
+ }
7526
7556
  }
7527
- console.warn("\u{1F399}\uFE0F Creating dubbing job in ElevenLabs...");
7528
- const elevenLabsLangCode = toISO639_3(toLanguageCode);
7529
- const normalizedFromLanguageCode = fromLanguageCode?.trim();
7530
- const elevenLabsSourceLangCode = normalizedFromLanguageCode ? toISO639_3(normalizedFromLanguageCode) : void 0;
7531
- console.warn(
7532
- `\u{1F50D} Creating dubbing job for asset ${assetId}: ${elevenLabsSourceLangCode ?? "auto"} -> ${elevenLabsLangCode}`
7533
- );
7557
+ let staticRenditionCleanup = "not_created";
7534
7558
  let dubbingId;
7559
+ let presignedUrl;
7560
+ let uploadedTrackId;
7561
+ let captionsPresignedUrl;
7562
+ let captionsTrackId;
7535
7563
  try {
7536
- dubbingId = await createElevenLabsDubbingJob({
7537
- sourceUrl: audioUrl,
7538
- assetId,
7539
- elevenLabsLangCode,
7540
- elevenLabsSourceLangCode,
7541
- numSpeakers,
7542
- credentials
7543
- });
7544
- console.warn(`\u2705 Dubbing job created with ID: ${dubbingId}`);
7545
- } catch (error) {
7546
- wrapError(error, "Failed to create ElevenLabs dubbing job");
7547
- }
7548
- console.warn("\u23F3 Waiting for dubbing to complete...");
7549
- const dubbingPollTimeoutSeconds = options.dubbingPollTimeoutSeconds ?? DEFAULT_DUBBING_POLL_TIMEOUT_SECONDS;
7550
- const maxPollAttempts = Math.max(1, Math.ceil(dubbingPollTimeoutSeconds * 1e3 / DUBBING_POLL_INTERVAL_MS));
7551
- let dubbingStatus = "dubbing";
7552
- let pollAttempts = 0;
7553
- let targetLanguages = [];
7554
- while (dubbingStatus !== "dubbed" && pollAttempts < maxPollAttempts) {
7555
- await sleep2(DUBBING_POLL_INTERVAL_MS);
7556
- pollAttempts++;
7557
- try {
7558
- const statusResult = await checkElevenLabsDubbingStatus({
7559
- dubbingId,
7564
+ if (!hasReadyAudioStaticRendition(currentAsset)) {
7565
+ currentAsset = await waitForAudioStaticRendition({
7566
+ assetId,
7567
+ initialAsset: currentAsset,
7560
7568
  credentials
7561
7569
  });
7562
- dubbingStatus = statusResult.status;
7563
- targetLanguages = statusResult.targetLanguages;
7564
- } catch (error) {
7565
- wrapError(error, "Failed to check dubbing status");
7566
7570
  }
7567
- if (dubbingStatus === "failed") {
7568
- throw new MuxAiError("ElevenLabs reported that the dubbing job failed.", { type: "processing_error" });
7571
+ const audioRendition = getReadyAudioStaticRendition(currentAsset);
7572
+ if (!audioRendition) {
7573
+ throw new MuxAiError(
7574
+ "Unable to obtain an audio-only static rendition for this asset. Please verify static renditions are enabled in Mux.",
7575
+ { type: "validation_error" }
7576
+ );
7569
7577
  }
7570
- }
7571
- if (dubbingStatus !== "dubbed") {
7572
- throw new MuxAiError("Audio translation timed out or failed. Please try again.", { type: "timeout_error", retryable: true });
7573
- }
7574
- console.warn("\u2705 Dubbing completed successfully!");
7575
- let presignedUrl;
7576
- let uploadedTrackId;
7577
- let captionsPresignedUrl;
7578
- let captionsTrackId;
7579
- if (uploadToS3) {
7580
- console.warn("\u{1F4E5} Downloading dubbed audio from ElevenLabs and staging to S3...");
7581
- const downloadLangCode = targetLanguages[0] ?? toISO639_1(toLanguageCode);
7578
+ let audioUrl = `${getMuxStreamOrigin()}/${playbackId}/audio.m4a`;
7579
+ if (policy === "signed") {
7580
+ audioUrl = await signUrl(audioUrl, playbackId, "video", void 0, credentials);
7581
+ }
7582
+ console.warn("\u{1F399}\uFE0F Creating dubbing job in ElevenLabs...");
7583
+ const elevenLabsLangCode = toISO639_3(toLanguageCode);
7584
+ const normalizedFromLanguageCode = fromLanguageCode?.trim();
7585
+ const elevenLabsSourceLangCode = normalizedFromLanguageCode ? toISO639_3(normalizedFromLanguageCode) : void 0;
7586
+ console.warn(
7587
+ `\u{1F50D} Creating dubbing job for asset ${assetId}: ${elevenLabsSourceLangCode ?? "auto"} -> ${elevenLabsLangCode}`
7588
+ );
7582
7589
  try {
7583
- presignedUrl = await downloadAndUploadDubbedAudio({
7584
- dubbingId,
7585
- languageCode: downloadLangCode,
7590
+ dubbingId = await createElevenLabsDubbingJob({
7591
+ sourceUrl: audioUrl,
7586
7592
  assetId,
7587
- toLanguageCode,
7588
- s3Endpoint,
7589
- s3Region,
7590
- s3Bucket,
7591
- storageAdapter: effectiveStorageAdapter,
7592
- s3SignedUrlExpirySeconds: options.s3SignedUrlExpirySeconds,
7593
+ elevenLabsLangCode,
7594
+ elevenLabsSourceLangCode,
7595
+ numSpeakers,
7593
7596
  credentials
7594
7597
  });
7595
- console.warn("\u2705 Dubbed audio staged to S3 successfully!");
7598
+ console.warn(`\u2705 Dubbing job created with ID: ${dubbingId}`);
7596
7599
  } catch (error) {
7597
- wrapError(error, "Failed to download and upload dubbed audio");
7598
- }
7599
- if (uploadToMux) {
7600
- console.warn("\u{1F4F9} Adding dubbed audio track to Mux asset...");
7601
- const muxLangCode = toISO639_1(toLanguageCode);
7600
+ wrapError(error, "Failed to create ElevenLabs dubbing job");
7601
+ }
7602
+ console.warn("\u23F3 Waiting for dubbing to complete...");
7603
+ const dubbingPollTimeoutSeconds = options.dubbingPollTimeoutSeconds ?? DEFAULT_DUBBING_POLL_TIMEOUT_SECONDS;
7604
+ const maxPollAttempts = Math.max(1, Math.ceil(dubbingPollTimeoutSeconds * 1e3 / DUBBING_POLL_INTERVAL_MS));
7605
+ let dubbingStatus = "dubbing";
7606
+ let pollAttempts = 0;
7607
+ let targetLanguages = [];
7608
+ while (dubbingStatus !== "dubbed" && pollAttempts < maxPollAttempts) {
7609
+ await sleep2(DUBBING_POLL_INTERVAL_MS);
7610
+ pollAttempts++;
7602
7611
  try {
7603
- uploadedTrackId = await createAudioTrackOnMux(assetId, muxLangCode, presignedUrl, credentials);
7604
- const languageName = new Intl.DisplayNames(["en"], { type: "language" }).of(muxLangCode) || muxLangCode.toUpperCase();
7605
- const trackName = `${languageName} (auto-dubbed)`;
7606
- console.warn(`\u2705 Track added to Mux asset with ID: ${uploadedTrackId}`);
7607
- console.warn(`\u{1F4CB} Track name: "${trackName}"`);
7612
+ const statusResult = await checkElevenLabsDubbingStatus({
7613
+ dubbingId,
7614
+ credentials
7615
+ });
7616
+ dubbingStatus = statusResult.status;
7617
+ targetLanguages = statusResult.targetLanguages;
7608
7618
  } catch (error) {
7609
- console.warn(`\u26A0\uFE0F Failed to add audio track to Mux asset: ${error instanceof Error ? error.message : "Unknown error"}`);
7610
- console.warn("\u{1F517} You can manually add the track using this presigned URL:");
7611
- console.warn(presignedUrl);
7619
+ wrapError(error, "Failed to check dubbing status");
7620
+ }
7621
+ if (dubbingStatus === "failed") {
7622
+ throw new MuxAiError("ElevenLabs reported that the dubbing job failed.", { type: "processing_error" });
7612
7623
  }
7613
7624
  }
7614
- try {
7615
- console.warn("\u{1F4E5} Downloading dub transcript from ElevenLabs and staging to S3...");
7616
- captionsPresignedUrl = await downloadAndUploadDubTranscript({
7617
- dubbingId,
7618
- languageCode: downloadLangCode,
7619
- assetId,
7620
- toLanguageCode,
7621
- s3Endpoint,
7622
- s3Region,
7623
- s3Bucket,
7624
- storageAdapter: effectiveStorageAdapter,
7625
- s3SignedUrlExpirySeconds: options.s3SignedUrlExpirySeconds,
7626
- credentials
7627
- });
7628
- if (uploadCaptionsToMux) {
7629
- console.warn("\u{1F4F9} Adding dubbed captions track to Mux asset...");
7625
+ if (dubbingStatus !== "dubbed") {
7626
+ throw new MuxAiError("Audio translation timed out or failed. Please try again.", { type: "timeout_error", retryable: true });
7627
+ }
7628
+ console.warn("\u2705 Dubbing completed successfully!");
7629
+ if (uploadToS3) {
7630
+ console.warn("\u{1F4E5} Downloading dubbed audio from ElevenLabs and staging to S3...");
7631
+ const downloadLangCode = targetLanguages[0] ?? toISO639_1(toLanguageCode);
7632
+ try {
7633
+ presignedUrl = await downloadAndUploadDubbedAudio({
7634
+ dubbingId,
7635
+ languageCode: downloadLangCode,
7636
+ assetId,
7637
+ toLanguageCode,
7638
+ s3Endpoint,
7639
+ s3Region,
7640
+ s3Bucket,
7641
+ storageAdapter: effectiveStorageAdapter,
7642
+ s3SignedUrlExpirySeconds: options.s3SignedUrlExpirySeconds,
7643
+ credentials
7644
+ });
7645
+ console.warn("\u2705 Dubbed audio staged to S3 successfully!");
7646
+ } catch (error) {
7647
+ wrapError(error, "Failed to download and upload dubbed audio");
7648
+ }
7649
+ if (uploadToMux) {
7650
+ console.warn("\u{1F4F9} Adding dubbed audio track to Mux asset...");
7630
7651
  const muxLangCode = toISO639_1(toLanguageCode);
7631
- const languageName = new Intl.DisplayNames(["en"], { type: "language" }).of(muxLangCode) || muxLangCode.toUpperCase();
7632
- captionsTrackId = await createTextTrackOnMux(
7652
+ try {
7653
+ uploadedTrackId = await createAudioTrackOnMux(assetId, muxLangCode, presignedUrl, credentials);
7654
+ const languageName = new Intl.DisplayNames(["en"], { type: "language" }).of(muxLangCode) || muxLangCode.toUpperCase();
7655
+ const trackName = `${languageName} (auto-dubbed)`;
7656
+ console.warn(`\u2705 Track added to Mux asset with ID: ${uploadedTrackId}`);
7657
+ console.warn(`\u{1F4CB} Track name: "${trackName}"`);
7658
+ } catch (error) {
7659
+ console.warn(`\u26A0\uFE0F Failed to add audio track to Mux asset: ${error instanceof Error ? error.message : "Unknown error"}`);
7660
+ console.warn("\u{1F517} You can manually add the track using this presigned URL:");
7661
+ console.warn(presignedUrl);
7662
+ }
7663
+ }
7664
+ try {
7665
+ console.warn("\u{1F4E5} Downloading dub transcript from ElevenLabs and staging to S3...");
7666
+ captionsPresignedUrl = await downloadAndUploadDubTranscript({
7667
+ dubbingId,
7668
+ languageCode: downloadLangCode,
7633
7669
  assetId,
7634
- muxLangCode,
7635
- `${languageName} (auto-dubbed)`,
7636
- captionsPresignedUrl,
7670
+ toLanguageCode,
7671
+ s3Endpoint,
7672
+ s3Region,
7673
+ s3Bucket,
7674
+ storageAdapter: effectiveStorageAdapter,
7675
+ s3SignedUrlExpirySeconds: options.s3SignedUrlExpirySeconds,
7637
7676
  credentials
7638
- );
7639
- console.warn(`\u2705 Captions track added to Mux asset with ID: ${captionsTrackId}`);
7677
+ });
7678
+ if (uploadCaptionsToMux) {
7679
+ console.warn("\u{1F4F9} Adding dubbed captions track to Mux asset...");
7680
+ const muxLangCode = toISO639_1(toLanguageCode);
7681
+ const languageName = new Intl.DisplayNames(["en"], { type: "language" }).of(muxLangCode) || muxLangCode.toUpperCase();
7682
+ captionsTrackId = await createTextTrackOnMux(
7683
+ assetId,
7684
+ muxLangCode,
7685
+ `${languageName} (auto-dubbed)`,
7686
+ captionsPresignedUrl,
7687
+ credentials
7688
+ );
7689
+ console.warn(`\u2705 Captions track added to Mux asset with ID: ${captionsTrackId}`);
7690
+ }
7691
+ } catch (error) {
7692
+ console.warn(`\u26A0\uFE0F Failed to attach dubbed captions: ${error instanceof Error ? error.message : "Unknown error"}`);
7693
+ if (captionsPresignedUrl) {
7694
+ console.warn("\u{1F517} You can manually add the captions track using this presigned URL:");
7695
+ console.warn(captionsPresignedUrl);
7696
+ }
7640
7697
  }
7641
- } catch (error) {
7642
- console.warn(`\u26A0\uFE0F Failed to attach dubbed captions: ${error instanceof Error ? error.message : "Unknown error"}`);
7643
- if (captionsPresignedUrl) {
7644
- console.warn("\u{1F517} You can manually add the captions track using this presigned URL:");
7645
- console.warn(captionsPresignedUrl);
7698
+ }
7699
+ } finally {
7700
+ if (createdStaticRenditionId) {
7701
+ if (staticRenditionCleanupOption === "keep") {
7702
+ console.warn(
7703
+ `\u2139\uFE0F Keeping static rendition ${createdStaticRenditionId} on asset ${assetId} (staticRenditionCleanup: "keep")`
7704
+ );
7705
+ staticRenditionCleanup = "kept";
7706
+ } else {
7707
+ staticRenditionCleanup = await deleteCreatedStaticRendition(assetId, createdStaticRenditionId, credentials);
7646
7708
  }
7647
7709
  }
7648
7710
  }
@@ -7656,6 +7718,8 @@ async function translateAudio(assetId, toLanguageCode, options = {}) {
7656
7718
  presignedUrl,
7657
7719
  captionsTrackId,
7658
7720
  captionsPresignedUrl,
7721
+ createdStaticRenditionId,
7722
+ staticRenditionCleanup,
7659
7723
  usage: {
7660
7724
  metadata: {
7661
7725
  assetDurationSeconds
@@ -7669,6 +7733,7 @@ import {
7669
7733
  APICallError as APICallError3,
7670
7734
  generateText as generateText7,
7671
7735
  NoObjectGeneratedError as NoObjectGeneratedError2,
7736
+ NoOutputGeneratedError as NoOutputGeneratedError2,
7672
7737
  Output as Output7,
7673
7738
  RetryError as RetryError2,
7674
7739
  TypeValidationError
@@ -7832,7 +7897,7 @@ function shouldSplitChunkTranslationError(error) {
7832
7897
  if (isProviderServiceError(error)) {
7833
7898
  return false;
7834
7899
  }
7835
- return NoObjectGeneratedError2.isInstance(error) || TypeValidationError.isInstance(error) || isTranslationChunkValidationError(error);
7900
+ return NoObjectGeneratedError2.isInstance(error) || NoOutputGeneratedError2.isInstance(error) || TypeValidationError.isInstance(error) || isIncompleteGenerationError(error) || isTranslationChunkValidationError(error);
7836
7901
  }
7837
7902
  function resolveTranslationChunkingOptions(options) {
7838
7903
  const targetChunkDurationSeconds = Math.max(
@@ -7929,9 +7994,13 @@ function buildTranslationChunkRequests(vttContent, assetDurationSeconds, chunkin
7929
7994
  if (typeof assetDurationSeconds !== "number" || assetDurationSeconds < resolvedChunking.minimumAssetDurationSeconds) {
7930
7995
  return {
7931
7996
  preamble,
7932
- chunks: [
7933
- createTranslationChunkRequest("chunk-0", cues, cueBlocks)
7934
- ]
7997
+ chunks: splitTranslationChunkRequestByBudget(
7998
+ "chunk-0",
7999
+ cues,
8000
+ cueBlocks,
8001
+ resolvedChunking.maxCuesPerChunk,
8002
+ resolvedChunking.maxCueTextTokensPerChunk
8003
+ )
7935
8004
  };
7936
8005
  }
7937
8006
  const targetChunkDurationSeconds = resolvedChunking.targetChunkDurationSeconds;
@@ -8192,7 +8261,11 @@ async function translateChunkWithFallback({
8192
8261
  );
8193
8262
  return {
8194
8263
  translatedVtt: concatenateVttSegments([leftResult.translatedVtt, rightResult.translatedVtt]),
8195
- usage: aggregateTokenUsage([leftResult.usage, rightResult.usage]),
8264
+ usage: aggregateTokenUsage([
8265
+ ...failedAttemptUsage ? [failedAttemptUsage] : [],
8266
+ leftResult.usage,
8267
+ rightResult.usage
8268
+ ]),
8196
8269
  scrubbedCueCounts: mergeScrubbedCueCounts(
8197
8270
  leftResult.scrubbedCueCounts,
8198
8271
  rightResult.scrubbedCueCounts