@mux/ai 0.36.0 → 0.37.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.
@@ -1,4 +1,4 @@
1
- export { A as ASK_QUESTIONS_DEFAULT_MAX_ANSWER_OPTION_LENGTH, j as ASK_QUESTIONS_DEFAULT_MAX_FREE_FORM_ANSWER_LENGTH, k as ASK_QUESTIONS_MAX_QUESTION_LENGTH, l as AskQuestionsOptions, m as AskQuestionsResult, n as AskQuestionsType, o as AudioTranslationOptions, p as AudioTranslationResult, q as AutoCensorProfanityOptions, B as BurnedInCaptionsAnalysis, r as BurnedInCaptionsOptions, s as BurnedInCaptionsPromptOverrides, u as BurnedInCaptionsPromptSections, v as BurnedInCaptionsResult, C as CaptionReplacement, w as CensorMode, x as Chapter, y as ChapterSystemPromptSections, z as ChaptersOptions, D as ChaptersPromptOverrides, E as ChaptersPromptSections, F as ChaptersResult, G as ChaptersType, H as DEFAULT_DESCRIPTION_LENGTH, J as DEFAULT_SUMMARY_KEYWORD_LIMIT, K as DEFAULT_TITLE_LENGTH, M as EditCaptionsOptions, N as EditCaptionsResult, O as EmbeddingsOptions, P as EmbeddingsResult, Q as EngagementInsightsOptions, R as EngagementInsightsResult, T as GOOGLE_VISION_LIKELIHOOD_TO_SCORE, U as HIVE_SEXUAL_CATEGORIES, V as HIVE_VIOLENCE_CATEGORIES, W as HiveModerationOutput, X as HiveModerationSource, Y as ModerationOptions, Z as ModerationProvider, _ as ModerationResult, $ as MomentInsight, a0 as OverallInsight, a1 as ProfanityDetectionPayload, a2 as Question, a3 as QuestionAnswer, a4 as QuestionAnswerType, a5 as ReplacementRecord, a6 as StaticRenditionCleanupOutcome, a7 as SummarizationOptions, a8 as SummarizationPromptOverrides, a9 as SummarizationPromptSections, aa as SummaryAndTagsResult, ab as SummaryType, ac as ThumbnailModerationScore, ad as TranslationChunkingOptions, ae as TranslationOptions, af as TranslationPayload, ag as TranslationResult, ah as aggregateTokenUsage, ai as applyOverrideLists, aj as applyReplacements, ak as askQuestions, al as buildReplacementRegex, am as burnedInCaptionsSchema, an as censorVttContent, ao as chapterSchema, ap as chaptersSchema, aq as createReplacer, ar as editCaptions, as as extractTranscriptSegmentsForHotspots, at as generateChapters, au as generateEmbeddings, av as generateEngagementInsights, aw as generateVideoEmbeddings, ax as getModerationScores, ay as getSummaryAndTags, az as hasBurnedInCaptions, aA as mapShotsToHotspots, aB as normalizeTranslatedVtt, aC as profanityDetectionSchema, aD as questionAnswerSchema, aE as shouldSplitChunkTranslationError, aF as summarySchema, aG as transformCueText, aH as translateAudio, aI as translateCaptions, aJ as translationSchema, aK as validateNeverTranslateTerms, aL as verifyNeverTranslateTerms } from '../index-C2FORyvQ.js';
1
+ export { A as ASK_QUESTIONS_DEFAULT_MAX_ANSWER_OPTION_LENGTH, j as ASK_QUESTIONS_DEFAULT_MAX_FREE_FORM_ANSWER_LENGTH, k as ASK_QUESTIONS_MAX_QUESTION_LENGTH, l as AskQuestionsOptions, m as AskQuestionsResult, n as AskQuestionsType, o as AudioTranslationOptions, p as AudioTranslationResult, q as AutoCensorProfanityOptions, B as BurnedInCaptionsAnalysis, r as BurnedInCaptionsOptions, s as BurnedInCaptionsPromptOverrides, u as BurnedInCaptionsPromptSections, v as BurnedInCaptionsResult, C as CaptionReplacement, w as CensorMode, x as Chapter, y as ChapterSystemPromptSections, z as ChaptersOptions, D as ChaptersPromptOverrides, E as ChaptersPromptSections, F as ChaptersResult, G as ChaptersType, H as DEFAULT_DESCRIPTION_LENGTH, J as DEFAULT_SUMMARY_KEYWORD_LIMIT, K as DEFAULT_TITLE_LENGTH, M as EditCaptionsOptions, N as EditCaptionsResult, O as EmbeddingsOptions, P as EmbeddingsResult, Q as EngagementInsightsOptions, R as EngagementInsightsResult, T as GOOGLE_VISION_LIKELIHOOD_TO_SCORE, U as HIVE_SEXUAL_CATEGORIES, V as HIVE_VIOLENCE_CATEGORIES, W as HiveModerationOutput, X as HiveModerationSource, Y as ModerationOptions, Z as ModerationProvider, _ as ModerationResult, $ as MomentInsight, a0 as OverallInsight, a1 as ProfanityDetectionPayload, a2 as Question, a3 as QuestionAnswer, a4 as QuestionAnswerType, a5 as ReplacementRecord, a6 as SpeakerReplacement, a7 as StaticRenditionCleanupOutcome, a8 as SummarizationOptions, a9 as SummarizationPromptOverrides, aa as SummarizationPromptSections, ab as SummaryAndTagsResult, ac as SummaryType, ad as ThumbnailModerationScore, ae as TranslationChunkingOptions, af as TranslationOptions, ag as TranslationPayload, ah as TranslationResult, ai as aggregateTokenUsage, aj as applyOverrideLists, ak as applyReplacements, al as applySpeakerReplacements, am as askQuestions, an as buildReplacementRegex, ao as burnedInCaptionsSchema, ap as censorVttContent, aq as chapterSchema, ar as chaptersSchema, as as createReplacer, at as editCaptions, au as extractTranscriptSegmentsForHotspots, av as generateChapters, aw as generateEmbeddings, ax as generateEngagementInsights, ay as generateVideoEmbeddings, az as getModerationScores, aA as getSummaryAndTags, aB as hasBurnedInCaptions, aC as mapShotsToHotspots, aD as normalizeTranslatedVtt, aE as profanityDetectionSchema, aF as questionAnswerSchema, aG as shouldSplitChunkTranslationError, aH as summarySchema, aI as transformCueText, aJ as translateAudio, aK as translateCaptions, aL as translationSchema, aM as validateNeverTranslateTerms, aN as verifyNeverTranslateTerms } from '../index-BupL84pY.js';
2
2
  import 'zod';
3
3
  import '@ai-sdk/anthropic';
4
4
  import '@ai-sdk/google';
@@ -4207,6 +4207,27 @@ function applyReplacements(rawVtt, replacements) {
4207
4207
  });
4208
4208
  return { editedVtt, replacements: records };
4209
4209
  }
4210
+ function applySpeakerReplacements(rawVtt, speakerReplacements) {
4211
+ const replacementsByLabel = new Map(
4212
+ speakerReplacements.filter((replacement) => replacement.find.length > 0).map((replacement) => [replacement.find, replacement.replace])
4213
+ );
4214
+ if (replacementsByLabel.size === 0) {
4215
+ return { editedVtt: rawVtt, replacements: [] };
4216
+ }
4217
+ const records = [];
4218
+ const editedVtt = transformCueTextBlocks(rawVtt, (cueText, cueStartTime) => {
4219
+ return cueText.replace(/^(\s*)\[([^\]\r\n]+)\](?=\s|$)/, (marker, leadingWhitespace, label) => {
4220
+ const replacement = replacementsByLabel.get(label);
4221
+ if (replacement === void 0)
4222
+ return marker;
4223
+ const before = `[${label}]`;
4224
+ const after = `[${replacement}]`;
4225
+ records.push({ cueStartTime, before, after });
4226
+ return `${leadingWhitespace}${after}`;
4227
+ });
4228
+ });
4229
+ return { editedVtt, replacements: records };
4230
+ }
4210
4231
  async function identifyProfanityWithAI({
4211
4232
  plainText,
4212
4233
  provider,
@@ -4309,6 +4330,7 @@ async function editCaptionsInternal(assetId, trackId, options, collectedUsage) {
4309
4330
  model,
4310
4331
  autoCensorProfanity: autoCensorOption,
4311
4332
  replacements: replacementsOption,
4333
+ speakerReplacements: speakerReplacementsOption,
4312
4334
  deleteOriginalTrack,
4313
4335
  uploadToS3: uploadToS3Option,
4314
4336
  uploadToMux: uploadToMuxOption,
@@ -4321,8 +4343,9 @@ async function editCaptionsInternal(assetId, trackId, options, collectedUsage) {
4321
4343
  } = options;
4322
4344
  const hasAutoCensor = !!autoCensorOption;
4323
4345
  const hasReplacements = !!replacementsOption && replacementsOption.length > 0;
4324
- if (!hasAutoCensor && !hasReplacements) {
4325
- throw new MuxAiError("At least one of autoCensorProfanity or replacements must be provided.", { type: "validation_error" });
4346
+ const hasSpeakerReplacements = !!speakerReplacementsOption && speakerReplacementsOption.length > 0;
4347
+ if (!hasAutoCensor && !hasReplacements && !hasSpeakerReplacements) {
4348
+ throw new MuxAiError("At least one of autoCensorProfanity, replacements, or speakerReplacements must be provided.", { type: "validation_error" });
4326
4349
  }
4327
4350
  if (autoCensorOption && !provider) {
4328
4351
  throw new MuxAiError("provider is required when using autoCensorProfanity.", { type: "validation_error" });
@@ -4330,6 +4353,16 @@ async function editCaptionsInternal(assetId, trackId, options, collectedUsage) {
4330
4353
  const deleteOriginal = deleteOriginalTrack !== false;
4331
4354
  const uploadToMux = uploadToMuxOption !== false;
4332
4355
  const uploadToS3 = uploadToS3Option || uploadToMux;
4356
+ for (const replacement of speakerReplacementsOption ?? []) {
4357
+ const hasInvalidFindCharacter = replacement.find.includes("[") || replacement.find.includes("]") || /[\r\n]/.test(replacement.find);
4358
+ const hasInvalidReplaceCharacter = replacement.replace.includes("[") || replacement.replace.includes("]") || /[\r\n]/.test(replacement.replace);
4359
+ if (!replacement.find || !replacement.replace || hasInvalidFindCharacter || hasInvalidReplaceCharacter) {
4360
+ throw new MuxAiError(
4361
+ "Speaker replacement labels must be non-empty and must not contain square brackets or newlines.",
4362
+ { type: "validation_error" }
4363
+ );
4364
+ }
4365
+ }
4333
4366
  const s3Endpoint = providedS3Endpoint ?? env_default.S3_ENDPOINT;
4334
4367
  const s3Region = providedS3Region ?? env_default.S3_REGION ?? "auto";
4335
4368
  const s3Bucket = providedS3Bucket ?? env_default.S3_BUCKET;
@@ -4411,6 +4444,16 @@ async function editCaptionsInternal(assetId, trackId, options, collectedUsage) {
4411
4444
  totalReplacementCount += censorReplacements.length;
4412
4445
  autoCensorResult = { replacements: censorReplacements };
4413
4446
  }
4447
+ let speakerReplacementsResult;
4448
+ if (speakerReplacementsOption && speakerReplacementsOption.length > 0) {
4449
+ const { editedVtt: afterSpeakerReplacements, replacements: speakerReplacements } = applySpeakerReplacements(
4450
+ editedVtt,
4451
+ speakerReplacementsOption
4452
+ );
4453
+ editedVtt = afterSpeakerReplacements;
4454
+ totalReplacementCount += speakerReplacements.length;
4455
+ speakerReplacementsResult = { replacements: speakerReplacements };
4456
+ }
4414
4457
  let replacementsResult;
4415
4458
  if (replacementsOption && replacementsOption.length > 0) {
4416
4459
  const { editedVtt: afterReplacements, replacements: staticReplacements } = applyReplacements(editedVtt, replacementsOption);
@@ -4473,6 +4516,7 @@ async function editCaptionsInternal(assetId, trackId, options, collectedUsage) {
4473
4516
  totalReplacementCount,
4474
4517
  autoCensorProfanity: autoCensorResult,
4475
4518
  replacements: replacementsResult,
4519
+ speakerReplacements: speakerReplacementsResult,
4476
4520
  uploadedTrackId,
4477
4521
  presignedUrl,
4478
4522
  usage: usageWithMetadata,
@@ -8239,6 +8283,7 @@ export {
8239
8283
  aggregateTokenUsage,
8240
8284
  applyOverrideLists,
8241
8285
  applyReplacements,
8286
+ applySpeakerReplacements,
8242
8287
  askQuestions,
8243
8288
  buildReplacementRegex,
8244
8289
  burnedInCaptionsSchema,