vidspotai-shared 1.0.82-dev.0 → 1.0.83
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 +11 -1
- package/lib/globals/aiModels/enums.d.ts.map +1 -1
- package/lib/globals/aiModels/enums.js +24 -1
- package/lib/globals/aiModels/index.d.ts.map +1 -1
- package/lib/globals/aiModels/index.js +2 -0
- package/lib/globals/aiModels/providers/anthropic.d.ts +12 -0
- package/lib/globals/aiModels/providers/anthropic.d.ts.map +1 -0
- package/lib/globals/aiModels/providers/anthropic.js +88 -0
- package/lib/globals/aiModels/providers/google.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/google.js +115 -10
- package/lib/globals/aiModels/providers/openai.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/openai.js +63 -4
- package/lib/globals/aiModels/tierHelpers.d.ts +12 -0
- package/lib/globals/aiModels/tierHelpers.d.ts.map +1 -1
- package/lib/globals/aiModels/tierHelpers.js +83 -0
- package/lib/globals/aiModels/types.d.ts +19 -0
- package/lib/globals/aiModels/types.d.ts.map +1 -1
- package/lib/globals/types.d.ts +120 -1
- package/lib/globals/types.d.ts.map +1 -1
- package/lib/globals/types.js +135 -1
- package/lib/models/agent.model.d.ts +41 -1
- package/lib/models/agent.model.d.ts.map +1 -1
- package/lib/models/index.d.ts +1 -0
- package/lib/models/index.d.ts.map +1 -1
- package/lib/models/index.js +1 -0
- package/lib/models/social.model.d.ts +180 -0
- package/lib/models/social.model.d.ts.map +1 -0
- package/lib/models/social.model.js +2 -0
- package/lib/models/user.model.d.ts +10 -0
- package/lib/models/user.model.d.ts.map +1 -1
- package/lib/models/video.model.d.ts +6 -0
- package/lib/models/video.model.d.ts.map +1 -1
- package/lib/schemas/brief.schema.d.ts +46 -0
- package/lib/schemas/brief.schema.d.ts.map +1 -1
- package/lib/schemas/brief.schema.js +72 -1
- package/lib/schemas/index.d.ts +1 -0
- package/lib/schemas/index.d.ts.map +1 -1
- package/lib/schemas/index.js +1 -0
- package/lib/schemas/project.schema.d.ts +70 -3
- package/lib/schemas/project.schema.d.ts.map +1 -1
- package/lib/schemas/project.schema.js +12 -0
- package/lib/schemas/social.schema.d.ts +91 -0
- package/lib/schemas/social.schema.d.ts.map +1 -0
- package/lib/schemas/social.schema.js +114 -0
- package/lib/schemas/videoPlan.schema.d.ts +117 -3
- package/lib/schemas/videoPlan.schema.d.ts.map +1 -1
- package/lib/schemas/videoPlan.schema.js +141 -1
- package/lib/services/agent/chatAgent.d.ts +25 -1
- package/lib/services/agent/chatAgent.d.ts.map +1 -1
- package/lib/services/agent/chatAgent.js +145 -9
- package/lib/services/agent/costPreflight.d.ts +11 -1
- package/lib/services/agent/costPreflight.d.ts.map +1 -1
- package/lib/services/agent/costPreflight.js +18 -1
- package/lib/services/agent/covers/coverPlanner.d.ts +41 -0
- package/lib/services/agent/covers/coverPlanner.d.ts.map +1 -0
- package/lib/services/agent/covers/coverPlanner.js +278 -0
- package/lib/services/agent/covers/covers.schema.d.ts +158 -0
- package/lib/services/agent/covers/covers.schema.d.ts.map +1 -0
- package/lib/services/agent/covers/covers.schema.js +166 -0
- package/lib/services/agent/covers/index.d.ts +3 -0
- package/lib/services/agent/covers/index.d.ts.map +1 -0
- package/lib/services/agent/covers/index.js +18 -0
- package/lib/services/agent/critic.d.ts +10 -0
- package/lib/services/agent/critic.d.ts.map +1 -1
- package/lib/services/agent/critic.js +37 -1
- package/lib/services/agent/editClassifier.d.ts +4 -4
- package/lib/services/agent/editClassifier.js +2 -2
- package/lib/services/agent/editExisting/editAssembler.d.ts +78 -0
- package/lib/services/agent/editExisting/editAssembler.d.ts.map +1 -0
- package/lib/services/agent/editExisting/editAssembler.js +172 -0
- package/lib/services/agent/editExisting/editExisting.schema.d.ts +119 -0
- package/lib/services/agent/editExisting/editExisting.schema.d.ts.map +1 -0
- package/lib/services/agent/editExisting/editExisting.schema.js +157 -0
- package/lib/services/agent/editExisting/highlightPicker.d.ts +48 -0
- package/lib/services/agent/editExisting/highlightPicker.d.ts.map +1 -0
- package/lib/services/agent/editExisting/highlightPicker.js +199 -0
- package/lib/services/agent/editExisting/index.d.ts +4 -0
- package/lib/services/agent/editExisting/index.d.ts.map +1 -0
- package/lib/services/agent/editExisting/index.js +19 -0
- package/lib/services/agent/eval/recorder.d.ts +13 -1
- package/lib/services/agent/eval/recorder.d.ts.map +1 -1
- package/lib/services/agent/eval/recorder.js +59 -0
- package/lib/services/agent/eval/seedBriefs.d.ts +4 -3
- package/lib/services/agent/eval/seedBriefs.d.ts.map +1 -1
- package/lib/services/agent/eval/seedBriefs.js +283 -3
- package/lib/services/agent/eval/types.d.ts +10 -0
- package/lib/services/agent/eval/types.d.ts.map +1 -1
- package/lib/services/agent/executor/core.d.ts +70 -0
- package/lib/services/agent/executor/core.d.ts.map +1 -0
- package/lib/services/agent/executor/core.js +250 -0
- package/lib/services/agent/executor/duration.d.ts +20 -0
- package/lib/services/agent/executor/duration.d.ts.map +1 -0
- package/lib/services/agent/executor/duration.js +46 -0
- package/lib/services/agent/executor/index.d.ts +15 -0
- package/lib/services/agent/executor/index.d.ts.map +1 -0
- package/lib/services/agent/executor/index.js +32 -0
- package/lib/services/agent/executor/types.d.ts +183 -0
- package/lib/services/agent/executor/types.d.ts.map +1 -0
- package/lib/services/agent/executor/types.js +29 -0
- package/lib/services/agent/executor/visual.d.ts +32 -0
- package/lib/services/agent/executor/visual.d.ts.map +1 -0
- package/lib/services/agent/executor/visual.js +400 -0
- package/lib/services/agent/executor/voice.d.ts +17 -0
- package/lib/services/agent/executor/voice.d.ts.map +1 -0
- package/lib/services/agent/executor/voice.js +119 -0
- package/lib/services/agent/extendChain.d.ts +101 -0
- package/lib/services/agent/extendChain.d.ts.map +1 -0
- package/lib/services/agent/extendChain.js +177 -0
- package/lib/services/agent/index.d.ts +11 -1
- package/lib/services/agent/index.d.ts.map +1 -1
- package/lib/services/agent/index.js +11 -1
- package/lib/services/agent/llmCaller.d.ts +7 -8
- package/lib/services/agent/llmCaller.d.ts.map +1 -1
- package/lib/services/agent/llmCallerAnthropic.d.ts +44 -31
- package/lib/services/agent/llmCallerAnthropic.d.ts.map +1 -1
- package/lib/services/agent/llmCallerAnthropic.js +135 -60
- package/lib/services/agent/llmCallerFactory.d.ts +34 -0
- package/lib/services/agent/llmCallerFactory.d.ts.map +1 -0
- package/lib/services/agent/llmCallerFactory.js +31 -0
- package/lib/services/agent/llmCallerGemini.d.ts +62 -0
- package/lib/services/agent/llmCallerGemini.d.ts.map +1 -0
- package/lib/services/agent/llmCallerGemini.js +235 -0
- package/lib/services/agent/llmCallerOpenai.d.ts +56 -0
- package/lib/services/agent/llmCallerOpenai.d.ts.map +1 -0
- package/lib/services/agent/llmCallerOpenai.js +230 -0
- package/lib/services/agent/llmCallerRegistry.d.ts.map +1 -1
- package/lib/services/agent/llmCallerRegistry.js +7 -7
- package/lib/services/agent/llmCallerRouting.d.ts +63 -0
- package/lib/services/agent/llmCallerRouting.d.ts.map +1 -0
- package/lib/services/agent/llmCallerRouting.js +124 -0
- package/lib/services/agent/llmModelRegistry.d.ts +59 -0
- package/lib/services/agent/llmModelRegistry.d.ts.map +1 -0
- package/lib/services/agent/llmModelRegistry.js +168 -0
- package/lib/services/agent/llmRetry.d.ts +57 -0
- package/lib/services/agent/llmRetry.d.ts.map +1 -0
- package/lib/services/agent/llmRetry.js +102 -0
- package/lib/services/agent/modelRouter.d.ts +3 -3
- package/lib/services/agent/modelRouter.d.ts.map +1 -1
- package/lib/services/agent/modelRouter.js +27 -13
- package/lib/services/agent/planMutations.d.ts +54 -1
- package/lib/services/agent/planMutations.d.ts.map +1 -1
- package/lib/services/agent/planMutations.js +78 -0
- package/lib/services/agent/planner/Planner.d.ts +0 -17
- package/lib/services/agent/planner/Planner.d.ts.map +1 -1
- package/lib/services/agent/planner/Planner.js +67 -303
- package/lib/services/agent/planner/overlayRegen.d.ts +38 -0
- package/lib/services/agent/planner/overlayRegen.d.ts.map +1 -0
- package/lib/services/agent/planner/overlayRegen.js +145 -0
- package/lib/services/agent/planner/plannerMessages.d.ts +34 -0
- package/lib/services/agent/planner/plannerMessages.d.ts.map +1 -0
- package/lib/services/agent/planner/plannerMessages.js +185 -0
- package/lib/services/agent/planner/promptSections.d.ts +12 -0
- package/lib/services/agent/planner/promptSections.d.ts.map +1 -1
- package/lib/services/agent/planner/promptSections.js +57 -0
- package/lib/services/agent/planner/scriptFirstPlanner.d.ts +35 -0
- package/lib/services/agent/planner/scriptFirstPlanner.d.ts.map +1 -0
- package/lib/services/agent/planner/scriptFirstPlanner.js +140 -0
- package/lib/services/agent/planner/structuralRules.d.ts +10 -0
- package/lib/services/agent/planner/structuralRules.d.ts.map +1 -1
- package/lib/services/agent/planner/structuralRules.js +92 -9
- package/lib/services/agent/planner/validators.d.ts +18 -0
- package/lib/services/agent/planner/validators.d.ts.map +1 -1
- package/lib/services/agent/planner/validators.js +97 -0
- package/lib/services/agent/planner.d.ts +2 -1
- package/lib/services/agent/planner.d.ts.map +1 -1
- package/lib/services/agent/planner.js +5 -1
- package/lib/services/agent/priorProject.d.ts +26 -0
- package/lib/services/agent/priorProject.d.ts.map +1 -0
- package/lib/services/agent/priorProject.js +51 -0
- package/lib/services/agent/providerFallback/chains.d.ts.map +1 -1
- package/lib/services/agent/providerFallback/chains.js +27 -15
- package/lib/services/agent/repurpose/index.d.ts +3 -0
- package/lib/services/agent/repurpose/index.d.ts.map +1 -0
- package/lib/services/agent/repurpose/index.js +18 -0
- package/lib/services/agent/repurpose/repurpose.schema.d.ts +132 -0
- package/lib/services/agent/repurpose/repurpose.schema.d.ts.map +1 -0
- package/lib/services/agent/repurpose/repurpose.schema.js +144 -0
- package/lib/services/agent/repurpose/shortsPicker.d.ts +25 -0
- package/lib/services/agent/repurpose/shortsPicker.d.ts.map +1 -0
- package/lib/services/agent/repurpose/shortsPicker.js +218 -0
- package/lib/services/agent/runHelpers.d.ts +21 -2
- package/lib/services/agent/runHelpers.d.ts.map +1 -1
- package/lib/services/agent/runHelpers.js +71 -2
- package/lib/services/agent/tools/animateImage.tool.d.ts +1 -0
- package/lib/services/agent/tools/animateImage.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/animateImage.tool.js +12 -0
- package/lib/services/agent/tools/chapterOutline.tool.d.ts +42 -0
- package/lib/services/agent/tools/chapterOutline.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/chapterOutline.tool.js +115 -0
- package/lib/services/agent/tools/composeScene.tool.d.ts +65 -2
- package/lib/services/agent/tools/composeScene.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/estimateCost.tool.d.ts +28 -1
- package/lib/services/agent/tools/estimateCost.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/estimateCost.tool.js +55 -7
- package/lib/services/agent/tools/extendVideo.tool.d.ts +26 -0
- package/lib/services/agent/tools/extendVideo.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/extendVideo.tool.js +149 -0
- package/lib/services/agent/tools/generateScript.tool.d.ts +184 -0
- package/lib/services/agent/tools/generateScript.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/generateScript.tool.js +123 -0
- package/lib/services/agent/tools/generateVideo.tool.d.ts +1 -0
- package/lib/services/agent/tools/generateVideo.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/generateVideo.tool.js +20 -1
- package/lib/services/agent/tools/index.d.ts +4 -0
- package/lib/services/agent/tools/index.d.ts.map +1 -1
- package/lib/services/agent/tools/index.js +4 -0
- package/lib/services/agent/tools/matchBrollToScript.tool.d.ts +50 -0
- package/lib/services/agent/tools/matchBrollToScript.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/matchBrollToScript.tool.js +139 -0
- package/lib/services/agent/tools/planVideo.tool.d.ts +57 -1
- package/lib/services/agent/tools/planVideo.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/planVideo.tool.js +3 -3
- package/lib/services/agent/tools/render.tool.d.ts +22 -1
- package/lib/services/agent/tools/render.tool.d.ts.map +1 -1
- package/lib/services/aiGen/aiGenFactory.service.d.ts.map +1 -1
- package/lib/services/aiGen/aiGenFactory.service.js +18 -3
- package/lib/services/aiGen/helpers.d.ts +8 -0
- package/lib/services/aiGen/helpers.d.ts.map +1 -1
- package/lib/services/aiGen/helpers.js +12 -0
- package/lib/services/aiGen/providers/anthropic/anthropic.service.d.ts +26 -0
- package/lib/services/aiGen/providers/anthropic/anthropic.service.d.ts.map +1 -0
- package/lib/services/aiGen/providers/anthropic/anthropic.service.js +95 -0
- package/lib/services/aiGen/providers/google/google.service.d.ts +25 -1
- package/lib/services/aiGen/providers/google/google.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/google/google.service.js +136 -237
- package/lib/services/aiGen/providers/google/googleApiKeys.d.ts +71 -0
- package/lib/services/aiGen/providers/google/googleApiKeys.d.ts.map +1 -0
- package/lib/services/aiGen/providers/google/googleApiKeys.js +137 -0
- package/lib/services/aiGen/providers/google/googleErrors.d.ts +13 -0
- package/lib/services/aiGen/providers/google/googleErrors.d.ts.map +1 -0
- package/lib/services/aiGen/providers/google/googleErrors.js +102 -0
- package/lib/services/aiGen/providers/google/googleFetch.d.ts +8 -0
- package/lib/services/aiGen/providers/google/googleFetch.d.ts.map +1 -0
- package/lib/services/aiGen/providers/google/googleFetch.js +96 -0
- package/lib/services/aiGen/providers/google/googleKeyPool.d.ts +52 -0
- package/lib/services/aiGen/providers/google/googleKeyPool.d.ts.map +1 -0
- package/lib/services/aiGen/providers/google/googleKeyPool.js +129 -0
- package/lib/services/aiGen/providers/google/googleMusic.d.ts +15 -0
- package/lib/services/aiGen/providers/google/googleMusic.d.ts.map +1 -0
- package/lib/services/aiGen/providers/google/googleMusic.js +77 -0
- package/lib/services/aiGen/providers/kling/kling.service.d.ts +7 -3
- package/lib/services/aiGen/providers/kling/kling.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/kling/kling.service.js +23 -367
- package/lib/services/aiGen/providers/kling/klingCredits.d.ts +9 -0
- package/lib/services/aiGen/providers/kling/klingCredits.d.ts.map +1 -0
- package/lib/services/aiGen/providers/kling/klingCredits.js +63 -0
- package/lib/services/aiGen/providers/kling/klingRequests.d.ts +32 -0
- package/lib/services/aiGen/providers/kling/klingRequests.d.ts.map +1 -0
- package/lib/services/aiGen/providers/kling/klingRequests.js +194 -0
- package/lib/services/aiGen/providers/kling/klingStatus.d.ts +16 -0
- package/lib/services/aiGen/providers/kling/klingStatus.d.ts.map +1 -0
- package/lib/services/aiGen/providers/kling/klingStatus.js +173 -0
- package/lib/services/aiGen/providers/pixverse/pixverse.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/pixverse/pixverse.service.js +7 -1
- package/lib/services/bullmq.service.d.ts +61 -0
- package/lib/services/bullmq.service.d.ts.map +1 -1
- package/lib/services/bullmq.service.js +124 -2
- package/lib/services/crypto/index.d.ts +2 -0
- package/lib/services/crypto/index.d.ts.map +1 -0
- package/lib/services/crypto/index.js +17 -0
- package/lib/services/crypto/tokenVault.d.ts +47 -0
- package/lib/services/crypto/tokenVault.d.ts.map +1 -0
- package/lib/services/crypto/tokenVault.js +179 -0
- package/lib/services/editor/captionStyleHint.d.ts +3 -0
- package/lib/services/editor/captionStyleHint.d.ts.map +1 -0
- package/lib/services/editor/captionStyleHint.js +112 -0
- package/lib/services/editor/planToProject.d.ts +7 -66
- package/lib/services/editor/planToProject.d.ts.map +1 -1
- package/lib/services/editor/planToProject.helpers.d.ts +40 -0
- package/lib/services/editor/planToProject.helpers.d.ts.map +1 -0
- package/lib/services/editor/planToProject.helpers.js +177 -0
- package/lib/services/editor/planToProject.js +197 -180
- package/lib/services/editor/planToProject.types.d.ts +94 -0
- package/lib/services/editor/planToProject.types.d.ts.map +1 -0
- package/lib/services/editor/planToProject.types.js +2 -0
- package/lib/services/firestore.service.d.ts +5 -0
- package/lib/services/firestore.service.d.ts.map +1 -1
- package/lib/services/firestore.service.js +13 -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/promptEnhancer/index.d.ts +18 -0
- package/lib/services/promptEnhancer/index.d.ts.map +1 -0
- package/lib/services/promptEnhancer/index.js +33 -0
- package/lib/services/promptEnhancer/models.d.ts +54 -0
- package/lib/services/promptEnhancer/models.d.ts.map +1 -0
- package/lib/services/promptEnhancer/models.js +37 -0
- package/lib/services/promptEnhancer/profiles/agent.profile.d.ts +14 -0
- package/lib/services/promptEnhancer/profiles/agent.profile.d.ts.map +1 -0
- package/lib/services/promptEnhancer/profiles/agent.profile.js +40 -0
- package/lib/services/promptEnhancer/profiles/avatar.profile.d.ts +13 -0
- package/lib/services/promptEnhancer/profiles/avatar.profile.d.ts.map +1 -0
- package/lib/services/promptEnhancer/profiles/avatar.profile.js +40 -0
- package/lib/services/promptEnhancer/profiles/base.d.ts +28 -0
- package/lib/services/promptEnhancer/profiles/base.d.ts.map +1 -0
- package/lib/services/promptEnhancer/profiles/base.js +35 -0
- package/lib/services/promptEnhancer/profiles/image.profile.d.ts +11 -0
- package/lib/services/promptEnhancer/profiles/image.profile.d.ts.map +1 -0
- package/lib/services/promptEnhancer/profiles/image.profile.js +42 -0
- package/lib/services/promptEnhancer/profiles/index.d.ts +12 -0
- package/lib/services/promptEnhancer/profiles/index.d.ts.map +1 -0
- package/lib/services/promptEnhancer/profiles/index.js +33 -0
- package/lib/services/promptEnhancer/profiles/video.profile.d.ts +15 -0
- package/lib/services/promptEnhancer/profiles/video.profile.d.ts.map +1 -0
- package/lib/services/promptEnhancer/profiles/video.profile.js +81 -0
- package/lib/services/promptEnhancer/promptEnhancer.service.d.ts +45 -0
- package/lib/services/promptEnhancer/promptEnhancer.service.d.ts.map +1 -0
- package/lib/services/promptEnhancer/promptEnhancer.service.js +157 -0
- package/lib/services/promptEnhancer/schema.d.ts +19 -0
- package/lib/services/promptEnhancer/schema.d.ts.map +1 -0
- package/lib/services/promptEnhancer/schema.js +43 -0
- package/lib/services/promptEnhancer/types.d.ts +112 -0
- package/lib/services/promptEnhancer/types.d.ts.map +1 -0
- package/lib/services/promptEnhancer/types.js +2 -0
- package/lib/services/rateLimiter/distributedRateLimiter.service.d.ts +60 -5
- package/lib/services/rateLimiter/distributedRateLimiter.service.d.ts.map +1 -1
- package/lib/services/rateLimiter/distributedRateLimiter.service.js +184 -16
- package/lib/services/socialAI/captionGen.d.ts +81 -0
- package/lib/services/socialAI/captionGen.d.ts.map +1 -0
- package/lib/services/socialAI/captionGen.js +206 -0
- package/lib/services/socialAI/hookScore.d.ts +85 -0
- package/lib/services/socialAI/hookScore.d.ts.map +1 -0
- package/lib/services/socialAI/hookScore.js +170 -0
- package/lib/services/socialAI/index.d.ts +3 -0
- package/lib/services/socialAI/index.d.ts.map +1 -0
- package/lib/services/socialAI/index.js +18 -0
- package/lib/services/socialAccounts/index.d.ts +2 -0
- package/lib/services/socialAccounts/index.d.ts.map +1 -0
- package/lib/services/socialAccounts/index.js +17 -0
- package/lib/services/socialAccounts/socialAccountService.d.ts +25 -0
- package/lib/services/socialAccounts/socialAccountService.d.ts.map +1 -0
- package/lib/services/socialAccounts/socialAccountService.js +105 -0
- package/lib/services/socialEngage/factory.d.ts +7 -0
- package/lib/services/socialEngage/factory.d.ts.map +1 -0
- package/lib/services/socialEngage/factory.js +25 -0
- package/lib/services/socialEngage/index.d.ts +6 -0
- package/lib/services/socialEngage/index.d.ts.map +1 -0
- package/lib/services/socialEngage/index.js +21 -0
- package/lib/services/socialEngage/meta.engage.d.ts +17 -0
- package/lib/services/socialEngage/meta.engage.d.ts.map +1 -0
- package/lib/services/socialEngage/meta.engage.js +128 -0
- package/lib/services/socialEngage/metaWebhook.d.ts +50 -0
- package/lib/services/socialEngage/metaWebhook.d.ts.map +1 -0
- package/lib/services/socialEngage/metaWebhook.js +93 -0
- package/lib/services/socialEngage/types.d.ts +72 -0
- package/lib/services/socialEngage/types.d.ts.map +1 -0
- package/lib/services/socialEngage/types.js +10 -0
- package/lib/services/socialEngage/youtube.engage.d.ts +9 -0
- package/lib/services/socialEngage/youtube.engage.d.ts.map +1 -0
- package/lib/services/socialEngage/youtube.engage.js +87 -0
- package/lib/services/socialFormat/aspectGeometry.d.ts +74 -0
- package/lib/services/socialFormat/aspectGeometry.d.ts.map +1 -0
- package/lib/services/socialFormat/aspectGeometry.js +135 -0
- package/lib/services/socialFormat/index.d.ts +2 -0
- package/lib/services/socialFormat/index.d.ts.map +1 -0
- package/lib/services/socialFormat/index.js +19 -0
- package/lib/services/socialInsights/index.d.ts +3 -0
- package/lib/services/socialInsights/index.d.ts.map +1 -0
- package/lib/services/socialInsights/index.js +18 -0
- package/lib/services/socialInsights/recommendations.d.ts +131 -0
- package/lib/services/socialInsights/recommendations.d.ts.map +1 -0
- package/lib/services/socialInsights/recommendations.js +277 -0
- package/lib/services/socialInsights/timeBuckets.d.ts +35 -0
- package/lib/services/socialInsights/timeBuckets.d.ts.map +1 -0
- package/lib/services/socialInsights/timeBuckets.js +78 -0
- package/lib/services/socialMetrics/factory.d.ts +5 -0
- package/lib/services/socialMetrics/factory.d.ts.map +1 -0
- package/lib/services/socialMetrics/factory.js +24 -0
- package/lib/services/socialMetrics/index.d.ts +6 -0
- package/lib/services/socialMetrics/index.d.ts.map +1 -0
- package/lib/services/socialMetrics/index.js +21 -0
- package/lib/services/socialMetrics/meta.metrics.d.ts +22 -0
- package/lib/services/socialMetrics/meta.metrics.d.ts.map +1 -0
- package/lib/services/socialMetrics/meta.metrics.js +137 -0
- package/lib/services/socialMetrics/tiktok.metrics.d.ts +8 -0
- package/lib/services/socialMetrics/tiktok.metrics.d.ts.map +1 -0
- package/lib/services/socialMetrics/tiktok.metrics.js +43 -0
- package/lib/services/socialMetrics/types.d.ts +54 -0
- package/lib/services/socialMetrics/types.d.ts.map +1 -0
- package/lib/services/socialMetrics/types.js +2 -0
- package/lib/services/socialMetrics/youtube.metrics.d.ts +8 -0
- package/lib/services/socialMetrics/youtube.metrics.d.ts.map +1 -0
- package/lib/services/socialMetrics/youtube.metrics.js +43 -0
- package/lib/services/socialOAuth/factory.d.ts +7 -0
- package/lib/services/socialOAuth/factory.d.ts.map +1 -0
- package/lib/services/socialOAuth/factory.js +42 -0
- package/lib/services/socialOAuth/index.d.ts +11 -0
- package/lib/services/socialOAuth/index.d.ts.map +1 -0
- package/lib/services/socialOAuth/index.js +26 -0
- package/lib/services/socialOAuth/linkedin.oauth.d.ts +14 -0
- package/lib/services/socialOAuth/linkedin.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/linkedin.oauth.js +127 -0
- package/lib/services/socialOAuth/meta.oauth.d.ts +31 -0
- package/lib/services/socialOAuth/meta.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/meta.oauth.js +214 -0
- package/lib/services/socialOAuth/oauthState.d.ts +14 -0
- package/lib/services/socialOAuth/oauthState.d.ts.map +1 -0
- package/lib/services/socialOAuth/oauthState.js +66 -0
- package/lib/services/socialOAuth/pinterest.oauth.d.ts +15 -0
- package/lib/services/socialOAuth/pinterest.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/pinterest.oauth.js +126 -0
- package/lib/services/socialOAuth/threads.oauth.d.ts +14 -0
- package/lib/services/socialOAuth/threads.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/threads.oauth.js +129 -0
- package/lib/services/socialOAuth/tiktok.oauth.d.ts +15 -0
- package/lib/services/socialOAuth/tiktok.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/tiktok.oauth.js +151 -0
- package/lib/services/socialOAuth/types.d.ts +67 -0
- package/lib/services/socialOAuth/types.d.ts.map +1 -0
- package/lib/services/socialOAuth/types.js +2 -0
- package/lib/services/socialOAuth/x.oauth.d.ts +17 -0
- package/lib/services/socialOAuth/x.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/x.oauth.js +134 -0
- package/lib/services/socialOAuth/youtube.oauth.d.ts +15 -0
- package/lib/services/socialOAuth/youtube.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/youtube.oauth.js +156 -0
- package/lib/services/socialPublish/factory.d.ts +5 -0
- package/lib/services/socialPublish/factory.d.ts.map +1 -0
- package/lib/services/socialPublish/factory.js +32 -0
- package/lib/services/socialPublish/index.d.ts +10 -0
- package/lib/services/socialPublish/index.d.ts.map +1 -0
- package/lib/services/socialPublish/index.js +25 -0
- package/lib/services/socialPublish/linkedin.publish.d.ts +9 -0
- package/lib/services/socialPublish/linkedin.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/linkedin.publish.js +143 -0
- package/lib/services/socialPublish/meta.publish.d.ts +28 -0
- package/lib/services/socialPublish/meta.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/meta.publish.js +149 -0
- package/lib/services/socialPublish/pinterest.publish.d.ts +13 -0
- package/lib/services/socialPublish/pinterest.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/pinterest.publish.js +130 -0
- package/lib/services/socialPublish/threads.publish.d.ts +12 -0
- package/lib/services/socialPublish/threads.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/threads.publish.js +96 -0
- package/lib/services/socialPublish/tiktok.publish.d.ts +13 -0
- package/lib/services/socialPublish/tiktok.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/tiktok.publish.js +118 -0
- package/lib/services/socialPublish/types.d.ts +47 -0
- package/lib/services/socialPublish/types.d.ts.map +1 -0
- package/lib/services/socialPublish/types.js +2 -0
- package/lib/services/socialPublish/x.publish.d.ts +12 -0
- package/lib/services/socialPublish/x.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/x.publish.js +147 -0
- package/lib/services/socialPublish/youtube.publish.d.ts +9 -0
- package/lib/services/socialPublish/youtube.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/youtube.publish.js +107 -0
- package/lib/services/stock/index.d.ts +2 -0
- package/lib/services/stock/index.d.ts.map +1 -0
- package/lib/services/stock/index.js +17 -0
- package/lib/services/stock/realPersonSafety.d.ts +99 -0
- package/lib/services/stock/realPersonSafety.d.ts.map +1 -0
- package/lib/services/stock/realPersonSafety.js +248 -0
- package/lib/services/translation/index.d.ts +2 -0
- package/lib/services/translation/index.d.ts.map +1 -0
- package/lib/services/translation/index.js +9 -0
- package/lib/services/translation/translation.service.d.ts +50 -0
- package/lib/services/translation/translation.service.d.ts.map +1 -0
- package/lib/services/translation/translation.service.js +211 -0
- package/lib/utils/helpers.d.ts +2 -4
- package/lib/utils/helpers.d.ts.map +1 -1
- package/lib/utils/helpers.js +9 -63
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.d.ts.map +1 -1
- package/lib/utils/index.js +1 -0
- package/lib/utils/renderTier.d.ts +26 -0
- package/lib/utils/renderTier.d.ts.map +1 -0
- package/lib/utils/renderTier.js +34 -0
- package/package.json +1 -1
|
@@ -5,6 +5,7 @@ exports.isVideoModelCapable = isVideoModelCapable;
|
|
|
5
5
|
exports.buildVideoChain = buildVideoChain;
|
|
6
6
|
exports.snapDurationForModel = snapDurationForModel;
|
|
7
7
|
const aiModels_1 = require("../../../globals/aiModels");
|
|
8
|
+
const helpers_1 = require("../../aiGen/helpers");
|
|
8
9
|
/**
|
|
9
10
|
* Provider-chain configuration per modality (F3.3).
|
|
10
11
|
* Ordered primary → fallback. The wrapper walks the chain on recoverable
|
|
@@ -133,20 +134,30 @@ function normalizeAspect(a) {
|
|
|
133
134
|
function gcd(a, b) {
|
|
134
135
|
return b === 0 ? a : gcd(b, a % b);
|
|
135
136
|
}
|
|
136
|
-
// AG-
|
|
137
|
-
//
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
137
|
+
// AG-1: last-frame (FLF) support is now read from the SAME source of truth the
|
|
138
|
+
// prod API-time guard uses — a model declares `lastFrameImageUrl` in its config
|
|
139
|
+
// `fields` (see aiGen/helpers.modelSupportsLastFrame). The old hardcoded
|
|
140
|
+
// END_FRAME_MODELS set had drifted (it listed veo-3.1-lite, pixverse-v5.6 and
|
|
141
|
+
// seedance-2.0, none of which actually declare the field), so the agent gate
|
|
142
|
+
// would pass a request the provider/validator then rejected — wasting a chain
|
|
143
|
+
// slot. Reading the config removes that drift and self-maintains.
|
|
144
|
+
//
|
|
145
|
+
// REMOVED FOR v2 (AG-1) — kept for reference: the stale hardcoded allow-list.
|
|
146
|
+
// const END_FRAME_MODELS = new Set<string>([
|
|
147
|
+
// EVideoGenModels.GOOGLE_VEO_3_1,
|
|
148
|
+
// EVideoGenModels.GOOGLE_VEO_3_1_FAST,
|
|
149
|
+
// EVideoGenModels.GOOGLE_VEO_3_1_LITE,
|
|
150
|
+
// EVideoGenModels.KLING_V2_6,
|
|
151
|
+
// EVideoGenModels.KLING_V2_5_TURBO,
|
|
152
|
+
// EVideoGenModels.KLING_V3_0,
|
|
153
|
+
// EVideoGenModels.RUNWAY_GEN4_TURBO,
|
|
154
|
+
// EVideoGenModels.RUNWAY_GEN4_5,
|
|
155
|
+
// EVideoGenModels.BYTEDANCE_SEEDANCE_2_0,
|
|
156
|
+
// EVideoGenModels.PIXVERSE_V5_6,
|
|
157
|
+
// ]);
|
|
158
|
+
// AG-16: small allow-list for native-audio support — not yet on the schema as a
|
|
159
|
+
// queryable field, so kept hardcoded (conservative). Extend when audio becomes
|
|
160
|
+
// a proper config field like lastFrameImageUrl did.
|
|
150
161
|
const AUDIO_MODELS = new Set([
|
|
151
162
|
aiModels_1.EVideoGenModels.GOOGLE_VEO_3,
|
|
152
163
|
aiModels_1.EVideoGenModels.GOOGLE_VEO_3_1,
|
|
@@ -156,7 +167,8 @@ const AUDIO_MODELS = new Set([
|
|
|
156
167
|
aiModels_1.EVideoGenModels.KLING_AVATAR,
|
|
157
168
|
]);
|
|
158
169
|
function supportsEndFrame(m) {
|
|
159
|
-
|
|
170
|
+
// Single source of truth: model config declares `lastFrameImageUrl` in fields.
|
|
171
|
+
return (0, helpers_1.modelSupportsLastFrame)(m);
|
|
160
172
|
}
|
|
161
173
|
function supportsAudio(m) {
|
|
162
174
|
return AUDIO_MODELS.has(m);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/services/agent/repurpose/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./repurpose.schema"), exports);
|
|
18
|
+
__exportStar(require("./shortsPicker"), exports);
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* X8 Social Suite · Phase 6 · E3 — "auto-repurpose" schemas.
|
|
4
|
+
*
|
|
5
|
+
* One long source video → an LLM picks the strongest STANDALONE moments → each
|
|
6
|
+
* becomes an independent, platform-native vertical short (its own title + hook
|
|
7
|
+
* + score). This is opus.pro's core loop; we can do it AND host the source
|
|
8
|
+
* generation, so the long-form and its shorts share one brain + one bill.
|
|
9
|
+
*
|
|
10
|
+
* Deliberately a sibling of L-5 (edit-existing), not a fork of it. L-5 picks N
|
|
11
|
+
* segments and CONCATENATES them into ONE tighter recut; E3 picks N
|
|
12
|
+
* INDEPENDENT spans and emits N separate shorts. They share the ffmpeg
|
|
13
|
+
* primitives (cut/probe/upload) and the ASR transcript shape, but the
|
|
14
|
+
* selection brain and the output shape are different — so E3 gets its own pure
|
|
15
|
+
* picker (shortsPicker.ts) and its own worker, leaving the proven L-5 path
|
|
16
|
+
* untouched.
|
|
17
|
+
*
|
|
18
|
+
* As with the rest of the agent surface, the PURE logic (span selection,
|
|
19
|
+
* clamping, scoring, credit math) lives in `shared` so it is unit-/eval-able;
|
|
20
|
+
* the IO-heavy stages (download → ASR → ffmpeg cut → B2 reframe → upload) run
|
|
21
|
+
* in the node-express worker where ffmpeg already is.
|
|
22
|
+
*/
|
|
23
|
+
export declare const RepurposeRequestSchema: z.ZodObject<{
|
|
24
|
+
sourceVideoUrl: z.ZodString;
|
|
25
|
+
sourceDurationSec: z.ZodNumber;
|
|
26
|
+
maxShorts: z.ZodOptional<z.ZodNumber>;
|
|
27
|
+
targetShortSec: z.ZodOptional<z.ZodNumber>;
|
|
28
|
+
aspect: z.ZodOptional<z.ZodEnum<{
|
|
29
|
+
"9:16": "9:16";
|
|
30
|
+
"1:1": "1:1";
|
|
31
|
+
"4:5": "4:5";
|
|
32
|
+
"16:9": "16:9";
|
|
33
|
+
}>>;
|
|
34
|
+
language: z.ZodOptional<z.ZodString>;
|
|
35
|
+
instructions: z.ZodOptional<z.ZodString>;
|
|
36
|
+
tone: z.ZodOptional<z.ZodString>;
|
|
37
|
+
title: z.ZodOptional<z.ZodString>;
|
|
38
|
+
}, z.core.$strict>;
|
|
39
|
+
export type RepurposeRequest = z.infer<typeof RepurposeRequestSchema>;
|
|
40
|
+
/** Bounds for a single short, enforced after the LLM picks (see clampShorts). */
|
|
41
|
+
export declare const MIN_SHORT_MS = 3000;
|
|
42
|
+
export declare const MAX_SHORT_MS = 180000;
|
|
43
|
+
export declare const SHORT_TITLE_MAX = 100;
|
|
44
|
+
export declare const SHORT_HOOK_MAX = 280;
|
|
45
|
+
export declare const SHORT_REASON_MAX = 500;
|
|
46
|
+
export declare const SHORT_LABEL_MAX = 120;
|
|
47
|
+
/**
|
|
48
|
+
* One standalone short: a single contiguous span of the source plus the copy
|
|
49
|
+
* needed to post it. (v1 is one span per short — a jump-cut micro-montage per
|
|
50
|
+
* short is a deferred enhancement; the shape stays span-based so it's easy to
|
|
51
|
+
* extend later.) Per-platform caption variants are NOT produced here — the E1
|
|
52
|
+
* caption generator can enrich each short downstream from `title`/`hook`.
|
|
53
|
+
*/
|
|
54
|
+
export declare const ShortCandidateSchema: z.ZodObject<{
|
|
55
|
+
startMs: z.ZodNumber;
|
|
56
|
+
endMs: z.ZodNumber;
|
|
57
|
+
title: z.ZodString;
|
|
58
|
+
hook: z.ZodString;
|
|
59
|
+
reason: z.ZodString;
|
|
60
|
+
score: z.ZodNumber;
|
|
61
|
+
label: z.ZodOptional<z.ZodString>;
|
|
62
|
+
}, z.core.$strict>;
|
|
63
|
+
export type ShortCandidate = z.infer<typeof ShortCandidateSchema>;
|
|
64
|
+
export declare const ShortPlanSchema: z.ZodObject<{
|
|
65
|
+
shorts: z.ZodArray<z.ZodObject<{
|
|
66
|
+
startMs: z.ZodNumber;
|
|
67
|
+
endMs: z.ZodNumber;
|
|
68
|
+
title: z.ZodString;
|
|
69
|
+
hook: z.ZodString;
|
|
70
|
+
reason: z.ZodString;
|
|
71
|
+
score: z.ZodNumber;
|
|
72
|
+
label: z.ZodOptional<z.ZodString>;
|
|
73
|
+
}, z.core.$strict>>;
|
|
74
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
75
|
+
}, z.core.$strict>;
|
|
76
|
+
export type ShortPlan = z.infer<typeof ShortPlanSchema>;
|
|
77
|
+
/**
|
|
78
|
+
* Tiny job envelope — same design rule as EditJobPayload: the full request
|
|
79
|
+
* lives on `agentProjects/{projectId}.repurposeRequest`, the worker reads it at
|
|
80
|
+
* job start. Keeps the Redis stream light.
|
|
81
|
+
*/
|
|
82
|
+
export declare const RepurposeJobPayloadSchema: z.ZodObject<{
|
|
83
|
+
runId: z.ZodString;
|
|
84
|
+
projectId: z.ZodString;
|
|
85
|
+
userId: z.ZodString;
|
|
86
|
+
enqueuedAt: z.ZodNumber;
|
|
87
|
+
}, z.core.$strict>;
|
|
88
|
+
export type RepurposeJobPayload = z.infer<typeof RepurposeJobPayloadSchema>;
|
|
89
|
+
/**
|
|
90
|
+
* A finished short on `agentProjects/{projectId}.shorts[]`. Carries the copy
|
|
91
|
+
* the composer needs (title/hook) plus the reframed MP4 and its source span so
|
|
92
|
+
* the user can trace / re-edit it.
|
|
93
|
+
*/
|
|
94
|
+
export interface ProducedShort {
|
|
95
|
+
index: number;
|
|
96
|
+
title: string;
|
|
97
|
+
hook: string;
|
|
98
|
+
reason: string;
|
|
99
|
+
score: number;
|
|
100
|
+
/** Source span this short was cut from, ms. */
|
|
101
|
+
sourceStartMs: number;
|
|
102
|
+
sourceEndMs: number;
|
|
103
|
+
/** Output aspect (the requested target, e.g. "9:16"). */
|
|
104
|
+
aspect: string;
|
|
105
|
+
/** Long-lived signed URL of the reframed short MP4. */
|
|
106
|
+
mp4Url: string;
|
|
107
|
+
durationMs: number;
|
|
108
|
+
width: number;
|
|
109
|
+
height: number;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Flat USD overheads beyond the per-second ASR cost:
|
|
113
|
+
* - the shorts-picker LLM call (one structured call over the transcript), and
|
|
114
|
+
* - our ffmpeg compute per short (cut + B2 reframe + upload — our own metal,
|
|
115
|
+
* priced so the op isn't free).
|
|
116
|
+
*/
|
|
117
|
+
export declare const REPURPOSE_PICKER_LLM_USD = 0.05;
|
|
118
|
+
export declare const REPURPOSE_COMPUTE_PER_SHORT_USD = 0.03;
|
|
119
|
+
/** Default shorts assumed for the upfront estimate when maxShorts is omitted. */
|
|
120
|
+
export declare const DEFAULT_MAX_SHORTS = 5;
|
|
121
|
+
/**
|
|
122
|
+
* Pure upfront credit estimate for a repurpose job. The controller deducts this
|
|
123
|
+
* before enqueue; the worker reconciles against the REAL ASR duration and the
|
|
124
|
+
* actual number of shorts produced, refunding any overcharge. 1 credit = $0.10.
|
|
125
|
+
* Shorts picking needs no diarization (no speaker-aware Q→A constraint), so no
|
|
126
|
+
* diarization surcharge — unlike L-5's podcast/interview goals.
|
|
127
|
+
*/
|
|
128
|
+
export declare function estimateRepurposeCredits(args: {
|
|
129
|
+
sourceDurationSec: number;
|
|
130
|
+
maxShorts?: number;
|
|
131
|
+
}): number;
|
|
132
|
+
//# sourceMappingURL=repurpose.schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repurpose.schema.d.ts","sourceRoot":"","sources":["../../../../src/services/agent/repurpose/repurpose.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;kBA4BxB,CAAC;AACZ,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAItE,iFAAiF;AACjF,eAAO,MAAM,YAAY,OAAQ,CAAC;AAClC,eAAO,MAAM,YAAY,SAAU,CAAC;AACpC,eAAO,MAAM,eAAe,MAAM,CAAC;AACnC,eAAO,MAAM,cAAc,MAAM,CAAC;AAClC,eAAO,MAAM,gBAAgB,MAAM,CAAC;AACpC,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;kBAqB7B,CAAC;AACL,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,eAAe;;;;;;;;;;;kBAMjB,CAAC;AACZ,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAIxD;;;;GAIG;AACH,eAAO,MAAM,yBAAyB;;;;;kBAO3B,CAAC;AACZ,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAI5E;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAID;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAC7C,eAAO,MAAM,+BAA+B,OAAO,CAAC;AAGpD,iFAAiF;AACjF,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAQT"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_MAX_SHORTS = exports.REPURPOSE_COMPUTE_PER_SHORT_USD = exports.REPURPOSE_PICKER_LLM_USD = exports.RepurposeJobPayloadSchema = exports.ShortPlanSchema = exports.ShortCandidateSchema = exports.SHORT_LABEL_MAX = exports.SHORT_REASON_MAX = exports.SHORT_HOOK_MAX = exports.SHORT_TITLE_MAX = exports.MAX_SHORT_MS = exports.MIN_SHORT_MS = exports.RepurposeRequestSchema = void 0;
|
|
4
|
+
exports.estimateRepurposeCredits = estimateRepurposeCredits;
|
|
5
|
+
const zod_1 = require("zod");
|
|
6
|
+
const project_schema_1 = require("../../../schemas/project.schema");
|
|
7
|
+
const helpers_1 = require("../../../utils/helpers");
|
|
8
|
+
/**
|
|
9
|
+
* X8 Social Suite · Phase 6 · E3 — "auto-repurpose" schemas.
|
|
10
|
+
*
|
|
11
|
+
* One long source video → an LLM picks the strongest STANDALONE moments → each
|
|
12
|
+
* becomes an independent, platform-native vertical short (its own title + hook
|
|
13
|
+
* + score). This is opus.pro's core loop; we can do it AND host the source
|
|
14
|
+
* generation, so the long-form and its shorts share one brain + one bill.
|
|
15
|
+
*
|
|
16
|
+
* Deliberately a sibling of L-5 (edit-existing), not a fork of it. L-5 picks N
|
|
17
|
+
* segments and CONCATENATES them into ONE tighter recut; E3 picks N
|
|
18
|
+
* INDEPENDENT spans and emits N separate shorts. They share the ffmpeg
|
|
19
|
+
* primitives (cut/probe/upload) and the ASR transcript shape, but the
|
|
20
|
+
* selection brain and the output shape are different — so E3 gets its own pure
|
|
21
|
+
* picker (shortsPicker.ts) and its own worker, leaving the proven L-5 path
|
|
22
|
+
* untouched.
|
|
23
|
+
*
|
|
24
|
+
* As with the rest of the agent surface, the PURE logic (span selection,
|
|
25
|
+
* clamping, scoring, credit math) lives in `shared` so it is unit-/eval-able;
|
|
26
|
+
* the IO-heavy stages (download → ASR → ffmpeg cut → B2 reframe → upload) run
|
|
27
|
+
* in the node-express worker where ffmpeg already is.
|
|
28
|
+
*/
|
|
29
|
+
// ─── request (the controller body) ───────────────────────────────────────────
|
|
30
|
+
exports.RepurposeRequestSchema = zod_1.z
|
|
31
|
+
.object({
|
|
32
|
+
/** Publicly-fetchable URL of the long source video (Firebase Storage / signed). */
|
|
33
|
+
sourceVideoUrl: zod_1.z.string().url(),
|
|
34
|
+
/**
|
|
35
|
+
* Source duration in seconds — the uploader knows it, and we need it for the
|
|
36
|
+
* UPFRONT credit estimate (ASR is billed per second). The worker reconciles
|
|
37
|
+
* against the real ASR `audioDuration` after transcription.
|
|
38
|
+
*/
|
|
39
|
+
sourceDurationSec: zod_1.z.number().positive(),
|
|
40
|
+
/** Hard cap on how many shorts to produce. Picker default is 5 if omitted. */
|
|
41
|
+
maxShorts: zod_1.z.number().int().positive().max(20).optional(),
|
|
42
|
+
/**
|
|
43
|
+
* Target length of EACH short in seconds. The picker treats this as a soft
|
|
44
|
+
* aim (it won't pad weak material to hit it). Omitted → ~30s default.
|
|
45
|
+
*/
|
|
46
|
+
targetShortSec: zod_1.z.number().positive().max(180).optional(),
|
|
47
|
+
/** Output aspect for the shorts. Default 9:16 (Reels/Shorts/TikTok). */
|
|
48
|
+
aspect: project_schema_1.AspectSchema.optional(),
|
|
49
|
+
/** ASR language hint (e.g. "en", "es"). Omitted → AssemblyAI autodetect. */
|
|
50
|
+
language: zod_1.z.string().min(2).max(10).optional(),
|
|
51
|
+
/** Free-form steering for the picker ("focus on the product demo", etc.). */
|
|
52
|
+
instructions: zod_1.z.string().max(2000).optional(),
|
|
53
|
+
/** Tone hint for the generated hooks ("energetic", "professional"). */
|
|
54
|
+
tone: zod_1.z.string().max(200).optional(),
|
|
55
|
+
/** Display title prefix for the produced shorts / project. */
|
|
56
|
+
title: zod_1.z.string().max(200).optional(),
|
|
57
|
+
})
|
|
58
|
+
.strict();
|
|
59
|
+
// ─── short candidates (LLM output) ───────────────────────────────────────────
|
|
60
|
+
/** Bounds for a single short, enforced after the LLM picks (see clampShorts). */
|
|
61
|
+
exports.MIN_SHORT_MS = 3000;
|
|
62
|
+
exports.MAX_SHORT_MS = 180000;
|
|
63
|
+
exports.SHORT_TITLE_MAX = 100;
|
|
64
|
+
exports.SHORT_HOOK_MAX = 280;
|
|
65
|
+
exports.SHORT_REASON_MAX = 500;
|
|
66
|
+
exports.SHORT_LABEL_MAX = 120;
|
|
67
|
+
/**
|
|
68
|
+
* One standalone short: a single contiguous span of the source plus the copy
|
|
69
|
+
* needed to post it. (v1 is one span per short — a jump-cut micro-montage per
|
|
70
|
+
* short is a deferred enhancement; the shape stays span-based so it's easy to
|
|
71
|
+
* extend later.) Per-platform caption variants are NOT produced here — the E1
|
|
72
|
+
* caption generator can enrich each short downstream from `title`/`hook`.
|
|
73
|
+
*/
|
|
74
|
+
exports.ShortCandidateSchema = zod_1.z
|
|
75
|
+
.object({
|
|
76
|
+
/** Inclusive start in the SOURCE timeline, ms. */
|
|
77
|
+
startMs: zod_1.z.number().nonnegative(),
|
|
78
|
+
/** Exclusive end in the SOURCE timeline, ms. Must be > startMs (refined below). */
|
|
79
|
+
endMs: zod_1.z.number().positive(),
|
|
80
|
+
/** Short, scroll-stopping title (used by YouTube Shorts). */
|
|
81
|
+
title: zod_1.z.string().max(exports.SHORT_TITLE_MAX),
|
|
82
|
+
/** First-line caption hook — the opening line that earns the watch. */
|
|
83
|
+
hook: zod_1.z.string().max(exports.SHORT_HOOK_MAX),
|
|
84
|
+
/** Why this moment stands alone as a short — surfaced in the UI + eval. */
|
|
85
|
+
reason: zod_1.z.string().max(exports.SHORT_REASON_MAX),
|
|
86
|
+
/** Predicted engagement 0–100 (used to rank when more are picked than the cap). */
|
|
87
|
+
score: zod_1.z.number().min(0).max(100),
|
|
88
|
+
/** Optional short human label (e.g. "The pricing reveal"). */
|
|
89
|
+
label: zod_1.z.string().max(exports.SHORT_LABEL_MAX).optional(),
|
|
90
|
+
})
|
|
91
|
+
.strict()
|
|
92
|
+
.refine((s) => s.endMs > s.startMs, {
|
|
93
|
+
message: "endMs must be greater than startMs",
|
|
94
|
+
path: ["endMs"],
|
|
95
|
+
});
|
|
96
|
+
exports.ShortPlanSchema = zod_1.z
|
|
97
|
+
.object({
|
|
98
|
+
shorts: zod_1.z.array(exports.ShortCandidateSchema).min(1),
|
|
99
|
+
/** One-line description of the repurpose run (optional; shown in UI). */
|
|
100
|
+
summary: zod_1.z.string().max(500).optional(),
|
|
101
|
+
})
|
|
102
|
+
.strict();
|
|
103
|
+
// ─── BullMQ envelope ─────────────────────────────────────────────────────────
|
|
104
|
+
/**
|
|
105
|
+
* Tiny job envelope — same design rule as EditJobPayload: the full request
|
|
106
|
+
* lives on `agentProjects/{projectId}.repurposeRequest`, the worker reads it at
|
|
107
|
+
* job start. Keeps the Redis stream light.
|
|
108
|
+
*/
|
|
109
|
+
exports.RepurposeJobPayloadSchema = zod_1.z
|
|
110
|
+
.object({
|
|
111
|
+
runId: zod_1.z.string().min(1),
|
|
112
|
+
projectId: zod_1.z.string().min(1),
|
|
113
|
+
userId: zod_1.z.string().min(1),
|
|
114
|
+
enqueuedAt: zod_1.z.number().int().nonnegative(),
|
|
115
|
+
})
|
|
116
|
+
.strict();
|
|
117
|
+
// ─── cost ────────────────────────────────────────────────────────────────────
|
|
118
|
+
/**
|
|
119
|
+
* Flat USD overheads beyond the per-second ASR cost:
|
|
120
|
+
* - the shorts-picker LLM call (one structured call over the transcript), and
|
|
121
|
+
* - our ffmpeg compute per short (cut + B2 reframe + upload — our own metal,
|
|
122
|
+
* priced so the op isn't free).
|
|
123
|
+
*/
|
|
124
|
+
exports.REPURPOSE_PICKER_LLM_USD = 0.05;
|
|
125
|
+
exports.REPURPOSE_COMPUTE_PER_SHORT_USD = 0.03;
|
|
126
|
+
/** AssemblyAI Universal-2 base rate, $/hr (mirrors AssemblyAIService / L-5). */
|
|
127
|
+
const ASR_USD_PER_HOUR = 0.15;
|
|
128
|
+
/** Default shorts assumed for the upfront estimate when maxShorts is omitted. */
|
|
129
|
+
exports.DEFAULT_MAX_SHORTS = 5;
|
|
130
|
+
/**
|
|
131
|
+
* Pure upfront credit estimate for a repurpose job. The controller deducts this
|
|
132
|
+
* before enqueue; the worker reconciles against the REAL ASR duration and the
|
|
133
|
+
* actual number of shorts produced, refunding any overcharge. 1 credit = $0.10.
|
|
134
|
+
* Shorts picking needs no diarization (no speaker-aware Q→A constraint), so no
|
|
135
|
+
* diarization surcharge — unlike L-5's podcast/interview goals.
|
|
136
|
+
*/
|
|
137
|
+
function estimateRepurposeCredits(args) {
|
|
138
|
+
const shorts = args.maxShorts ?? exports.DEFAULT_MAX_SHORTS;
|
|
139
|
+
const asrUsd = (ASR_USD_PER_HOUR / 3600) * Math.max(0, args.sourceDurationSec);
|
|
140
|
+
const totalUsd = asrUsd +
|
|
141
|
+
exports.REPURPOSE_PICKER_LLM_USD +
|
|
142
|
+
exports.REPURPOSE_COMPUTE_PER_SHORT_USD * Math.max(1, shorts);
|
|
143
|
+
return (0, helpers_1.getCreditsFromCost)(totalUsd);
|
|
144
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { LlmCaller } from "../llmCaller";
|
|
2
|
+
import { TranscriptForPicking } from "../editExisting/highlightPicker";
|
|
3
|
+
import { RepurposeRequest, ShortCandidate } from "./repurpose.schema";
|
|
4
|
+
/**
|
|
5
|
+
* Clamp shorts into [0, sourceDurationMs], cap each to MAX_SHORT_MS, drop
|
|
6
|
+
* slivers below MIN_SHORT_MS, sort chronologically, and remove overlaps (a
|
|
7
|
+
* later span starting before the previous one ended is pushed forward; if that
|
|
8
|
+
* collapses it below the minimum, it's dropped). Also clamps the copy fields
|
|
9
|
+
* and score. Pure + idempotent — safe on already-clean input.
|
|
10
|
+
*/
|
|
11
|
+
export declare function clampShorts(shorts: ShortCandidate[], sourceDurationMs: number): ShortCandidate[];
|
|
12
|
+
/**
|
|
13
|
+
* Pick standalone shorts from a transcript. Retries up to `maxRetries` times,
|
|
14
|
+
* feeding the model its previous problems. Throws only if every attempt yields
|
|
15
|
+
* zero usable shorts.
|
|
16
|
+
*/
|
|
17
|
+
export declare function pickShortsCore(llm: LlmCaller, args: {
|
|
18
|
+
request: RepurposeRequest;
|
|
19
|
+
transcript: TranscriptForPicking;
|
|
20
|
+
maxRetries?: number;
|
|
21
|
+
}): Promise<{
|
|
22
|
+
shorts: ShortCandidate[];
|
|
23
|
+
summary?: string;
|
|
24
|
+
}>;
|
|
25
|
+
//# sourceMappingURL=shortsPicker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shortsPicker.d.ts","sourceRoot":"","sources":["../../../../src/services/agent/repurpose/shortsPicker.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,SAAS,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,EAEL,oBAAoB,EACrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAIL,gBAAgB,EAChB,cAAc,EAKf,MAAM,oBAAoB,CAAC;AAwG5B;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,cAAc,EAAE,EACxB,gBAAgB,EAAE,MAAM,GACvB,cAAc,EAAE,CA4BlB;AAmDD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,SAAS,EACd,IAAI,EAAE;IACJ,OAAO,EAAE,gBAAgB,CAAC;IAC1B,UAAU,EAAE,oBAAoB,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GACA,OAAO,CAAC;IAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA0DzD"}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.clampShorts = clampShorts;
|
|
4
|
+
exports.pickShortsCore = pickShortsCore;
|
|
5
|
+
const zod_1 = require("zod");
|
|
6
|
+
const logger_1 = require("../../../utils/logger");
|
|
7
|
+
const modelRouter_1 = require("../modelRouter");
|
|
8
|
+
const highlightPicker_1 = require("../editExisting/highlightPicker");
|
|
9
|
+
const repurpose_schema_1 = require("./repurpose.schema");
|
|
10
|
+
/**
|
|
11
|
+
* X8 Social Suite · Phase 6 · E3 — shorts picker. The reasoning core of the
|
|
12
|
+
* auto-repurpose pipeline: given an ASR transcript of a LONG video, an LLM
|
|
13
|
+
* selects the strongest STANDALONE spans, each of which becomes an independent
|
|
14
|
+
* vertical short with its own title, hook, and predicted-engagement score.
|
|
15
|
+
*
|
|
16
|
+
* Pure (injected LlmCaller), so the worker, scripts, and a no-spend eval can
|
|
17
|
+
* all drive it. Reuses L-5's transcript shape + `buildTranscriptLines` (same
|
|
18
|
+
* AssemblyAI output), but the selection bias is the opposite: L-5 keeps a
|
|
19
|
+
* continuous "best of" recut; here every pick must work ALONE as a clip.
|
|
20
|
+
*/
|
|
21
|
+
const DEFAULT_TARGET_SHORT_SEC = 30;
|
|
22
|
+
/**
|
|
23
|
+
* The raw LLM output. Looser than ShortCandidateSchema (no refine / max) on
|
|
24
|
+
* purpose — we bounds-check + clamp afterwards so a slightly-off model answer
|
|
25
|
+
* is repaired rather than rejected.
|
|
26
|
+
*/
|
|
27
|
+
const LlmShortsSchema = zod_1.z.object({
|
|
28
|
+
shorts: zod_1.z
|
|
29
|
+
.array(zod_1.z.object({
|
|
30
|
+
startMs: zod_1.z.number(),
|
|
31
|
+
endMs: zod_1.z.number(),
|
|
32
|
+
title: zod_1.z.string(),
|
|
33
|
+
hook: zod_1.z.string(),
|
|
34
|
+
reason: zod_1.z.string(),
|
|
35
|
+
score: zod_1.z.number(),
|
|
36
|
+
label: zod_1.z.string().optional(),
|
|
37
|
+
}))
|
|
38
|
+
.min(1),
|
|
39
|
+
summary: zod_1.z.string().optional(),
|
|
40
|
+
});
|
|
41
|
+
function fmtTs(ms) {
|
|
42
|
+
const totalSec = Math.floor(ms / 1000);
|
|
43
|
+
const m = Math.floor(totalSec / 60);
|
|
44
|
+
const s = totalSec % 60;
|
|
45
|
+
return `${m}:${String(s).padStart(2, "0")}`;
|
|
46
|
+
}
|
|
47
|
+
function buildMessages(request, transcript, feedback) {
|
|
48
|
+
const targetSec = request.targetShortSec ?? DEFAULT_TARGET_SHORT_SEC;
|
|
49
|
+
const maxShorts = request.maxShorts ?? repurpose_schema_1.DEFAULT_MAX_SHORTS;
|
|
50
|
+
const system = [
|
|
51
|
+
"You are a short-form video strategist (think the editor behind a viral",
|
|
52
|
+
"Reels/TikTok/Shorts channel). You are given a timestamped transcript of a",
|
|
53
|
+
"LONG source video and must choose the spans that would each become the",
|
|
54
|
+
"BEST STANDALONE vertical short. Output only spans that exist in the",
|
|
55
|
+
"transcript, using millisecond start/end times taken from the bracketed",
|
|
56
|
+
"timestamps.",
|
|
57
|
+
"",
|
|
58
|
+
"Each short MUST work on its own with no other context:",
|
|
59
|
+
"- It opens on a strong hook and resolves a complete thought (never cut",
|
|
60
|
+
" mid-sentence).",
|
|
61
|
+
"- It is self-contained: a viewer who never saw the rest still gets value.",
|
|
62
|
+
`- Aim for roughly ${Math.round(targetSec)}s each (a tight ${repurpose_schema_1.MIN_SHORT_MS / 1000}–${repurpose_schema_1.MAX_SHORT_MS / 1000}s is the hard range); shorter & punchier beats padded.`,
|
|
63
|
+
"- Spans must NOT overlap each other and must lie within the video bounds.",
|
|
64
|
+
`- Every span must lie within [0, ${transcript.audioDurationMs}] ms.`,
|
|
65
|
+
"",
|
|
66
|
+
"For each short also write:",
|
|
67
|
+
"- `title`: a scroll-stopping title (≤ ~10 words) for YouTube Shorts.",
|
|
68
|
+
"- `hook`: the first-line caption that earns the watch (curiosity / payoff /",
|
|
69
|
+
" bold claim) — one or two sentences.",
|
|
70
|
+
"- `reason`: why this moment stands alone as a short.",
|
|
71
|
+
"- `score`: 0–100 predicted engagement; reserve 80+ for genuinely strong picks.",
|
|
72
|
+
"Pick QUALITY over quantity — only spans that are actually share-worthy.",
|
|
73
|
+
].join("\n");
|
|
74
|
+
const langLine = request.language
|
|
75
|
+
? `Write the title and hook in this language (BCP-47 "${request.language}").`
|
|
76
|
+
: "Write the title and hook in the same language the transcript is spoken in.";
|
|
77
|
+
const toneLine = request.tone
|
|
78
|
+
? `Tone for the title/hook: ${request.tone}.`
|
|
79
|
+
: "";
|
|
80
|
+
const user = [
|
|
81
|
+
`GOAL: repurpose this long video into up to ${maxShorts} standalone vertical shorts.`,
|
|
82
|
+
langLine,
|
|
83
|
+
toneLine,
|
|
84
|
+
request.instructions ? `ADDITIONAL INSTRUCTIONS: ${request.instructions}` : "",
|
|
85
|
+
feedback ? `\nYOUR PREVIOUS ANSWER HAD PROBLEMS — FIX THESE:\n${feedback}` : "",
|
|
86
|
+
"",
|
|
87
|
+
`TRANSCRIPT (total ${fmtTs(transcript.audioDurationMs)}):`,
|
|
88
|
+
(0, highlightPicker_1.buildTranscriptLines)(transcript),
|
|
89
|
+
]
|
|
90
|
+
.filter(Boolean)
|
|
91
|
+
.join("\n");
|
|
92
|
+
return [
|
|
93
|
+
{ role: "system", content: system },
|
|
94
|
+
{ role: "user", content: user },
|
|
95
|
+
];
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Clamp shorts into [0, sourceDurationMs], cap each to MAX_SHORT_MS, drop
|
|
99
|
+
* slivers below MIN_SHORT_MS, sort chronologically, and remove overlaps (a
|
|
100
|
+
* later span starting before the previous one ended is pushed forward; if that
|
|
101
|
+
* collapses it below the minimum, it's dropped). Also clamps the copy fields
|
|
102
|
+
* and score. Pure + idempotent — safe on already-clean input.
|
|
103
|
+
*/
|
|
104
|
+
function clampShorts(shorts, sourceDurationMs) {
|
|
105
|
+
const bounded = shorts
|
|
106
|
+
.map((s) => {
|
|
107
|
+
const startMs = Math.max(0, Math.min(s.startMs, sourceDurationMs));
|
|
108
|
+
let endMs = Math.max(0, Math.min(s.endMs, sourceDurationMs));
|
|
109
|
+
if (endMs - startMs > repurpose_schema_1.MAX_SHORT_MS)
|
|
110
|
+
endMs = startMs + repurpose_schema_1.MAX_SHORT_MS;
|
|
111
|
+
return {
|
|
112
|
+
startMs,
|
|
113
|
+
endMs,
|
|
114
|
+
title: (s.title ?? "").slice(0, repurpose_schema_1.SHORT_TITLE_MAX),
|
|
115
|
+
hook: (s.hook ?? "").slice(0, repurpose_schema_1.SHORT_HOOK_MAX),
|
|
116
|
+
reason: (s.reason ?? "").slice(0, repurpose_schema_1.SHORT_REASON_MAX),
|
|
117
|
+
score: Math.max(0, Math.min(100, Number.isFinite(s.score) ? s.score : 0)),
|
|
118
|
+
...(s.label ? { label: s.label.slice(0, repurpose_schema_1.SHORT_LABEL_MAX) } : {}),
|
|
119
|
+
};
|
|
120
|
+
})
|
|
121
|
+
.filter((s) => s.endMs - s.startMs >= repurpose_schema_1.MIN_SHORT_MS)
|
|
122
|
+
.sort((a, b) => a.startMs - b.startMs);
|
|
123
|
+
const out = [];
|
|
124
|
+
let prevEnd = 0;
|
|
125
|
+
for (const s of bounded) {
|
|
126
|
+
const start = Math.max(s.startMs, prevEnd);
|
|
127
|
+
if (s.endMs - start < repurpose_schema_1.MIN_SHORT_MS)
|
|
128
|
+
continue; // collapsed by overlap removal
|
|
129
|
+
out.push({ ...s, startMs: start });
|
|
130
|
+
prevEnd = s.endMs;
|
|
131
|
+
}
|
|
132
|
+
return out;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Validate + repair a raw LLM selection against the transcript bounds and the
|
|
136
|
+
* request constraints. Returns cleaned shorts (top-`maxShorts` by score, then
|
|
137
|
+
* re-sorted chronologically) and human-readable problems used as retry feedback.
|
|
138
|
+
*/
|
|
139
|
+
function validateSelection(raw, request, audioDurationMs) {
|
|
140
|
+
const problems = [];
|
|
141
|
+
const maxShorts = request.maxShorts ?? repurpose_schema_1.DEFAULT_MAX_SHORTS;
|
|
142
|
+
const mapped = raw.shorts.map((s) => ({
|
|
143
|
+
startMs: s.startMs,
|
|
144
|
+
endMs: s.endMs,
|
|
145
|
+
title: s.title ?? "",
|
|
146
|
+
hook: s.hook ?? "",
|
|
147
|
+
reason: s.reason ?? "",
|
|
148
|
+
score: s.score ?? 0,
|
|
149
|
+
...(s.label ? { label: s.label } : {}),
|
|
150
|
+
}));
|
|
151
|
+
const outOfBounds = mapped.filter((s) => s.startMs < 0 || s.endMs > audioDurationMs + 250 || s.endMs <= s.startMs);
|
|
152
|
+
if (outOfBounds.length > 0) {
|
|
153
|
+
problems.push(`${outOfBounds.length} short(s) were out of bounds or had endMs ≤ startMs (video is ${audioDurationMs}ms). Keep every span inside [0, ${audioDurationMs}] with endMs > startMs.`);
|
|
154
|
+
}
|
|
155
|
+
let cleaned = clampShorts(mapped, audioDurationMs);
|
|
156
|
+
if (cleaned.length === 0) {
|
|
157
|
+
return { shorts: [], problems };
|
|
158
|
+
}
|
|
159
|
+
if (cleaned.length > maxShorts) {
|
|
160
|
+
// Keep the strongest by score, then restore chronological order.
|
|
161
|
+
cleaned = [...cleaned]
|
|
162
|
+
.sort((a, b) => b.score - a.score)
|
|
163
|
+
.slice(0, maxShorts)
|
|
164
|
+
.sort((a, b) => a.startMs - b.startMs);
|
|
165
|
+
}
|
|
166
|
+
return { shorts: cleaned, problems };
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Pick standalone shorts from a transcript. Retries up to `maxRetries` times,
|
|
170
|
+
* feeding the model its previous problems. Throws only if every attempt yields
|
|
171
|
+
* zero usable shorts.
|
|
172
|
+
*/
|
|
173
|
+
async function pickShortsCore(llm, args) {
|
|
174
|
+
const router = new modelRouter_1.ModelRouter();
|
|
175
|
+
const maxRetries = args.maxRetries ?? 2;
|
|
176
|
+
const { request, transcript } = args;
|
|
177
|
+
let feedback;
|
|
178
|
+
let lastProblems = [];
|
|
179
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
180
|
+
const res = await llm.structured({
|
|
181
|
+
model: router.pickFor("planner"),
|
|
182
|
+
fallbackModel: router.fallbackFor("planner"),
|
|
183
|
+
schema: LlmShortsSchema,
|
|
184
|
+
schemaName: "ShortPlan",
|
|
185
|
+
messages: buildMessages(request, transcript, feedback),
|
|
186
|
+
temperature: 0.4,
|
|
187
|
+
maxTokens: 8000,
|
|
188
|
+
});
|
|
189
|
+
const { shorts, problems } = validateSelection(res.data, request, transcript.audioDurationMs);
|
|
190
|
+
lastProblems = problems;
|
|
191
|
+
if (shorts.length > 0 && problems.length === 0) {
|
|
192
|
+
logger_1.logger.info("repurpose.picker: selection accepted", {
|
|
193
|
+
attempt,
|
|
194
|
+
shorts: shorts.length,
|
|
195
|
+
audioDurationMs: transcript.audioDurationMs,
|
|
196
|
+
});
|
|
197
|
+
return { shorts, ...(res.data.summary ? { summary: res.data.summary } : {}) };
|
|
198
|
+
}
|
|
199
|
+
// Usable-but-imperfect on the final attempt: accept rather than throw — a
|
|
200
|
+
// few good shorts beat failing the whole job.
|
|
201
|
+
if (shorts.length > 0 && attempt === maxRetries) {
|
|
202
|
+
logger_1.logger.warn("repurpose.picker: accepting imperfect selection on last attempt", {
|
|
203
|
+
shorts: shorts.length,
|
|
204
|
+
problems,
|
|
205
|
+
});
|
|
206
|
+
return { shorts, ...(res.data.summary ? { summary: res.data.summary } : {}) };
|
|
207
|
+
}
|
|
208
|
+
feedback =
|
|
209
|
+
problems.join("\n") ||
|
|
210
|
+
"Your previous answer returned no usable shorts. Select at least one strong, self-contained span with valid timestamps.";
|
|
211
|
+
logger_1.logger.warn("repurpose.picker: retrying", {
|
|
212
|
+
attempt,
|
|
213
|
+
problems,
|
|
214
|
+
durationMs: transcript.audioDurationMs,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
throw new Error(`repurpose.picker: no usable shorts after ${maxRetries + 1} attempts (${lastProblems.join("; ")})`);
|
|
218
|
+
}
|