@mevdragon/vidfarm-devcli 0.14.0 → 0.15.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/.agents/skills/embedded-captions/CATALOG.md +93 -0
- package/.agents/skills/embedded-captions/SKILL.md +286 -0
- package/.agents/skills/embedded-captions/assets/brand/CDPR-fankit-terms.txt +35 -0
- package/.agents/skills/embedded-captions/assets/brand/cyberpunk-widths.json +115 -0
- package/.agents/skills/embedded-captions/assets/fonts/char-widths.json +2211 -0
- package/.agents/skills/embedded-captions/assets/strokefonts/HersheyScript1.svg +242 -0
- package/.agents/skills/embedded-captions/assets/strokefonts/HersheyScriptMed.svg +242 -0
- package/.agents/skills/embedded-captions/dna/README.md +148 -0
- package/.agents/skills/embedded-captions/dna/chrome.json +68 -0
- package/.agents/skills/embedded-captions/dna/cream.json +69 -0
- package/.agents/skills/embedded-captions/dna/documentary.json +62 -0
- package/.agents/skills/embedded-captions/dna/editorial.json +70 -0
- package/.agents/skills/embedded-captions/dna/glitch.json +82 -0
- package/.agents/skills/embedded-captions/dna/ink.json +65 -0
- package/.agents/skills/embedded-captions/dna/keynote.json +62 -0
- package/.agents/skills/embedded-captions/dna/loud.json +75 -0
- package/.agents/skills/embedded-captions/dna/neon.json +58 -0
- package/.agents/skills/embedded-captions/dna/velocity.json +89 -0
- package/.agents/skills/embedded-captions/modes/cinematic/README.md +48 -0
- package/.agents/skills/embedded-captions/modes/cinematic/_archive/champion/spec.md +98 -0
- package/.agents/skills/embedded-captions/modes/cinematic/_archive/champion/template.html +188 -0
- package/.agents/skills/embedded-captions/modes/cinematic/_archive/memory-wall/spec.md +134 -0
- package/.agents/skills/embedded-captions/modes/cinematic/_archive/memory-wall/template.html +179 -0
- package/.agents/skills/embedded-captions/modes/cinematic/_archive/portrait-header/spec.md +81 -0
- package/.agents/skills/embedded-captions/modes/cinematic/_archive/portrait-header/template.html +170 -0
- package/.agents/skills/embedded-captions/modes/cinematic/cinematic-cream/spec.md +16 -0
- package/.agents/skills/embedded-captions/modes/cinematic/cinematic-cream/template.html +226 -0
- package/.agents/skills/embedded-captions/modes/cinematic/engine.html +355 -0
- package/.agents/skills/embedded-captions/modes/standard/_anatomy.md +233 -0
- package/.agents/skills/embedded-captions/modes/standard/_motion.md +192 -0
- package/.agents/skills/embedded-captions/modes/standard/fonts/build-fonts-css.cjs +97 -0
- package/.agents/skills/embedded-captions/references/aesthetic-principles.md +168 -0
- package/.agents/skills/embedded-captions/references/anti-patterns.md +188 -0
- package/.agents/skills/embedded-captions/references/bespoke-vs-presets.md +178 -0
- package/.agents/skills/embedded-captions/references/caption-grouping.md +130 -0
- package/.agents/skills/embedded-captions/references/composition-craft.md +522 -0
- package/.agents/skills/embedded-captions/references/direction-catalog.md +138 -0
- package/.agents/skills/embedded-captions/references/example-renders/champion.html +371 -0
- package/.agents/skills/embedded-captions/references/example-renders/memory-wall.html +334 -0
- package/.agents/skills/embedded-captions/references/failure-modes.md +145 -0
- package/.agents/skills/embedded-captions/references/layout-heuristics.md +238 -0
- package/.agents/skills/embedded-captions/references/motion-vocabulary.md +148 -0
- package/.agents/skills/embedded-captions/references/rail.md +68 -0
- package/.agents/skills/embedded-captions/references/reference-bar.md +47 -0
- package/.agents/skills/embedded-captions/references/scene-types.md +94 -0
- package/.agents/skills/embedded-captions/references/test-set.md +66 -0
- package/.agents/skills/embedded-captions/references/typographic-moves.md +266 -0
- package/.agents/skills/embedded-captions/references/typography-presets.md +63 -0
- package/.agents/skills/embedded-captions/scripts/audio-envelope.cjs +95 -0
- package/.agents/skills/embedded-captions/scripts/check-occlusion.cjs +250 -0
- package/.agents/skills/embedded-captions/scripts/check-overflow.cjs +194 -0
- package/.agents/skills/embedded-captions/scripts/check-rail-climax.cjs +233 -0
- package/.agents/skills/embedded-captions/scripts/check-timing.cjs +173 -0
- package/.agents/skills/embedded-captions/scripts/fill-timings.cjs +124 -0
- package/.agents/skills/embedded-captions/scripts/fit-fonts.cjs +158 -0
- package/.agents/skills/embedded-captions/scripts/gen-stroke-path.py +46 -0
- package/.agents/skills/embedded-captions/scripts/inject-fonts.cjs +169 -0
- package/.agents/skills/embedded-captions/scripts/lib-dna.cjs +201 -0
- package/.agents/skills/embedded-captions/scripts/make-cinematic.cjs +1205 -0
- package/.agents/skills/embedded-captions/scripts/make-composition.cjs +404 -0
- package/.agents/skills/embedded-captions/scripts/make-theme.cjs +8781 -0
- package/.agents/skills/embedded-captions/scripts/matte.cjs +294 -0
- package/.agents/skills/embedded-captions/scripts/measure-layout.cjs +293 -0
- package/.agents/skills/embedded-captions/scripts/prepare.sh +39 -0
- package/.agents/skills/embedded-captions/scripts/preview-frames.cjs +268 -0
- package/.agents/skills/embedded-captions/scripts/render-and-composite.sh +509 -0
- package/.agents/skills/embedded-captions/scripts/render-theme.sh +34 -0
- package/.agents/skills/embedded-captions/scripts/safe-zones.cjs +813 -0
- package/.agents/skills/embedded-captions/scripts/transcribe.cjs +349 -0
- package/.agents/skills/embedded-captions/themes/PORTING.md +49 -0
- package/.agents/skills/embedded-captions/themes/README.md +244 -0
- package/.agents/skills/embedded-captions/themes/anchor.json +27 -0
- package/.agents/skills/embedded-captions/themes/arcade.json +51 -0
- package/.agents/skills/embedded-captions/themes/aurora.json +41 -0
- package/.agents/skills/embedded-captions/themes/biolume.json +35 -0
- package/.agents/skills/embedded-captions/themes/brush.json +74 -0
- package/.agents/skills/embedded-captions/themes/chalkboard.json +52 -0
- package/.agents/skills/embedded-captions/themes/dossier.json +56 -0
- package/.agents/skills/embedded-captions/themes/graffiti.json +62 -0
- package/.agents/skills/embedded-captions/themes/hologram.json +41 -0
- package/.agents/skills/embedded-captions/themes/inkwater.json +43 -0
- package/.agents/skills/embedded-captions/themes/laser.json +46 -0
- package/.agents/skills/embedded-captions/themes/lastpage.json +33 -0
- package/.agents/skills/embedded-captions/themes/neonsign.json +53 -0
- package/.agents/skills/embedded-captions/themes/nightcity.json +56 -0
- package/.agents/skills/embedded-captions/themes/ordnance.json +54 -0
- package/.agents/skills/embedded-captions/themes/papercut.json +37 -0
- package/.agents/skills/embedded-captions/themes/popup.json +46 -0
- package/.agents/skills/embedded-captions/themes/ransom.json +62 -0
- package/.agents/skills/embedded-captions/themes/scoreboard.json +54 -0
- package/.agents/skills/embedded-captions/themes/spectrum.json +46 -0
- package/.agents/skills/embedded-captions/themes/stardust.json +29 -0
- package/.agents/skills/embedded-captions/themes/stomp.json +43 -0
- package/.agents/skills/embedded-captions/themes/terminal.json +49 -0
- package/.agents/skills/embedded-captions/themes/thunder.json +44 -0
- package/.agents/skills/embedded-captions/themes/transit.json +44 -0
- package/.agents/skills/embedded-captions/themes/vhs.json +47 -0
- package/.agents/skills/faceless-explainer/SKILL.md +209 -0
- package/.agents/skills/faceless-explainer/references/cut-catalog.md +215 -0
- package/.agents/skills/faceless-explainer/references/motion-language.md +156 -0
- package/.agents/skills/faceless-explainer/references/story-design.md +248 -0
- package/.agents/skills/faceless-explainer/references/visual-design.md +146 -0
- package/.agents/skills/faceless-explainer/scripts/assemble-index.mjs +570 -0
- package/.agents/skills/faceless-explainer/scripts/audio.mjs +260 -0
- package/.agents/skills/faceless-explainer/scripts/build-frame.mjs +536 -0
- package/.agents/skills/faceless-explainer/scripts/captions.mjs +508 -0
- package/.agents/skills/faceless-explainer/scripts/lib/assets.mjs +55 -0
- package/.agents/skills/faceless-explainer/scripts/lib/dimensions.mjs +45 -0
- package/.agents/skills/faceless-explainer/scripts/lib/storyboard.mjs +249 -0
- package/.agents/skills/faceless-explainer/scripts/lib/tokens.mjs +204 -0
- package/.agents/skills/faceless-explainer/scripts/lib/transition-registry.mjs +38 -0
- package/.agents/skills/faceless-explainer/scripts/lib/transitions.json +71 -0
- package/.agents/skills/faceless-explainer/scripts/transitions.mjs +320 -0
- package/.agents/skills/faceless-explainer/sub-agents/frame-worker.md +75 -0
- package/.agents/skills/flockposter/LICENSE +17 -0
- package/.agents/skills/flockposter/README.md +72 -0
- package/.agents/skills/flockposter/SKILL.md +562 -0
- package/.agents/skills/flockposter/examples/cli-instagram-reel.sh +21 -0
- package/.agents/skills/flockposter/examples/cli-multi-platform.json +69 -0
- package/.agents/skills/flockposter/examples/cli-tiktok-upload-only.sh +22 -0
- package/.agents/skills/flockposter/examples/cli-x-thread.sh +17 -0
- package/.agents/skills/flockposter/examples/cli-youtube-short.sh +21 -0
- package/.agents/skills/flockposter/examples/public-api-instagram-reel.json +28 -0
- package/.agents/skills/general-video/SKILL.md +143 -0
- package/.agents/skills/hyperframes/SKILL.md +160 -0
- package/.agents/skills/hyperframes-animation/SKILL.md +84 -0
- package/.agents/skills/hyperframes-animation/adapters/animate-text.md +64 -0
- package/.agents/skills/hyperframes-animation/adapters/animejs.md +114 -0
- package/.agents/skills/hyperframes-animation/adapters/css-animations.md +143 -0
- package/.agents/skills/hyperframes-animation/adapters/gsap-easing-and-stagger.md +118 -0
- package/.agents/skills/hyperframes-animation/adapters/gsap-timeline-and-labels.md +96 -0
- package/.agents/skills/hyperframes-animation/adapters/gsap-transforms-and-perf.md +96 -0
- package/.agents/skills/hyperframes-animation/adapters/gsap.md +105 -0
- package/.agents/skills/hyperframes-animation/adapters/html-in-canvas-patterns.md +507 -0
- package/.agents/skills/hyperframes-animation/adapters/lottie.md +117 -0
- package/.agents/skills/hyperframes-animation/adapters/three.md +131 -0
- package/.agents/skills/hyperframes-animation/adapters/typegpu.md +178 -0
- package/.agents/skills/hyperframes-animation/adapters/waapi.md +101 -0
- package/.agents/skills/hyperframes-animation/blueprints/comparison-split.md +27 -0
- package/.agents/skills/hyperframes-animation/blueprints/constellation-hub.md +44 -0
- package/.agents/skills/hyperframes-animation/blueprints/cta-morph-press.md +28 -0
- package/.agents/skills/hyperframes-animation/blueprints/cursor-ui-demo.md +57 -0
- package/.agents/skills/hyperframes-animation/blueprints/dataviz-countup.md +46 -0
- package/.agents/skills/hyperframes-animation/blueprints/device-surface-showcase.md +53 -0
- package/.agents/skills/hyperframes-animation/blueprints/grid-card-assemble.md +66 -0
- package/.agents/skills/hyperframes-animation/blueprints/kinetic-type-beats.md +78 -0
- package/.agents/skills/hyperframes-animation/blueprints/logo-assemble-lockup.md +69 -0
- package/.agents/skills/hyperframes-animation/blueprints/overwhelm-surround.md +28 -0
- package/.agents/skills/hyperframes-animation/blueprints/spatial-pan-stations.md +37 -0
- package/.agents/skills/hyperframes-animation/blueprints/ticker-takeover.md +29 -0
- package/.agents/skills/hyperframes-animation/blueprints/titlecard-reveal.md +42 -0
- package/.agents/skills/hyperframes-animation/blueprints/typewriter-reveal.md +51 -0
- package/.agents/skills/hyperframes-animation/blueprints/video-text-pivot.md +30 -0
- package/.agents/skills/hyperframes-animation/blueprints-index.md +146 -0
- package/.agents/skills/hyperframes-animation/examples/assets/avatars/02.avif +0 -0
- package/.agents/skills/hyperframes-animation/examples/assets/brands/github.avif +0 -0
- package/.agents/skills/hyperframes-animation/examples/assets/brands/nvidia.avif +0 -0
- package/.agents/skills/hyperframes-animation/examples/assets/brands/visa.avif +0 -0
- package/.agents/skills/hyperframes-animation/examples/assets/brands/zoominfo.avif +0 -0
- package/.agents/skills/hyperframes-animation/examples/brand-reveal-assemble-zoom.html +382 -0
- package/.agents/skills/hyperframes-animation/examples/comparison-split-cards.html +649 -0
- package/.agents/skills/hyperframes-animation/examples/concept-demo-decode-pan.html +520 -0
- package/.agents/skills/hyperframes-animation/examples/cta-morph-press.html +468 -0
- package/.agents/skills/hyperframes-animation/examples/cta-orbit-collapse.html +1298 -0
- package/.agents/skills/hyperframes-animation/examples/demo-page-scroll-spotlight.html +759 -0
- package/.agents/skills/hyperframes-animation/examples/hook-counter-burst.html +729 -0
- package/.agents/skills/hyperframes-animation/examples/messaging-multi-phrase.html +352 -0
- package/.agents/skills/hyperframes-animation/examples/metric-video-text-pivot.html +779 -0
- package/.agents/skills/hyperframes-animation/examples/problem-mockup-overwhelm.html +1374 -0
- package/.agents/skills/hyperframes-animation/examples/proof-logo-chain.html +861 -0
- package/.agents/skills/hyperframes-animation/examples/takeover-ticker-displace.html +347 -0
- package/.agents/skills/hyperframes-animation/examples/workflow-approve-press.html +606 -0
- package/.agents/skills/hyperframes-animation/rules/3d-page-scroll.md +227 -0
- package/.agents/skills/hyperframes-animation/rules/3d-text-depth-layers.md +297 -0
- package/.agents/skills/hyperframes-animation/rules/ai-tracking-box.md +382 -0
- package/.agents/skills/hyperframes-animation/rules/ambient-glow-bloom.md +305 -0
- package/.agents/skills/hyperframes-animation/rules/asr-keyword-glow.md +286 -0
- package/.agents/skills/hyperframes-animation/rules/avatar-cloud-network.md +371 -0
- package/.agents/skills/hyperframes-animation/rules/camera-cursor-tracking.md +246 -0
- package/.agents/skills/hyperframes-animation/rules/card-morph-anchor.md +267 -0
- package/.agents/skills/hyperframes-animation/rules/center-outward-expansion.md +227 -0
- package/.agents/skills/hyperframes-animation/rules/context-sensitive-cursor.md +257 -0
- package/.agents/skills/hyperframes-animation/rules/coordinate-target-zoom.md +332 -0
- package/.agents/skills/hyperframes-animation/rules/counting-dynamic-scale.md +283 -0
- package/.agents/skills/hyperframes-animation/rules/css-marker-patterns.md +373 -0
- package/.agents/skills/hyperframes-animation/rules/cursor-click-ripple.md +262 -0
- package/.agents/skills/hyperframes-animation/rules/depth-of-field-blur.md +313 -0
- package/.agents/skills/hyperframes-animation/rules/depth-scatter-assemble.md +303 -0
- package/.agents/skills/hyperframes-animation/rules/discrete-text-sequence.md +273 -0
- package/.agents/skills/hyperframes-animation/rules/dynamic-content-sequencing.md +307 -0
- package/.agents/skills/hyperframes-animation/rules/gsap-effects.md +299 -0
- package/.agents/skills/hyperframes-animation/rules/hacker-flip-3d.md +223 -0
- package/.agents/skills/hyperframes-animation/rules/kinetic-beat-slam.md +183 -0
- package/.agents/skills/hyperframes-animation/rules/motion-blur-streak.md +328 -0
- package/.agents/skills/hyperframes-animation/rules/multi-phase-camera.md +273 -0
- package/.agents/skills/hyperframes-animation/rules/orbit-3d-entry.md +301 -0
- package/.agents/skills/hyperframes-animation/rules/physics-press-reaction.md +350 -0
- package/.agents/skills/hyperframes-animation/rules/press-release-spring.md +296 -0
- package/.agents/skills/hyperframes-animation/rules/reactive-displacement.md +277 -0
- package/.agents/skills/hyperframes-animation/rules/scale-swap-transition.md +298 -0
- package/.agents/skills/hyperframes-animation/rules/sine-wave-loop.md +278 -0
- package/.agents/skills/hyperframes-animation/rules/split-tilt-cards.md +277 -0
- package/.agents/skills/hyperframes-animation/rules/spring-pop-entrance.md +273 -0
- package/.agents/skills/hyperframes-animation/rules/stat-bars-and-fills.md +156 -0
- package/.agents/skills/hyperframes-animation/rules/svg-icon-enrichment.md +329 -0
- package/.agents/skills/hyperframes-animation/rules/svg-path-draw.md +274 -0
- package/.agents/skills/hyperframes-animation/rules/vertical-spring-ticker.md +239 -0
- package/.agents/skills/hyperframes-animation/rules/viewport-change.md +349 -0
- package/.agents/skills/hyperframes-animation/rules-index.md +86 -0
- package/.agents/skills/hyperframes-animation/scripts/animation-map.mjs +606 -0
- package/.agents/skills/hyperframes-animation/scripts/package-loader.mjs +288 -0
- package/.agents/skills/hyperframes-animation/scripts/package-loader.test.mjs +62 -0
- package/.agents/skills/hyperframes-animation/techniques.md +507 -0
- package/.agents/skills/hyperframes-animation/transitions/TRANSITION-REGISTRY.md +167 -0
- package/.agents/skills/hyperframes-animation/transitions/catalog.md +127 -0
- package/.agents/skills/hyperframes-animation/transitions/css-3d.md +12 -0
- package/.agents/skills/hyperframes-animation/transitions/css-blur.md +51 -0
- package/.agents/skills/hyperframes-animation/transitions/css-cover.md +43 -0
- package/.agents/skills/hyperframes-animation/transitions/css-destruction.md +95 -0
- package/.agents/skills/hyperframes-animation/transitions/css-dissolve.md +66 -0
- package/.agents/skills/hyperframes-animation/transitions/css-distortion.md +45 -0
- package/.agents/skills/hyperframes-animation/transitions/css-grid.md +10 -0
- package/.agents/skills/hyperframes-animation/transitions/css-light.md +49 -0
- package/.agents/skills/hyperframes-animation/transitions/css-mechanical.md +30 -0
- package/.agents/skills/hyperframes-animation/transitions/css-other.md +25 -0
- package/.agents/skills/hyperframes-animation/transitions/css-push.md +41 -0
- package/.agents/skills/hyperframes-animation/transitions/css-radial.md +37 -0
- package/.agents/skills/hyperframes-animation/transitions/css-scale.md +24 -0
- package/.agents/skills/hyperframes-animation/transitions/overview.md +153 -0
- package/.agents/skills/hyperframes-cli/SKILL.md +113 -0
- package/.agents/skills/hyperframes-cli/references/doctor-browser.md +45 -0
- package/.agents/skills/hyperframes-cli/references/init-and-scaffold.md +55 -0
- package/.agents/skills/hyperframes-cli/references/lambda.md +132 -0
- package/.agents/skills/hyperframes-cli/references/lint-validate-inspect.md +121 -0
- package/.agents/skills/hyperframes-cli/references/preview-render.md +149 -0
- package/.agents/skills/hyperframes-cli/references/upgrade-info-misc.md +75 -0
- package/.agents/skills/hyperframes-core/SKILL.md +78 -0
- package/.agents/skills/hyperframes-core/references/composition-patterns.md +263 -0
- package/.agents/skills/hyperframes-core/references/data-attributes.md +70 -0
- package/.agents/skills/hyperframes-core/references/determinism-rules.md +68 -0
- package/.agents/skills/hyperframes-core/references/full-screen-motion.md +62 -0
- package/.agents/skills/hyperframes-core/references/minimal-composition.md +66 -0
- package/.agents/skills/hyperframes-core/references/script-format.md +49 -0
- package/.agents/skills/hyperframes-core/references/storyboard-format.md +95 -0
- package/.agents/skills/hyperframes-core/references/sub-compositions.md +237 -0
- package/.agents/skills/hyperframes-core/references/subagent-dispatch.md +41 -0
- package/.agents/skills/hyperframes-core/references/tailwind.md +125 -0
- package/.agents/skills/hyperframes-core/references/tracks-and-clips.md +76 -0
- package/.agents/skills/hyperframes-core/references/variables-and-media.md +90 -0
- package/.agents/skills/hyperframes-creative/SKILL.md +70 -0
- package/.agents/skills/hyperframes-creative/frame-presets/biennale-yellow/FRAME.md +289 -0
- package/.agents/skills/hyperframes-creative/frame-presets/biennale-yellow/caption-skin.html +221 -0
- package/.agents/skills/hyperframes-creative/frame-presets/biennale-yellow/frame-showcase.html +1214 -0
- package/.agents/skills/hyperframes-creative/frame-presets/blockframe/FRAME.md +275 -0
- package/.agents/skills/hyperframes-creative/frame-presets/blockframe/caption-skin.html +224 -0
- package/.agents/skills/hyperframes-creative/frame-presets/blockframe/frame-showcase.html +1347 -0
- package/.agents/skills/hyperframes-creative/frame-presets/blue-professional/FRAME.md +307 -0
- package/.agents/skills/hyperframes-creative/frame-presets/blue-professional/caption-skin.html +223 -0
- package/.agents/skills/hyperframes-creative/frame-presets/blue-professional/frame-showcase.html +1372 -0
- package/.agents/skills/hyperframes-creative/frame-presets/bold-poster/FRAME.md +275 -0
- package/.agents/skills/hyperframes-creative/frame-presets/bold-poster/caption-skin.html +230 -0
- package/.agents/skills/hyperframes-creative/frame-presets/bold-poster/frame-showcase.html +1140 -0
- package/.agents/skills/hyperframes-creative/frame-presets/broadside/FRAME.md +284 -0
- package/.agents/skills/hyperframes-creative/frame-presets/broadside/caption-skin.html +225 -0
- package/.agents/skills/hyperframes-creative/frame-presets/broadside/frame-showcase.html +1166 -0
- package/.agents/skills/hyperframes-creative/frame-presets/capsule/FRAME.md +284 -0
- package/.agents/skills/hyperframes-creative/frame-presets/capsule/caption-skin.html +224 -0
- package/.agents/skills/hyperframes-creative/frame-presets/capsule/frame-showcase.html +1465 -0
- package/.agents/skills/hyperframes-creative/frame-presets/cartesian/FRAME.md +278 -0
- package/.agents/skills/hyperframes-creative/frame-presets/cartesian/caption-skin.html +222 -0
- package/.agents/skills/hyperframes-creative/frame-presets/cartesian/frame-showcase.html +1263 -0
- package/.agents/skills/hyperframes-creative/frame-presets/claude/FRAME.md +277 -0
- package/.agents/skills/hyperframes-creative/frame-presets/claude/caption-skin.html +224 -0
- package/.agents/skills/hyperframes-creative/frame-presets/claude/frame-showcase.html +1439 -0
- package/.agents/skills/hyperframes-creative/frame-presets/cobalt-grid/FRAME.md +265 -0
- package/.agents/skills/hyperframes-creative/frame-presets/cobalt-grid/caption-skin.html +238 -0
- package/.agents/skills/hyperframes-creative/frame-presets/cobalt-grid/frame-showcase.html +1468 -0
- package/.agents/skills/hyperframes-creative/frame-presets/coral/FRAME.md +314 -0
- package/.agents/skills/hyperframes-creative/frame-presets/coral/caption-skin.html +226 -0
- package/.agents/skills/hyperframes-creative/frame-presets/coral/frame-showcase.html +1268 -0
- package/.agents/skills/hyperframes-creative/frame-presets/creative-mode/FRAME.md +333 -0
- package/.agents/skills/hyperframes-creative/frame-presets/creative-mode/caption-skin.html +227 -0
- package/.agents/skills/hyperframes-creative/frame-presets/creative-mode/frame-showcase.html +1330 -0
- package/.agents/skills/hyperframes-creative/frame-presets/daisy-days/FRAME.md +274 -0
- package/.agents/skills/hyperframes-creative/frame-presets/daisy-days/caption-skin.html +230 -0
- package/.agents/skills/hyperframes-creative/frame-presets/daisy-days/frame-showcase.html +1444 -0
- package/.agents/skills/hyperframes-creative/frame-presets/editorial-forest/FRAME.md +265 -0
- package/.agents/skills/hyperframes-creative/frame-presets/editorial-forest/caption-skin.html +223 -0
- package/.agents/skills/hyperframes-creative/frame-presets/editorial-forest/frame-showcase.html +1273 -0
- package/.agents/skills/hyperframes-creative/palettes/bold-energetic.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/clean-corporate.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/dark-premium.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/jewel-rich.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/monochrome.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/nature-earth.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/neon-electric.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/pastel-soft.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/warm-editorial.md +14 -0
- package/.agents/skills/hyperframes-creative/references/audio-reactive.md +76 -0
- package/.agents/skills/hyperframes-creative/references/beat-direction.md +164 -0
- package/.agents/skills/hyperframes-creative/references/composition-patterns.md +199 -0
- package/.agents/skills/hyperframes-creative/references/data-in-motion.md +19 -0
- package/.agents/skills/hyperframes-creative/references/design-adherence.md +19 -0
- package/.agents/skills/hyperframes-creative/references/design-picker.md +123 -0
- package/.agents/skills/hyperframes-creative/references/design-spec.md +55 -0
- package/.agents/skills/hyperframes-creative/references/house-style.md +73 -0
- package/.agents/skills/hyperframes-creative/references/motion-principles.md +150 -0
- package/.agents/skills/hyperframes-creative/references/narration.md +92 -0
- package/.agents/skills/hyperframes-creative/references/prompt-expansion.md +68 -0
- package/.agents/skills/hyperframes-creative/references/typography.md +218 -0
- package/.agents/skills/hyperframes-creative/references/video-composition.md +63 -0
- package/.agents/skills/hyperframes-creative/references/visual-styles.md +457 -0
- package/.agents/skills/hyperframes-creative/scripts/contrast-report.mjs +353 -0
- package/.agents/skills/hyperframes-creative/scripts/extract-audio-data.py +188 -0
- package/.agents/skills/hyperframes-creative/scripts/package-loader.mjs +288 -0
- package/.agents/skills/hyperframes-creative/scripts/package-loader.test.mjs +62 -0
- package/.agents/skills/hyperframes-creative/templates/design-picker.html +1432 -0
- package/.agents/skills/hyperframes-keyframes/SKILL.md +237 -0
- package/.agents/skills/hyperframes-keyframes/agents/openai.yaml +4 -0
- package/.agents/skills/hyperframes-keyframes/references/keyframe-patterns.md +106 -0
- package/.agents/skills/motion-graphics/SKILL.md +172 -0
- package/.agents/skills/motion-graphics/agents/builder.md +40 -0
- package/.agents/skills/motion-graphics/agents/director.md +53 -0
- package/.agents/skills/motion-graphics/agents/finalize.md +17 -0
- package/.agents/skills/motion-graphics/catalog-map.md +40 -0
- package/.agents/skills/motion-graphics/categories/asset-fusion/module.md +37 -0
- package/.agents/skills/motion-graphics/categories/charts/module.md +21 -0
- package/.agents/skills/motion-graphics/categories/kinetic-type/module.md +19 -0
- package/.agents/skills/motion-graphics/categories/logo-reveal/module.md +17 -0
- package/.agents/skills/motion-graphics/categories/lower-thirds/module.md +16 -0
- package/.agents/skills/motion-graphics/categories/maps/bake-basemap.mjs +273 -0
- package/.agents/skills/motion-graphics/categories/maps/module.md +61 -0
- package/.agents/skills/motion-graphics/categories/news/module.md +56 -0
- package/.agents/skills/motion-graphics/categories/stat/module.md +21 -0
- package/.agents/skills/motion-graphics/categories/tweet/module.md +16 -0
- package/.agents/skills/motion-graphics/categories/webpage/module.md +21 -0
- package/.agents/skills/motion-graphics/grounding/PROTOCOL.md +64 -0
- package/.agents/skills/motion-graphics/grounding/locate.mjs +227 -0
- package/.agents/skills/motion-graphics/phases/source/guide.md +21 -0
- package/.agents/skills/motion-graphics/references/builder-contract.md +38 -0
- package/.agents/skills/motion-graphics/references/motion-vocabulary.md +43 -0
- package/.agents/skills/motion-graphics/references/shot-plan-ir.md +54 -0
- package/.agents/skills/motion-graphics/samples/asset-fusion/_ref-circle-highlight.html +306 -0
- package/.agents/skills/product-launch-video/SKILL.md +208 -0
- package/.agents/skills/product-launch-video/references/cut-catalog.md +220 -0
- package/.agents/skills/product-launch-video/references/motion-language.md +156 -0
- package/.agents/skills/product-launch-video/references/story-design.md +373 -0
- package/.agents/skills/product-launch-video/references/visual-design.md +126 -0
- package/.agents/skills/product-launch-video/scripts/assemble-index.mjs +570 -0
- package/.agents/skills/product-launch-video/scripts/audio.mjs +260 -0
- package/.agents/skills/product-launch-video/scripts/build-frame.mjs +536 -0
- package/.agents/skills/product-launch-video/scripts/captions.mjs +508 -0
- package/.agents/skills/product-launch-video/scripts/lib/assets.mjs +55 -0
- package/.agents/skills/product-launch-video/scripts/lib/dimensions.mjs +45 -0
- package/.agents/skills/product-launch-video/scripts/lib/pad-frame-duration.mjs +36 -0
- package/.agents/skills/product-launch-video/scripts/lib/pad-frame-duration.test.mjs +76 -0
- package/.agents/skills/product-launch-video/scripts/lib/storyboard.mjs +249 -0
- package/.agents/skills/product-launch-video/scripts/lib/tokens.mjs +204 -0
- package/.agents/skills/product-launch-video/scripts/lib/transition-registry.mjs +38 -0
- package/.agents/skills/product-launch-video/scripts/lib/transitions.json +71 -0
- package/.agents/skills/product-launch-video/scripts/stage-assets.mjs +39 -0
- package/.agents/skills/product-launch-video/scripts/transitions.mjs +327 -0
- package/.agents/skills/product-launch-video/sub-agents/frame-worker.md +75 -0
- package/.agents/skills/slideshow/SKILL.md +550 -0
- package/.agents/skills/slideshow/references/standalone-harness.md +1020 -0
- package/.agents/skills/talking-head-recut/NOTICE.md +39 -0
- package/.agents/skills/talking-head-recut/SKILL.md +1195 -0
- package/.agents/skills/talking-head-recut/assets/vendor/gsap.min.js +10 -0
- package/.agents/skills/talking-head-recut/references/DESIGN_INDEX.md +145 -0
- package/.agents/skills/talking-head-recut/references/frames/clean.html +92 -0
- package/.agents/skills/talking-head-recut/references/frames/hairline.html +171 -0
- package/.agents/skills/talking-head-recut/references/frames/polaroid.html +131 -0
- package/.agents/skills/talking-head-recut/references/layouts/overlay.html +164 -0
- package/.agents/skills/talking-head-recut/references/layouts/pip.html +143 -0
- package/.agents/skills/talking-head-recut/references/layouts/split.html +121 -0
- package/.agents/skills/talking-head-recut/references/layouts/stack.html +109 -0
- package/.agents/skills/talking-head-recut/references/styles/academic.html +172 -0
- package/.agents/skills/talking-head-recut/references/styles/audit.html +170 -0
- package/.agents/skills/talking-head-recut/references/styles/editorial.html +189 -0
- package/.agents/skills/talking-head-recut/references/styles/geom.html +181 -0
- package/.agents/skills/talking-head-recut/references/styles/minimal.html +130 -0
- package/.agents/skills/talking-head-recut/references/styles/spotlight.html +142 -0
- package/.agents/skills/talking-head-recut/references/styles/swiss.html +188 -0
- package/.agents/skills/talking-head-recut/references/styles/terminal.html +196 -0
- package/.agents/skills/talking-head-recut/references/styles/whiteboard.html +170 -0
- package/.agents/skills/talking-head-recut/references/styles/xhs.html +206 -0
- package/.agents/skills/vidfarm-media/SKILL.md +85 -0
- package/.agents/skills/vidfarm-media/references/tts.md +54 -0
- package/.agents/skills/vidfarm-media/scripts/audio.mjs +628 -0
- package/.agents/skills/vidfarm-media/scripts/wait-bgm.mjs +31 -0
- package/.agents/skills/website-to-video/SKILL.md +145 -0
- package/.agents/skills/website-to-video/assets/sfx/CREDITS.md +35 -0
- package/.agents/skills/website-to-video/assets/sfx/manifest.json +97 -0
- package/.agents/skills/website-to-video/references/beat-builder-guide.md +263 -0
- package/.agents/skills/website-to-video/references/capabilities.md +713 -0
- package/.agents/skills/website-to-video/references/step-0-capture.md +55 -0
- package/.agents/skills/website-to-video/references/step-1-design.md +333 -0
- package/.agents/skills/website-to-video/references/step-2-brief.md +178 -0
- package/.agents/skills/website-to-video/references/step-3-storyboard.md +572 -0
- package/.agents/skills/website-to-video/references/step-4-vo.md +225 -0
- package/.agents/skills/website-to-video/references/step-5-build.md +483 -0
- package/.agents/skills/website-to-video/references/step-6-validate.md +341 -0
- package/.agents/skills/website-to-video/scripts/w2h-verify.mjs +759 -0
- package/SKILL.director.md +37 -0
- package/SKILL.platform.md +6 -1
- package/demo/dist/app.js +295 -11
- package/dist/src/app.js +317 -133
- package/dist/src/cli.js +529 -12
- package/dist/src/composition-runtime.js +262 -3
- package/dist/src/devcli/doctor.js +192 -0
- package/dist/src/devcli/hyperframes-cli.js +118 -0
- package/dist/src/devcli/skills.js +476 -0
- package/dist/src/devcli/stills.js +249 -0
- package/dist/src/editor-chat.js +255 -0
- package/dist/src/hyperframes/composition.js +5 -5
- package/dist/src/services/composition-lint.js +199 -0
- package/dist/src/services/hyperframes.js +67 -13
- package/package.json +2 -1
package/dist/src/app.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
2
|
-
import { createWriteStream, existsSync, mkdirSync, readFileSync, rmSync, statSync } from "node:fs";
|
|
2
|
+
import { createWriteStream, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync } from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { Readable } from "node:stream";
|
|
5
5
|
import { pipeline as streamPipeline } from "node:stream/promises";
|
|
@@ -35,7 +35,7 @@ import { resolveRootFileCandidates } from "./lib/package-root.js";
|
|
|
35
35
|
import { stripTrackingParams } from "./lib/url-clean.js";
|
|
36
36
|
import { addSeconds, nowIso } from "./lib/time.js";
|
|
37
37
|
import { templateRegistry } from "./registry.js";
|
|
38
|
-
import { buildEditorChatSystemInstruction, compactEditorChatModelMessages, defaultEditorChatModel, EDITOR_CHAT_PROVIDER_PRIORITY, extractEditorChatCompositionBrief, formatEditorChatCurrentDateTime, toEditorChatModelMessages } from "./editor-chat.js";
|
|
38
|
+
import { buildAsyncJobHandoffText, buildEditorChatGuardrailNotice, buildEditorChatSystemInstruction, collectVerifiedHttpJobIds, compactEditorChatModelMessages, createLoadSkillTool, createStreamingJobIdRedactor, defaultEditorChatModel, EDITOR_CHAT_PROVIDER_PRIORITY, extractEditorChatCompositionBrief, formatEditorChatCurrentDateTime, lintReplaceCompositionAction, readAsyncJobHandoff, toEditorChatModelMessages } from "./editor-chat.js";
|
|
39
39
|
import { apiCallHistoryStore } from "./services/api-call-history.js";
|
|
40
40
|
import { AuthService } from "./services/auth.js";
|
|
41
41
|
import { BillingService } from "./services/billing.js";
|
|
@@ -54,7 +54,7 @@ import { loadSpeechAudioLocally, MAX_LOCAL_TRANSCRIBE_AUDIO_BYTES } from "./devc
|
|
|
54
54
|
import { DescribeExecutionCommand, SFNClient, StartExecutionCommand } from "@aws-sdk/client-sfn";
|
|
55
55
|
import { clipRecords, makeUserPreset } from "./services/clip-records.js";
|
|
56
56
|
import { matchScenesToClips, searchUserClips, vectorIndex } from "./services/clip-search.js";
|
|
57
|
-
import { BUILTIN_PRESETS, buildEffectiveGuidance, ClipModelClient, cosineSimilarity, detectLocalAgent, effectiveHuntDurationSec, estimateScanCostFromDuration, hasFfmpeg, LocalAgentClipClient, normalizeCropFocus, normalizeHuntSpec, parseClipHuntPrompt, probeVideo, resolveDurationBand, scanVideo } from "./services/clip-curation/index.js";
|
|
57
|
+
import { BUILTIN_PRESETS, buildClipEmbeddingText, buildEffectiveGuidance, ClipModelClient, cosineSimilarity, detectLocalAgent, effectiveHuntDurationSec, estimateScanCostFromDuration, hasFfmpeg, LocalAgentClipClient, normalizeCropFocus, normalizeHuntSpec, parseClipHuntPrompt, probeVideo, resolveDurationBand, scanVideo } from "./services/clip-curation/index.js";
|
|
58
58
|
import { analyzeCastMembers, annotateScenesFromSource, buildSmartDecomposedHtml, HyperframesService, smartDecomposeVideo, stampCompositionIdentity } from "./services/hyperframes.js";
|
|
59
59
|
import { buildPendingSceneAnnotationsState } from "./services/scene-annotations.js";
|
|
60
60
|
import { createPrimitiveJobContext } from "./primitive-context.js";
|
|
@@ -3609,7 +3609,12 @@ function normalizeEditorChatPath(input) {
|
|
|
3609
3609
|
// and NEVER runs GhostCut on the long-form source — "no text" is a
|
|
3610
3610
|
// scene-selection filter; caption removal stays a per-finished-clip
|
|
3611
3611
|
// primitive (/api/v1/primitives/videos/remove-captions).
|
|
3612
|
-
CLIPS_PREFIX
|
|
3612
|
+
CLIPS_PREFIX,
|
|
3613
|
+
// Public skill knowledge: the vendored skill packs (load_skill fetches
|
|
3614
|
+
// these too) and per-template SKILL.md manifests. Read-only markdown.
|
|
3615
|
+
"/skill/",
|
|
3616
|
+
"/skill-pack/",
|
|
3617
|
+
"/discover/skills/"
|
|
3613
3618
|
];
|
|
3614
3619
|
const parsed = trimmed.startsWith("http://") || trimmed.startsWith("https://")
|
|
3615
3620
|
? new URL(trimmed)
|
|
@@ -4463,95 +4468,14 @@ function createEditorActionTool() {
|
|
|
4463
4468
|
explanation: z.string().describe("One-sentence reason shown in the UI.")
|
|
4464
4469
|
}),
|
|
4465
4470
|
execute: async (args) => {
|
|
4471
|
+
const linted = lintReplaceCompositionAction(args);
|
|
4472
|
+
if (linted) {
|
|
4473
|
+
return linted;
|
|
4474
|
+
}
|
|
4466
4475
|
return { ...args };
|
|
4467
4476
|
}
|
|
4468
4477
|
});
|
|
4469
4478
|
}
|
|
4470
|
-
const JOB_ID_PATTERN = /\bjob_[a-z0-9]+\b/gi;
|
|
4471
|
-
const HTTP_TOOL_CLAIM_PATTERN = /\b(?:http_request|REST API call|API call|GET\s+https?:\/\/|POST\s+https?:\/\/|GET\s+\/api\/|POST\s+\/api\/)/i;
|
|
4472
|
-
function collectJobIdsFromUnknown(value, output = new Set()) {
|
|
4473
|
-
if (typeof value === "string") {
|
|
4474
|
-
for (const match of value.matchAll(JOB_ID_PATTERN)) {
|
|
4475
|
-
output.add(match[0]);
|
|
4476
|
-
}
|
|
4477
|
-
return output;
|
|
4478
|
-
}
|
|
4479
|
-
if (Array.isArray(value)) {
|
|
4480
|
-
for (const entry of value) {
|
|
4481
|
-
collectJobIdsFromUnknown(entry, output);
|
|
4482
|
-
}
|
|
4483
|
-
return output;
|
|
4484
|
-
}
|
|
4485
|
-
if (value && typeof value === "object") {
|
|
4486
|
-
for (const entry of Object.values(value)) {
|
|
4487
|
-
collectJobIdsFromUnknown(entry, output);
|
|
4488
|
-
}
|
|
4489
|
-
}
|
|
4490
|
-
return output;
|
|
4491
|
-
}
|
|
4492
|
-
function collectVerifiedHttpJobIds(toolResult) {
|
|
4493
|
-
if (!toolResult || typeof toolResult !== "object") {
|
|
4494
|
-
return new Set();
|
|
4495
|
-
}
|
|
4496
|
-
const record = toolResult;
|
|
4497
|
-
return collectJobIdsFromUnknown(record.response?.body ?? record.result?.body);
|
|
4498
|
-
}
|
|
4499
|
-
function readAsyncJobHandoff(output) {
|
|
4500
|
-
if (!output || typeof output !== "object") {
|
|
4501
|
-
return null;
|
|
4502
|
-
}
|
|
4503
|
-
const record = output;
|
|
4504
|
-
const body = record.response?.body;
|
|
4505
|
-
if (!body || typeof body !== "object") {
|
|
4506
|
-
return null;
|
|
4507
|
-
}
|
|
4508
|
-
const job = body;
|
|
4509
|
-
if (typeof job.job_id !== "string" || typeof job.status !== "string") {
|
|
4510
|
-
return null;
|
|
4511
|
-
}
|
|
4512
|
-
if (job.status === "succeeded" || job.status === "failed" || job.status === "cancelled") {
|
|
4513
|
-
return null;
|
|
4514
|
-
}
|
|
4515
|
-
return {
|
|
4516
|
-
jobId: job.job_id,
|
|
4517
|
-
tracer: typeof job.tracer === "string" ? job.tracer : null,
|
|
4518
|
-
status: job.status,
|
|
4519
|
-
isNewQueuedJob: record.request?.method === "POST" && record.response?.status === 202
|
|
4520
|
-
};
|
|
4521
|
-
}
|
|
4522
|
-
function buildAsyncJobHandoffText(input) {
|
|
4523
|
-
if (!input.isNewQueuedJob) {
|
|
4524
|
-
return `Render \`${input.jobId}\` is ${input.status}.`;
|
|
4525
|
-
}
|
|
4526
|
-
return [
|
|
4527
|
-
`Started render \`${input.jobId}\`${input.tracer ? ` with tracer \`${input.tracer}\`` : ""}.`,
|
|
4528
|
-
"If it takes a while, ask for an update later and I can check it for you."
|
|
4529
|
-
].join("\n\n");
|
|
4530
|
-
}
|
|
4531
|
-
function buildEditorChatGuardrailNotice(input) {
|
|
4532
|
-
const mentionedJobIds = collectJobIdsFromUnknown(input.assistantText);
|
|
4533
|
-
const unverifiedJobIds = [...mentionedJobIds].filter((jobId) => !input.verifiedJobIds.has(jobId));
|
|
4534
|
-
const notices = [];
|
|
4535
|
-
if (input.redactedJobIds.size) {
|
|
4536
|
-
notices.push("Guardrail: I withheld unverified job ID text because it did not come from a visible HTTP response card.");
|
|
4537
|
-
}
|
|
4538
|
-
else if (unverifiedJobIds.length) {
|
|
4539
|
-
notices.push("Guardrail: I mentioned an unverified job ID. Ignore it unless it appears in a visible HTTP response card.");
|
|
4540
|
-
}
|
|
4541
|
-
if (!input.hasHttpRequestResult && HTTP_TOOL_CLAIM_PATTERN.test(input.assistantText)) {
|
|
4542
|
-
notices.push("Guardrail: no `http_request` tool result was recorded for this response, so any claimed REST/API call should be treated as not executed.");
|
|
4543
|
-
}
|
|
4544
|
-
return notices.length ? `\n\n${notices.join("\n\n")}` : "";
|
|
4545
|
-
}
|
|
4546
|
-
function redactUnverifiedJobIds(input) {
|
|
4547
|
-
return input.text.replace(JOB_ID_PATTERN, (jobId) => {
|
|
4548
|
-
if (input.verifiedJobIds.has(jobId)) {
|
|
4549
|
-
return jobId;
|
|
4550
|
-
}
|
|
4551
|
-
input.redactedJobIds.add(jobId);
|
|
4552
|
-
return "[unverified job id]";
|
|
4553
|
-
});
|
|
4554
|
-
}
|
|
4555
4479
|
function normalizeHistoryAttachments(attachments) {
|
|
4556
4480
|
return Array.isArray(attachments)
|
|
4557
4481
|
? attachments.map((attachment) => ({
|
|
@@ -4595,6 +4519,10 @@ async function streamEditorChatAgent(input, send) {
|
|
|
4595
4519
|
vidfarmApiKey: input.vidfarmApiKey,
|
|
4596
4520
|
abortSignal: input.abortSignal
|
|
4597
4521
|
}),
|
|
4522
|
+
load_skill: createLoadSkillTool({
|
|
4523
|
+
publicBaseUrl: config.PUBLIC_BASE_URL,
|
|
4524
|
+
abortSignal: input.abortSignal
|
|
4525
|
+
}),
|
|
4598
4526
|
frontend_action: createEditorFrontendActionTool({
|
|
4599
4527
|
tracerRegistry
|
|
4600
4528
|
}),
|
|
@@ -4621,6 +4549,7 @@ async function streamEditorChatAgent(input, send) {
|
|
|
4621
4549
|
let hasHttpRequestResult = false;
|
|
4622
4550
|
const verifiedJobIds = new Set();
|
|
4623
4551
|
const redactedJobIds = new Set();
|
|
4552
|
+
const jobIdRedactor = createStreamingJobIdRedactor({ verifiedJobIds, redactedJobIds });
|
|
4624
4553
|
const toolExchangeOrder = [];
|
|
4625
4554
|
const toolExchangeMap = new Map();
|
|
4626
4555
|
const httpExchanges = [];
|
|
@@ -4635,16 +4564,14 @@ async function streamEditorChatAgent(input, send) {
|
|
|
4635
4564
|
case "text-delta":
|
|
4636
4565
|
assistantTextForAudit += part.text;
|
|
4637
4566
|
{
|
|
4638
|
-
const safeText =
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
delta: safeText
|
|
4647
|
-
});
|
|
4567
|
+
const safeText = jobIdRedactor.push(part.text);
|
|
4568
|
+
if (safeText) {
|
|
4569
|
+
assistantTextForUser += safeText;
|
|
4570
|
+
send({
|
|
4571
|
+
type: "text-delta",
|
|
4572
|
+
delta: safeText
|
|
4573
|
+
});
|
|
4574
|
+
}
|
|
4648
4575
|
}
|
|
4649
4576
|
break;
|
|
4650
4577
|
case "tool-call":
|
|
@@ -4738,6 +4665,14 @@ async function streamEditorChatAgent(input, send) {
|
|
|
4738
4665
|
break;
|
|
4739
4666
|
case "finish":
|
|
4740
4667
|
{
|
|
4668
|
+
const heldText = jobIdRedactor.flush();
|
|
4669
|
+
if (heldText) {
|
|
4670
|
+
assistantTextForUser += heldText;
|
|
4671
|
+
send({
|
|
4672
|
+
type: "text-delta",
|
|
4673
|
+
delta: heldText
|
|
4674
|
+
});
|
|
4675
|
+
}
|
|
4741
4676
|
const guardrailNotice = buildEditorChatGuardrailNotice({
|
|
4742
4677
|
assistantText: assistantTextForAudit,
|
|
4743
4678
|
verifiedJobIds,
|
|
@@ -5677,21 +5612,193 @@ const PUBLIC_SKILL_FILES = {
|
|
|
5677
5612
|
"vidfarm-director": "SKILL.director.md",
|
|
5678
5613
|
"vidfarm-platform": "SKILL.platform.md"
|
|
5679
5614
|
};
|
|
5615
|
+
// Vendored skill packs (the heygen-scrubbed hyperframes pack + vidfarm-media)
|
|
5616
|
+
// mirrored from .agents/skills. Vidfarm is the distribution origin: the devcli
|
|
5617
|
+
// (`vidfarm skills add`) and the chat copilot's load_skill tool both pull from
|
|
5618
|
+
// these routes, so customers never fetch skills from an upstream vendor org.
|
|
5619
|
+
const SKILL_PACK_NAME_PATTERN = /^[a-z0-9][a-z0-9_-]{0,64}$/;
|
|
5620
|
+
const SKILL_PACK_IGNORED_ENTRIES = new Set([".DS_Store", "node_modules", ".git"]);
|
|
5621
|
+
function resolveSkillPackDir(name) {
|
|
5622
|
+
if (!SKILL_PACK_NAME_PATTERN.test(name)) {
|
|
5623
|
+
return null;
|
|
5624
|
+
}
|
|
5625
|
+
for (const candidate of resolveRootFileCandidates(path.join(".agents", "skills", name))) {
|
|
5626
|
+
try {
|
|
5627
|
+
if (statSync(candidate).isDirectory()) {
|
|
5628
|
+
return candidate;
|
|
5629
|
+
}
|
|
5630
|
+
}
|
|
5631
|
+
catch {
|
|
5632
|
+
continue;
|
|
5633
|
+
}
|
|
5634
|
+
}
|
|
5635
|
+
return null;
|
|
5636
|
+
}
|
|
5637
|
+
function listSkillPackFiles(dir, prefix = "") {
|
|
5638
|
+
const files = [];
|
|
5639
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
5640
|
+
if (SKILL_PACK_IGNORED_ENTRIES.has(entry.name)) {
|
|
5641
|
+
continue;
|
|
5642
|
+
}
|
|
5643
|
+
const relative = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
5644
|
+
const absolute = path.join(dir, entry.name);
|
|
5645
|
+
if (entry.isDirectory()) {
|
|
5646
|
+
files.push(...listSkillPackFiles(absolute, relative));
|
|
5647
|
+
}
|
|
5648
|
+
else if (entry.isFile()) {
|
|
5649
|
+
files.push(relative);
|
|
5650
|
+
}
|
|
5651
|
+
}
|
|
5652
|
+
return files.sort();
|
|
5653
|
+
}
|
|
5654
|
+
function readSkillPackDescription(dir) {
|
|
5655
|
+
try {
|
|
5656
|
+
const skillMd = readFileSync(path.join(dir, "SKILL.md"), "utf8");
|
|
5657
|
+
const match = skillMd.match(/^description:\s*(.+)$/m);
|
|
5658
|
+
return match ? match[1].trim().slice(0, 300) : "";
|
|
5659
|
+
}
|
|
5660
|
+
catch {
|
|
5661
|
+
return "";
|
|
5662
|
+
}
|
|
5663
|
+
}
|
|
5680
5664
|
app.get("/skill/:name", (c) => {
|
|
5681
5665
|
const name = c.req.param("name").replace(/\.md$/i, "");
|
|
5682
5666
|
const filename = PUBLIC_SKILL_FILES[name];
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
|
|
5667
|
+
const contents = filename
|
|
5668
|
+
? readRootSkillFile(filename)
|
|
5669
|
+
: (() => {
|
|
5670
|
+
const packDir = resolveSkillPackDir(name);
|
|
5671
|
+
if (!packDir) {
|
|
5672
|
+
return "";
|
|
5673
|
+
}
|
|
5674
|
+
try {
|
|
5675
|
+
return readFileSync(path.join(packDir, "SKILL.md"), "utf8");
|
|
5676
|
+
}
|
|
5677
|
+
catch {
|
|
5678
|
+
return "";
|
|
5679
|
+
}
|
|
5680
|
+
})();
|
|
5687
5681
|
if (!contents) {
|
|
5688
|
-
return c.text("Skill file unavailable", 404);
|
|
5682
|
+
return c.text(filename ? "Skill file unavailable" : "Unknown skill", 404);
|
|
5689
5683
|
}
|
|
5690
5684
|
return c.body(contents, 200, {
|
|
5691
5685
|
"content-type": "text/markdown; charset=utf-8",
|
|
5692
5686
|
"cache-control": "no-cache"
|
|
5693
5687
|
});
|
|
5694
5688
|
});
|
|
5689
|
+
app.get("/skill-pack/index.json", (c) => {
|
|
5690
|
+
const skills = [];
|
|
5691
|
+
for (const candidate of resolveRootFileCandidates(path.join(".agents", "skills"))) {
|
|
5692
|
+
let entries;
|
|
5693
|
+
try {
|
|
5694
|
+
entries = readdirSync(candidate);
|
|
5695
|
+
}
|
|
5696
|
+
catch {
|
|
5697
|
+
continue;
|
|
5698
|
+
}
|
|
5699
|
+
for (const entry of entries.sort()) {
|
|
5700
|
+
if (!SKILL_PACK_NAME_PATTERN.test(entry) || skills.some((skill) => skill.name === entry)) {
|
|
5701
|
+
continue;
|
|
5702
|
+
}
|
|
5703
|
+
const dir = path.join(candidate, entry);
|
|
5704
|
+
try {
|
|
5705
|
+
if (!statSync(dir).isDirectory()) {
|
|
5706
|
+
continue;
|
|
5707
|
+
}
|
|
5708
|
+
}
|
|
5709
|
+
catch {
|
|
5710
|
+
continue;
|
|
5711
|
+
}
|
|
5712
|
+
skills.push({ name: entry, description: readSkillPackDescription(dir) });
|
|
5713
|
+
}
|
|
5714
|
+
break;
|
|
5715
|
+
}
|
|
5716
|
+
return c.json({ skills });
|
|
5717
|
+
});
|
|
5718
|
+
// Manifest hashing reads every file in a pack (hyperframes-animation alone is
|
|
5719
|
+
// ~100 files) — memoize per pack dir, invalidated by a cheap stat signature,
|
|
5720
|
+
// so `vidfarm skills update` sweeps don't re-hash 5MB per request.
|
|
5721
|
+
const skillPackManifestCache = new Map();
|
|
5722
|
+
app.get("/skill-pack/:name/manifest.json", (c) => {
|
|
5723
|
+
const packDir = resolveSkillPackDir(c.req.param("name"));
|
|
5724
|
+
if (!packDir) {
|
|
5725
|
+
return c.json({ error: "Unknown skill pack." }, 404);
|
|
5726
|
+
}
|
|
5727
|
+
const relativePaths = listSkillPackFiles(packDir);
|
|
5728
|
+
const signature = relativePaths
|
|
5729
|
+
.map((relative) => {
|
|
5730
|
+
try {
|
|
5731
|
+
const stats = statSync(path.join(packDir, relative));
|
|
5732
|
+
return `${relative}:${stats.size}:${stats.mtimeMs}`;
|
|
5733
|
+
}
|
|
5734
|
+
catch {
|
|
5735
|
+
return `${relative}:missing`;
|
|
5736
|
+
}
|
|
5737
|
+
})
|
|
5738
|
+
.join("|");
|
|
5739
|
+
const cached = skillPackManifestCache.get(packDir);
|
|
5740
|
+
if (cached && cached.signature === signature) {
|
|
5741
|
+
return c.json(cached.manifest);
|
|
5742
|
+
}
|
|
5743
|
+
const files = relativePaths.map((relative) => {
|
|
5744
|
+
const bytes = readFileSync(path.join(packDir, relative));
|
|
5745
|
+
return {
|
|
5746
|
+
path: relative,
|
|
5747
|
+
size: bytes.length,
|
|
5748
|
+
sha256: createHash("sha256").update(bytes).digest("hex")
|
|
5749
|
+
};
|
|
5750
|
+
});
|
|
5751
|
+
const manifest = { name: path.basename(packDir), files };
|
|
5752
|
+
skillPackManifestCache.set(packDir, { signature, manifest });
|
|
5753
|
+
return c.json(manifest);
|
|
5754
|
+
});
|
|
5755
|
+
app.get("/skill-pack/:name/files/*", (c) => {
|
|
5756
|
+
const packDir = resolveSkillPackDir(c.req.param("name"));
|
|
5757
|
+
if (!packDir) {
|
|
5758
|
+
return c.text("Unknown skill pack.", 404);
|
|
5759
|
+
}
|
|
5760
|
+
const marker = "/files/";
|
|
5761
|
+
const rawPath = c.req.path.slice(c.req.path.indexOf(marker) + marker.length);
|
|
5762
|
+
let relative;
|
|
5763
|
+
try {
|
|
5764
|
+
relative = rawPath
|
|
5765
|
+
.split("/")
|
|
5766
|
+
.map((segment) => decodeURIComponent(segment))
|
|
5767
|
+
.join("/");
|
|
5768
|
+
}
|
|
5769
|
+
catch {
|
|
5770
|
+
return c.text("Bad file path.", 400);
|
|
5771
|
+
}
|
|
5772
|
+
const resolved = path.resolve(packDir, relative);
|
|
5773
|
+
if (resolved !== packDir && !resolved.startsWith(packDir + path.sep)) {
|
|
5774
|
+
return c.text("Bad file path.", 400);
|
|
5775
|
+
}
|
|
5776
|
+
let bytes;
|
|
5777
|
+
try {
|
|
5778
|
+
bytes = readFileSync(resolved);
|
|
5779
|
+
}
|
|
5780
|
+
catch {
|
|
5781
|
+
return c.text("File not found.", 404);
|
|
5782
|
+
}
|
|
5783
|
+
const ext = path.extname(resolved).toLowerCase();
|
|
5784
|
+
const contentType = ext === ".md" || ext === ".markdown" ? "text/markdown; charset=utf-8"
|
|
5785
|
+
: ext === ".json" ? "application/json; charset=utf-8"
|
|
5786
|
+
: ext === ".mjs" || ext === ".cjs" || ext === ".js" ? "text/javascript; charset=utf-8"
|
|
5787
|
+
: ext === ".html" ? "text/html; charset=utf-8"
|
|
5788
|
+
: ext === ".css" ? "text/css; charset=utf-8"
|
|
5789
|
+
: ext === ".txt" || ext === ".srt" || ext === ".vtt" || ext === ".sh" || ext === ".yaml" || ext === ".yml" ? "text/plain; charset=utf-8"
|
|
5790
|
+
: ext === ".png" ? "image/png"
|
|
5791
|
+
: ext === ".avif" ? "image/avif"
|
|
5792
|
+
: ext === ".webp" ? "image/webp"
|
|
5793
|
+
: ext === ".jpg" || ext === ".jpeg" ? "image/jpeg"
|
|
5794
|
+
: ext === ".mp3" ? "audio/mpeg"
|
|
5795
|
+
: ext === ".woff2" ? "font/woff2"
|
|
5796
|
+
: "application/octet-stream";
|
|
5797
|
+
return c.body(new Uint8Array(bytes), 200, {
|
|
5798
|
+
"content-type": contentType,
|
|
5799
|
+
"cache-control": "no-cache"
|
|
5800
|
+
});
|
|
5801
|
+
});
|
|
5695
5802
|
if (config.SENTRY_DEBUG_ROUTE === "true") {
|
|
5696
5803
|
app.get("/debug-sentry", () => {
|
|
5697
5804
|
Sentry.logger.info("User triggered test error", {
|
|
@@ -6601,7 +6708,13 @@ app.post(`${COMPOSITIONS_PREFIX}/:forkId/captions`, async (c) => {
|
|
|
6601
6708
|
const text = str("text");
|
|
6602
6709
|
if (text) {
|
|
6603
6710
|
const windowStart = Math.max(0, num("start") ?? 0);
|
|
6604
|
-
const
|
|
6711
|
+
const availableWindow = compositionDuration - windowStart;
|
|
6712
|
+
// When the composition declares no usable window (missing data-duration,
|
|
6713
|
+
// or windowStart at/after the end), fall back to a word-count estimate
|
|
6714
|
+
// (~0.32s/word, same as the /audio/captions primitive) instead of
|
|
6715
|
+
// cramming the whole script into a 0.4s window of overlapping cues.
|
|
6716
|
+
const estimatedWindow = Math.max(0.4, text.trim().split(/\s+/).filter(Boolean).length * 0.32);
|
|
6717
|
+
const windowDuration = num("duration") ?? (availableWindow > 0.4 ? availableWindow : estimatedWindow);
|
|
6605
6718
|
cues = cuesFromText(text, windowStart + offsetSec, windowDuration, { maxWordsPerCue: maxWords });
|
|
6606
6719
|
sourceNote = "text";
|
|
6607
6720
|
}
|
|
@@ -14938,6 +15051,31 @@ app.get(`${USER_PREFIX}/me/generated-media`, async (c) => {
|
|
|
14938
15051
|
next_cursor: page.nextCursor
|
|
14939
15052
|
});
|
|
14940
15053
|
});
|
|
15054
|
+
// OpenAI's embedding models are named text-embedding-3-* / text-embedding-ada-*;
|
|
15055
|
+
// Gemini's family INCLUDES text-embedding-004 (plus gemini-embedding-*), so a
|
|
15056
|
+
// bare startsWith("text-embedding") misroutes a Gemini-built library to OpenAI
|
|
15057
|
+
// and returns cross-space (garbage) cosine scores. Match the OpenAI naming
|
|
15058
|
+
// precisely; everything else is gemini.
|
|
15059
|
+
function inferEmbeddingProviderFromModel(model) {
|
|
15060
|
+
return model && /^text-embedding-(3|ada)/i.test(model) ? "openai" : "gemini";
|
|
15061
|
+
}
|
|
15062
|
+
// Embed-capable client for populating/searching a clip library. Matches the
|
|
15063
|
+
// library's existing embedding space when one exists (so vectors stay
|
|
15064
|
+
// cosine-comparable); otherwise takes the first embed-capable saved key
|
|
15065
|
+
// (gemini → openai; openrouter can't embed). Null → no key, keyword-only.
|
|
15066
|
+
async function buildClipLibraryEmbedder(customerId) {
|
|
15067
|
+
const existing = await clipRecords.getLibraryEmbeddingModel(customerId);
|
|
15068
|
+
const providers = existing ? [inferEmbeddingProviderFromModel(existing)] : ["gemini", "openai"];
|
|
15069
|
+
for (const provider of providers) {
|
|
15070
|
+
const apiKey = await resolveCustomerProviderKey(customerId, provider);
|
|
15071
|
+
if (!apiKey)
|
|
15072
|
+
continue;
|
|
15073
|
+
const client = new ClipModelClient({ provider, apiKey });
|
|
15074
|
+
if (client.canEmbed)
|
|
15075
|
+
return client;
|
|
15076
|
+
}
|
|
15077
|
+
return null;
|
|
15078
|
+
}
|
|
14941
15079
|
// Embedder for My Files notes — the same BYOK seam clip search uses. Prefer the
|
|
14942
15080
|
// provider matching the embedding model the file library was built with (from
|
|
14943
15081
|
// the newest annotated attachment) so query vectors stay cosine-comparable; a
|
|
@@ -14946,7 +15084,7 @@ app.get(`${USER_PREFIX}/me/generated-media`, async (c) => {
|
|
|
14946
15084
|
async function buildFileNotesEmbedder(customerId) {
|
|
14947
15085
|
const attachments = await serverlessRecords.listUserAttachments(customerId);
|
|
14948
15086
|
const libModel = attachments.find((a) => a.notesEmbeddingModel && Array.isArray(a.notesEmbedding) && a.notesEmbedding.length > 0)?.notesEmbeddingModel ?? null;
|
|
14949
|
-
const providers = libModel ? [libModel
|
|
15087
|
+
const providers = libModel ? [inferEmbeddingProviderFromModel(libModel)] : ["gemini", "openai"];
|
|
14950
15088
|
for (const provider of providers) {
|
|
14951
15089
|
const apiKey = await resolveCustomerProviderKey(customerId, provider);
|
|
14952
15090
|
if (!apiKey)
|
|
@@ -16162,7 +16300,7 @@ async function pickClipProviderFromKeys(customerId) {
|
|
|
16162
16300
|
*/
|
|
16163
16301
|
async function buildMatchEmbedder(customerId) {
|
|
16164
16302
|
const libModel = await clipRecords.getLibraryEmbeddingModel(customerId);
|
|
16165
|
-
const provider = libModel
|
|
16303
|
+
const provider = inferEmbeddingProviderFromModel(libModel);
|
|
16166
16304
|
const key = await resolveCustomerProviderKey(customerId, provider);
|
|
16167
16305
|
if (!key)
|
|
16168
16306
|
return null;
|
|
@@ -16532,29 +16670,54 @@ app.post(`${CLIPS_PREFIX}/scan`, async (c) => {
|
|
|
16532
16670
|
const computeEstimate = effectiveDurationSec
|
|
16533
16671
|
? estimateClipScanComputeUsd(effectiveDurationSec, huntSpec.duration_band?.target_sec)
|
|
16534
16672
|
: null;
|
|
16535
|
-
|
|
16536
|
-
|
|
16537
|
-
|
|
16538
|
-
|
|
16539
|
-
|
|
16540
|
-
|
|
16541
|
-
|
|
16542
|
-
|
|
16543
|
-
|
|
16544
|
-
|
|
16545
|
-
|
|
16546
|
-
|
|
16547
|
-
|
|
16548
|
-
|
|
16549
|
-
|
|
16550
|
-
|
|
16551
|
-
|
|
16552
|
-
|
|
16553
|
-
|
|
16554
|
-
|
|
16555
|
-
|
|
16556
|
-
|
|
16557
|
-
|
|
16673
|
+
// Records first: a Dynamo failure here aborts submission before anything
|
|
16674
|
+
// is billed, and the warm probe lambda's later status:"scanning" write is
|
|
16675
|
+
// never clobbered back to "pending" by a post-start putScanRecords.
|
|
16676
|
+
await putScanRecords({ scanStatus: "running" });
|
|
16677
|
+
let executionArn;
|
|
16678
|
+
try {
|
|
16679
|
+
const res = await clipScanSfn.send(new StartExecutionCommand({
|
|
16680
|
+
stateMachineArn: config.VIDFARM_CLIP_SCAN_STATE_MACHINE_ARN,
|
|
16681
|
+
name: scanId.replace(/[^A-Za-z0-9-_]/g, "-").slice(0, 80),
|
|
16682
|
+
input: JSON.stringify({
|
|
16683
|
+
scan_id: scanId,
|
|
16684
|
+
owner_id: customer.id,
|
|
16685
|
+
source_video_id: sourceVideoId,
|
|
16686
|
+
source_filename: filename,
|
|
16687
|
+
raw_s3_uri: rawS3Uri ?? "",
|
|
16688
|
+
tier,
|
|
16689
|
+
provider,
|
|
16690
|
+
tag_api_key: tagApiKey,
|
|
16691
|
+
embedding_provider: client.embeddingProvider ?? "",
|
|
16692
|
+
embedding_api_key: embeddingKey ?? "",
|
|
16693
|
+
guidance_prompt: guidancePrompt,
|
|
16694
|
+
frames_per_scene: framesPerScene,
|
|
16695
|
+
include_audio: includeAudio,
|
|
16696
|
+
hunt_spec: huntSpec,
|
|
16697
|
+
tracer
|
|
16698
|
+
})
|
|
16699
|
+
}));
|
|
16700
|
+
executionArn = res.executionArn;
|
|
16701
|
+
}
|
|
16702
|
+
catch (error) {
|
|
16703
|
+
// The execution never started — roll the scan (and its source) to failed
|
|
16704
|
+
// so pollers do not spin on a "running" record that will never progress,
|
|
16705
|
+
// mirroring the lazy-reconcile failure path.
|
|
16706
|
+
const orphan = await clipRecords.getScan(customer.id, scanId);
|
|
16707
|
+
if (orphan)
|
|
16708
|
+
await clipRecords.putScan({ ...orphan, status: "failed", error: "Failed to start the scan pipeline.", updated_at: nowIso() });
|
|
16709
|
+
const orphanSource = await clipRecords.getSource(customer.id, sourceVideoId);
|
|
16710
|
+
if (orphanSource && orphanSource.status !== "complete")
|
|
16711
|
+
await clipRecords.putSource({ ...orphanSource, status: "failed", updated_at: nowIso() });
|
|
16712
|
+
throw error;
|
|
16713
|
+
}
|
|
16714
|
+
// Attach the execution ARN for lazy SFN reconciliation (best-effort — the
|
|
16715
|
+
// record is already pollable; spread the current record so a runner that
|
|
16716
|
+
// has already advanced the status is not regressed).
|
|
16717
|
+
const startedScan = await clipRecords.getScan(customer.id, scanId);
|
|
16718
|
+
if (startedScan)
|
|
16719
|
+
await clipRecords.putScan({ ...startedScan, execution_arn: executionArn, updated_at: nowIso() });
|
|
16720
|
+
return scanResponse({ status: "running", executionArn, pipeline: "cloud", estimate, computeEstimate });
|
|
16558
16721
|
}
|
|
16559
16722
|
// ── vidfarm serve (no deployed pipeline): LOCAL-FIRST, cloud as backup ──
|
|
16560
16723
|
// Same policy as `vidfarm clips scan`: the user's local claude/codex CLI
|
|
@@ -16856,6 +17019,11 @@ async function mirrorUpstreamClipsToLocal(input) {
|
|
|
16856
17019
|
if (!feed.ok || !feed.json)
|
|
16857
17020
|
throw new Error(`Upstream clip feed unavailable (HTTP ${feed.status}).`);
|
|
16858
17021
|
let stored = 0;
|
|
17022
|
+
// Upstream /clips/feed strips the embedding vector, so re-embed each mirrored
|
|
17023
|
+
// clip on the owner's BYOK key — otherwise it lands with no embedding and is
|
|
17024
|
+
// permanently invisible to semantic clip search (keyword-only). Fail-soft:
|
|
17025
|
+
// no embed-capable key → store without embedding (keyword-only), as before.
|
|
17026
|
+
const embedder = await buildClipLibraryEmbedder(ownerId);
|
|
16859
17027
|
for (const raw of feed.json.clips ?? []) {
|
|
16860
17028
|
const clipId = typeof raw.clip_id === "string" ? raw.clip_id : null;
|
|
16861
17029
|
const viewUrl = typeof raw.view_url === "string" ? raw.view_url : null;
|
|
@@ -16875,16 +17043,32 @@ async function mirrorUpstreamClipsToLocal(input) {
|
|
|
16875
17043
|
await storage.putBuffer(thumbKey, new Uint8Array(await thumbRes.arrayBuffer()), "image/jpeg");
|
|
16876
17044
|
}
|
|
16877
17045
|
}
|
|
16878
|
-
const { view_url: _v, thumbnail_url: _t, ...rest } = raw;
|
|
17046
|
+
const { view_url: _v, thumbnail_url: _t, embedding: _e, embedding_model: _em, ...rest } = raw;
|
|
16879
17047
|
void _v;
|
|
16880
17048
|
void _t;
|
|
16881
|
-
|
|
17049
|
+
void _e;
|
|
17050
|
+
void _em;
|
|
17051
|
+
const clip = {
|
|
16882
17052
|
...rest,
|
|
16883
17053
|
owner_id: ownerId,
|
|
16884
17054
|
source_video_id: scan.source_video_id,
|
|
16885
17055
|
file_path: clipKey,
|
|
16886
17056
|
thumbnail_path: thumbKey
|
|
16887
|
-
}
|
|
17057
|
+
};
|
|
17058
|
+
if (embedder?.embeddingModelId) {
|
|
17059
|
+
try {
|
|
17060
|
+
const [vector] = await embedder.embedDocuments([buildClipEmbeddingText(clip.tags, clip.description)]);
|
|
17061
|
+
if (vector?.length) {
|
|
17062
|
+
clip.embedding = vector;
|
|
17063
|
+
clip.embedding_model = embedder.embeddingModelId;
|
|
17064
|
+
}
|
|
17065
|
+
}
|
|
17066
|
+
catch (error) {
|
|
17067
|
+
devLog("clip_scan.upstream_mirror_embed_failed", { scan_id: scan.scan_id, clip_id: clipId, ...devErrorFields(error) }, "warn");
|
|
17068
|
+
}
|
|
17069
|
+
}
|
|
17070
|
+
await clipRecords.putClip(clip);
|
|
17071
|
+
await vectorIndex.upsert(ownerId, clip);
|
|
16888
17072
|
stored++;
|
|
16889
17073
|
}
|
|
16890
17074
|
const source = await clipRecords.getSource(ownerId, scan.source_video_id);
|