@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 CHANGED
@@ -69,7 +69,7 @@ Workflows are high-level functions that handle complete media AI tasks end-to-en
69
69
  | Workflow | What it does | Providers | Audio-only |
70
70
  | --- | --- | --- | :---: |
71
71
  | [`getSummaryAndTags`](./docs/WORKFLOWS.md#video-summarization) | Generate titles, descriptions, and tags | OpenAI, Anthropic, Google | Yes |
72
- | [`getModerationScores`](./docs/WORKFLOWS.md#content-moderation) | Detect inappropriate content | OpenAI, Hive | Yes |
72
+ | [`getModerationScores`](./docs/WORKFLOWS.md#content-moderation) | Detect inappropriate content | OpenAI, Hive, Google Vision | Yes |
73
73
  | [`hasBurnedInCaptions`](./docs/WORKFLOWS.md#burned-in-caption-detection) | Detect hardcoded subtitles in video frames | OpenAI, Anthropic, Google | — |
74
74
  | [`askQuestions`](./docs/WORKFLOWS.md#ask-questions) | Answer yes/no questions about asset content | OpenAI, Anthropic, Google | Yes |
75
75
  | [`generateChapters`](./docs/WORKFLOWS.md#chapter-generation) | Create chapter markers from transcripts | OpenAI, Anthropic, Google | Yes |
@@ -2,7 +2,7 @@ import { z } from 'zod';
2
2
  import { createAnthropic } from '@ai-sdk/anthropic';
3
3
  import { createGoogleGenerativeAI } from '@ai-sdk/google';
4
4
  import { createOpenAI } from '@ai-sdk/openai';
5
- import { M as MuxAIOptions, I as ImageSubmissionMode, h as TokenUsage, b as ChunkingStrategy, j as VideoEmbeddingsResult, H as Hotspot, t as Shot, i as ToneType, f as StorageAdapter } from './shots-BFYOfBgN.js';
5
+ import { M as MuxAIOptions, I as ImageSubmissionMode, h as TokenUsage, b as ChunkingStrategy, j as VideoEmbeddingsResult, H as Hotspot, t as Shot, i as ToneType, f as StorageAdapter } from './shots-mGJfYGiO.js';
6
6
 
7
7
  interface ImageDownloadOptions {
8
8
  /** Request timeout in milliseconds (default: 10000) */
@@ -856,7 +856,7 @@ interface ModerationResult {
856
856
  };
857
857
  }
858
858
  /** Provider list accepted by `getModerationScores`. */
859
- type ModerationProvider = "openai" | "hive";
859
+ type ModerationProvider = "openai" | "hive" | "google-vision-api";
860
860
  type HiveModerationSource = {
861
861
  kind: "url";
862
862
  value: string;
@@ -900,6 +900,11 @@ interface ModerationOptions extends MuxAIOptions {
900
900
  /** Download tuning used when `imageSubmissionMode` === 'base64'. */
901
901
  imageDownloadOptions?: ImageDownloadOptions;
902
902
  }
903
+ /**
904
+ * Linear mapping of Google Vision SafeSearch `Likelihood` enum (UNKNOWN..VERY_LIKELY)
905
+ * onto a 0..1 score. This mapping may change in future versions of `@mux/ai`.
906
+ */
907
+ declare const GOOGLE_VISION_LIKELIHOOD_TO_SCORE: Record<string, number>;
903
908
  declare const HIVE_SEXUAL_CATEGORIES: string[];
904
909
  declare const HIVE_VIOLENCE_CATEGORIES: string[];
905
910
  /**
@@ -911,6 +916,9 @@ declare const HIVE_VIOLENCE_CATEGORIES: string[];
911
916
  * - provider 'openai' uses OpenAI's hosted moderation endpoint (requires OPENAI_API_KEY)
912
917
  * Ref: https://platform.openai.com/docs/guides/moderation
913
918
  * - provider 'hive' uses Hive's moderation API for thumbnails only (requires HIVE_API_KEY)
919
+ * - provider 'google-vision-api' uses Google Cloud Vision SafeSearch for thumbnails only
920
+ * (requires GOOGLE_VISION_API_KEY).
921
+ * Ref: https://cloud.google.com/vision/docs/detecting-safe-search
914
922
  */
915
923
  declare function getModerationScores(assetId: string, options?: ModerationOptions): Promise<ModerationResult>;
916
924
 
@@ -1360,6 +1368,7 @@ type index_EmbeddingsOptions = EmbeddingsOptions;
1360
1368
  type index_EmbeddingsResult = EmbeddingsResult;
1361
1369
  type index_EngagementInsightsOptions = EngagementInsightsOptions;
1362
1370
  type index_EngagementInsightsResult = EngagementInsightsResult;
1371
+ declare const index_GOOGLE_VISION_LIKELIHOOD_TO_SCORE: typeof GOOGLE_VISION_LIKELIHOOD_TO_SCORE;
1363
1372
  declare const index_HIVE_SEXUAL_CATEGORIES: typeof HIVE_SEXUAL_CATEGORIES;
1364
1373
  declare const index_HIVE_VIOLENCE_CATEGORIES: typeof HIVE_VIOLENCE_CATEGORIES;
1365
1374
  type index_HiveModerationOutput = HiveModerationOutput;
@@ -1414,7 +1423,7 @@ declare const index_translateAudio: typeof translateAudio;
1414
1423
  declare const index_translateCaptions: typeof translateCaptions;
1415
1424
  declare const index_translationSchema: typeof translationSchema;
1416
1425
  declare namespace index {
1417
- export { 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_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 };
1426
+ export { 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 };
1418
1427
  }
1419
1428
 
1420
- export { type TranslationResult as $, type AskQuestionsOptions as A, type BurnedInCaptionsAnalysis as B, type CaptionReplacement as C, DEFAULT_DESCRIPTION_LENGTH as D, type EditCaptionsOptions as E, type HiveModerationOutput as F, type HiveModerationSource as G, HIVE_SEXUAL_CATEGORIES as H, type ModerationProvider as I, type ModerationResult as J, type MomentInsight as K, type QuestionAnswer as L, type ModerationOptions as M, type QuestionAnswerType as N, type OverallInsight as O, type ProfanityDetectionPayload as P, type Question as Q, type ReplacementRecord as R, type SummarizationOptions as S, type SummarizationPromptOverrides as T, type SummarizationPromptSections as U, type SummaryAndTagsResult as V, type SummaryType as W, type ThumbnailModerationScore as X, type TranslationChunkingOptions as Y, type TranslationOptions as Z, type TranslationPayload as _, type AskQuestionsResult as a, aggregateTokenUsage as a0, applyOverrideLists as a1, applyReplacements as a2, askQuestions as a3, buildReplacementRegex as a4, burnedInCaptionsSchema as a5, censorVttContent as a6, chapterSchema as a7, chaptersSchema as a8, createReplacer as a9, editCaptions as aa, extractTranscriptSegmentsForHotspots as ab, generateChapters as ac, generateEmbeddings as ad, generateEngagementInsights as ae, generateVideoEmbeddings as af, getModerationScores as ag, getSummaryAndTags as ah, hasBurnedInCaptions as ai, mapShotsToHotspots as aj, normalizeTranslatedVtt as ak, profanityDetectionSchema as al, questionAnswerSchema as am, shouldSplitChunkTranslationError as an, summarySchema as ao, transformCueText as ap, translateAudio as aq, translateCaptions as ar, translationSchema as as, type AskQuestionsType as b, type AudioTranslationOptions as c, type AudioTranslationResult as d, type AutoCensorProfanityOptions as e, type BurnedInCaptionsOptions as f, type BurnedInCaptionsPromptOverrides as g, type BurnedInCaptionsPromptSections as h, index as i, type BurnedInCaptionsResult as j, type CensorMode as k, type Chapter as l, type ChapterSystemPromptSections as m, type ChaptersOptions as n, type ChaptersPromptOverrides as o, type ChaptersPromptSections as p, type ChaptersResult as q, type ChaptersType as r, DEFAULT_SUMMARY_KEYWORD_LIMIT as s, DEFAULT_TITLE_LENGTH as t, type EditCaptionsResult as u, type EmbeddingsOptions as v, type EmbeddingsResult as w, type EngagementInsightsOptions as x, type EngagementInsightsResult as y, HIVE_VIOLENCE_CATEGORIES as z };
1429
+ export { type TranslationPayload as $, type AskQuestionsOptions as A, type BurnedInCaptionsAnalysis as B, type CaptionReplacement as C, DEFAULT_DESCRIPTION_LENGTH as D, type EditCaptionsOptions as E, type HiveModerationOutput as F, GOOGLE_VISION_LIKELIHOOD_TO_SCORE as G, HIVE_SEXUAL_CATEGORIES as H, type HiveModerationSource as I, type ModerationProvider as J, type ModerationResult as K, type MomentInsight as L, type ModerationOptions as M, type QuestionAnswer as N, type OverallInsight as O, type ProfanityDetectionPayload as P, type Question as Q, type QuestionAnswerType as R, type ReplacementRecord as S, type SummarizationOptions as T, type SummarizationPromptOverrides as U, type SummarizationPromptSections as V, type SummaryAndTagsResult as W, type SummaryType as X, type ThumbnailModerationScore as Y, type TranslationChunkingOptions as Z, type TranslationOptions as _, type AskQuestionsResult as a, type TranslationResult as a0, aggregateTokenUsage as a1, applyOverrideLists as a2, applyReplacements as a3, askQuestions as a4, buildReplacementRegex as a5, burnedInCaptionsSchema as a6, censorVttContent as a7, chapterSchema as a8, chaptersSchema as a9, createReplacer as aa, editCaptions as ab, extractTranscriptSegmentsForHotspots as ac, generateChapters as ad, generateEmbeddings as ae, generateEngagementInsights as af, generateVideoEmbeddings as ag, getModerationScores as ah, getSummaryAndTags as ai, hasBurnedInCaptions as aj, mapShotsToHotspots as ak, normalizeTranslatedVtt as al, profanityDetectionSchema as am, questionAnswerSchema as an, shouldSplitChunkTranslationError as ao, summarySchema as ap, transformCueText as aq, translateAudio as ar, translateCaptions as as, translationSchema as at, type AskQuestionsType as b, type AudioTranslationOptions as c, type AudioTranslationResult as d, type AutoCensorProfanityOptions as e, type BurnedInCaptionsOptions as f, type BurnedInCaptionsPromptOverrides as g, type BurnedInCaptionsPromptSections as h, index as i, type BurnedInCaptionsResult as j, type CensorMode as k, type Chapter as l, type ChapterSystemPromptSections as m, type ChaptersOptions as n, type ChaptersPromptOverrides as o, type ChaptersPromptSections as p, type ChaptersResult as q, type ChaptersType as r, DEFAULT_SUMMARY_KEYWORD_LIMIT as s, DEFAULT_TITLE_LENGTH as t, type EditCaptionsResult as u, type EmbeddingsOptions as v, type EmbeddingsResult as w, type EngagementInsightsOptions as x, type EngagementInsightsResult as y, HIVE_VIOLENCE_CATEGORIES as z };
@@ -1,4 +1,4 @@
1
- import { k as WorkflowCredentialsInput, A as AssetTextTrack, d as MuxAsset, T as TextChunk, b as ChunkingStrategy, o as CompletedShotsResult, p as ErroredShotsResult, H as Hotspot, q as HotspotOptions, r as HotspotResponse, s as PendingShotsResult, t as Shot, u as ShotRequestOptions, v as ShotsResult, w as WaitForShotsOptions, x as getHotspotsForAsset, y as getHotspotsForPlaybackId, z as getHotspotsForVideo, B as getShotsForAsset, D as requestShotsForAsset, F as waitForShotsForAsset } from './shots-BFYOfBgN.js';
1
+ import { k as WorkflowCredentialsInput, A as AssetTextTrack, d as MuxAsset, T as TextChunk, b as ChunkingStrategy, o as CompletedShotsResult, p as ErroredShotsResult, H as Hotspot, q as HotspotOptions, r as HotspotResponse, s as PendingShotsResult, t as Shot, u as ShotRequestOptions, v as ShotsResult, w as WaitForShotsOptions, x as getHotspotsForAsset, y as getHotspotsForPlaybackId, z as getHotspotsForVideo, B as getShotsForAsset, D as requestShotsForAsset, F as waitForShotsForAsset } from './shots-mGJfYGiO.js';
2
2
 
3
3
  interface HeatmapOptions {
4
4
  /** Time window for results, e.g., '7:days' (default: '7:days') */
package/dist/index.d.ts CHANGED
@@ -1,15 +1,15 @@
1
- import { W as WorkflowCredentials, S as StoragePutObjectInput, a as StoragePresignGetObjectInput } from './shots-BFYOfBgN.js';
2
- 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 StorageAdapter, T as TextChunk, g as TokenChunkingConfig, h as TokenUsage, i as ToneType, U as UsageMetadata, V as VTTChunkingConfig, j as VideoEmbeddingsResult, k as WorkflowCredentialsInput, l as WorkflowMuxClient, m as decryptFromWorkflow, n as encryptForWorkflow } from './shots-BFYOfBgN.js';
1
+ import { W as WorkflowCredentials, S as StoragePutObjectInput, a as StoragePresignGetObjectInput } from './shots-mGJfYGiO.js';
2
+ 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 StorageAdapter, T as TextChunk, g as TokenChunkingConfig, h as TokenUsage, i as ToneType, U as UsageMetadata, V as VTTChunkingConfig, j as VideoEmbeddingsResult, k as WorkflowCredentialsInput, l as WorkflowMuxClient, m as decryptFromWorkflow, n as encryptForWorkflow } from './shots-mGJfYGiO.js';
3
3
  import { WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from '@workflow/serde';
4
- export { i as primitives } from './index-Drj9Cy_k.js';
5
- export { i as workflows } from './index-DXMIJjUa.js';
4
+ export { i as primitives } from './index-bjQi1ZCj.js';
5
+ export { i as workflows } from './index-DwNtsg-u.js';
6
6
  import '@mux/mux-node';
7
7
  import 'zod';
8
8
  import '@ai-sdk/anthropic';
9
9
  import '@ai-sdk/google';
10
10
  import '@ai-sdk/openai';
11
11
 
12
- var version = "0.20.0";
12
+ var version = "0.21.1";
13
13
 
14
14
  type MuxAiErrorType = "validation_error" | "processing_error" | "timeout_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.20.0";
8
+ var version = "0.21.1";
9
9
 
10
10
  // src/lib/prompt-fragments.ts
11
11
  import dedent from "dedent";
@@ -83,6 +83,7 @@ var EnvSchema = z.object({
83
83
  GOOGLE_GENERATIVE_AI_API_KEY: optionalString("Google Generative AI API key for Gemini-backed workflows.", "Google Generative AI API key"),
84
84
  ELEVENLABS_API_KEY: optionalString("ElevenLabs API key for audio translation.", "ElevenLabs API key"),
85
85
  HIVE_API_KEY: optionalString("Hive Visual Moderation API key.", "Hive API key"),
86
+ GOOGLE_VISION_API_KEY: optionalString("Google Vision API key for SafeSearch moderation.", "Google Vision API key"),
86
87
  // S3-Compatible Storage (required for translation & audio dubbing)
87
88
  S3_ENDPOINT: optionalString("S3-compatible endpoint for uploads.", "S3 endpoint"),
88
89
  S3_REGION: optionalString("S3 region (defaults to 'auto' when omitted)."),
@@ -763,23 +764,26 @@ function resolveProviderApiKeyFromCredentials(provider, resolved) {
763
764
  const openaiApiKey = readString(record, "openaiApiKey");
764
765
  const anthropicApiKey = readString(record, "anthropicApiKey");
765
766
  const googleApiKey = readString(record, "googleApiKey");
767
+ const googleVisionApiKey = readString(record, "googleVisionApiKey");
766
768
  const hiveApiKey = readString(record, "hiveApiKey");
767
769
  const elevenLabsApiKey = readString(record, "elevenLabsApiKey");
768
770
  const apiKeyMap = {
769
- openai: openaiApiKey ?? env_default.OPENAI_API_KEY,
770
- anthropic: anthropicApiKey ?? env_default.ANTHROPIC_API_KEY,
771
- google: googleApiKey ?? env_default.GOOGLE_GENERATIVE_AI_API_KEY,
772
- hive: hiveApiKey ?? env_default.HIVE_API_KEY,
773
- elevenlabs: elevenLabsApiKey ?? env_default.ELEVENLABS_API_KEY
771
+ "openai": openaiApiKey ?? env_default.OPENAI_API_KEY,
772
+ "anthropic": anthropicApiKey ?? env_default.ANTHROPIC_API_KEY,
773
+ "google": googleApiKey ?? env_default.GOOGLE_GENERATIVE_AI_API_KEY,
774
+ "google-vision-api": googleVisionApiKey ?? env_default.GOOGLE_VISION_API_KEY,
775
+ "hive": hiveApiKey ?? env_default.HIVE_API_KEY,
776
+ "elevenlabs": elevenLabsApiKey ?? env_default.ELEVENLABS_API_KEY
774
777
  };
775
778
  const apiKey = apiKeyMap[provider];
776
779
  if (!apiKey) {
777
780
  const envVarNames = {
778
- openai: "OPENAI_API_KEY",
779
- anthropic: "ANTHROPIC_API_KEY",
780
- google: "GOOGLE_GENERATIVE_AI_API_KEY",
781
- hive: "HIVE_API_KEY",
782
- elevenlabs: "ELEVENLABS_API_KEY"
781
+ "openai": "OPENAI_API_KEY",
782
+ "anthropic": "ANTHROPIC_API_KEY",
783
+ "google": "GOOGLE_GENERATIVE_AI_API_KEY",
784
+ "google-vision-api": "GOOGLE_VISION_API_KEY",
785
+ "hive": "HIVE_API_KEY",
786
+ "elevenlabs": "ELEVENLABS_API_KEY"
783
787
  };
784
788
  throw new Error(
785
789
  `${provider} API key is required. Provide ${provider} credentials via workflow credentials or set ${envVarNames[provider]} environment variable.`
@@ -2554,6 +2558,7 @@ __export(workflows_exports, {
2554
2558
  DEFAULT_DESCRIPTION_LENGTH: () => DEFAULT_DESCRIPTION_LENGTH,
2555
2559
  DEFAULT_SUMMARY_KEYWORD_LIMIT: () => DEFAULT_SUMMARY_KEYWORD_LIMIT,
2556
2560
  DEFAULT_TITLE_LENGTH: () => DEFAULT_TITLE_LENGTH,
2561
+ GOOGLE_VISION_LIKELIHOOD_TO_SCORE: () => GOOGLE_VISION_LIKELIHOOD_TO_SCORE,
2557
2562
  HIVE_SEXUAL_CATEGORIES: () => HIVE_SEXUAL_CATEGORIES,
2558
2563
  HIVE_VIOLENCE_CATEGORIES: () => HIVE_VIOLENCE_CATEGORIES,
2559
2564
  aggregateTokenUsage: () => aggregateTokenUsage,
@@ -5174,6 +5179,15 @@ var OPENAI_MODERATION_BASE_DELAY_MS = 750;
5174
5179
  var OPENAI_MODERATION_MAX_DELAY_MS = 3e3;
5175
5180
  var MIN_SAMPLE_COVERAGE_FOR_CONFIDENT_THRESHOLDING = 0.5;
5176
5181
  var MIN_SUCCESSFUL_THUMBNAILS_FOR_CONFIDENT_THRESHOLDING = 3;
5182
+ var GOOGLE_VISION_ENDPOINT = "https://vision.googleapis.com/v1/images:annotate";
5183
+ var GOOGLE_VISION_LIKELIHOOD_TO_SCORE = {
5184
+ UNKNOWN: 0,
5185
+ VERY_UNLIKELY: 0.2,
5186
+ UNLIKELY: 0.4,
5187
+ POSSIBLE: 0.6,
5188
+ LIKELY: 0.8,
5189
+ VERY_LIKELY: 1
5190
+ };
5177
5191
  var HIVE_ENDPOINT = "https://api.thehive.ai/api/v2/task/sync";
5178
5192
  var HIVE_SEXUAL_CATEGORIES = [
5179
5193
  "general_nsfw",
@@ -5502,6 +5516,98 @@ async function requestHiveModeration(images, maxConcurrent = 5, submissionMode =
5502
5516
  }));
5503
5517
  return await processConcurrently(targets, moderateImageWithHive, maxConcurrent);
5504
5518
  }
5519
+ async function moderateImageWithGoogleVision(entry) {
5520
+ "use step";
5521
+ try {
5522
+ const apiKey = await getApiKeyFromEnv("google-vision-api", entry.credentials);
5523
+ const imageField = entry.isBase64 ? { content: entry.image } : { source: { imageUri: entry.image } };
5524
+ const controller = new AbortController();
5525
+ const timeout = setTimeout(() => controller.abort(), 15e3);
5526
+ let res;
5527
+ try {
5528
+ res = await fetch(GOOGLE_VISION_ENDPOINT, {
5529
+ method: "POST",
5530
+ headers: {
5531
+ "Accept": "application/json",
5532
+ "Content-Type": "application/json",
5533
+ "X-goog-api-key": apiKey
5534
+ },
5535
+ body: JSON.stringify({
5536
+ requests: [
5537
+ {
5538
+ image: imageField,
5539
+ features: [{ type: "SAFE_SEARCH_DETECTION" }]
5540
+ }
5541
+ ]
5542
+ }),
5543
+ signal: controller.signal
5544
+ });
5545
+ } catch (err) {
5546
+ if (err?.name === "AbortError") {
5547
+ throw new Error("Google Vision request timed out after 15s");
5548
+ }
5549
+ throw err;
5550
+ } finally {
5551
+ clearTimeout(timeout);
5552
+ }
5553
+ const json = await res.json().catch(() => void 0);
5554
+ if (!res.ok) {
5555
+ throw new Error(
5556
+ `Google Vision moderation error: ${res.status} ${res.statusText} - ${JSON.stringify(json)}`
5557
+ );
5558
+ }
5559
+ const perImage = json?.responses?.[0];
5560
+ if (perImage?.error) {
5561
+ throw new Error(
5562
+ `Google Vision per-image error: ${perImage.error.code} ${perImage.error.message || "Unknown error"}`
5563
+ );
5564
+ }
5565
+ const annotation = perImage?.safeSearchAnnotation;
5566
+ if (!annotation) {
5567
+ throw new Error(`Google Vision response missing safeSearchAnnotation: ${JSON.stringify(json)}`);
5568
+ }
5569
+ const adultLikelihood = typeof annotation.adult === "string" ? annotation.adult : "UNKNOWN";
5570
+ const violenceLikelihood = typeof annotation.violence === "string" ? annotation.violence : "UNKNOWN";
5571
+ const sexual = GOOGLE_VISION_LIKELIHOOD_TO_SCORE[adultLikelihood] ?? 0;
5572
+ const violence = GOOGLE_VISION_LIKELIHOOD_TO_SCORE[violenceLikelihood] ?? 0;
5573
+ return {
5574
+ url: entry.url,
5575
+ time: entry.time,
5576
+ sexual,
5577
+ violence,
5578
+ error: false
5579
+ };
5580
+ } catch (error) {
5581
+ return {
5582
+ url: entry.url,
5583
+ time: entry.time,
5584
+ sexual: 0,
5585
+ violence: 0,
5586
+ error: true,
5587
+ errorMessage: error instanceof Error ? error.message : String(error)
5588
+ };
5589
+ }
5590
+ }
5591
+ async function requestGoogleVisionModeration(images, maxConcurrent = 5, submissionMode = "url", downloadOptions, credentials) {
5592
+ "use step";
5593
+ const imageUrls = images.map((img) => img.url);
5594
+ const timeByUrl = new Map(images.map((img) => [img.url, img.time]));
5595
+ const targets = submissionMode === "base64" ? (await downloadImagesAsBase64(imageUrls, downloadOptions, maxConcurrent)).map((img) => ({
5596
+ url: img.url,
5597
+ time: timeByUrl.get(img.url),
5598
+ // Vision REST wants raw base64; downloadImagesAsBase64 returns a data URI.
5599
+ image: img.base64Data.startsWith("data:") ? img.base64Data.split(",")[1] : img.base64Data,
5600
+ isBase64: true,
5601
+ credentials
5602
+ })) : images.map((img) => ({
5603
+ url: img.url,
5604
+ time: img.time,
5605
+ image: img.url,
5606
+ isBase64: false,
5607
+ credentials
5608
+ }));
5609
+ return processConcurrently(targets, moderateImageWithGoogleVision, maxConcurrent);
5610
+ }
5505
5611
  async function getThumbnailUrlsFromTimestamps(playbackId, timestampsMs, options) {
5506
5612
  "use step";
5507
5613
  const { width, shouldSign, credentials } = options;
@@ -5565,8 +5671,11 @@ async function getModerationScores(assetId, options = {}) {
5565
5671
  );
5566
5672
  } else if (provider === "hive") {
5567
5673
  throw new Error("Hive does not support transcript moderation in this workflow. Use provider: 'openai' for audio-only assets.");
5674
+ } else if (provider === "google-vision-api") {
5675
+ throw new Error("google-vision-api is image-only and does not support transcript moderation. Use provider: 'openai' for audio-only assets.");
5568
5676
  } else {
5569
- throw new Error(`Unsupported moderation provider: ${provider}`);
5677
+ const exhaustiveCheck = provider;
5678
+ throw new Error(`Unsupported moderation provider: ${exhaustiveCheck}`);
5570
5679
  }
5571
5680
  } else {
5572
5681
  const estimatedIntervalCount = duration <= 50 ? 5 : Math.ceil(duration / thumbnailInterval);
@@ -5609,8 +5718,17 @@ async function getModerationScores(assetId, options = {}) {
5609
5718
  imageDownloadOptions,
5610
5719
  credentials
5611
5720
  );
5721
+ } else if (provider === "google-vision-api") {
5722
+ thumbnailScores = await requestGoogleVisionModeration(
5723
+ thumbnailUrls,
5724
+ maxConcurrent,
5725
+ imageSubmissionMode,
5726
+ imageDownloadOptions,
5727
+ credentials
5728
+ );
5612
5729
  } else {
5613
- throw new Error(`Unsupported moderation provider: ${provider}`);
5730
+ const exhaustiveCheck = provider;
5731
+ throw new Error(`Unsupported moderation provider: ${exhaustiveCheck}`);
5614
5732
  }
5615
5733
  }
5616
5734
  const failed = thumbnailScores.filter((s) => s.error);