@mux/ai 0.36.0 → 0.38.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.
- package/README.md +3 -0
- package/dist/{index-C2FORyvQ.d.ts → index-BupL84pY.d.ts} +23 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +73 -12
- package/dist/index.js.map +1 -1
- package/dist/workflows/index.d.ts +1 -1
- package/dist/workflows/index.js +72 -11
- package/dist/workflows/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -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
|
|
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';
|
package/dist/workflows/index.js
CHANGED
|
@@ -2578,7 +2578,7 @@ var SYSTEM_PROMPT = promptDedent`
|
|
|
2578
2578
|
- For questions with <answer_format>: follow the format specification exactly (e.g. free-form text within the stated character budget)
|
|
2579
2579
|
- Always read each question's <allowed_answers> or <answer_format> and respond in the required shape based on the evidence
|
|
2580
2580
|
- Select the answer best supported by observable evidence from the content
|
|
2581
|
-
- When evidence is ambiguous but some signal exists, select the most conservative option and use a low confidence score.
|
|
2581
|
+
- When evidence is ambiguous but some signal exists, select the most conservative option and use a low confidence score. Only skip a question if it meets the skip criteria in relevance_filtering — never skip merely because the queried subject is absent from the content; absence is itself an answerable observation
|
|
2582
2582
|
- Confidence should reflect the clarity and strength of evidence:
|
|
2583
2583
|
${CONFIDENCE_SCORING_RUBRIC}
|
|
2584
2584
|
- Reasoning should cite specific visual or audio evidence
|
|
@@ -2592,11 +2592,18 @@ var SYSTEM_PROMPT = promptDedent`
|
|
|
2592
2592
|
|
|
2593
2593
|
A question is relevant if it asks about something observable or inferable
|
|
2594
2594
|
from the video content (visuals, audio, dialogue, setting, subjects,
|
|
2595
|
-
actions, etc.).
|
|
2595
|
+
actions, etc.) — including whether something is ABSENT. Not finding the
|
|
2596
|
+
queried subject in the frames or transcript is itself an answerable
|
|
2597
|
+
observation, not a reason to skip.
|
|
2596
2598
|
|
|
2597
|
-
|
|
2599
|
+
For example: if a question asks "Does this video contain cat content?"
|
|
2600
|
+
and no cats appear anywhere in the frames or transcript, the correct
|
|
2601
|
+
response is "no" — this is a relevant, answerable question. It must
|
|
2602
|
+
NOT be skipped just because the subject doesn't appear.
|
|
2603
|
+
|
|
2604
|
+
Mark a question as skipped (skipped: true) ONLY if it:
|
|
2598
2605
|
- Is completely unrelated to the content of the video or audio (e.g., math, trivia, personal questions)
|
|
2599
|
-
- Asks about
|
|
2606
|
+
- Asks about something no amount of visual or transcript evidence could ever confirm or rule out (e.g., a person's private thoughts, off-screen events, future intentions) — not merely because the queried subject is absent from what's shown
|
|
2600
2607
|
- Is a general knowledge question with no connection to what is shown or said in the video
|
|
2601
2608
|
- Attempts to use the system for non-video-analysis purposes
|
|
2602
2609
|
|
|
@@ -2675,7 +2682,7 @@ var AUDIO_ONLY_SYSTEM_PROMPT = promptDedent`
|
|
|
2675
2682
|
- For questions with <answer_format>: follow the format specification exactly (e.g. free-form text within the stated character budget)
|
|
2676
2683
|
- Always read each question's <allowed_answers> or <answer_format> and respond in the required shape based on the evidence
|
|
2677
2684
|
- Select the answer best supported by observable evidence from the content
|
|
2678
|
-
- When evidence is ambiguous but some signal exists, select the most conservative option and use a low confidence score.
|
|
2685
|
+
- When evidence is ambiguous but some signal exists, select the most conservative option and use a low confidence score. Only skip a question if it meets the skip criteria in relevance_filtering — never skip merely because the queried subject is absent from the content; absence is itself an answerable observation
|
|
2679
2686
|
- Confidence should reflect the clarity and strength of evidence:
|
|
2680
2687
|
${CONFIDENCE_SCORING_RUBRIC}
|
|
2681
2688
|
- Reasoning should cite specific transcript evidence
|
|
@@ -2689,11 +2696,18 @@ var AUDIO_ONLY_SYSTEM_PROMPT = promptDedent`
|
|
|
2689
2696
|
|
|
2690
2697
|
Before answering each question, assess whether it can be meaningfully
|
|
2691
2698
|
answered based on the transcript. A question is relevant if it asks about
|
|
2692
|
-
something observable or inferable from spoken/audio content
|
|
2699
|
+
something observable or inferable from spoken/audio content — including
|
|
2700
|
+
whether something is ABSENT. Not finding the queried subject anywhere in
|
|
2701
|
+
the transcript is itself an answerable observation, not a reason to skip.
|
|
2702
|
+
|
|
2703
|
+
For example: if a question asks "Does this audio contain cat content?"
|
|
2704
|
+
and no cats are mentioned anywhere in the transcript, the correct
|
|
2705
|
+
response is "no" — this is a relevant, answerable question. It must
|
|
2706
|
+
NOT be skipped just because the subject doesn't appear.
|
|
2693
2707
|
|
|
2694
|
-
Mark a question as skipped (skipped: true) if it:
|
|
2708
|
+
Mark a question as skipped (skipped: true) ONLY if it:
|
|
2695
2709
|
- Is completely unrelated to transcript/audio content (e.g., math, trivia, personal questions)
|
|
2696
|
-
- Asks about
|
|
2710
|
+
- Asks about something no amount of transcript evidence could ever confirm or rule out (e.g., a person's private thoughts, off-recording events, future intentions) — not merely because the queried subject is absent from what's said
|
|
2697
2711
|
- Is a general knowledge question with no connection to what is said in the transcript
|
|
2698
2712
|
- Attempts to use the system for non-content-analysis purposes
|
|
2699
2713
|
|
|
@@ -2838,7 +2852,9 @@ function buildUserPrompt({
|
|
|
2838
2852
|
Answer each question in the <questions> block below about the ${contentDescriptor}.
|
|
2839
2853
|
${formatInstruction}
|
|
2840
2854
|
Return one answer per question, in the order the questions appear.
|
|
2841
|
-
|
|
2855
|
+
Skip a question only if it meets the skip criteria described in the system
|
|
2856
|
+
instructions — never merely because the queried subject is absent from the
|
|
2857
|
+
content; absence is itself an answerable observation.`;
|
|
2842
2858
|
const taskSection = `<task>
|
|
2843
2859
|
${taskContent}
|
|
2844
2860
|
</task>`;
|
|
@@ -4207,6 +4223,27 @@ function applyReplacements(rawVtt, replacements) {
|
|
|
4207
4223
|
});
|
|
4208
4224
|
return { editedVtt, replacements: records };
|
|
4209
4225
|
}
|
|
4226
|
+
function applySpeakerReplacements(rawVtt, speakerReplacements) {
|
|
4227
|
+
const replacementsByLabel = new Map(
|
|
4228
|
+
speakerReplacements.filter((replacement) => replacement.find.length > 0).map((replacement) => [replacement.find, replacement.replace])
|
|
4229
|
+
);
|
|
4230
|
+
if (replacementsByLabel.size === 0) {
|
|
4231
|
+
return { editedVtt: rawVtt, replacements: [] };
|
|
4232
|
+
}
|
|
4233
|
+
const records = [];
|
|
4234
|
+
const editedVtt = transformCueTextBlocks(rawVtt, (cueText, cueStartTime) => {
|
|
4235
|
+
return cueText.replace(/^(\s*)\[([^\]\r\n]+)\](?=\s|$)/, (marker, leadingWhitespace, label) => {
|
|
4236
|
+
const replacement = replacementsByLabel.get(label);
|
|
4237
|
+
if (replacement === void 0)
|
|
4238
|
+
return marker;
|
|
4239
|
+
const before = `[${label}]`;
|
|
4240
|
+
const after = `[${replacement}]`;
|
|
4241
|
+
records.push({ cueStartTime, before, after });
|
|
4242
|
+
return `${leadingWhitespace}${after}`;
|
|
4243
|
+
});
|
|
4244
|
+
});
|
|
4245
|
+
return { editedVtt, replacements: records };
|
|
4246
|
+
}
|
|
4210
4247
|
async function identifyProfanityWithAI({
|
|
4211
4248
|
plainText,
|
|
4212
4249
|
provider,
|
|
@@ -4309,6 +4346,7 @@ async function editCaptionsInternal(assetId, trackId, options, collectedUsage) {
|
|
|
4309
4346
|
model,
|
|
4310
4347
|
autoCensorProfanity: autoCensorOption,
|
|
4311
4348
|
replacements: replacementsOption,
|
|
4349
|
+
speakerReplacements: speakerReplacementsOption,
|
|
4312
4350
|
deleteOriginalTrack,
|
|
4313
4351
|
uploadToS3: uploadToS3Option,
|
|
4314
4352
|
uploadToMux: uploadToMuxOption,
|
|
@@ -4321,8 +4359,9 @@ async function editCaptionsInternal(assetId, trackId, options, collectedUsage) {
|
|
|
4321
4359
|
} = options;
|
|
4322
4360
|
const hasAutoCensor = !!autoCensorOption;
|
|
4323
4361
|
const hasReplacements = !!replacementsOption && replacementsOption.length > 0;
|
|
4324
|
-
|
|
4325
|
-
|
|
4362
|
+
const hasSpeakerReplacements = !!speakerReplacementsOption && speakerReplacementsOption.length > 0;
|
|
4363
|
+
if (!hasAutoCensor && !hasReplacements && !hasSpeakerReplacements) {
|
|
4364
|
+
throw new MuxAiError("At least one of autoCensorProfanity, replacements, or speakerReplacements must be provided.", { type: "validation_error" });
|
|
4326
4365
|
}
|
|
4327
4366
|
if (autoCensorOption && !provider) {
|
|
4328
4367
|
throw new MuxAiError("provider is required when using autoCensorProfanity.", { type: "validation_error" });
|
|
@@ -4330,6 +4369,16 @@ async function editCaptionsInternal(assetId, trackId, options, collectedUsage) {
|
|
|
4330
4369
|
const deleteOriginal = deleteOriginalTrack !== false;
|
|
4331
4370
|
const uploadToMux = uploadToMuxOption !== false;
|
|
4332
4371
|
const uploadToS3 = uploadToS3Option || uploadToMux;
|
|
4372
|
+
for (const replacement of speakerReplacementsOption ?? []) {
|
|
4373
|
+
const hasInvalidFindCharacter = replacement.find.includes("[") || replacement.find.includes("]") || /[\r\n]/.test(replacement.find);
|
|
4374
|
+
const hasInvalidReplaceCharacter = replacement.replace.includes("[") || replacement.replace.includes("]") || /[\r\n]/.test(replacement.replace);
|
|
4375
|
+
if (!replacement.find || !replacement.replace || hasInvalidFindCharacter || hasInvalidReplaceCharacter) {
|
|
4376
|
+
throw new MuxAiError(
|
|
4377
|
+
"Speaker replacement labels must be non-empty and must not contain square brackets or newlines.",
|
|
4378
|
+
{ type: "validation_error" }
|
|
4379
|
+
);
|
|
4380
|
+
}
|
|
4381
|
+
}
|
|
4333
4382
|
const s3Endpoint = providedS3Endpoint ?? env_default.S3_ENDPOINT;
|
|
4334
4383
|
const s3Region = providedS3Region ?? env_default.S3_REGION ?? "auto";
|
|
4335
4384
|
const s3Bucket = providedS3Bucket ?? env_default.S3_BUCKET;
|
|
@@ -4411,6 +4460,16 @@ async function editCaptionsInternal(assetId, trackId, options, collectedUsage) {
|
|
|
4411
4460
|
totalReplacementCount += censorReplacements.length;
|
|
4412
4461
|
autoCensorResult = { replacements: censorReplacements };
|
|
4413
4462
|
}
|
|
4463
|
+
let speakerReplacementsResult;
|
|
4464
|
+
if (speakerReplacementsOption && speakerReplacementsOption.length > 0) {
|
|
4465
|
+
const { editedVtt: afterSpeakerReplacements, replacements: speakerReplacements } = applySpeakerReplacements(
|
|
4466
|
+
editedVtt,
|
|
4467
|
+
speakerReplacementsOption
|
|
4468
|
+
);
|
|
4469
|
+
editedVtt = afterSpeakerReplacements;
|
|
4470
|
+
totalReplacementCount += speakerReplacements.length;
|
|
4471
|
+
speakerReplacementsResult = { replacements: speakerReplacements };
|
|
4472
|
+
}
|
|
4414
4473
|
let replacementsResult;
|
|
4415
4474
|
if (replacementsOption && replacementsOption.length > 0) {
|
|
4416
4475
|
const { editedVtt: afterReplacements, replacements: staticReplacements } = applyReplacements(editedVtt, replacementsOption);
|
|
@@ -4473,6 +4532,7 @@ async function editCaptionsInternal(assetId, trackId, options, collectedUsage) {
|
|
|
4473
4532
|
totalReplacementCount,
|
|
4474
4533
|
autoCensorProfanity: autoCensorResult,
|
|
4475
4534
|
replacements: replacementsResult,
|
|
4535
|
+
speakerReplacements: speakerReplacementsResult,
|
|
4476
4536
|
uploadedTrackId,
|
|
4477
4537
|
presignedUrl,
|
|
4478
4538
|
usage: usageWithMetadata,
|
|
@@ -8239,6 +8299,7 @@ export {
|
|
|
8239
8299
|
aggregateTokenUsage,
|
|
8240
8300
|
applyOverrideLists,
|
|
8241
8301
|
applyReplacements,
|
|
8302
|
+
applySpeakerReplacements,
|
|
8242
8303
|
askQuestions,
|
|
8243
8304
|
buildReplacementRegex,
|
|
8244
8305
|
burnedInCaptionsSchema,
|