Commit Graph

27 Commits

Author SHA1 Message Date
Karl Weinmeister
30018a6a8f feat(tools): add Google Lyria and direct Google Veo generation tools 2026-07-09 07:11:06 -07:00
Calesthio
9566c3488f Merge pull request #317 from ziyu4huang/fix/music-gen-force-instrumental
fix(music_gen): send force_instrumental per music-gen-usage mandate (§8 #8)
2026-07-06 21:47:32 -07:00
Ziyu Huang
dbc639f608 fix(music_gen): send force_instrumental per music-gen-usage mandate
skills/creative/music-gen-usage.md mandates 'Always set
force_instrumental=true for video background', but music_gen.py never
sent the kwarg, so ElevenLabs could return vocal tracks that collide
with narration/dialogue.

- Add force_instrumental to input_schema (default True) so the mandate
  holds by default; callers may opt out only with an explicit False.
- Include force_instrumental in the /v1/music payload.
- Add tests pinning: kwarg sent True by default, explicit opt-out
  honored, and the schema default.

Refs: docs/REVIEW-image-to-video-voice.md §8 #8

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-07 07:42:35 +08:00
Ziyu Huang
0ab9779a04 fix(audio_mixer): parameterize loudnorm LUFS target
audio_mixer hard-coded loudnorm I=-16 (Apple Podcasts) in both _mix
and _full_mix. sound-design.md targets -14 for YouTube/TikTok/IG, and
edit_decisions.metadata.loudnorm_target is the declarative form — but
the mixer never read it, so the executed loudness silently defaulted
to podcast levels regardless of the target platform.

- Add loudnorm_target to input_schema (default -16, clamped to [-40, 0]).
- Extract _loudnorm_filter() helper and use it in _mix and _full_mix so
  a director can forward edit_decisions.metadata.loudnorm_target (or a
  caller can pass it directly) to hit the right platform target.
- Add tests pinning: default -16, -14 honored, out-of-range clamped,
  non-numeric fallback, and the schema default.

Refs: docs/REVIEW-image-to-video-voice.md §8 #1

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-07 07:32:44 +08:00
0xDevNinja
4c10481011 fix(audio_mixer): stop segmented_music from halving narration volume
`_segmented_music` mixed the video's audio with the shaped music via
`amix=inputs=2`, whose default `normalize=1` scales every input by 1/inputs
(x0.5, -6 dB). Unlike `_mix` and `_full_mix`, this path has no `loudnorm` stage
afterward to re-normalize, so the narration was permanently attenuated across
the entire timeline — including the stretches where the music volume expression
evaluates to 0. A one-second music segment quietly dropped the narration by
~6 dB for the whole video.

Add `normalize=0` to the amix: the music is already scaled to `music_volume`
by the `volume` expression, so speech passes at unity. Verified with ffmpeg —
narration in a no-music region tracks the stereo/aac conversion baseline
instead of sitting 6 dB below it.
2026-07-06 13:12:33 +05:30
Calesthio
97fa905ded Merge pull request #266 from 0xDevNinja/fix/audio-mixer-ducking-filtergraph
fix: three independent zero-key correctness bugs (audio_mixer ducking, scene-variation run count, source-media schema)
2026-07-05 06:48:28 -07:00
Calesthio
e09afaa280 Merge pull request #240 from yiyabo/feat/dashscope-integration
Add DashScope (Alibaba Cloud Bailian) provider: image gen + TTS + ASR
2026-07-03 18:04:53 -07:00
0xDevNinja
6426662083 fix(audio_mixer): asplit speech stream so ducking graph is CI-portable
The prior fix removed the dangling pad but still reused the speech filter
output for two consumers (sidechain key + final mix). FFmpeg auto-splits a
reused *input* label on some builds (macOS) but the Linux ffmpeg on CI rejects
it, so both full_mix ducking tests failed there.

Build a single [speech_all] stream and asplit it into [speech_key] (sidechain
key) and [speech_out] (final mix) so every filter label is produced once and
consumed once. Verified the generated graph for the single- and multi-narration
cases: no label is consumed more than once.

Refs #265
2026-07-03 12:58:29 +05:30
calesthio
280400d479 Ship Backlot living storyboard release hardening 2026-07-02 12:19:06 -07:00
0xDevNinja
febc9244d3 fix(audio_mixer): drop dangling speech_dup pad in full_mix ducking
full_mix with ducking enabled (the default) failed for a single narration
track + one music bed — the most common shape — because the ducking branch
appended an acopy[speech_dup] filter whose output pad was never consumed,
leaving the filtergraph with a dangling output that ffmpeg rejects.

For a single speech track speech_out is '[a0]' (starts with '[a'), so the
guarded append fired; the compensating pop() only removes the empty-string
case from the multi-speech branch, so the dead pad survived exactly in the
single-narration case. The speech stream is already re-derived for the final
mix via [speech_out], and ffmpeg auto-splits the reused input label, so the
duplicate is unnecessary. Multi-speech and SFX paths are unaffected.

Adds regression tests for single- and multi-narration full_mix with ducking.

Closes #265
2026-07-02 16:41:58 +05:30
Yiyabo
b4bed5735a dashscope: fix multi-image download and complete idempotency keys
Address PR #240 review feedback from @calesthio:

1. dashscope_image: save EVERY returned image URL, not just the first.
   The tool advertised multiple_outputs and accepted n>1 but only read
   content[0], silently dropping paid outputs. Now collects all image
   URLs across choices/content and downloads each to a distinct indexed
   path (foo.png -> foo_1.png, foo_2.png, ...). images_generated now
   reflects the actual count downloaded.

   Per Qwen Cloud docs, a multi-output task is SUCCEEDED if at least one
   image is generated; choices with finish_reason != "stop" are skipped
   to avoid downloading partial/failed results.

2. Complete idempotency_key_fields so different requests no longer
   collide and reuse stale artifacts:
   - image: + negative_prompt, seed, prompt_extend, watermark
   - tts:   + instructions
   - asr:   + enable_words, language_hints

Adds 19 regression tests (114 total, all pass, no API keys needed):
- TestDashscopeImageMultiOutput: URL extraction across choices / within
  one choice / failed-choice skipping, path resolution for
  single/multi/no-extension, end-to-end multi-image download with a
  mocked 3-URL DashScope response verifying all 3 files land on disk,
  single-image legacy path behavior
- TestDashscopeIdempotencyKeys: field presence + key-differs-on-value
  for every newly added field across all three tools
2026-07-02 00:37:51 +08:00
Calesthio
7b8d59186d Merge pull request #223 from 0xDevNinja/feat/issue-168-music-library-preflight
feat(audio): add music_library tool so user tracks surface at preflight
2026-06-30 20:40:14 -07:00
Yiyabo
b836416ac2 dashscope: add TTS provider (qwen3-tts-flash) 2026-06-30 14:35:34 +08:00
calesthio
5e4943a41b Add expressive TTS governance 2026-06-29 12:16:07 -07:00
0xDevNinja
add955696d feat(audio): add music_library tool so user tracks surface at preflight
AGENT_GUIDE.md requires the music decision to be made at the proposal stage,
but the only check for the user's music_library/ folder lived in the
asset-director skills, which run later. A user could approve a creative
direction without ever being told a free, intentional music option was sitting
on disk (issue #168).

music_library/ was already referenced as a source_tool in asset artifacts but
had no backing tool. Add a small read-only tool that scans the library folder
(default <project root>/music_library, override via MUSIC_LIBRARY_DIR or a
library_dir input) and lists the audio tracks it finds, with best-effort
durations via ffprobe when present.

Because it inherits BaseTool, the registry auto-discovers it and it appears in
the preflight provider menu alongside music_gen and the stock music sources:
- AVAILABLE when the folder holds at least one audio track
- UNAVAILABLE otherwise, with install_instructions telling the user how to add
  tracks

So the user sees their music options before approving creative direction, with
no orchestration code changes. Read-only: no side effects, no cost.

Closes #168
2026-06-29 13:24:48 +05:30
Harsh Dadiya Wappnet
3656222356 fix: resolve skill loading warnings and correct video-toolkit naming 2026-06-25 19:00:47 +05:30
Shubham
806f7ee1ac feat(google): support service-account auth for TTS + Imagen, fix false availability
Google's TTS and Imagen tools advertised service-account auth
(GOOGLE_APPLICATION_CREDENTIALS) but only ever authenticated with an API
key string, so users with a service-account JSON could not use either tool.
google_tts.get_status() also over-reported availability when the JSON was
set, then failed at execute() — a silent-availability bug.

Separately, both hand-rolled _load_dotenv parsers kept inline comments as
values, so after `cp .env.example .env` every keyed tool falsely reported
"available" with no real credentials.

Changes:
- Add tools/google_credentials.py: lazy google-auth Bearer-token helper.
- google_tts: authenticate via Cloud TTS Bearer token when only a service
  account is configured; make get_status() honest.
- google_imagen: route service-account auth to Vertex AI
  ({location}-aiplatform.googleapis.com) with project/location resolution,
  alongside the existing AI Studio API-key path.
- Fix both _load_dotenv parsers to strip inline comments (quote-aware).
- Add google-auth to requirements; document the new env vars in .env.example.
- .gitignore: never commit GCP service-account key files.

Verified locally with a real service account: TTS produced a valid MP3 and
Imagen produced a valid 1408x768 PNG via Vertex AI. Existing test suite
passes (2 unrelated pre-existing failures only).

Closes #131

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 17:53:10 +05:30
jiangjiahui5
3ee8548226 feat(tts): add Doubao Speech provider
Add Volcengine Doubao Speech 2.0 as a TTS provider for Mandarin narration with async timestamp metadata, provider documentation, and setup guidance.
2026-05-04 21:40:17 +08:00
calesthio
cf3527fbbe docmontage: end-tag overlay default + Chirp 3 HD as default TTS voice
End-tag now composited over final body footage (ProRes 4444 with alpha)
instead of concatenated as a black card. Updated idea-director,
edit-director, compose-director, and pipeline manifest with overlay-first
instructions. Default Google TTS voice changed from Neural2-D to
Chirp3-HD-Orus across tool code and docs.
2026-04-11 21:38:36 -07:00
calesthio
d5e754ba0f Add Chirp 3 HD and Journey voice support to Google TTS
Route Chirp and Journey voice families to the v1beta1 API endpoint
automatically. Adds beta voice detection, dynamic API version
selection, and Chirp3-HD cost estimation ($30/1M chars).
2026-04-06 12:13:41 -07:00
calesthio
7ca04e66d8 Add Grok media providers and improve selector routing 2026-04-05 15:31:37 -07:00
calesthio
1e5fda3c5c Fix OpenAI TTS passing null instructions to API
The instructions parameter was passed as None when not provided,
causing a 400 error. Now only included when explicitly set. Also
adds speed passthrough support.
2026-04-04 13:10:29 -07:00
calesthio
2cd36fa8e0 Implementation spec: governance, decision intelligence, theme system, and E2E bug fixes
Implements the 2026-04-02 transformation spec (Phases 1-8) and fixes all
critical bugs found during 5-pipeline E2E testing.

Governance & Decision Intelligence:
- Pipeline-specific stage order in checkpoint (replaces global STAGES list)
- Provider scoring engine (lib/scoring.py) with 7-dimension weighted ranking
- Decision log artifact enforced at proposal/idea stage across all 10 pipelines
- Delivery promise classifier prevents silent motion-to-still downgrades
- Structured shot language in scene_plan schema (camera, lens, lighting, DOF)
- Variation checker and slideshow risk scorer block samey output before render
- Creative intake, capability extension, and creative-intake meta skills
- Final self-review artifact with 5 mandatory checks before presenting output
- Source media review contract for user-supplied footage

Render & Theme System:
- Remotion AnimatedBackground now derives colors from playbook (no more hardcoded
  dark blue fintech gradient on every video)
- video_compose builds custom ThemeConfig from playbook YAML colors/fonts —
  custom playbooks flow through to Remotion automatically
- Explainer component wires theme to all child components (charts, cards, etc.)
- resolveAsset() handles absolute paths on Windows/Unix via file:// URIs
- RENDERER_FAMILY_MAP synced with actual Remotion compositions

Critical Bug Fixes:
- Windows npx subprocess: run_command() resolves .cmd wrappers via shutil.which()
- Silent renderer downgrade: Remotion failure now returns explicit error with
  options instead of silently falling back to FFmpeg
- .env inline comment parsing strips trailing # comments from API keys
- concat_path UnboundLocalError in video_compose finally block
- audio_mixer and showcase_card capture=True kwarg bug
- Selector estimate_cost() calls fixed (_select_tool -> _select_best_tool)
- asset_manifest schema expanded with provider, license, subtype fields
- screen-demo subtitle_gen moved from required to optional tools
- Duration drift detection in post-render final review (>25% warns)
2026-04-03 09:35:09 -07:00
calesthio
358b8647f5 Talking-head pipeline: 8 new tools, Remotion TalkingHead composition, and skill rewrites
New tools: face_tracker, visual_qa, eye_enhance, auto_reframe, remotion_caption_burn, showcase_card, silence_cutter. Updated audio_mixer with segmented_music operation and subtitle_gen with ASR corrections. Registered TalkingHead composition in Root.tsx. Rewrote compose/edit/scene director skills for full enhancement chain, Remotion captions, multi-clip assembly, and visual QA. Gitignore cleanup: exclude test demo-props, downloaded music, and generated images.
2026-04-01 10:00:15 -07:00
calesthio
8cac647193 One-key formula: AI images, TTS narration, auto music, subtitles, and self-review pipeline
Prove that adding one API key (OPENAI_API_KEY) to the zero-key foundation
produces dramatically better videos for ~$0.69 each. Two compositions built:
The Abyss (deep ocean visual essay) and VOID (neural interface product ad).

New tools:
- audio_probe: ffprobe wrapper with probe_duration() helper
- composition_validator: pre-render checks (asset existence, audio-video sync)
- pixabay_music: royalty-free music scraper (no API key needed)
- freesound_music: Freesound API search + download

Remotion upgrades:
- BackgroundImageLayer: AI images behind data scenes with ken-burns + dark overlay
- Gradient support: all 9 components changed from backgroundColor to background CSS
- CaptionOverlay: word spacing fix, WhisperX word-level subtitles
- HeroTitle: reduced overlay opacity so background images show through

Process codified in agent skills:
- compose-director: audio acquisition flow (present user with voice/music/subtitle
  options), mandatory pre-render validation, post-render self-review (extract
  frames + transcribe + inspect + present findings to user)
- scene-director: narration duration budgeting (word budget from video duration)
- remotion skill: pre-render validation section
- TTS tool: now returns audio_duration_seconds in result

README updated with VOID product ad video embed.
2026-03-30 16:54:13 -07:00
calesthio
4327000433 Add Google Imagen and Google Cloud TTS provider tools
Two new provider tools following the BaseTool pattern with auto-discovery:
- google_imagen: Imagen 4 image generation via Generative Language REST API
- google_tts: Google Cloud TTS with 700+ voices across 50+ languages

Both share GOOGLE_API_KEY env var. Selectors auto-discover them — no
selector code changes needed. Docs and contract tests updated.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 09:06:26 -07:00
calesthio
a3e735cc7a Initial release — OpenMontage: the first open-source agentic video production system
11 production pipelines, 47 tools, 124 agent skills.
Supports cloud APIs (fal.ai, OpenAI, ElevenLabs, Suno, HeyGen, Runway) and
free local providers (diffusers, Piper TTS, WAN 2.1, Hunyuan, CogVideo).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 08:25:17 -07:00