@mux/ai 0.20.0 → 0.21.1
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 +1 -1
- package/dist/{index-DXMIJjUa.d.ts → index-DwNtsg-u.d.ts} +13 -4
- package/dist/{index-Drj9Cy_k.d.ts → index-bjQi1ZCj.d.ts} +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +131 -13
- package/dist/index.js.map +1 -1
- package/dist/primitives/index.d.ts +2 -2
- package/dist/primitives/index.js +1 -0
- package/dist/primitives/index.js.map +1 -1
- package/dist/{shots-BFYOfBgN.d.ts → shots-mGJfYGiO.d.ts} +2 -0
- package/dist/workflows/index.d.ts +2 -2
- package/dist/workflows/index.js +130 -12
- package/dist/workflows/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -120,6 +120,8 @@ interface WorkflowCredentials {
|
|
|
120
120
|
anthropicApiKey?: string;
|
|
121
121
|
/** Optional direct Google API key for per-request credential injection. */
|
|
122
122
|
googleApiKey?: string;
|
|
123
|
+
/** Optional direct Google Vision API key for per-request credential injection. */
|
|
124
|
+
googleVisionApiKey?: string;
|
|
123
125
|
/** Optional direct Hive API key for per-request credential injection. */
|
|
124
126
|
hiveApiKey?: string;
|
|
125
127
|
/** Optional direct ElevenLabs API key for per-request credential injection. */
|
|
@@ -1,7 +1,7 @@
|
|
|
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, x as EngagementInsightsOptions, y as EngagementInsightsResult, H as HIVE_SEXUAL_CATEGORIES, z as HIVE_VIOLENCE_CATEGORIES, F as HiveModerationOutput,
|
|
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, x as EngagementInsightsOptions, y as EngagementInsightsResult, G as GOOGLE_VISION_LIKELIHOOD_TO_SCORE, H as HIVE_SEXUAL_CATEGORIES, z as HIVE_VIOLENCE_CATEGORIES, F as HiveModerationOutput, I as HiveModerationSource, M as ModerationOptions, J as ModerationProvider, K as ModerationResult, L as MomentInsight, O as OverallInsight, P as ProfanityDetectionPayload, Q as Question, N as QuestionAnswer, R as QuestionAnswerType, S as ReplacementRecord, T as SummarizationOptions, U as SummarizationPromptOverrides, V as SummarizationPromptSections, W as SummaryAndTagsResult, X as SummaryType, Y as ThumbnailModerationScore, Z as TranslationChunkingOptions, _ as TranslationOptions, $ as TranslationPayload, a0 as TranslationResult, a1 as aggregateTokenUsage, a2 as applyOverrideLists, a3 as applyReplacements, a4 as askQuestions, a5 as buildReplacementRegex, a6 as burnedInCaptionsSchema, a7 as censorVttContent, a8 as chapterSchema, a9 as chaptersSchema, aa as createReplacer, ab as editCaptions, ac as extractTranscriptSegmentsForHotspots, ad as generateChapters, ae as generateEmbeddings, af as generateEngagementInsights, ag as generateVideoEmbeddings, ah as getModerationScores, ai as getSummaryAndTags, aj as hasBurnedInCaptions, ak as mapShotsToHotspots, al as normalizeTranslatedVtt, am as profanityDetectionSchema, an as questionAnswerSchema, ao as shouldSplitChunkTranslationError, ap as summarySchema, aq as transformCueText, ar as translateAudio, as as translateCaptions, at as translationSchema } from '../index-DwNtsg-u.js';
|
|
2
2
|
import 'zod';
|
|
3
3
|
import '@ai-sdk/anthropic';
|
|
4
4
|
import '@ai-sdk/google';
|
|
5
5
|
import '@ai-sdk/openai';
|
|
6
|
-
import '../shots-
|
|
6
|
+
import '../shots-mGJfYGiO.js';
|
|
7
7
|
import '@mux/mux-node';
|
package/dist/workflows/index.js
CHANGED
|
@@ -186,6 +186,7 @@ var EnvSchema = z.object({
|
|
|
186
186
|
GOOGLE_GENERATIVE_AI_API_KEY: optionalString("Google Generative AI API key for Gemini-backed workflows.", "Google Generative AI API key"),
|
|
187
187
|
ELEVENLABS_API_KEY: optionalString("ElevenLabs API key for audio translation.", "ElevenLabs API key"),
|
|
188
188
|
HIVE_API_KEY: optionalString("Hive Visual Moderation API key.", "Hive API key"),
|
|
189
|
+
GOOGLE_VISION_API_KEY: optionalString("Google Vision API key for SafeSearch moderation.", "Google Vision API key"),
|
|
189
190
|
// S3-Compatible Storage (required for translation & audio dubbing)
|
|
190
191
|
S3_ENDPOINT: optionalString("S3-compatible endpoint for uploads.", "S3 endpoint"),
|
|
191
192
|
S3_REGION: optionalString("S3 region (defaults to 'auto' when omitted)."),
|
|
@@ -809,23 +810,26 @@ function resolveProviderApiKeyFromCredentials(provider, resolved) {
|
|
|
809
810
|
const openaiApiKey = readString(record, "openaiApiKey");
|
|
810
811
|
const anthropicApiKey = readString(record, "anthropicApiKey");
|
|
811
812
|
const googleApiKey = readString(record, "googleApiKey");
|
|
813
|
+
const googleVisionApiKey = readString(record, "googleVisionApiKey");
|
|
812
814
|
const hiveApiKey = readString(record, "hiveApiKey");
|
|
813
815
|
const elevenLabsApiKey = readString(record, "elevenLabsApiKey");
|
|
814
816
|
const apiKeyMap = {
|
|
815
|
-
openai: openaiApiKey ?? env_default.OPENAI_API_KEY,
|
|
816
|
-
anthropic: anthropicApiKey ?? env_default.ANTHROPIC_API_KEY,
|
|
817
|
-
google: googleApiKey ?? env_default.GOOGLE_GENERATIVE_AI_API_KEY,
|
|
818
|
-
|
|
819
|
-
|
|
817
|
+
"openai": openaiApiKey ?? env_default.OPENAI_API_KEY,
|
|
818
|
+
"anthropic": anthropicApiKey ?? env_default.ANTHROPIC_API_KEY,
|
|
819
|
+
"google": googleApiKey ?? env_default.GOOGLE_GENERATIVE_AI_API_KEY,
|
|
820
|
+
"google-vision-api": googleVisionApiKey ?? env_default.GOOGLE_VISION_API_KEY,
|
|
821
|
+
"hive": hiveApiKey ?? env_default.HIVE_API_KEY,
|
|
822
|
+
"elevenlabs": elevenLabsApiKey ?? env_default.ELEVENLABS_API_KEY
|
|
820
823
|
};
|
|
821
824
|
const apiKey = apiKeyMap[provider];
|
|
822
825
|
if (!apiKey) {
|
|
823
826
|
const envVarNames = {
|
|
824
|
-
openai: "OPENAI_API_KEY",
|
|
825
|
-
anthropic: "ANTHROPIC_API_KEY",
|
|
826
|
-
google: "GOOGLE_GENERATIVE_AI_API_KEY",
|
|
827
|
-
|
|
828
|
-
|
|
827
|
+
"openai": "OPENAI_API_KEY",
|
|
828
|
+
"anthropic": "ANTHROPIC_API_KEY",
|
|
829
|
+
"google": "GOOGLE_GENERATIVE_AI_API_KEY",
|
|
830
|
+
"google-vision-api": "GOOGLE_VISION_API_KEY",
|
|
831
|
+
"hive": "HIVE_API_KEY",
|
|
832
|
+
"elevenlabs": "ELEVENLABS_API_KEY"
|
|
829
833
|
};
|
|
830
834
|
throw new Error(
|
|
831
835
|
`${provider} API key is required. Provide ${provider} credentials via workflow credentials or set ${envVarNames[provider]} environment variable.`
|
|
@@ -4859,6 +4863,15 @@ var OPENAI_MODERATION_BASE_DELAY_MS = 750;
|
|
|
4859
4863
|
var OPENAI_MODERATION_MAX_DELAY_MS = 3e3;
|
|
4860
4864
|
var MIN_SAMPLE_COVERAGE_FOR_CONFIDENT_THRESHOLDING = 0.5;
|
|
4861
4865
|
var MIN_SUCCESSFUL_THUMBNAILS_FOR_CONFIDENT_THRESHOLDING = 3;
|
|
4866
|
+
var GOOGLE_VISION_ENDPOINT = "https://vision.googleapis.com/v1/images:annotate";
|
|
4867
|
+
var GOOGLE_VISION_LIKELIHOOD_TO_SCORE = {
|
|
4868
|
+
UNKNOWN: 0,
|
|
4869
|
+
VERY_UNLIKELY: 0.2,
|
|
4870
|
+
UNLIKELY: 0.4,
|
|
4871
|
+
POSSIBLE: 0.6,
|
|
4872
|
+
LIKELY: 0.8,
|
|
4873
|
+
VERY_LIKELY: 1
|
|
4874
|
+
};
|
|
4862
4875
|
var HIVE_ENDPOINT = "https://api.thehive.ai/api/v2/task/sync";
|
|
4863
4876
|
var HIVE_SEXUAL_CATEGORIES = [
|
|
4864
4877
|
"general_nsfw",
|
|
@@ -5187,6 +5200,98 @@ async function requestHiveModeration(images, maxConcurrent = 5, submissionMode =
|
|
|
5187
5200
|
}));
|
|
5188
5201
|
return await processConcurrently(targets, moderateImageWithHive, maxConcurrent);
|
|
5189
5202
|
}
|
|
5203
|
+
async function moderateImageWithGoogleVision(entry) {
|
|
5204
|
+
"use step";
|
|
5205
|
+
try {
|
|
5206
|
+
const apiKey = await getApiKeyFromEnv("google-vision-api", entry.credentials);
|
|
5207
|
+
const imageField = entry.isBase64 ? { content: entry.image } : { source: { imageUri: entry.image } };
|
|
5208
|
+
const controller = new AbortController();
|
|
5209
|
+
const timeout = setTimeout(() => controller.abort(), 15e3);
|
|
5210
|
+
let res;
|
|
5211
|
+
try {
|
|
5212
|
+
res = await fetch(GOOGLE_VISION_ENDPOINT, {
|
|
5213
|
+
method: "POST",
|
|
5214
|
+
headers: {
|
|
5215
|
+
"Accept": "application/json",
|
|
5216
|
+
"Content-Type": "application/json",
|
|
5217
|
+
"X-goog-api-key": apiKey
|
|
5218
|
+
},
|
|
5219
|
+
body: JSON.stringify({
|
|
5220
|
+
requests: [
|
|
5221
|
+
{
|
|
5222
|
+
image: imageField,
|
|
5223
|
+
features: [{ type: "SAFE_SEARCH_DETECTION" }]
|
|
5224
|
+
}
|
|
5225
|
+
]
|
|
5226
|
+
}),
|
|
5227
|
+
signal: controller.signal
|
|
5228
|
+
});
|
|
5229
|
+
} catch (err) {
|
|
5230
|
+
if (err?.name === "AbortError") {
|
|
5231
|
+
throw new Error("Google Vision request timed out after 15s");
|
|
5232
|
+
}
|
|
5233
|
+
throw err;
|
|
5234
|
+
} finally {
|
|
5235
|
+
clearTimeout(timeout);
|
|
5236
|
+
}
|
|
5237
|
+
const json = await res.json().catch(() => void 0);
|
|
5238
|
+
if (!res.ok) {
|
|
5239
|
+
throw new Error(
|
|
5240
|
+
`Google Vision moderation error: ${res.status} ${res.statusText} - ${JSON.stringify(json)}`
|
|
5241
|
+
);
|
|
5242
|
+
}
|
|
5243
|
+
const perImage = json?.responses?.[0];
|
|
5244
|
+
if (perImage?.error) {
|
|
5245
|
+
throw new Error(
|
|
5246
|
+
`Google Vision per-image error: ${perImage.error.code} ${perImage.error.message || "Unknown error"}`
|
|
5247
|
+
);
|
|
5248
|
+
}
|
|
5249
|
+
const annotation = perImage?.safeSearchAnnotation;
|
|
5250
|
+
if (!annotation) {
|
|
5251
|
+
throw new Error(`Google Vision response missing safeSearchAnnotation: ${JSON.stringify(json)}`);
|
|
5252
|
+
}
|
|
5253
|
+
const adultLikelihood = typeof annotation.adult === "string" ? annotation.adult : "UNKNOWN";
|
|
5254
|
+
const violenceLikelihood = typeof annotation.violence === "string" ? annotation.violence : "UNKNOWN";
|
|
5255
|
+
const sexual = GOOGLE_VISION_LIKELIHOOD_TO_SCORE[adultLikelihood] ?? 0;
|
|
5256
|
+
const violence = GOOGLE_VISION_LIKELIHOOD_TO_SCORE[violenceLikelihood] ?? 0;
|
|
5257
|
+
return {
|
|
5258
|
+
url: entry.url,
|
|
5259
|
+
time: entry.time,
|
|
5260
|
+
sexual,
|
|
5261
|
+
violence,
|
|
5262
|
+
error: false
|
|
5263
|
+
};
|
|
5264
|
+
} catch (error) {
|
|
5265
|
+
return {
|
|
5266
|
+
url: entry.url,
|
|
5267
|
+
time: entry.time,
|
|
5268
|
+
sexual: 0,
|
|
5269
|
+
violence: 0,
|
|
5270
|
+
error: true,
|
|
5271
|
+
errorMessage: error instanceof Error ? error.message : String(error)
|
|
5272
|
+
};
|
|
5273
|
+
}
|
|
5274
|
+
}
|
|
5275
|
+
async function requestGoogleVisionModeration(images, maxConcurrent = 5, submissionMode = "url", downloadOptions, credentials) {
|
|
5276
|
+
"use step";
|
|
5277
|
+
const imageUrls = images.map((img) => img.url);
|
|
5278
|
+
const timeByUrl = new Map(images.map((img) => [img.url, img.time]));
|
|
5279
|
+
const targets = submissionMode === "base64" ? (await downloadImagesAsBase64(imageUrls, downloadOptions, maxConcurrent)).map((img) => ({
|
|
5280
|
+
url: img.url,
|
|
5281
|
+
time: timeByUrl.get(img.url),
|
|
5282
|
+
// Vision REST wants raw base64; downloadImagesAsBase64 returns a data URI.
|
|
5283
|
+
image: img.base64Data.startsWith("data:") ? img.base64Data.split(",")[1] : img.base64Data,
|
|
5284
|
+
isBase64: true,
|
|
5285
|
+
credentials
|
|
5286
|
+
})) : images.map((img) => ({
|
|
5287
|
+
url: img.url,
|
|
5288
|
+
time: img.time,
|
|
5289
|
+
image: img.url,
|
|
5290
|
+
isBase64: false,
|
|
5291
|
+
credentials
|
|
5292
|
+
}));
|
|
5293
|
+
return processConcurrently(targets, moderateImageWithGoogleVision, maxConcurrent);
|
|
5294
|
+
}
|
|
5190
5295
|
async function getThumbnailUrlsFromTimestamps(playbackId, timestampsMs, options) {
|
|
5191
5296
|
"use step";
|
|
5192
5297
|
const { width, shouldSign, credentials } = options;
|
|
@@ -5250,8 +5355,11 @@ async function getModerationScores(assetId, options = {}) {
|
|
|
5250
5355
|
);
|
|
5251
5356
|
} else if (provider === "hive") {
|
|
5252
5357
|
throw new Error("Hive does not support transcript moderation in this workflow. Use provider: 'openai' for audio-only assets.");
|
|
5358
|
+
} else if (provider === "google-vision-api") {
|
|
5359
|
+
throw new Error("google-vision-api is image-only and does not support transcript moderation. Use provider: 'openai' for audio-only assets.");
|
|
5253
5360
|
} else {
|
|
5254
|
-
|
|
5361
|
+
const exhaustiveCheck = provider;
|
|
5362
|
+
throw new Error(`Unsupported moderation provider: ${exhaustiveCheck}`);
|
|
5255
5363
|
}
|
|
5256
5364
|
} else {
|
|
5257
5365
|
const estimatedIntervalCount = duration <= 50 ? 5 : Math.ceil(duration / thumbnailInterval);
|
|
@@ -5294,8 +5402,17 @@ async function getModerationScores(assetId, options = {}) {
|
|
|
5294
5402
|
imageDownloadOptions,
|
|
5295
5403
|
credentials
|
|
5296
5404
|
);
|
|
5405
|
+
} else if (provider === "google-vision-api") {
|
|
5406
|
+
thumbnailScores = await requestGoogleVisionModeration(
|
|
5407
|
+
thumbnailUrls,
|
|
5408
|
+
maxConcurrent,
|
|
5409
|
+
imageSubmissionMode,
|
|
5410
|
+
imageDownloadOptions,
|
|
5411
|
+
credentials
|
|
5412
|
+
);
|
|
5297
5413
|
} else {
|
|
5298
|
-
|
|
5414
|
+
const exhaustiveCheck = provider;
|
|
5415
|
+
throw new Error(`Unsupported moderation provider: ${exhaustiveCheck}`);
|
|
5299
5416
|
}
|
|
5300
5417
|
}
|
|
5301
5418
|
const failed = thumbnailScores.filter((s) => s.error);
|
|
@@ -6999,6 +7116,7 @@ export {
|
|
|
6999
7116
|
DEFAULT_DESCRIPTION_LENGTH,
|
|
7000
7117
|
DEFAULT_SUMMARY_KEYWORD_LIMIT,
|
|
7001
7118
|
DEFAULT_TITLE_LENGTH,
|
|
7119
|
+
GOOGLE_VISION_LIKELIHOOD_TO_SCORE,
|
|
7002
7120
|
HIVE_SEXUAL_CATEGORIES,
|
|
7003
7121
|
HIVE_VIOLENCE_CATEGORIES,
|
|
7004
7122
|
aggregateTokenUsage,
|