vidspotai-shared 1.0.68 → 1.0.69-dev.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/lib/globals/aiModels/enums.d.ts +63 -6
- package/lib/globals/aiModels/enums.d.ts.map +1 -1
- package/lib/globals/aiModels/enums.js +78 -9
- package/lib/globals/aiModels/index.d.ts +2 -30
- package/lib/globals/aiModels/index.d.ts.map +1 -1
- package/lib/globals/aiModels/index.js +7 -35
- package/lib/globals/aiModels/providers/alibaba.d.ts +4 -0
- package/lib/globals/aiModels/providers/alibaba.d.ts.map +1 -0
- package/lib/globals/aiModels/providers/alibaba.js +194 -0
- package/lib/globals/aiModels/providers/bytedance.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/bytedance.js +19 -0
- package/lib/globals/aiModels/providers/elevenlabs.d.ts +14 -0
- package/lib/globals/aiModels/providers/elevenlabs.d.ts.map +1 -0
- package/lib/globals/aiModels/providers/elevenlabs.js +29 -0
- package/lib/globals/aiModels/providers/google.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/google.js +150 -2
- package/lib/globals/aiModels/providers/kling.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/kling.js +280 -37
- package/lib/globals/aiModels/providers/minimax.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/minimax.js +76 -11
- package/lib/globals/aiModels/providers/openai.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/openai.js +90 -6
- package/lib/globals/aiModels/providers/pixverse.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/pixverse.js +111 -29
- package/lib/globals/aiModels/providers/pixverseTemplates.d.ts +36 -0
- package/lib/globals/aiModels/providers/pixverseTemplates.d.ts.map +1 -0
- package/lib/globals/aiModels/providers/pixverseTemplates.js +42 -0
- package/lib/globals/aiModels/providers/runway.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/runway.js +64 -2
- package/lib/globals/aiModels/tierHelpers.d.ts +33 -0
- package/lib/globals/aiModels/tierHelpers.d.ts.map +1 -0
- package/lib/globals/aiModels/tierHelpers.js +109 -0
- package/lib/globals/aiModels/types.d.ts +20 -1
- package/lib/globals/aiModels/types.d.ts.map +1 -1
- package/lib/globals/ttsModels/index.d.ts +2 -0
- package/lib/globals/ttsModels/index.d.ts.map +1 -1
- package/lib/globals/ttsModels/index.js +9 -1
- package/lib/globals/ttsModels/providers/minimax.d.ts +8 -0
- package/lib/globals/ttsModels/providers/minimax.d.ts.map +1 -0
- package/lib/globals/ttsModels/providers/minimax.js +18 -0
- package/lib/globals/ttsModels/providers/openai.d.ts +12 -0
- package/lib/globals/ttsModels/providers/openai.d.ts.map +1 -0
- package/lib/globals/ttsModels/providers/openai.js +22 -0
- package/lib/globals/ttsModels/types.d.ts +1 -1
- package/lib/globals/ttsModels/types.d.ts.map +1 -1
- package/lib/globals/ttsModels/voices.d.ts +39 -4
- package/lib/globals/ttsModels/voices.d.ts.map +1 -1
- package/lib/globals/ttsModels/voices.js +273 -26
- package/lib/globals/types.d.ts +59 -1
- package/lib/globals/types.d.ts.map +1 -1
- package/lib/globals/types.js +81 -2
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/models/agent.model.d.ts +357 -0
- package/lib/models/agent.model.d.ts.map +1 -0
- package/lib/models/agent.model.js +21 -0
- package/lib/models/cachedAsset.model.d.ts +18 -0
- package/lib/models/cachedAsset.model.d.ts.map +1 -0
- package/lib/models/cachedAsset.model.js +2 -0
- package/lib/models/cachedRawAsset.model.d.ts +20 -0
- package/lib/models/cachedRawAsset.model.d.ts.map +1 -0
- package/lib/models/cachedRawAsset.model.js +2 -0
- package/lib/models/image.model.d.ts +47 -0
- package/lib/models/image.model.d.ts.map +1 -0
- package/lib/models/image.model.js +2 -0
- package/lib/models/index.d.ts +6 -0
- package/lib/models/index.d.ts.map +1 -1
- package/lib/models/index.js +6 -0
- package/lib/models/notification.model.d.ts +25 -0
- package/lib/models/notification.model.d.ts.map +1 -0
- package/lib/models/notification.model.js +2 -0
- package/lib/models/ref.model.d.ts +80 -0
- package/lib/models/ref.model.d.ts.map +1 -0
- package/lib/models/ref.model.js +13 -0
- package/lib/models/share.model.d.ts +29 -0
- package/lib/models/share.model.d.ts.map +1 -0
- package/lib/models/share.model.js +2 -0
- package/lib/models/user.model.d.ts +12 -1
- package/lib/models/user.model.d.ts.map +1 -1
- package/lib/models/video.model.d.ts +120 -8
- package/lib/models/video.model.d.ts.map +1 -1
- package/lib/models/video.model.js +10 -0
- package/lib/schemas/agentPersona.schema.d.ts +10 -0
- package/lib/schemas/agentPersona.schema.d.ts.map +1 -0
- package/lib/schemas/agentPersona.schema.js +11 -0
- package/lib/schemas/agentRunJob.schema.d.ts +105 -0
- package/lib/schemas/agentRunJob.schema.d.ts.map +1 -0
- package/lib/schemas/agentRunJob.schema.js +88 -0
- package/lib/schemas/brandKit.schema.d.ts +113 -0
- package/lib/schemas/brandKit.schema.d.ts.map +1 -0
- package/lib/schemas/brandKit.schema.js +46 -0
- package/lib/schemas/brief.schema.d.ts +263 -0
- package/lib/schemas/brief.schema.d.ts.map +1 -0
- package/lib/schemas/brief.schema.js +157 -0
- package/lib/schemas/index.d.ts +7 -0
- package/lib/schemas/index.d.ts.map +1 -0
- package/lib/schemas/index.js +22 -0
- package/lib/schemas/project.schema.d.ts +1025 -0
- package/lib/schemas/project.schema.d.ts.map +1 -0
- package/lib/schemas/project.schema.js +256 -0
- package/lib/schemas/videoPlan.schema.d.ts +590 -0
- package/lib/schemas/videoPlan.schema.d.ts.map +1 -0
- package/lib/schemas/videoPlan.schema.js +412 -0
- package/lib/services/agent/beatSnap.d.ts +10 -0
- package/lib/services/agent/beatSnap.d.ts.map +1 -0
- package/lib/services/agent/beatSnap.js +128 -0
- package/lib/services/agent/bibleBuilder.d.ts +43 -0
- package/lib/services/agent/bibleBuilder.d.ts.map +1 -0
- package/lib/services/agent/bibleBuilder.js +102 -0
- package/lib/services/agent/bibleImageVision.d.ts +45 -0
- package/lib/services/agent/bibleImageVision.d.ts.map +1 -0
- package/lib/services/agent/bibleImageVision.js +169 -0
- package/lib/services/agent/chatAgent.d.ts +79 -0
- package/lib/services/agent/chatAgent.d.ts.map +1 -0
- package/lib/services/agent/chatAgent.js +136 -0
- package/lib/services/agent/costPreflight.d.ts +61 -0
- package/lib/services/agent/costPreflight.d.ts.map +1 -0
- package/lib/services/agent/costPreflight.js +143 -0
- package/lib/services/agent/critic.d.ts +103 -0
- package/lib/services/agent/critic.d.ts.map +1 -0
- package/lib/services/agent/critic.js +139 -0
- package/lib/services/agent/editClassifier.d.ts +262 -0
- package/lib/services/agent/editClassifier.d.ts.map +1 -0
- package/lib/services/agent/editClassifier.js +186 -0
- package/lib/services/agent/eval/index.d.ts +5 -0
- package/lib/services/agent/eval/index.d.ts.map +1 -0
- package/lib/services/agent/eval/index.js +20 -0
- package/lib/services/agent/eval/judge.d.ts +14 -0
- package/lib/services/agent/eval/judge.d.ts.map +1 -0
- package/lib/services/agent/eval/judge.js +96 -0
- package/lib/services/agent/eval/recorder.d.ts +28 -0
- package/lib/services/agent/eval/recorder.d.ts.map +1 -0
- package/lib/services/agent/eval/recorder.js +100 -0
- package/lib/services/agent/eval/seedBriefs.d.ts +16 -0
- package/lib/services/agent/eval/seedBriefs.d.ts.map +1 -0
- package/lib/services/agent/eval/seedBriefs.js +1188 -0
- package/lib/services/agent/eval/types.d.ts +230 -0
- package/lib/services/agent/eval/types.d.ts.map +1 -0
- package/lib/services/agent/eval/types.js +73 -0
- package/lib/services/agent/executor.d.ts +141 -0
- package/lib/services/agent/executor.d.ts.map +1 -0
- package/lib/services/agent/executor.js +561 -0
- package/lib/services/agent/globalActions.d.ts +49 -0
- package/lib/services/agent/globalActions.d.ts.map +1 -0
- package/lib/services/agent/globalActions.js +328 -0
- package/lib/services/agent/index.d.ts +38 -0
- package/lib/services/agent/index.d.ts.map +1 -0
- package/lib/services/agent/index.js +53 -0
- package/lib/services/agent/llmCaller.d.ts +144 -0
- package/lib/services/agent/llmCaller.d.ts.map +1 -0
- package/lib/services/agent/llmCaller.js +16 -0
- package/lib/services/agent/llmCallerAnthropic.d.ts +90 -0
- package/lib/services/agent/llmCallerAnthropic.d.ts.map +1 -0
- package/lib/services/agent/llmCallerAnthropic.js +255 -0
- package/lib/services/agent/llmCallerGateway.d.ts +61 -0
- package/lib/services/agent/llmCallerGateway.d.ts.map +1 -0
- package/lib/services/agent/llmCallerGateway.js +360 -0
- package/lib/services/agent/llmCallerRegistry.d.ts +6 -0
- package/lib/services/agent/llmCallerRegistry.d.ts.map +1 -0
- package/lib/services/agent/llmCallerRegistry.js +39 -0
- package/lib/services/agent/modelQualityNotes.d.ts +100 -0
- package/lib/services/agent/modelQualityNotes.d.ts.map +1 -0
- package/lib/services/agent/modelQualityNotes.js +248 -0
- package/lib/services/agent/modelRouter.d.ts +41 -0
- package/lib/services/agent/modelRouter.d.ts.map +1 -0
- package/lib/services/agent/modelRouter.js +65 -0
- package/lib/services/agent/musicSelect.d.ts +23 -0
- package/lib/services/agent/musicSelect.d.ts.map +1 -0
- package/lib/services/agent/musicSelect.js +109 -0
- package/lib/services/agent/overlayRenderer.d.ts +67 -0
- package/lib/services/agent/overlayRenderer.d.ts.map +1 -0
- package/lib/services/agent/overlayRenderer.js +253 -0
- package/lib/services/agent/perSceneCritic.d.ts +90 -0
- package/lib/services/agent/perSceneCritic.d.ts.map +1 -0
- package/lib/services/agent/perSceneCritic.js +125 -0
- package/lib/services/agent/personas.d.ts +78 -0
- package/lib/services/agent/personas.d.ts.map +1 -0
- package/lib/services/agent/personas.js +177 -0
- package/lib/services/agent/planDiff.d.ts +76 -0
- package/lib/services/agent/planDiff.d.ts.map +1 -0
- package/lib/services/agent/planDiff.js +182 -0
- package/lib/services/agent/planMutations.d.ts +46 -0
- package/lib/services/agent/planMutations.d.ts.map +1 -0
- package/lib/services/agent/planMutations.js +120 -0
- package/lib/services/agent/planner/Planner.d.ts +107 -0
- package/lib/services/agent/planner/Planner.d.ts.map +1 -0
- package/lib/services/agent/planner/Planner.js +591 -0
- package/lib/services/agent/planner/overlaySanity.d.ts +7 -0
- package/lib/services/agent/planner/overlaySanity.d.ts.map +1 -0
- package/lib/services/agent/planner/overlaySanity.js +86 -0
- package/lib/services/agent/planner/promptSections.d.ts +25 -0
- package/lib/services/agent/planner/promptSections.d.ts.map +1 -0
- package/lib/services/agent/planner/promptSections.js +174 -0
- package/lib/services/agent/planner/repair.d.ts +16 -0
- package/lib/services/agent/planner/repair.d.ts.map +1 -0
- package/lib/services/agent/planner/repair.js +51 -0
- package/lib/services/agent/planner/structuralRules.d.ts +10 -0
- package/lib/services/agent/planner/structuralRules.d.ts.map +1 -0
- package/lib/services/agent/planner/structuralRules.js +111 -0
- package/lib/services/agent/planner/validators.d.ts +65 -0
- package/lib/services/agent/planner/validators.d.ts.map +1 -0
- package/lib/services/agent/planner/validators.js +284 -0
- package/lib/services/agent/planner.d.ts +3 -0
- package/lib/services/agent/planner.d.ts.map +1 -0
- package/lib/services/agent/planner.js +14 -0
- package/lib/services/agent/providerFallback/chains.d.ts +100 -0
- package/lib/services/agent/providerFallback/chains.d.ts.map +1 -0
- package/lib/services/agent/providerFallback/chains.js +198 -0
- package/lib/services/agent/providerFallback/classifier.d.ts +36 -0
- package/lib/services/agent/providerFallback/classifier.d.ts.map +1 -0
- package/lib/services/agent/providerFallback/classifier.js +103 -0
- package/lib/services/agent/providerFallback/index.d.ts +4 -0
- package/lib/services/agent/providerFallback/index.d.ts.map +1 -0
- package/lib/services/agent/providerFallback/index.js +19 -0
- package/lib/services/agent/providerFallback/withFallback.d.ts +60 -0
- package/lib/services/agent/providerFallback/withFallback.d.ts.map +1 -0
- package/lib/services/agent/providerFallback/withFallback.js +93 -0
- package/lib/services/agent/providerTaskCache.d.ts +50 -0
- package/lib/services/agent/providerTaskCache.d.ts.map +1 -0
- package/lib/services/agent/providerTaskCache.js +98 -0
- package/lib/services/agent/qualityGate.d.ts +82 -0
- package/lib/services/agent/qualityGate.d.ts.map +1 -0
- package/lib/services/agent/qualityGate.js +232 -0
- package/lib/services/agent/referenceImageRenderer.d.ts +37 -0
- package/lib/services/agent/referenceImageRenderer.d.ts.map +1 -0
- package/lib/services/agent/referenceImageRenderer.js +92 -0
- package/lib/services/agent/regenCore.d.ts +60 -0
- package/lib/services/agent/regenCore.d.ts.map +1 -0
- package/lib/services/agent/regenCore.js +487 -0
- package/lib/services/agent/runHelpers.d.ts +44 -0
- package/lib/services/agent/runHelpers.d.ts.map +1 -0
- package/lib/services/agent/runHelpers.js +196 -0
- package/lib/services/agent/sceneLayoutVision.d.ts +90 -0
- package/lib/services/agent/sceneLayoutVision.d.ts.map +1 -0
- package/lib/services/agent/sceneLayoutVision.js +212 -0
- package/lib/services/agent/stitchedVideoCritic.d.ts +136 -0
- package/lib/services/agent/stitchedVideoCritic.d.ts.map +1 -0
- package/lib/services/agent/stitchedVideoCritic.gemini.d.ts +26 -0
- package/lib/services/agent/stitchedVideoCritic.gemini.d.ts.map +1 -0
- package/lib/services/agent/stitchedVideoCritic.gemini.js +198 -0
- package/lib/services/agent/stitchedVideoCritic.js +162 -0
- package/lib/services/agent/taskPoller.d.ts +65 -0
- package/lib/services/agent/taskPoller.d.ts.map +1 -0
- package/lib/services/agent/taskPoller.js +176 -0
- package/lib/services/agent/textOverlayStyles.d.ts +60 -0
- package/lib/services/agent/textOverlayStyles.d.ts.map +1 -0
- package/lib/services/agent/textOverlayStyles.js +174 -0
- package/lib/services/agent/toolRegistry.d.ts +73 -0
- package/lib/services/agent/toolRegistry.d.ts.map +1 -0
- package/lib/services/agent/toolRegistry.js +95 -0
- package/lib/services/agent/tools/analyzeReference.tool.d.ts +36 -0
- package/lib/services/agent/tools/analyzeReference.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/analyzeReference.tool.js +44 -0
- package/lib/services/agent/tools/animateImage.tool.d.ts +24 -0
- package/lib/services/agent/tools/animateImage.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/animateImage.tool.js +115 -0
- package/lib/services/agent/tools/animateImageWithMotionBrush.tool.d.ts +32 -0
- package/lib/services/agent/tools/animateImageWithMotionBrush.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/animateImageWithMotionBrush.tool.js +135 -0
- package/lib/services/agent/tools/composeScene.tool.d.ts +978 -0
- package/lib/services/agent/tools/composeScene.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/composeScene.tool.js +90 -0
- package/lib/services/agent/tools/estimateCost.tool.d.ts +352 -0
- package/lib/services/agent/tools/estimateCost.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/estimateCost.tool.js +62 -0
- package/lib/services/agent/tools/generateAvatarVideo.tool.d.ts +32 -0
- package/lib/services/agent/tools/generateAvatarVideo.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/generateAvatarVideo.tool.js +143 -0
- package/lib/services/agent/tools/generateCaptions.tool.d.ts +42 -0
- package/lib/services/agent/tools/generateCaptions.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/generateCaptions.tool.js +196 -0
- package/lib/services/agent/tools/generateImage.tool.d.ts +74 -0
- package/lib/services/agent/tools/generateImage.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/generateImage.tool.js +206 -0
- package/lib/services/agent/tools/generateVideo.tool.d.ts +31 -0
- package/lib/services/agent/tools/generateVideo.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/generateVideo.tool.js +153 -0
- package/lib/services/agent/tools/generateVoiceover.tool.d.ts +44 -0
- package/lib/services/agent/tools/generateVoiceover.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/generateVoiceover.tool.js +206 -0
- package/lib/services/agent/tools/index.d.ts +20 -0
- package/lib/services/agent/tools/index.d.ts.map +1 -0
- package/lib/services/agent/tools/index.js +35 -0
- package/lib/services/agent/tools/planVideo.tool.d.ts +343 -0
- package/lib/services/agent/tools/planVideo.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/planVideo.tool.js +46 -0
- package/lib/services/agent/tools/render.tool.d.ts +367 -0
- package/lib/services/agent/tools/render.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/render.tool.js +48 -0
- package/lib/services/agent/tools/searchMusic.tool.d.ts +49 -0
- package/lib/services/agent/tools/searchMusic.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/searchMusic.tool.js +74 -0
- package/lib/services/agent/tools/searchStock.tool.d.ts +41 -0
- package/lib/services/agent/tools/searchStock.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/searchStock.tool.js +314 -0
- package/lib/services/agent/tools/searchUserLibrary.tool.d.ts +59 -0
- package/lib/services/agent/tools/searchUserLibrary.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/searchUserLibrary.tool.js +58 -0
- package/lib/services/agent/ttsDuration.d.ts +29 -0
- package/lib/services/agent/ttsDuration.d.ts.map +1 -0
- package/lib/services/agent/ttsDuration.js +60 -0
- package/lib/services/aiGen/aiGenFactory.service.d.ts +21 -1
- package/lib/services/aiGen/aiGenFactory.service.d.ts.map +1 -1
- package/lib/services/aiGen/aiGenFactory.service.js +84 -21
- package/lib/services/aiGen/canonicalAdapters/cameraControl.types.d.ts +31 -0
- package/lib/services/aiGen/canonicalAdapters/cameraControl.types.d.ts.map +1 -0
- package/lib/services/aiGen/canonicalAdapters/cameraControl.types.js +2 -0
- package/lib/services/aiGen/canonicalAdapters/index.d.ts +3 -0
- package/lib/services/aiGen/canonicalAdapters/index.d.ts.map +1 -0
- package/lib/services/aiGen/canonicalAdapters/index.js +18 -0
- package/lib/services/aiGen/canonicalAdapters/multiShot.types.d.ts +23 -0
- package/lib/services/aiGen/canonicalAdapters/multiShot.types.d.ts.map +1 -0
- package/lib/services/aiGen/canonicalAdapters/multiShot.types.js +12 -0
- package/lib/services/aiGen/helpers.d.ts.map +1 -1
- package/lib/services/aiGen/helpers.js +10 -0
- package/lib/services/aiGen/providers/alibaba/alibaba.d.ts +14 -3
- package/lib/services/aiGen/providers/alibaba/alibaba.d.ts.map +1 -1
- package/lib/services/aiGen/providers/alibaba/alibaba.js +155 -22
- package/lib/services/aiGen/providers/baseAiGenProvider.service.d.ts +22 -4
- package/lib/services/aiGen/providers/baseAiGenProvider.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/baseAiGenProvider.service.js +32 -0
- package/lib/services/aiGen/providers/bytedance/bytedance.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/bytedance/bytedance.service.js +13 -19
- package/lib/services/aiGen/providers/elevenlabs/elevenlabs.service.d.ts +18 -0
- package/lib/services/aiGen/providers/elevenlabs/elevenlabs.service.d.ts.map +1 -0
- package/lib/services/aiGen/providers/elevenlabs/elevenlabs.service.js +102 -0
- package/lib/services/aiGen/providers/fal/falImage.service.d.ts +15 -0
- package/lib/services/aiGen/providers/fal/falImage.service.d.ts.map +1 -0
- package/lib/services/aiGen/providers/fal/falImage.service.js +141 -0
- package/lib/services/aiGen/providers/fal/index.d.ts +2 -0
- package/lib/services/aiGen/providers/fal/index.d.ts.map +1 -0
- package/lib/services/aiGen/providers/fal/index.js +17 -0
- package/lib/services/aiGen/providers/google/google.service.d.ts +11 -2
- package/lib/services/aiGen/providers/google/google.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/google/google.service.js +245 -28
- package/lib/services/aiGen/providers/index.d.ts +3 -0
- package/lib/services/aiGen/providers/index.d.ts.map +1 -1
- package/lib/services/aiGen/providers/index.js +3 -0
- package/lib/services/aiGen/providers/kling/cameraAdapter.d.ts +4 -0
- package/lib/services/aiGen/providers/kling/cameraAdapter.d.ts.map +1 -0
- package/lib/services/aiGen/providers/kling/cameraAdapter.js +53 -0
- package/lib/services/aiGen/providers/kling/index.d.ts +1 -0
- package/lib/services/aiGen/providers/kling/index.d.ts.map +1 -1
- package/lib/services/aiGen/providers/kling/index.js +1 -0
- package/lib/services/aiGen/providers/kling/kling.service.d.ts +12 -1
- package/lib/services/aiGen/providers/kling/kling.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/kling/kling.service.js +357 -26
- package/lib/services/aiGen/providers/kling/klingImage.service.d.ts +21 -0
- package/lib/services/aiGen/providers/kling/klingImage.service.d.ts.map +1 -0
- package/lib/services/aiGen/providers/kling/klingImage.service.js +208 -0
- package/lib/services/aiGen/providers/kling/types.d.ts +105 -0
- package/lib/services/aiGen/providers/kling/types.d.ts.map +1 -1
- package/lib/services/aiGen/providers/minimax/minimax.service.d.ts +15 -2
- package/lib/services/aiGen/providers/minimax/minimax.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/minimax/minimax.service.js +128 -5
- package/lib/services/aiGen/providers/minimax/types.d.ts +10 -1
- package/lib/services/aiGen/providers/minimax/types.d.ts.map +1 -1
- package/lib/services/aiGen/providers/openai/openai.service.d.ts +8 -2
- package/lib/services/aiGen/providers/openai/openai.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/openai/openai.service.js +184 -7
- package/lib/services/aiGen/providers/pexels/index.d.ts +2 -0
- package/lib/services/aiGen/providers/pexels/index.d.ts.map +1 -0
- package/lib/services/aiGen/providers/{azure → pexels}/index.js +1 -1
- package/lib/services/aiGen/providers/pexels/pexels.service.d.ts +11 -0
- package/lib/services/aiGen/providers/pexels/pexels.service.d.ts.map +1 -0
- package/lib/services/aiGen/providers/pexels/pexels.service.js +150 -0
- package/lib/services/aiGen/providers/pixabay/index.d.ts +2 -0
- package/lib/services/aiGen/providers/pixabay/index.d.ts.map +1 -0
- package/lib/services/aiGen/providers/pixabay/index.js +17 -0
- package/lib/services/aiGen/providers/pixabay/pixabay.service.d.ts +12 -0
- package/lib/services/aiGen/providers/pixabay/pixabay.service.d.ts.map +1 -0
- package/lib/services/aiGen/providers/pixabay/pixabay.service.js +156 -0
- package/lib/services/aiGen/providers/pixverse/pixverse.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/pixverse/pixverse.service.js +125 -2
- package/lib/services/aiGen/providers/runway/cameraAdapter.d.ts +3 -0
- package/lib/services/aiGen/providers/runway/cameraAdapter.d.ts.map +1 -0
- package/lib/services/aiGen/providers/runway/cameraAdapter.js +46 -0
- package/lib/services/aiGen/providers/runway/runway.service.d.ts +12 -2
- package/lib/services/aiGen/providers/runway/runway.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/runway/runway.service.js +224 -21
- package/lib/services/aiGen/providers/types.d.ts +263 -6
- package/lib/services/aiGen/providers/types.d.ts.map +1 -1
- package/lib/services/aiGen/providers/unsplash/index.d.ts +2 -0
- package/lib/services/aiGen/providers/unsplash/index.d.ts.map +1 -0
- package/lib/services/aiGen/providers/unsplash/index.js +17 -0
- package/lib/services/aiGen/providers/unsplash/unsplash.service.d.ts +16 -0
- package/lib/services/aiGen/providers/unsplash/unsplash.service.d.ts.map +1 -0
- package/lib/services/aiGen/providers/unsplash/unsplash.service.js +131 -0
- package/lib/services/analytics.service.js +2 -4
- package/lib/services/apiUsageCounter.service.d.ts +20 -0
- package/lib/services/apiUsageCounter.service.d.ts.map +1 -0
- package/lib/services/apiUsageCounter.service.js +84 -0
- package/lib/services/asr/assemblyai.service.d.ts +72 -0
- package/lib/services/asr/assemblyai.service.d.ts.map +1 -0
- package/lib/services/asr/assemblyai.service.js +89 -0
- package/lib/services/asr/index.d.ts +3 -0
- package/lib/services/asr/index.d.ts.map +1 -0
- package/lib/services/asr/index.js +18 -0
- package/lib/services/asr/whisper.service.d.ts +18 -0
- package/lib/services/asr/whisper.service.d.ts.map +1 -0
- package/lib/services/asr/whisper.service.js +151 -0
- package/lib/services/assetCache.service.d.ts +54 -0
- package/lib/services/assetCache.service.d.ts.map +1 -0
- package/lib/services/assetCache.service.js +109 -0
- package/lib/services/audioAnalysis/index.d.ts +2 -0
- package/lib/services/audioAnalysis/index.d.ts.map +1 -0
- package/lib/services/audioAnalysis/index.js +17 -0
- package/lib/services/audioAnalysis/onsetDetection.service.d.ts +50 -0
- package/lib/services/audioAnalysis/onsetDetection.service.d.ts.map +1 -0
- package/lib/services/audioAnalysis/onsetDetection.service.js +140 -0
- package/lib/services/bullmq.service.d.ts +6 -1
- package/lib/services/bullmq.service.d.ts.map +1 -1
- package/lib/services/bullmq.service.js +62 -14
- package/lib/services/credit.service.d.ts.map +1 -1
- package/lib/services/credit.service.js +45 -7
- package/lib/services/credits/pricing.d.ts +58 -0
- package/lib/services/credits/pricing.d.ts.map +1 -0
- package/lib/services/credits/pricing.js +111 -0
- package/lib/services/editor/designToProject.d.ts +75 -0
- package/lib/services/editor/designToProject.d.ts.map +1 -0
- package/lib/services/editor/designToProject.js +295 -0
- package/lib/services/editor/planToProject.d.ts +84 -0
- package/lib/services/editor/planToProject.d.ts.map +1 -0
- package/lib/services/editor/planToProject.js +395 -0
- package/lib/services/editor/projectToDesign.d.ts +4 -0
- package/lib/services/editor/projectToDesign.d.ts.map +1 -0
- package/lib/services/editor/projectToDesign.js +186 -0
- package/lib/services/firestore.service.d.ts +17 -0
- package/lib/services/firestore.service.d.ts.map +1 -1
- package/lib/services/firestore.service.js +30 -0
- package/lib/services/gcp/index.d.ts +1 -0
- package/lib/services/gcp/index.d.ts.map +1 -1
- package/lib/services/gcp/index.js +1 -0
- package/lib/services/gcp/uploadAudioBuffer.d.ts +13 -0
- package/lib/services/gcp/uploadAudioBuffer.d.ts.map +1 -0
- package/lib/services/gcp/uploadAudioBuffer.js +28 -0
- package/lib/services/index.d.ts +13 -0
- package/lib/services/index.d.ts.map +1 -1
- package/lib/services/index.js +13 -0
- package/lib/services/musicGen/index.d.ts +6 -0
- package/lib/services/musicGen/index.d.ts.map +1 -0
- package/lib/services/musicGen/index.js +26 -0
- package/lib/services/musicGen/musicSearchFactory.service.d.ts +14 -0
- package/lib/services/musicGen/musicSearchFactory.service.d.ts.map +1 -0
- package/lib/services/musicGen/musicSearchFactory.service.js +59 -0
- package/lib/services/musicGen/providers/curated.service.d.ts +24 -0
- package/lib/services/musicGen/providers/curated.service.d.ts.map +1 -0
- package/lib/services/musicGen/providers/curated.service.js +173 -0
- package/lib/services/musicGen/providers/jamendo.service.d.ts +8 -0
- package/lib/services/musicGen/providers/jamendo.service.d.ts.map +1 -0
- package/lib/services/musicGen/providers/jamendo.service.js +113 -0
- package/lib/services/musicGen/providers/mubert.service.d.ts +10 -0
- package/lib/services/musicGen/providers/mubert.service.d.ts.map +1 -0
- package/lib/services/musicGen/providers/mubert.service.js +128 -0
- package/lib/services/musicGen/types.d.ts +46 -0
- package/lib/services/musicGen/types.d.ts.map +1 -0
- package/lib/services/musicGen/types.js +10 -0
- package/lib/services/notification.service.d.ts +22 -0
- package/lib/services/notification.service.d.ts.map +1 -0
- package/lib/services/notification.service.js +76 -0
- package/lib/services/rateLimiter/distributedRateLimiter.service.d.ts +78 -0
- package/lib/services/rateLimiter/distributedRateLimiter.service.d.ts.map +1 -0
- package/lib/services/rateLimiter/distributedRateLimiter.service.js +269 -0
- package/lib/services/rateLimiter/index.d.ts +2 -0
- package/lib/services/rateLimiter/index.d.ts.map +1 -0
- package/lib/services/rateLimiter/index.js +17 -0
- package/lib/services/redis.service.d.ts +9 -0
- package/lib/services/redis.service.d.ts.map +1 -1
- package/lib/services/redis.service.js +20 -11
- package/lib/services/redisOptions.d.ts +22 -0
- package/lib/services/redisOptions.d.ts.map +1 -0
- package/lib/services/redisOptions.js +51 -0
- package/lib/services/tts/index.d.ts +2 -0
- package/lib/services/tts/index.d.ts.map +1 -1
- package/lib/services/tts/index.js +2 -0
- package/lib/services/tts/providers/elevenlabs.service.d.ts.map +1 -1
- package/lib/services/tts/providers/elevenlabs.service.js +91 -24
- package/lib/services/tts/providers/minimax.service.d.ts +14 -0
- package/lib/services/tts/providers/minimax.service.d.ts.map +1 -0
- package/lib/services/tts/providers/minimax.service.js +78 -0
- package/lib/services/tts/providers/openai.service.d.ts +14 -0
- package/lib/services/tts/providers/openai.service.d.ts.map +1 -0
- package/lib/services/tts/providers/openai.service.js +73 -0
- package/lib/services/tts/ttsFactory.service.d.ts.map +1 -1
- package/lib/services/tts/ttsFactory.service.js +6 -0
- package/lib/services/tts/types.d.ts +33 -0
- package/lib/services/tts/types.d.ts.map +1 -1
- package/lib/utils/errors.d.ts +8 -0
- package/lib/utils/errors.d.ts.map +1 -1
- package/lib/utils/errors.js +8 -0
- package/lib/utils/helpers.d.ts +13 -0
- package/lib/utils/helpers.d.ts.map +1 -1
- package/lib/utils/helpers.js +48 -11
- package/lib/utils/logger.d.ts.map +1 -1
- package/lib/utils/logger.js +37 -1
- package/package.json +5 -1
- package/lib/services/aiGen/providers/azure/azure.service.d.ts +0 -14
- package/lib/services/aiGen/providers/azure/azure.service.d.ts.map +0 -1
- package/lib/services/aiGen/providers/azure/azure.service.js +0 -108
- package/lib/services/aiGen/providers/azure/index.d.ts +0 -2
- package/lib/services/aiGen/providers/azure/index.d.ts.map +0 -1
|
@@ -0,0 +1,591 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Planner = void 0;
|
|
4
|
+
exports.briefNeedsWebResearch = briefNeedsWebResearch;
|
|
5
|
+
const zod_1 = require("zod");
|
|
6
|
+
const videoPlan_schema_1 = require("../../../schemas/videoPlan.schema");
|
|
7
|
+
const llmCallerAnthropic_1 = require("../llmCallerAnthropic");
|
|
8
|
+
const llmCallerRegistry_1 = require("../llmCallerRegistry");
|
|
9
|
+
const modelRouter_1 = require("../modelRouter");
|
|
10
|
+
const personas_1 = require("../personas");
|
|
11
|
+
const modelQualityNotes_1 = require("../modelQualityNotes");
|
|
12
|
+
const promptSections_1 = require("./promptSections");
|
|
13
|
+
const structuralRules_1 = require("./structuralRules");
|
|
14
|
+
const repair_1 = require("./repair");
|
|
15
|
+
const overlaySanity_1 = require("./overlaySanity");
|
|
16
|
+
const costPreflight_1 = require("../costPreflight");
|
|
17
|
+
const validators_1 = require("./validators");
|
|
18
|
+
class Planner {
|
|
19
|
+
constructor(opts) {
|
|
20
|
+
this.opts = opts;
|
|
21
|
+
this.router = opts.router ?? new modelRouter_1.ModelRouter();
|
|
22
|
+
this.maxRetries = opts.maxRetries ?? 2;
|
|
23
|
+
}
|
|
24
|
+
async plan(brief, opts = {}) {
|
|
25
|
+
const model = this.router.pickFor("planner", {
|
|
26
|
+
premium: brief.tierBudget === "T3",
|
|
27
|
+
});
|
|
28
|
+
const fallbackModel = this.router.fallbackFor("planner");
|
|
29
|
+
// Resolve research flag. We only use research when the Anthropic caller
|
|
30
|
+
// is wired AND the brief implies real-world subjects — otherwise the
|
|
31
|
+
// gateway path (provider-portable) is preferred.
|
|
32
|
+
const anthropic = (0, llmCallerRegistry_1.getAnthropicCaller)();
|
|
33
|
+
const wantsResearch = opts.useWebResearch === true ||
|
|
34
|
+
(opts.useWebResearch !== false && briefNeedsWebResearch(brief));
|
|
35
|
+
let useResearchCall = wantsResearch &&
|
|
36
|
+
anthropic !== null &&
|
|
37
|
+
typeof anthropic.structuredWithTools === "function" &&
|
|
38
|
+
model.provider === "anthropic";
|
|
39
|
+
// T3 = premium → enable extended thinking on the Anthropic path. Budget
|
|
40
|
+
// sized for planner: 4K tokens covers multi-scene reasoning + research
|
|
41
|
+
// synthesis without bloating cost. We don't enable thinking on T0–T2
|
|
42
|
+
// because the planner's job there is mostly mechanical scene-spec
|
|
43
|
+
// emission and thinking would add ~$0.02 per call with no quality lift.
|
|
44
|
+
const premium = brief.tierBudget === "T3";
|
|
45
|
+
const thinkingBudget = premium ? 4096 : undefined;
|
|
46
|
+
let lastErrors;
|
|
47
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
48
|
+
const messages = this.buildMessages(brief, opts.persona, opts.brandKit ?? null, opts.styleMemory ?? null, opts.bible ?? null, lastErrors, useResearchCall);
|
|
49
|
+
let result;
|
|
50
|
+
try {
|
|
51
|
+
if (useResearchCall && anthropic?.structuredWithTools) {
|
|
52
|
+
// Research path: route through AnthropicLlmCaller so the model
|
|
53
|
+
// can invoke `web_search` server-side before emitting the plan.
|
|
54
|
+
// - `cachePrompt`: 90% discount on cache hits — every retry within
|
|
55
|
+
// 5 minutes pays ~10% of the system + tools tokens.
|
|
56
|
+
// - `thinking`: enabled on T3 premium briefs only.
|
|
57
|
+
// - Transient Anthropic errors fall through to the gateway path
|
|
58
|
+
// below via the catch — better to ship a non-researched plan
|
|
59
|
+
// than to 500 the whole /plan endpoint on an outage.
|
|
60
|
+
try {
|
|
61
|
+
result = await anthropic.structuredWithTools({
|
|
62
|
+
model,
|
|
63
|
+
messages,
|
|
64
|
+
schema: videoPlan_schema_1.VideoPlanSchema,
|
|
65
|
+
schemaName: "VideoPlan",
|
|
66
|
+
temperature: attempt === 0 ? 0.4 : 0.2,
|
|
67
|
+
serverTools: [{ type: "web_search", maxUses: 5 }],
|
|
68
|
+
maxToolRounds: 6,
|
|
69
|
+
cachePrompt: true,
|
|
70
|
+
...(thinkingBudget ? { thinking: { budgetTokens: thinkingBudget } } : {}),
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
catch (anthErr) {
|
|
74
|
+
if ((0, llmCallerAnthropic_1.isTransientLlmError)(anthErr)) {
|
|
75
|
+
// Downgrade: disable research for the rest of this plan call
|
|
76
|
+
// so we don't keep retrying the failing Anthropic path on
|
|
77
|
+
// subsequent attempts. The plan we produce won't be grounded,
|
|
78
|
+
// but it'll exist — and the warning flag tells the UI.
|
|
79
|
+
useResearchCall = false;
|
|
80
|
+
const fallbackMessages = this.buildMessages(brief, opts.persona, opts.brandKit ?? null, opts.styleMemory ?? null, opts.bible ?? null, lastErrors, false);
|
|
81
|
+
result = await this.opts.llm.structured({
|
|
82
|
+
model,
|
|
83
|
+
fallbackModel,
|
|
84
|
+
messages: fallbackMessages,
|
|
85
|
+
schema: videoPlan_schema_1.VideoPlanSchema,
|
|
86
|
+
schemaName: "VideoPlan",
|
|
87
|
+
temperature: attempt === 0 ? 0.4 : 0.2,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
throw anthErr;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
result = await this.opts.llm.structured({
|
|
97
|
+
model,
|
|
98
|
+
fallbackModel,
|
|
99
|
+
messages,
|
|
100
|
+
schema: videoPlan_schema_1.VideoPlanSchema,
|
|
101
|
+
schemaName: "VideoPlan",
|
|
102
|
+
temperature: attempt === 0 ? 0.4 : 0.2,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch (e) {
|
|
107
|
+
// AG-25: the gateway throws on schema-validation failures. Without this
|
|
108
|
+
// catch the planner's correction-retry loop never fires — a single
|
|
109
|
+
// sub-1ms scene duration from the LLM would crash the whole agent.
|
|
110
|
+
// Capture the error as correction context and let the loop retry.
|
|
111
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
112
|
+
if (/schema validation failed|non-JSON|empty response/i.test(msg)) {
|
|
113
|
+
lastErrors = `Previous attempt failed validation: ${msg.slice(0, 600)}. Ensure every scene has durationMs > 0, all required fields are populated, and the JSON parses cleanly.`;
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
throw e;
|
|
117
|
+
}
|
|
118
|
+
// Defense-in-depth: re-validate even though structured() should have.
|
|
119
|
+
const reparsed = videoPlan_schema_1.VideoPlanSchema.safeParse(result.data);
|
|
120
|
+
if (reparsed.success) {
|
|
121
|
+
// AG-9: duration contract. Brief.durationSec is the user's ask; if the
|
|
122
|
+
// plan under-delivers by >10%, re-prompt with an explicit correction.
|
|
123
|
+
const durationGap = (0, validators_1.checkDurationContract)(reparsed.data, brief);
|
|
124
|
+
if (durationGap) {
|
|
125
|
+
lastErrors = durationGap;
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
// AG-33: last-mile auto-correct — swap a known-bad preferredModel for
|
|
129
|
+
// a known-good one BEFORE we even run the validator. The planner
|
|
130
|
+
// sometimes can't break out of picking the same wrong model across
|
|
131
|
+
// retries (Test 1 picked runway-gen4-turbo for 2s scenes 3 times in
|
|
132
|
+
// a row). The retry loop still runs for genuinely ambiguous cases,
|
|
133
|
+
// but mechanical fixes (model X doesn't do duration Y → swap to model Z
|
|
134
|
+
// that does) shouldn't burn LLM cycles.
|
|
135
|
+
(0, repair_1.autoCorrectPreferredModels)(reparsed.data);
|
|
136
|
+
// AG-15: per-scene duration must be accepted by the picked model.
|
|
137
|
+
const capabilityGap = (0, validators_1.checkSceneDurationCapability)(reparsed.data);
|
|
138
|
+
if (capabilityGap) {
|
|
139
|
+
lastErrors = capabilityGap;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
// AG-28: per-scene VO must fit inside scene.durationMs (at default
|
|
143
|
+
// TTS speed). Without this the voiceover gets clipped mid-sentence
|
|
144
|
+
// when the stitcher renders. Test 1 had every line 1-1.8s over.
|
|
145
|
+
//
|
|
146
|
+
// Downgrade-on-last-attempt: if we've already burned every retry and
|
|
147
|
+
// the planner still can't produce a fit, ship the plan with a
|
|
148
|
+
// warning rather than throwing. The executor will still try the 1.15×
|
|
149
|
+
// speedup at render-time, and the UI surfaces the warning so the
|
|
150
|
+
// user can extend duration / shorten line / accept clipping.
|
|
151
|
+
const ttsGap = (0, validators_1.checkSceneTtsBudget)(reparsed.data);
|
|
152
|
+
if (ttsGap && attempt < this.maxRetries) {
|
|
153
|
+
lastErrors = ttsGap;
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
// Captions contract: faceless-yt and any brief that mentions captions
|
|
157
|
+
// MUST ship with at least one overlay per scene (either overlays[] or
|
|
158
|
+
// legacy onScreenText). Test 3 shipped 15 scenes with no captions
|
|
159
|
+
// despite the brief explicitly asking for "burned-in captions" — the
|
|
160
|
+
// planner happily emitted overlays:[] across the board.
|
|
161
|
+
const captionsGap = (0, validators_1.checkCaptionsContract)(reparsed.data, brief);
|
|
162
|
+
if (captionsGap) {
|
|
163
|
+
lastErrors = captionsGap;
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
// Overlay-content sanity: the planner sometimes copies the prompt's
|
|
167
|
+
// styling description verbatim into overlay.text (e.g. "Bold white
|
|
168
|
+
// sans-serif subtitle text in the lower third"). That string then
|
|
169
|
+
// gets burned onto the screen instead of the actual headline. Reject
|
|
170
|
+
// any overlay whose text reads like a typography/layout directive.
|
|
171
|
+
const overlaySanityGap = (0, overlaySanity_1.checkOverlayContentSanity)(reparsed.data);
|
|
172
|
+
if (overlaySanityGap) {
|
|
173
|
+
lastErrors = overlaySanityGap;
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
// Narration-density contract: for medium/slow pacing on a
|
|
177
|
+
// narration-driven plan (>50% of scenes carry a voiceoverLine),
|
|
178
|
+
// each scene must be >= 3500ms. Without this the planner happily
|
|
179
|
+
// ships 15 telegraphic 2-second scenes for a 30s "calm informational"
|
|
180
|
+
// brief, which reads like a TikTok listicle instead of an explainer.
|
|
181
|
+
const narrationGap = (0, validators_1.checkNarrationDensityContract)(reparsed.data, brief);
|
|
182
|
+
if (narrationGap) {
|
|
183
|
+
lastErrors = narrationGap;
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
// Persist the bible on the plan so downstream (executor / AG-13)
|
|
187
|
+
// has it without a second read. Planner doesn't author the bible.
|
|
188
|
+
if (opts.bible)
|
|
189
|
+
reparsed.data.bible = opts.bible;
|
|
190
|
+
// AG-31: voice style flows brief → plan. Don't trust the LLM to
|
|
191
|
+
// copy it through faithfully; overlay deterministically here.
|
|
192
|
+
if (brief.voice?.style && !reparsed.data.voiceStyle) {
|
|
193
|
+
reparsed.data.voiceStyle = brief.voice.style;
|
|
194
|
+
}
|
|
195
|
+
// AG-37 (rev 2): never trust planner-emitted voiceId — even with an
|
|
196
|
+
// explicit "ORCHESTRATOR-ONLY" docstring + system-prompt forbid line,
|
|
197
|
+
// GPT/Gemini occasionally invent a descriptive label like
|
|
198
|
+
// "female-young-adult-excited". That triggers the executor's strip-and-
|
|
199
|
+
// warn on every regen of the same trace, so kill it here once.
|
|
200
|
+
reparsed.data.voiceId = brief.voice?.voiceId;
|
|
201
|
+
// Soft-validation pass: vo-clip (if we downgraded after maxRetries)
|
|
202
|
+
// + trailing-silence. These ship with the plan; the UI surfaces them.
|
|
203
|
+
reparsed.data.warnings = (0, validators_1.collectPlanWarnings)(reparsed.data);
|
|
204
|
+
// Stamp credit estimates from estimateSceneCredits / estimatePlanCost
|
|
205
|
+
// so the storyboard chip + budget guard see real numbers. The LLM
|
|
206
|
+
// routinely emits estimatedCredits=0 for T0 scenes and a fabricated
|
|
207
|
+
// totalEstimatedCredits (observed: 0.72 cr for a 13-scene mixed plan
|
|
208
|
+
// that actually costs ~18 cr), which rounds to "1 cr" in the UI.
|
|
209
|
+
for (const s of reparsed.data.scenes) {
|
|
210
|
+
s.estimatedCredits = (0, costPreflight_1.estimateSceneCredits)(s);
|
|
211
|
+
}
|
|
212
|
+
reparsed.data.totalEstimatedCredits = (0, costPreflight_1.estimatePlanCost)(reparsed.data).totalCredits;
|
|
213
|
+
// Stamp billing-meta so /execute can charge for the right overhead
|
|
214
|
+
// bundle (web_search / extended-thinking). bibleBuilt is filled in by
|
|
215
|
+
// plan.controller after this returns — it knows cache-hit vs fresh.
|
|
216
|
+
reparsed.data.meta = {
|
|
217
|
+
...(reparsed.data.meta ?? {}),
|
|
218
|
+
usedWebResearch: useResearchCall,
|
|
219
|
+
usedThinking: !!thinkingBudget,
|
|
220
|
+
};
|
|
221
|
+
return reparsed.data;
|
|
222
|
+
}
|
|
223
|
+
lastErrors = reparsed.error.issues
|
|
224
|
+
.map((i) => `${i.path.join(".")}: ${i.message}`)
|
|
225
|
+
.join("; ");
|
|
226
|
+
}
|
|
227
|
+
throw new Error(`Planner failed to produce a valid VideoPlan after ${this.maxRetries + 1} attempts. Last errors: ${lastErrors}`);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Streaming variant of `plan()`. Yields raw token chunks from the model so
|
|
231
|
+
* the host (SSE endpoint) can forward them to the drawer for token-by-token
|
|
232
|
+
* rendering, then resolves to the validated VideoPlan once the structured
|
|
233
|
+
* payload is complete. Falls back to a single-shot call (one chunk = full
|
|
234
|
+
* text) when the LLM caller doesn't implement `structuredStream`.
|
|
235
|
+
*
|
|
236
|
+
* Retries are NOT streamed: only the first attempt is exposed to the UI;
|
|
237
|
+
* if validation fails we re-call `plan()` (non-streaming) and emit the
|
|
238
|
+
* final retry as a single chunk. Streaming retries would confuse callers
|
|
239
|
+
* who already painted partial JSON for the first attempt.
|
|
240
|
+
*/
|
|
241
|
+
planStream(brief, opts = {}) {
|
|
242
|
+
const model = this.router.pickFor("planner", {
|
|
243
|
+
premium: brief.tierBudget === "T3",
|
|
244
|
+
});
|
|
245
|
+
const messages = this.buildMessages(brief, opts.persona, opts.brandKit ?? null, opts.styleMemory ?? null, opts.bible ?? null);
|
|
246
|
+
if (!this.opts.llm.structuredStream) {
|
|
247
|
+
// Fallback path — emit the whole plan as one chunk after non-streaming call.
|
|
248
|
+
const result = this.plan(brief, opts);
|
|
249
|
+
const tokens = {
|
|
250
|
+
async *[Symbol.asyncIterator]() {
|
|
251
|
+
const plan = await result;
|
|
252
|
+
yield JSON.stringify(plan);
|
|
253
|
+
},
|
|
254
|
+
};
|
|
255
|
+
return { tokens, result };
|
|
256
|
+
}
|
|
257
|
+
const stream = this.opts.llm.structuredStream({
|
|
258
|
+
model,
|
|
259
|
+
fallbackModel: this.router.fallbackFor("planner"),
|
|
260
|
+
messages,
|
|
261
|
+
schema: videoPlan_schema_1.VideoPlanSchema,
|
|
262
|
+
schemaName: "VideoPlan",
|
|
263
|
+
temperature: 0.4,
|
|
264
|
+
});
|
|
265
|
+
const planner = this;
|
|
266
|
+
const result = (async () => {
|
|
267
|
+
try {
|
|
268
|
+
const r = await stream.result;
|
|
269
|
+
const reparsed = videoPlan_schema_1.VideoPlanSchema.safeParse(r.data);
|
|
270
|
+
if (reparsed.success) {
|
|
271
|
+
// Stream path skipped the validators loop; still attach soft warnings.
|
|
272
|
+
reparsed.data.warnings = (0, validators_1.collectPlanWarnings)(reparsed.data);
|
|
273
|
+
return reparsed.data;
|
|
274
|
+
}
|
|
275
|
+
// Validation tripped on a streamed payload — fall back to retry pass.
|
|
276
|
+
return planner.plan(brief, opts);
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
return planner.plan(brief, opts);
|
|
280
|
+
}
|
|
281
|
+
})();
|
|
282
|
+
return { tokens: stream.tokens, result };
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Stage 6 slice 4 — focused overlay regeneration for a single scene. The
|
|
286
|
+
* full `plan()` path is too expensive (and too lossy) for "I just want
|
|
287
|
+
* different headline / CTA copy on scene 3": it would re-validate every
|
|
288
|
+
* structural rule (duration / pacing / model capability / VO budget /
|
|
289
|
+
* narration density) against the unchanged scenes, then re-emit the
|
|
290
|
+
* whole plan — burning planner tokens and risking drift on fields the
|
|
291
|
+
* caller didn't ask to change.
|
|
292
|
+
*
|
|
293
|
+
* Instead we run a small structured-output call that ONLY emits
|
|
294
|
+
* `{ overlays: TextOverlay[] }` for one scene, keeping the prompt tight
|
|
295
|
+
* (just the scene context + the overlay-content rules + a free-form
|
|
296
|
+
* `instruction`) and the validator surface tiny (TextOverlaySchema +
|
|
297
|
+
* the style-leak sanity check). Caller is responsible for splicing the
|
|
298
|
+
* returned overlays into projectJson — this method is pure, no I/O
|
|
299
|
+
* beyond the LLM call.
|
|
300
|
+
*/
|
|
301
|
+
async regenerateOverlaysForScene(scene, brief, opts = {}) {
|
|
302
|
+
const model = this.router.pickFor("planner", {
|
|
303
|
+
premium: brief.tierBudget === "T3",
|
|
304
|
+
});
|
|
305
|
+
const fallbackModel = this.router.fallbackFor("planner");
|
|
306
|
+
const FocusedOverlaySchema = zod_1.z.object({
|
|
307
|
+
overlays: zod_1.z.array(videoPlan_schema_1.TextOverlaySchema).max(4),
|
|
308
|
+
});
|
|
309
|
+
const personaPack = opts.persona ? personas_1.PERSONA_PACKS[opts.persona] : null;
|
|
310
|
+
const brandKitSection = (0, promptSections_1.buildBrandKitSection)(opts.brandKit ?? null);
|
|
311
|
+
const bibleSection = (0, promptSections_1.buildBibleSection)(opts.bible ?? null);
|
|
312
|
+
const closingHint = opts.isClosingScene
|
|
313
|
+
? " - This IS the CLOSING scene — you MUST include role='cta' (max 5 words, brand + verb, e.g. 'Get HydraPure Today')."
|
|
314
|
+
: " - This is NOT the closing scene — do NOT emit role='cta' (CTA belongs only on the final scene).";
|
|
315
|
+
const watermarkHint = scene.sceneIndex === 0
|
|
316
|
+
? " - This IS scene 0 — you MAY include exactly one role='watermark' overlay with persistAcrossScenes:true (max 2 words, brand name)."
|
|
317
|
+
: " - This is NOT scene 0 — do NOT emit role='watermark' (watermark is emitted once on scene 0 and auto-carries forward).";
|
|
318
|
+
const overlayContract = [
|
|
319
|
+
"Emit ONLY this scene's overlays (array of TextOverlay, max 4 entries).",
|
|
320
|
+
"Each overlay = { text, role, position?, persistAcrossScenes?, emphasis?, animation?, startMs?, endMs? }.",
|
|
321
|
+
"CRITICAL: `text` is the LITERAL on-screen copy users will read — NOT a description of how it should look. Styling (font, color, position, drop-shadow) is applied automatically from the role.",
|
|
322
|
+
" GOOD: text:\"Your eyes lie to you\"",
|
|
323
|
+
" BAD: text:\"Bold white sans-serif subtitle in the lower third of a 9:16 frame\" (REJECTED as styling description)",
|
|
324
|
+
"Roles + word limits:",
|
|
325
|
+
" headline — top, big-bold, max 6 words (the hook).",
|
|
326
|
+
" subheadline — lower-third, medium, max 8 words.",
|
|
327
|
+
" body — lower-third, small, max 14 words (a supporting line of actual copy).",
|
|
328
|
+
" cta — bottom pill, bold, max 5 words, MUST combine brand + verb.",
|
|
329
|
+
" watermark — bottom-right tiny, max 2 words, just the brand name.",
|
|
330
|
+
" disclaimer — tiny bottom legal copy.",
|
|
331
|
+
" label — in-frame object/person label, max 3 words.",
|
|
332
|
+
"Max 4 overlays per scene. Don't emit two headlines on the same scene.",
|
|
333
|
+
"Emojis are OK — the renderer supports color glyphs natively.",
|
|
334
|
+
closingHint,
|
|
335
|
+
watermarkHint,
|
|
336
|
+
].join("\n");
|
|
337
|
+
const personaLine = personaPack
|
|
338
|
+
? `Persona: ${opts.persona} — ${personaPack.plannerPrompt.split("\n")[0]}`
|
|
339
|
+
: "";
|
|
340
|
+
const system = [
|
|
341
|
+
"You are a video-overlay copywriter.",
|
|
342
|
+
"Given ONE scene from a VideoPlan, emit a fresh `overlays[]` for that scene.",
|
|
343
|
+
"The rest of the plan (other scenes, VO, visuals, music) is fixed — do not comment on it, do not return it.",
|
|
344
|
+
"",
|
|
345
|
+
overlayContract,
|
|
346
|
+
personaLine,
|
|
347
|
+
brandKitSection,
|
|
348
|
+
bibleSection,
|
|
349
|
+
]
|
|
350
|
+
.filter(Boolean)
|
|
351
|
+
.join("\n");
|
|
352
|
+
const sceneContext = {
|
|
353
|
+
sceneIndex: scene.sceneIndex,
|
|
354
|
+
intent: scene.intent,
|
|
355
|
+
prompt: scene.prompt,
|
|
356
|
+
voiceoverLine: scene.voiceoverLine,
|
|
357
|
+
onScreenText: scene.onScreenText,
|
|
358
|
+
durationMs: scene.durationMs,
|
|
359
|
+
currentOverlays: scene.overlays ?? [],
|
|
360
|
+
};
|
|
361
|
+
const userParts = [
|
|
362
|
+
`Brief context:\n${JSON.stringify({
|
|
363
|
+
rawPrompt: brief.rawPrompt,
|
|
364
|
+
tone: brief.tone,
|
|
365
|
+
niche: brief.niche,
|
|
366
|
+
}, null, 2)}`,
|
|
367
|
+
`Scene:\n${JSON.stringify(sceneContext, null, 2)}`,
|
|
368
|
+
];
|
|
369
|
+
if (opts.instruction?.trim()) {
|
|
370
|
+
userParts.push(`Caller instruction: ${opts.instruction.trim()}`);
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
userParts.push("No specific instruction — produce a fresh, on-brand overlay set that fits the scene's intent and voiceoverLine.");
|
|
374
|
+
}
|
|
375
|
+
const user = userParts.join("\n\n");
|
|
376
|
+
let lastErrors;
|
|
377
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
378
|
+
const messages = [
|
|
379
|
+
{ role: "system", content: system },
|
|
380
|
+
{
|
|
381
|
+
role: "user",
|
|
382
|
+
content: lastErrors
|
|
383
|
+
? `${user}\n\nPrevious attempt failed validation: ${lastErrors}\nFix and try again.`
|
|
384
|
+
: user,
|
|
385
|
+
},
|
|
386
|
+
];
|
|
387
|
+
try {
|
|
388
|
+
const result = await this.opts.llm.structured({
|
|
389
|
+
model,
|
|
390
|
+
fallbackModel,
|
|
391
|
+
messages,
|
|
392
|
+
schema: FocusedOverlaySchema,
|
|
393
|
+
schemaName: "SceneOverlays",
|
|
394
|
+
temperature: attempt === 0 ? 0.6 : 0.3,
|
|
395
|
+
});
|
|
396
|
+
const overlays = result.data.overlays;
|
|
397
|
+
// Re-use the same style-leak validator the full-plan path uses by
|
|
398
|
+
// wrapping the overlays in a single-scene VideoPlan-shaped object.
|
|
399
|
+
// Cheaper than re-implementing the regex set here.
|
|
400
|
+
const probe = {
|
|
401
|
+
scenes: [{ ...scene, overlays }],
|
|
402
|
+
};
|
|
403
|
+
const leak = (0, overlaySanity_1.checkOverlayContentSanity)(probe);
|
|
404
|
+
if (leak) {
|
|
405
|
+
lastErrors = leak;
|
|
406
|
+
continue;
|
|
407
|
+
}
|
|
408
|
+
return overlays;
|
|
409
|
+
}
|
|
410
|
+
catch (e) {
|
|
411
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
412
|
+
if (/schema validation failed|non-JSON|empty response/i.test(msg)) {
|
|
413
|
+
lastErrors = `Previous attempt failed validation: ${msg.slice(0, 400)}.`;
|
|
414
|
+
continue;
|
|
415
|
+
}
|
|
416
|
+
throw e;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
throw new Error(`Planner failed to produce valid overlays for scene ${scene.sceneIndex} after ${this.maxRetries + 1} attempts. Last errors: ${lastErrors}`);
|
|
420
|
+
}
|
|
421
|
+
buildMessages(brief, persona, brandKit, styleMemory, bible, lastErrors, useResearchCall = false) {
|
|
422
|
+
const structuralRulesSection = (0, structuralRules_1.buildStructuralRulesSection)(brief);
|
|
423
|
+
const personaSection = persona
|
|
424
|
+
? [
|
|
425
|
+
"",
|
|
426
|
+
`Selected persona: ${persona}.`,
|
|
427
|
+
`Set plan.persona to "${persona}" in the output.`,
|
|
428
|
+
"Persona-specific structural rules (apply on top of the global tier rules):",
|
|
429
|
+
personas_1.PERSONA_PACKS[persona].plannerPrompt,
|
|
430
|
+
].join("\n")
|
|
431
|
+
: "";
|
|
432
|
+
const brandKitSection = (0, promptSections_1.buildBrandKitSection)(brandKit);
|
|
433
|
+
const styleMemorySection = (0, promptSections_1.buildStyleMemorySection)(styleMemory);
|
|
434
|
+
const bibleSection = (0, promptSections_1.buildBibleSection)(bible);
|
|
435
|
+
const modelCatalogSection = (0, promptSections_1.buildModelCatalogSection)();
|
|
436
|
+
const videoStrategySection = (0, promptSections_1.buildVideoStrategySection)(brief.videoStrategy);
|
|
437
|
+
// AG-39: warn the planner away from models with known capability gaps for
|
|
438
|
+
// dimensions this brief signals it cares about (brand text on product
|
|
439
|
+
// labels is the immediate driver). Empty string when nothing rated.
|
|
440
|
+
const modelQualitySection = (0, modelQualityNotes_1.renderModelQualityHintsForSystemPrompt)({
|
|
441
|
+
needsBrandText: (0, promptSections_1.briefMentionsBrandText)(brief),
|
|
442
|
+
needsCharacterContinuity: persona === "ugc-ad" || persona === "talking-head",
|
|
443
|
+
needsFastMotion: brief.tone?.toLowerCase()?.includes("energetic") || brief.tone?.toLowerCase()?.includes("action"),
|
|
444
|
+
needsCinematic: brief.tone?.toLowerCase()?.includes("cinematic"),
|
|
445
|
+
});
|
|
446
|
+
const researchSection = useResearchCall
|
|
447
|
+
? [
|
|
448
|
+
"",
|
|
449
|
+
"RESEARCH MODE — `web_search` is enabled. The brief mentions real-world",
|
|
450
|
+
"subjects (products, companies, people, places, events, or statistics).",
|
|
451
|
+
"Before planning, run targeted `web_search` calls (max 5) to ground the",
|
|
452
|
+
"plan in real facts: real product names, real feature lists, real logos,",
|
|
453
|
+
"real statistics, real quotes. Use the results to populate scene prompts,",
|
|
454
|
+
"voiceover lines, and overlay copy — NEVER fabricate company names,",
|
|
455
|
+
"product specs, or numbers. Cite findings implicitly via accurate copy;",
|
|
456
|
+
"do not embed raw URLs in the plan. When done researching, call the",
|
|
457
|
+
"`submit_VideoPlan` tool with the final plan.",
|
|
458
|
+
"",
|
|
459
|
+
].join("\n")
|
|
460
|
+
: "";
|
|
461
|
+
const system = [
|
|
462
|
+
"You are a video-production planner.",
|
|
463
|
+
"Given a VideoBrief, produce a VideoPlan: an ordered list of scenes",
|
|
464
|
+
"with per-scene asset strategy, tier, prompt, duration, and voiceover.",
|
|
465
|
+
researchSection,
|
|
466
|
+
"",
|
|
467
|
+
"Tier rules — respect brief.tierBudget as the maximum tier:",
|
|
468
|
+
" T0: stock footage / image with Ken-Burns motion.",
|
|
469
|
+
" T1: AI-generated still + camera motion.",
|
|
470
|
+
" T2: AI image-to-video on key frames only.",
|
|
471
|
+
" T3: full text-to-video (most expensive — use sparingly).",
|
|
472
|
+
"",
|
|
473
|
+
"Stock strategy bias — when budget is T0 and the scene depicts something",
|
|
474
|
+
"with natural motion (skies, light, water, traffic, hands at work,",
|
|
475
|
+
"animals, machinery, weather, crowds), prefer strategy='stock-video' over",
|
|
476
|
+
"'stock-image-ken-burns'. Static images with synthesized zoom feel like",
|
|
477
|
+
"a slideshow when chained for >3 cuts; real stock clips give the same",
|
|
478
|
+
"T0 cost with genuine motion. Only fall back to stock-image-ken-burns",
|
|
479
|
+
"when the subject is inherently still (diagrams, infographics, single",
|
|
480
|
+
"objects on a table, frozen moments) OR when the brief explicitly asks",
|
|
481
|
+
"for a poster/title-card feel.",
|
|
482
|
+
"",
|
|
483
|
+
videoStrategySection,
|
|
484
|
+
"",
|
|
485
|
+
"talking-head-avatar is wired and runs the kling-avatar pipeline (face",
|
|
486
|
+
"still + TTS lipsync). Pick it ONLY when the brand kit exposes a",
|
|
487
|
+
"presenterFaceUrl — set scene.avatarFaceUrl to that URL on every avatar",
|
|
488
|
+
"scene. If no presenter face is available, fall back to ai-image-to-video",
|
|
489
|
+
"or stock-video of a presenter instead.",
|
|
490
|
+
"",
|
|
491
|
+
"user-asset is wired and reuses the requesting user's existing library",
|
|
492
|
+
"(their previously generated images / videos / audio) instead of spending",
|
|
493
|
+
"credits to make a new asset. Pick user-asset when the brief mentions a",
|
|
494
|
+
"recurring brand subject (their product photo, spokesperson, b-roll) —",
|
|
495
|
+
"the executor falls back to stock-video if no library match scores high",
|
|
496
|
+
"enough, so picking it is safe.",
|
|
497
|
+
"",
|
|
498
|
+
"Keep total estimated credits as low as possible while honoring the",
|
|
499
|
+
"brief. Mix tiers within a single video where it helps cost without",
|
|
500
|
+
"harming quality (e.g. T2 hero shot + T0 b-roll between).",
|
|
501
|
+
"",
|
|
502
|
+
"Smart model routing — set preferredModel per scene from the catalog:",
|
|
503
|
+
" - Hero / opening-hook / product-reveal scenes: pick the highest-",
|
|
504
|
+
" quality model in the chosen tier (most expensive in that tier).",
|
|
505
|
+
" - B-roll / filler / transition scenes: pick the cheapest model in",
|
|
506
|
+
" the chosen tier — the audience won't notice the difference and",
|
|
507
|
+
" cost drops 3–5x.",
|
|
508
|
+
" - When in doubt for a non-hero scene, pick the median-cost model.",
|
|
509
|
+
" - preferredModel must match a key from the catalog below; the",
|
|
510
|
+
" executor will swap on rate-limit, so picking is best-effort, not",
|
|
511
|
+
" a hard contract.",
|
|
512
|
+
modelCatalogSection,
|
|
513
|
+
modelQualitySection,
|
|
514
|
+
// AG-14 fix: persona section moved above structuralRulesSection and
|
|
515
|
+
// bibleSection. The bible block has multiple "MUST" rules that were
|
|
516
|
+
// crowding out persona.hookStyle when persona was the last item before
|
|
517
|
+
// brandKit; on `seed-ugc-skincare` this regressed hookStrength to 0.4
|
|
518
|
+
// (planner picked a generic "Wait…" opener instead of the brief's
|
|
519
|
+
// problem-statement hook). Order is now: persona (voice + hookStyle) →
|
|
520
|
+
// structural rules → bible (entity verbatim re-statement).
|
|
521
|
+
personaSection,
|
|
522
|
+
structuralRulesSection,
|
|
523
|
+
bibleSection,
|
|
524
|
+
brandKitSection,
|
|
525
|
+
styleMemorySection,
|
|
526
|
+
]
|
|
527
|
+
.filter(Boolean)
|
|
528
|
+
.join("\n");
|
|
529
|
+
const user = [
|
|
530
|
+
`Brief:\n${JSON.stringify(brief, null, 2)}`,
|
|
531
|
+
lastErrors
|
|
532
|
+
? `\nYour previous attempt failed validation: ${lastErrors}\nFix the structure and try again.`
|
|
533
|
+
: "",
|
|
534
|
+
]
|
|
535
|
+
.filter(Boolean)
|
|
536
|
+
.join("\n");
|
|
537
|
+
return [
|
|
538
|
+
{ role: "system", content: system },
|
|
539
|
+
{ role: "user", content: user },
|
|
540
|
+
];
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
exports.Planner = Planner;
|
|
544
|
+
/**
|
|
545
|
+
* Heuristic — does the brief mention real-world entities that benefit from
|
|
546
|
+
* web grounding? A planner without research will happily invent fake app
|
|
547
|
+
* names, fabricate statistics, and miss real-world brand details. Triggers
|
|
548
|
+
* when the brief contains:
|
|
549
|
+
* - explicit "top N / best / popular / list of" framings
|
|
550
|
+
* - proper-noun-heavy briefs (≥2 capitalized non-sentence-start words)
|
|
551
|
+
* - listicle/comparison/news/review keywords
|
|
552
|
+
* - explicit time markers ("2026", "latest", "this year", "recent")
|
|
553
|
+
* - statistics signals ("statistics", "data", "percent", "study")
|
|
554
|
+
*
|
|
555
|
+
* Deliberately conservative — false negatives are fine (we just skip the
|
|
556
|
+
* search), false positives waste $0.01 per planner call. Override via
|
|
557
|
+
* `useWebResearch: true|false` when the caller knows better.
|
|
558
|
+
*/
|
|
559
|
+
function briefNeedsWebResearch(brief) {
|
|
560
|
+
const text = [
|
|
561
|
+
brief.rawPrompt ?? "",
|
|
562
|
+
brief.tone ?? "",
|
|
563
|
+
brief.niche ?? "",
|
|
564
|
+
]
|
|
565
|
+
.filter(Boolean)
|
|
566
|
+
.join(" ");
|
|
567
|
+
if (!text.trim())
|
|
568
|
+
return false;
|
|
569
|
+
const lower = text.toLowerCase();
|
|
570
|
+
const listicleSignals = /\b(top\s+\d+|best\s+\d*\s*\w+|popular|list\s+of|review|comparison|vs\.?|versus|trending|latest|recent|news|breaking|study|statistics?|data|percent|%|million|billion|industry|market|report)\b/;
|
|
571
|
+
if (listicleSignals.test(lower))
|
|
572
|
+
return true;
|
|
573
|
+
const yearMarker = /\b(20\d{2}|this\s+year|last\s+year)\b/;
|
|
574
|
+
if (yearMarker.test(lower))
|
|
575
|
+
return true;
|
|
576
|
+
// Count proper nouns that aren't sentence-starters — heuristic for
|
|
577
|
+
// "specific brands / people / places".
|
|
578
|
+
const words = text.split(/\s+/);
|
|
579
|
+
let properNouns = 0;
|
|
580
|
+
for (let i = 0; i < words.length; i++) {
|
|
581
|
+
const w = words[i] ?? "";
|
|
582
|
+
const prev = i > 0 ? words[i - 1] ?? "" : "";
|
|
583
|
+
const isSentenceStart = i === 0 || /[.!?]$/.test(prev);
|
|
584
|
+
if (!isSentenceStart && /^[A-Z][a-zA-Z0-9]{2,}/.test(w)) {
|
|
585
|
+
properNouns++;
|
|
586
|
+
if (properNouns >= 2)
|
|
587
|
+
return true;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
return false;
|
|
591
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { VideoPlan } from "../../../schemas/videoPlan.schema";
|
|
2
|
+
export declare function isStyleLeakText(text: string): {
|
|
3
|
+
leak: boolean;
|
|
4
|
+
reasons: string[];
|
|
5
|
+
};
|
|
6
|
+
export declare function checkOverlayContentSanity(plan: VideoPlan): string | null;
|
|
7
|
+
//# sourceMappingURL=overlaySanity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlaySanity.d.ts","sourceRoot":"","sources":["../../../../src/services/agent/planner/overlaySanity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAuB9D,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAgBlF;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAmDxE"}
|