@mux/ai 0.11.0 → 0.12.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/dist/{index-BapL6paa.d.ts → index-DyzifniY.d.ts} +21 -11
- package/dist/index.d.ts +2 -2
- package/dist/index.js +62 -30
- package/dist/index.js.map +1 -1
- package/dist/workflows/index.d.ts +1 -1
- package/dist/workflows/index.js +61 -29
- package/dist/workflows/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as AskQuestionsOptions, a as AskQuestionsResult, b as AskQuestionsType, c as AudioTranslationOptions, d as AudioTranslationResult, e as AutoCensorProfanityOptions, B as BurnedInCaptionsAnalysis, f as BurnedInCaptionsOptions, g as BurnedInCaptionsPromptOverrides, h as BurnedInCaptionsPromptSections, j as BurnedInCaptionsResult, C as CaptionReplacement, k as CensorMode, l as Chapter, m as ChapterSystemPromptSections, n as ChaptersOptions, o as ChaptersPromptOverrides, p as ChaptersPromptSections, q as ChaptersResult, r as ChaptersType, D as DEFAULT_DESCRIPTION_LENGTH, s as DEFAULT_SUMMARY_KEYWORD_LIMIT, t as DEFAULT_TITLE_LENGTH, E as EditCaptionsOptions, u as EditCaptionsResult, v as EmbeddingsOptions, w as EmbeddingsResult, H as HIVE_SEXUAL_CATEGORIES, x as HIVE_VIOLENCE_CATEGORIES, y as HiveModerationOutput, z as HiveModerationSource, M as ModerationOptions, F as ModerationProvider, G as ModerationResult, P as ProfanityDetectionPayload, Q as Question, I as QuestionAnswer, J as QuestionAnswerType, R as ReplacementRecord, S as SummarizationOptions, K as SummarizationPromptOverrides, L as SummarizationPromptSections, N as SummaryAndTagsResult, O as SummaryType, T as ThumbnailModerationScore, U as TranslationChunkingOptions, V as TranslationOptions, W as TranslationPayload, X as TranslationResult, Y as aggregateTokenUsage, Z as applyOverrideLists, _ as applyReplacements, $ as askQuestions, a0 as buildReplacementRegex, a1 as burnedInCaptionsSchema, a2 as censorVttContent, a3 as chapterSchema, a4 as chaptersSchema, a5 as createReplacer, a6 as editCaptions, a7 as generateChapters, a8 as generateEmbeddings, a9 as generateVideoEmbeddings, aa as getModerationScores, ab as getSummaryAndTags, ac as hasBurnedInCaptions, ad as profanityDetectionSchema, ae as questionAnswerSchema, af as shouldSplitChunkTranslationError, ag as summarySchema, ah as transformCueText, ai as translateAudio, aj as translateCaptions, ak as translationSchema } from '../index-
|
|
1
|
+
export { A as AskQuestionsOptions, a as AskQuestionsResult, b as AskQuestionsType, c as AudioTranslationOptions, d as AudioTranslationResult, e as AutoCensorProfanityOptions, B as BurnedInCaptionsAnalysis, f as BurnedInCaptionsOptions, g as BurnedInCaptionsPromptOverrides, h as BurnedInCaptionsPromptSections, j as BurnedInCaptionsResult, C as CaptionReplacement, k as CensorMode, l as Chapter, m as ChapterSystemPromptSections, n as ChaptersOptions, o as ChaptersPromptOverrides, p as ChaptersPromptSections, q as ChaptersResult, r as ChaptersType, D as DEFAULT_DESCRIPTION_LENGTH, s as DEFAULT_SUMMARY_KEYWORD_LIMIT, t as DEFAULT_TITLE_LENGTH, E as EditCaptionsOptions, u as EditCaptionsResult, v as EmbeddingsOptions, w as EmbeddingsResult, H as HIVE_SEXUAL_CATEGORIES, x as HIVE_VIOLENCE_CATEGORIES, y as HiveModerationOutput, z as HiveModerationSource, M as ModerationOptions, F as ModerationProvider, G as ModerationResult, P as ProfanityDetectionPayload, Q as Question, I as QuestionAnswer, J as QuestionAnswerType, R as ReplacementRecord, S as SummarizationOptions, K as SummarizationPromptOverrides, L as SummarizationPromptSections, N as SummaryAndTagsResult, O as SummaryType, T as ThumbnailModerationScore, U as TranslationChunkingOptions, V as TranslationOptions, W as TranslationPayload, X as TranslationResult, Y as aggregateTokenUsage, Z as applyOverrideLists, _ as applyReplacements, $ as askQuestions, a0 as buildReplacementRegex, a1 as burnedInCaptionsSchema, a2 as censorVttContent, a3 as chapterSchema, a4 as chaptersSchema, a5 as createReplacer, a6 as editCaptions, a7 as generateChapters, a8 as generateEmbeddings, a9 as generateVideoEmbeddings, aa as getModerationScores, ab as getSummaryAndTags, ac as hasBurnedInCaptions, ad as profanityDetectionSchema, ae as questionAnswerSchema, af as shouldSplitChunkTranslationError, ag as summarySchema, ah as transformCueText, ai as translateAudio, aj as translateCaptions, ak as translationSchema } from '../index-DyzifniY.js';
|
|
2
2
|
import 'zod';
|
|
3
3
|
import '@ai-sdk/anthropic';
|
|
4
4
|
import '@ai-sdk/google';
|
package/dist/workflows/index.js
CHANGED
|
@@ -1304,12 +1304,14 @@ async function fetchTranscriptForAsset(asset, playbackId, options = {}) {
|
|
|
1304
1304
|
// src/workflows/ask-questions.ts
|
|
1305
1305
|
var questionAnswerSchema = z2.object({
|
|
1306
1306
|
question: z2.string(),
|
|
1307
|
-
answer: z2.string(),
|
|
1307
|
+
answer: z2.string().optional(),
|
|
1308
1308
|
confidence: z2.number(),
|
|
1309
|
-
reasoning: z2.string()
|
|
1309
|
+
reasoning: z2.string(),
|
|
1310
|
+
skipped: z2.boolean()
|
|
1310
1311
|
});
|
|
1312
|
+
var SKIP_SENTINEL = "__SKIPPED__";
|
|
1311
1313
|
function createAskQuestionsSchema(allowedAnswers) {
|
|
1312
|
-
const answerSchema = z2.enum(allowedAnswers);
|
|
1314
|
+
const answerSchema = z2.enum([...allowedAnswers, SKIP_SENTINEL]);
|
|
1313
1315
|
return z2.object({
|
|
1314
1316
|
answers: z2.array(
|
|
1315
1317
|
questionAnswerSchema.extend({
|
|
@@ -1365,8 +1367,32 @@ var SYSTEM_PROMPT = dedent`
|
|
|
1365
1367
|
- Be precise: cite specific frames, objects, actions, or transcript quotes
|
|
1366
1368
|
</answer_guidelines>
|
|
1367
1369
|
|
|
1370
|
+
<relevance_filtering>
|
|
1371
|
+
Before answering each question, assess whether it can be meaningfully
|
|
1372
|
+
answered based on the video storyboard and/or transcript. A question is
|
|
1373
|
+
relevant if it asks about something observable or inferable from the
|
|
1374
|
+
video content (visuals, audio, dialogue, setting, subjects, actions, etc.).
|
|
1375
|
+
|
|
1376
|
+
Mark a question as skipped (skipped: true) if it:
|
|
1377
|
+
- Is completely unrelated to video content (e.g., math, trivia, personal questions)
|
|
1378
|
+
- Asks about information that cannot be determined from storyboard frames or transcript
|
|
1379
|
+
- Is a general knowledge question with no connection to what is shown or said in the video
|
|
1380
|
+
- Attempts to use the system for non-video-analysis purposes
|
|
1381
|
+
|
|
1382
|
+
For skipped questions:
|
|
1383
|
+
- Set skipped to true
|
|
1384
|
+
- Set answer to "${SKIP_SENTINEL}"
|
|
1385
|
+
- Set confidence to 0
|
|
1386
|
+
- Use the reasoning field to explain why the question is not answerable
|
|
1387
|
+
from the video content
|
|
1388
|
+
|
|
1389
|
+
For borderline questions that are loosely related to the video content,
|
|
1390
|
+
still answer them but use a lower confidence score to reflect uncertainty.
|
|
1391
|
+
</relevance_filtering>
|
|
1392
|
+
|
|
1368
1393
|
<constraints>
|
|
1369
|
-
- You MUST answer every question with one of the allowed response options
|
|
1394
|
+
- You MUST answer every relevant question with one of the allowed response options
|
|
1395
|
+
- Skip irrelevant questions as described in relevance_filtering
|
|
1370
1396
|
- Only describe observable evidence from frames or transcript
|
|
1371
1397
|
- Do not fabricate details or make unsupported assumptions
|
|
1372
1398
|
- Return structured data matching the requested schema exactly
|
|
@@ -1442,14 +1468,7 @@ async function analyzeQuestionsWithStoryboard(imageDataUrl, provider, modelId, u
|
|
|
1442
1468
|
]
|
|
1443
1469
|
});
|
|
1444
1470
|
return {
|
|
1445
|
-
result:
|
|
1446
|
-
answers: response.output.answers.map((answer) => ({
|
|
1447
|
-
...answer,
|
|
1448
|
-
// Strip numbering prefix (e.g., "1. " or "2. ") from questions
|
|
1449
|
-
question: answer.question.replace(/^\d+\.\s*/, ""),
|
|
1450
|
-
confidence: Math.min(1, Math.max(0, answer.confidence))
|
|
1451
|
-
}))
|
|
1452
|
-
},
|
|
1471
|
+
result: response.output,
|
|
1453
1472
|
usage: {
|
|
1454
1473
|
inputTokens: response.usage.inputTokens,
|
|
1455
1474
|
outputTokens: response.usage.outputTokens,
|
|
@@ -1555,9 +1574,20 @@ async function askQuestions(assetId, questions, options) {
|
|
|
1555
1574
|
`Expected ${questions.length} answers but received ${analysisResponse.result.answers.length}`
|
|
1556
1575
|
);
|
|
1557
1576
|
}
|
|
1577
|
+
const answers = analysisResponse.result.answers.map((raw) => {
|
|
1578
|
+
const isSkipped = raw.skipped || raw.answer === SKIP_SENTINEL;
|
|
1579
|
+
return {
|
|
1580
|
+
// Strip numbering prefix (e.g., "1. " or "2. ") from questions
|
|
1581
|
+
question: raw.question.replace(/^\d+\.\s*/, ""),
|
|
1582
|
+
confidence: isSkipped ? 0 : Math.min(1, Math.max(0, raw.confidence)),
|
|
1583
|
+
reasoning: raw.reasoning,
|
|
1584
|
+
skipped: isSkipped,
|
|
1585
|
+
...isSkipped ? {} : { answer: raw.answer }
|
|
1586
|
+
};
|
|
1587
|
+
});
|
|
1558
1588
|
return {
|
|
1559
1589
|
assetId,
|
|
1560
|
-
answers
|
|
1590
|
+
answers,
|
|
1561
1591
|
storyboardUrl: imageUrl,
|
|
1562
1592
|
usage: {
|
|
1563
1593
|
...analysisResponse.usage,
|
|
@@ -3760,43 +3790,43 @@ var DESCRIPTION_LENGTH_THRESHOLD_LARGE = 100;
|
|
|
3760
3790
|
function buildDescriptionGuidance(wordCount, contentType) {
|
|
3761
3791
|
if (wordCount < DESCRIPTION_LENGTH_THRESHOLD_SMALL) {
|
|
3762
3792
|
if (contentType === "video") {
|
|
3763
|
-
return dedent5`A brief summary of the video in
|
|
3793
|
+
return dedent5`A brief summary of the video in no more than ${wordCount} words. Shorter is fine.
|
|
3764
3794
|
Focus on the single most important subject or action.
|
|
3765
3795
|
Write in present tense.`;
|
|
3766
3796
|
}
|
|
3767
|
-
return dedent5`A brief summary of the audio content in
|
|
3797
|
+
return dedent5`A brief summary of the audio content in no more than ${wordCount} words. Shorter is fine.
|
|
3768
3798
|
Focus on the single most important topic or theme.
|
|
3769
3799
|
Write in present tense.`;
|
|
3770
3800
|
}
|
|
3771
3801
|
if (wordCount > DESCRIPTION_LENGTH_THRESHOLD_LARGE) {
|
|
3772
3802
|
if (contentType === "video") {
|
|
3773
3803
|
return dedent5`A detailed summary that describes what happens across the video.
|
|
3774
|
-
|
|
3804
|
+
Never exceed ${wordCount} words, but shorter is perfectly fine. You may use multiple sentences.
|
|
3775
3805
|
Be thorough: cover subjects, actions, setting, progression, and any notable details visible across frames.
|
|
3776
3806
|
Write in present tense. Be specific about observable details rather than making assumptions.
|
|
3777
3807
|
If the transcript provides dialogue or narration, incorporate key points but prioritize visual content.`;
|
|
3778
3808
|
}
|
|
3779
3809
|
return dedent5`A detailed summary that describes the audio content.
|
|
3780
|
-
|
|
3810
|
+
Never exceed ${wordCount} words, but shorter is perfectly fine. You may use multiple sentences.
|
|
3781
3811
|
Be thorough: cover topics, speakers, themes, progression, and any notable insights.
|
|
3782
3812
|
Write in present tense. Be specific about what is discussed or presented rather than making assumptions.
|
|
3783
3813
|
Focus on the spoken content and any key insights, dialogue, or narrative elements.`;
|
|
3784
3814
|
}
|
|
3785
3815
|
if (contentType === "video") {
|
|
3786
3816
|
return dedent5`A summary that describes what happens across the video.
|
|
3787
|
-
|
|
3817
|
+
Never exceed ${wordCount} words, but shorter is perfectly fine. You may use multiple sentences.
|
|
3788
3818
|
Cover the main subjects, actions, setting, and any notable progression visible across frames.
|
|
3789
3819
|
Write in present tense. Be specific about observable details rather than making assumptions.
|
|
3790
3820
|
If the transcript provides dialogue or narration, incorporate key points but prioritize visual content.`;
|
|
3791
3821
|
}
|
|
3792
3822
|
return dedent5`A summary that describes the audio content.
|
|
3793
|
-
|
|
3823
|
+
Never exceed ${wordCount} words, but shorter is perfectly fine. You may use multiple sentences.
|
|
3794
3824
|
Cover the main topics, speakers, themes, and any notable progression in the discussion or narration.
|
|
3795
3825
|
Write in present tense. Be specific about what is discussed or presented rather than making assumptions.
|
|
3796
3826
|
Focus on the spoken content and any key insights, dialogue, or narrative elements.`;
|
|
3797
3827
|
}
|
|
3798
3828
|
function createSummarizationBuilder({ titleLength, descriptionLength, tagCount } = {}) {
|
|
3799
|
-
const
|
|
3829
|
+
const titleLimit = titleLength ?? DEFAULT_TITLE_LENGTH;
|
|
3800
3830
|
const keywordLimit = tagCount ?? DEFAULT_SUMMARY_KEYWORD_LIMIT;
|
|
3801
3831
|
return createPromptBuilder({
|
|
3802
3832
|
template: {
|
|
@@ -3807,10 +3837,11 @@ function createSummarizationBuilder({ titleLength, descriptionLength, tagCount }
|
|
|
3807
3837
|
title: {
|
|
3808
3838
|
tag: "title_requirements",
|
|
3809
3839
|
content: dedent5`
|
|
3810
|
-
A
|
|
3811
|
-
${
|
|
3812
|
-
|
|
3813
|
-
|
|
3840
|
+
A concise, label-style title — not a sentence or description.
|
|
3841
|
+
Never exceed ${titleLimit} words, but shorter is better.
|
|
3842
|
+
Think of how a video card title, playlist entry, or file name would read — e.g. "Predator: Badlands Trailer" or "Chef Prepares Holiday Feast".
|
|
3843
|
+
Start with the primary subject or topic. Never begin with "A video of" or similar phrasing.
|
|
3844
|
+
Use specific nouns over lengthy descriptions. Avoid clauses, conjunctions, or narrative structure.`
|
|
3814
3845
|
},
|
|
3815
3846
|
description: {
|
|
3816
3847
|
tag: "description_requirements",
|
|
@@ -3841,7 +3872,7 @@ function createSummarizationBuilder({ titleLength, descriptionLength, tagCount }
|
|
|
3841
3872
|
});
|
|
3842
3873
|
}
|
|
3843
3874
|
function createAudioOnlyBuilder({ titleLength, descriptionLength, tagCount } = {}) {
|
|
3844
|
-
const
|
|
3875
|
+
const titleLimit = titleLength ?? DEFAULT_TITLE_LENGTH;
|
|
3845
3876
|
const keywordLimit = tagCount ?? DEFAULT_SUMMARY_KEYWORD_LIMIT;
|
|
3846
3877
|
return createPromptBuilder({
|
|
3847
3878
|
template: {
|
|
@@ -3852,10 +3883,11 @@ function createAudioOnlyBuilder({ titleLength, descriptionLength, tagCount } = {
|
|
|
3852
3883
|
title: {
|
|
3853
3884
|
tag: "title_requirements",
|
|
3854
3885
|
content: dedent5`
|
|
3855
|
-
A
|
|
3856
|
-
${
|
|
3857
|
-
|
|
3858
|
-
|
|
3886
|
+
A concise, label-style title — not a sentence or description.
|
|
3887
|
+
Never exceed ${titleLimit} words, but shorter is better.
|
|
3888
|
+
Think of how a podcast episode title or playlist entry would read — e.g. "Weekly News Roundup" or "Interview with Dr. Smith".
|
|
3889
|
+
Start with the primary subject or topic. Never begin with "An audio of" or similar phrasing.
|
|
3890
|
+
Use specific nouns over lengthy descriptions. Avoid clauses, conjunctions, or narrative structure.`
|
|
3859
3891
|
},
|
|
3860
3892
|
description: {
|
|
3861
3893
|
tag: "description_requirements",
|