agent-n-video-pipeline · v1.0.0 · 2026-10-21 · sha256 b360b743d3a86409
agent-n-video-pipeline v1.0.0A
Immutable. This exact content never changes and is served at /api/v1/blob/b360b743d3a86409.
---
name: agent-n-video-pipeline
description: >
Use this skill when producing a fully-local "Agent N presents a message" video on
the 16GB Apple-Silicon M5 executor: Kokoro mature TTS → LTX-2.3 MLX A2V
talking render with native lip sync → karaoke captions → trim → QA → X caption.
Replaces the old cloud Herald pipeline (grok-imagine + volcengine) with zero
cloud cost. Activates for Herald release videos, Agent N announcements, and
newsletter video messages.
version: 1.0.0
author: Hermes Agent
license: MIT
compatibility: >
Cross-platform: Hermes Agent (default profile orchestrates, M5 executor
renders locally). Scripts are plain bash/python + ffmpeg + ComfyUI REST.
platforms:
- hermes-agent
tags:
- video
- agent-n
- ltx
- local-generation
- talking-head
- herald
---
# Agent N Video Pipeline (Fully Local on M5)
Produce a character-consistent "Agent N presents a message" video entirely on
the 16 GB Apple-Silicon M5 executor. Port of the cloud Herald pipeline
(`hermes_build/herald_pipeline.sh` + `build_final_video.py`) that replaces both
cloud legs (grok-imagine image-to-video, volcengine lip-sync) with ONE local
MLX leg (LTX-2.3 A2V, native audio-to-video).
## One-command usage
```bash
# in the repo: scripts/ dir
./herald_pipeline_m5.sh --spec <spec.json> --anchor agentn_anchor_v1.png
# optional: --m5 192.168.212.46 (default) --voice <path> (skip TTS)
```
Spec JSON = single source of truth, same schema as the cloud Herald version:
`{ "script": "...", "prompt": "...", "out": "...", "duration": N, "voice": "..." }`.
Default spec (research-receipts) is embedded.
## Stages (all local)
1. **TTS** — Kokoro sid 10 (mature female voice) via `kokoro_tts.py`
(sherpa-onnx; model `~/.hermes/kokoro/kokoro-multi-lang-v1_0/`, download the
`kokoro-multi-lang-v1_0.tar.bz2` bundle from k2-fsa/sherpa-onnx
`tts-models` release if purged). Override with `--voice` to skip.
2. **Talking render + lip sync in ONE leg** — `build_final_video_m5.py` queues
LTX-2.3 MLX A2V on the M5 via ComfyUI REST: anchor image + audio →
speaking video. 512×512, frames = duration×24, cfg 3.0, low_ram,
`dgrauet/ltx-2.3-mlx-q4`. Then poll + pull the mp4.
3. **Karaoke captions** — `karaoke_burn.py` (PressStart2P, word-synced to the
TRUE script). Unchanged from the cloud pipeline.
4. **Trim** — ffmpeg to voice duration +2.5 s.
5. **QA gate** — `qa_review.py` (deterministic). Call separately in the repo.
6. **X caption** — `x_caption.py` (mentions @NousResearch/@Teknium).
## Segmented mode (recommended for >10 s messages)
Render in 3–8 s chunks, each re-anchored on the Agent N image (identity lock,
no cumulative drift), then concat (each segment carries its synced audio) →
karaoke on the stitched video. `queue_segments.py` does this: split voice by
sentence boundaries, queue one A2V per segment, stitch with ffmpeg concat.
## The anchor
The anchor image IS the identity lock — sheet-derived, front-facing, ≥512²,
mouth unobstructed, no burned-in text. Never drive identity from prompt alone.
## Performance facts (measured on M5 16GB, Q4, 512×512)
- ~16 s/frame on MPS with low_ram block-streaming (Q4). 2 s clip ≈ 13 min.
- 5 s ≈ 32 min, 8 s ≈ 51 min, 22 s ≈ 2.3 h single-pass → use segmented mode.
- Q8@512×768 swaps (5.5 GB swap) — do not use on 16 GB. Q4 + 512×512 + low_ram
is the reliable envelope.
## Pitfalls already climbed (do not re-climb)
- LTX-MLX-A2V node install: ltx-2-mlx@v0.14.15 pyproject has a readme-path bug
on subdir installs; clone repo, remove the `readme` line from both subpackage
pyprojects, pip install from local clone.
- Needs `transformers < 5.10` (mlx-lm 0.31 conflict).
- ltx-core-mlx requires ffmpeg on PATH: symlink `ffmpeg`/`ffprobe` into the
ComfyUI venv bin or export PATH (user-local brew `~/homebrew/opt/ffmpeg/bin`).
- ComfyUI must launch with `PYTORCH_MPS_HIGH_WATERMARK_RATIO=0.0`.
- Flat/calm TTS → near-static mouth (node README). Expressive takes articulate.
- First A2V run downloads the Q8/Q4 model (~8–10 GB) — subsequent runs cached.
- kokoro_tts.py writes long audio with `array('h')`, NOT `struct.pack("%dh",*s)`
(unpacking ~500k args breaks on long scripts); ensure output dir exists.
## Env gate before running
- M5 ComfyUI headless: `curl -s http://M5:8188/system_stats`
- Anchor staged in M5 `ComfyUI-Shared/input/`
- Kokoro model dir present; venv `~/.venvs/kokoro/bin/python` has sherpa_onnx
- LM Studio / llama-server off (frees ~5 GB)