| name | space-demo-video |
| description | Create a polished social demo video (MP4, 4:3, ~10s) for any Hugging Face Space with the space-demo-kit renderer. Use whenever the user asks for a demo, promo, showcase, or social video of a HF Space or model. Covers template selection (i2v, t2v, edit, avatar, a2a, gallery, vqa), manifest schema, live asset capture, rendering, verification, and delivery. |
Space Demo Video (space-demo-kit)
The kit renders a Gradio-style "app window" video: a hero intro where the input opens
near full-frame with the prompt typing in large text (readable at mobile feed size),
a morph into the app layout with the Space's real header (emoji, author/name, likes,
hardware), a Generate press, a progress sweep, and the real output filling the output
panel edge-to-edge. Text auto-fits its panels (short answers render huge, long ones stay
readable). Branding is extracted from the Space page automatically. Output: 1440x1080
(4:3), 30 fps, ~12–17 s, H.264, silent unless the task itself involves audio.
Kit location on this machine: /root/code/space-demo-kit
Render command (the ONLY way to produce the video):
cd /root/code/space-demo-kit && python3 render.py manifests/<name>.json
Golden rules
- Never design video frames by hand. No PIL cards, no ffmpeg drawtext/overlay design,
no custom HTML. The kit owns 100% of the design; you only supply facts and assets via a
manifest JSON.
- Real outputs. Generate the output by calling the live Space (
gradio_client) with a
real input. Only mock when live inference is impossible (quota, broken Space), and then
label it honestly in the manifest meta field (e.g. "mock demo assets") and tell the user.
- Real branding. Pull
emoji, colorFrom, colorTo, likes, and hardware from
https://huggingface.co/api/spaces/<id> (cardData + runtime.hardware.current).
If the user gives a MODEL id, resolve its demo Space first (model page / spaces field of
https://huggingface.co/api/models/<id>).
- Prompts under 160 chars. The renderer truncates displayed prompts around 150 chars;
pick or write inputs that fit.
- Verify before delivering:
ffprobe the MP4 (duration, 1440x1080) and look at the
contact sheet (no overflowing text, output visible). Then send the MP4 to the user as media.
- One look only. Never put a
"style" key in a manifest — the app-window template is the
only production design and the renderer ignores styles. Anything under experiments/ is a
rejected prototype: never use it as an example or reference.
Asset quality bar (hard requirements)
- Inputs must be real content: a real photograph, illustration, or clip at least 512 px on
the short side. NEVER an emoji, icon, favicon, logo, or clipart — tiny images upscale into
blurry blobs and ruin the video. Verify every asset with
file + dimensions before using it.
- Best input source: the Space's own example assets (the
examples in its Gradio config,
or files in the Space repo via https://huggingface.co/api/spaces/<id>/tree/main). They are
known to work with the model.
- Before/after coherence (
edit, a2a): the output MUST actually be derived from the
input. Never pair two unrelated assets — an incoherent before/after is worse than no video.
If live inference fails: retry via gradio_client (not hand-built HTTP calls), try another
example input, and if it still fails, report the failure to the user and STOP. Do not
fabricate the pair.
Template selection
| template | Space task | required manifest fields |
|---|
i2v | image → video | input_image, prompt, video (generated clip) |
t2v | text → video | prompt, video |
edit | image + instruction → image | input_image, prompt, before_image, after_image |
avatar | portrait + audio → talking video | input_image, audio, video (audio can be the generated mp4 itself) |
a2a | audio → audio | audio_in, audio_out |
gallery | one input → several images | input_image, prompt, outputs (list of {path, label}, 4 items) |
vqa | video/image + question → text | video, prompt, answer |
Text-to-image Spaces use t2v: turn the generated image into a short static clip first
(ffmpeg -loop 1 -i out.webp -t 6 -r 30 -pix_fmt yuv420p static.mp4) and pass it as video
(see manifests/z-image-turbo-demo.json). There is no t2i template.
Manifest schema
Common fields (all templates):
{
"name": "my-demo",
"template": "edit",
"space": {
"id": "owner/space-name",
"emoji": "🧬",
"colorFrom": "blue",
"colorTo": "gray",
"likes": 27,
"hardware": "zero-a10g"
},
"meta": "live output · zero-a10g",
"button": "Generate",
Plus the template-specific fields from the table. All asset paths are absolute paths on
this machine. Store working assets under /root/code/<project-dir>/ as usual.
Workflow
curl -s https://huggingface.co/api/spaces/<id> → metadata for space{} fields.
- Pick the template from the table. If the Space's task fits none of them, say so and pick
the closest; do NOT invent a new design.
- Capture assets: choose a good input (the Space's own example assets are ideal), run the
live Space with
gradio_client, download the real output. Verify the output file with
ffprobe/file before rendering.
- Write
manifests/<name>.json in the kit.
- Render (command above). First run downloads fonts/emoji (needs network) and, for video
inputs, extracts frames. A render takes roughly 3–5 minutes — do not assume it hung.
- Verify MP4 + contact sheet, then deliver the MP4 to the user as a media message.
Codex dispatch (OpenClaw — mandatory)
Demo-video requests are heavy (live inference + a ~2 min render). Do NOT run inference or
rendering inline in the main session — it blocks you for many minutes. ALWAYS dispatch a
codex session per the codex-monitor skill (setsid, </dev/null, CODEX_HOME pinned) and let
the CODEX_FINISHED wake drive verification + delivery. Include in the codex prompt:
"Read /root/code/space-demo-kit/skills/space-demo-video/SKILL.md and follow it exactly.
Use the kit's render.py for ALL visuals; do not design any frame yourself."
Gotchas
- Long Space ids auto-shrink in the footer; long repo names get ellipsized in the header — fine.
- The renderer needs Playwright + Chromium (already installed system-wide here).
- Audio templates (
avatar, a2a) mux the real audio automatically, delayed to the moment
playback starts on screen, at 2x gain with a limiter.
gallery wants exactly 4 outputs for the 2x2 grid.
vqa answers auto-fit the output panel: keep them 30–60 words so the type stays large.
- Do not edit
templates/app-window.html or render.py for a one-off video. If a Space
genuinely needs a new mode, report that instead of hacking around the kit.