---
name: gen-video
description: |
  AI video generation skill: produce a short clip from a text prompt. Backed by ab-api's `/model/genVideo` (Seedance 2.0 family).

  Use this skill immediately whenever the user asks for any of:
  - Text-to-video, AI-generated clip, "make a short video of ..."
  - Generate video with Doubao / Seedance
  - Image-to-video, first-frame / last-frame, reference-image-to-video
  - Omni-modal reference: borrow the look of a reference image, the camera work of a reference video, or the voice / music of a reference audio clip

  Even without an explicit "use AI", any request that turns a description into a moving clip should route here.
triggers:
  - Text-to-video, AI-generated clip, "make a short video of ..."
  - Generate video with Doubao / Seedance
  - Image-to-video, first-frame / last-frame, reference-image-to-video
  - Reference video / reference audio, "same camera move as this clip", "use this track"
---

# AI Video Generation Skill

Wraps ab-api's `POST /model/genVideo` (the same endpoint the web "Lingchuang AI Video" tool uses), authenticated with the **Tianyan privateToken**, routed through LiteLLM to **Seedance 2.0**. Generation is async — the handler submits the task and polls `/model/getVideoStatus` until completion.

> This skill was migrated from a Python script to an remixmate CLI HTTP handler (`entry.type: http`). The agent invocation is unchanged (same tool name `gen_video`, same params as in `skill.json`); local repro goes through `remixmate gen-video ...`.

## Models

The authoritative roster — ids, aliases and per-model limits — lives in the backend catalog
(`/model/capabilities`), which the CLI fetches at runtime. The table below mirrors it; when the
two disagree, the catalog wins.

All three are Seedance 2.0; they differ only in price tier and top resolution.

| LiteLLM `model` | Display name | Provider | Resolution | Notes |
|-----------------|--------------|----------|------------|-------|
| `doubao-seedance-2-0-mini-260615` | Seedance-2.0-mini | Volcano | `480p` `720p` | Default. Cheapest tier (~half the standard rate) |
| `doubao-seedance-2-0-fast-260128` | Seedance-2.0-fast | Volcano | `480p` `720p` | Mid tier |
| `doubao-seedance-2-0-260128` | Seedance-2.0 | Volcano | `480p` `720p` `1080p` | Highest quality; the only tier with 1080p |

**Model shortcuts** (`--model` / `-m` accepts these directly):
- `seedance-mini` / `seedance-2.0-mini` → Seedance-2.0-mini
- `seedance-fast` / `seedance-2.0-fast` → Seedance-2.0-fast
- `seedance` / `seedance-2.0` → Seedance-2.0

Veo 3.1 / Veo 3.1 Fast are **not available** — there is no working Veo channel on the gateway,
so they are absent from the catalog and `--model veo` will fail.

### Parameter ranges (identical across the three tiers, except resolution)

| | Seedance 2.0 mini / fast / standard |
|--|--|
| **Aspect ratio** | `adaptive` `16:9` `4:3` `1:1` `3:4` `9:16` `21:9` |
| **Resolution** | `480p` `720p` (`1080p` on `seedance` only) |
| **Duration** | 4–15 seconds (continuous integers) |
| **First / last frame** | yes |
| **Reference images** | yes, up to 9 |
| **Reference videos** | yes, up to 3 (public https URLs) |
| **Reference audio** | yes, up to 3 (public https URLs) |
| **Generated audio** | yes |
| **Fixed camera** | yes |
| **Web search** | yes, text-only input |
| **Negative prompt** | ignored (Veo-only parameter) |

4k output exists on the standard tier upstream but is **not offered here** — the credit
pricing table has no 4k row, so a 4k run would be billed at the 720p rate.

### Two input modes, and they do not mix

- **Pinned frames** — `--first-frame` / `--last-frame` fix the exact opening and closing
  images. Reference images may be added alongside.
- **Omni-modal reference** — `--reference` (images) / `--reference-video` / `--reference-audio`
  hand the model material to borrow from; it decides the framing.

Combining a pinned frame with a reference video or audio is rejected (by the CLI, and by the
backend). Audio alone is not a valid input either: `--reference-audio` needs at least one
reference image or video with it.

In the prompt, refer to attachments as **"image 1" / "video 2" / "audio 1"**, numbered per
type in the order you passed them. That is the only way the model can tell them apart —
file names and asset ids mean nothing to it.

Reference images and videos containing **real human faces are rejected upstream** by the
Seedance 2.0 content filter; the run fails before it charges.

## Auth & environment

No skill-local env file — the executing process inherits the system environment.

- **Enterprise OpenClaw**: auth is already injected, **no need** for `PRIV_TOKEN` / `--priv-token`.
- **Other environments**: configure the token. Without a token, non-interactive runs fail.

| Env var | Description | Default |
|---------|-------------|---------|
| `PRIV_TOKEN` | Tianyan token; `--priv-token` overrides | none |
| `MM_VIDEO_MODEL` | Default model id or shortcut | catalog default (`seedance-mini`) |
| `MM_API_BASE_URL` | API root; `--api-base-url` overrides | `https://api.remixmate.ai/api` |
| `AGENT_NAME` | Optional `x-invoke-agent` header | none |

## Operations

1. **Prompt**: include camera language ("aerial shot", "slow motion", "push-in") and dynamic descriptions for better results. Chinese or English both work. For pure image-to-video, an empty prompt with first/last frame is allowed.
2. **Async job**: video generation is async; the handler polls until completion (typically 1–3 minutes) and emits `__progress__` lines.
3. **Surface results**: stdout prints the video URL on its own line; show it directly to the user (no download needed — the URL is cloud-persisted).

### Text-to-video (default model: Seedance-2.0-mini)

```bash
remixmate gen-video \
  --prompt "<video description>" \
  --duration 5 \
  --ratio "16:9"
```

### First/last frame + audio

Frame images accept local file paths, HTTPS URLs, or data URIs (local files are base64-encoded into a data URI).

```bash
remixmate gen-video \
  --prompt "<transition description>" \
  --first-frame ./start.png \
  --last-frame ./end.png \
  --duration 8 \
  --generate-audio
```

### 1080p final cut

Only `seedance` (the standard tier) offers 1080p; it also costs roughly twice mini per second.

```bash
remixmate gen-video \
  --model seedance \
  --prompt "<video description>" \
  --duration 8 \
  --ratio "16:9" \
  --resolution 1080p
```

### With reference images

Pass `--reference` multiple times (up to 9).

```bash
remixmate gen-video \
  --prompt "<video description>" \
  --reference ./ref1.png \
  --reference ./ref2.png \
  --duration 8
```

### Omni-modal reference (image + video + audio)

Videos and audio must be public https URLs — unlike images they are not uploaded.

```bash
remixmate gen-video \
  --prompt "Keep the first-person framing of video 1 and use audio 1 as the score; the product from image 1 is lifted toward the lens" \
  --reference ./product.png \
  --reference-video https://example.com/handheld.mp4 \
  --reference-audio https://example.com/score.mp3 \
  --duration 8 \
  --generate-audio
```

### Fresh subjects (web search)

Only fires on text-only input; attaching any image / video / audio turns it off.

```bash
remixmate gen-video \
  --prompt "<a subject the model may not know: a new product, a current event>" \
  --web-search \
  --duration 5
```

## Common CLI flags

| Flag | Description | Default |
|------|-------------|---------|
| `-p` / `--prompt` | Video description (combinable with first/last frame or references) | — |
| `-m` / `--model` | Model id or shortcut (`seedance-mini` / `seedance-fast` / `seedance`) | see `MM_VIDEO_MODEL` |
| `-d` / `--duration` | Duration in seconds (4–15) | 5 |
| `-r` / `--ratio` | Aspect ratio; `adaptive` also accepted | `16:9` |
| `--resolution` | Resolution. `1080p` only on `seedance` | `720p` |
| `--first-frame` | First-frame image: local path, https URL, or data URI | none |
| `--last-frame` | Last-frame image | none |
| `--reference` | Reference image (repeatable, max 9) | none |
| `--reference-video` | Reference video, public https URL (repeatable, max 3) | none |
| `--reference-audio` | Reference audio, public https URL (repeatable, max 3) | none |
| `--generate-audio` | Generate native audio | off |
| `--camera-fixed` | Fixed camera | off |
| `--web-search` | Search the web first (text-only input) | off |
| `--return-last-frame` | Also return the clip's last frame, to chain shots | off |
| `--negative-prompt` | Negative prompt (Veo only; ignored by Seedance) | none |
| `--seed` | Random seed; `-1` = random | none |
| `--person-generation` | Person policy: `allow_all` / `dont_allow` (Veo) | none |
| `--api-base-url` | Override API root | see above |
| `--priv-token` | Override token | see above |

## Prompt tips

- Include camera language: "aerial shot", "slow motion", "push-in", "close-up".
- Describe motion explicitly.
- Example: `"At sunrise, an aerial drone shot of a futuristic city, golden light on glass facades, mist swirling, 4K ultra-clear"`.

## Credits

Every run charges credits. The CLI prints a footer on stdout when it does:

```
💳 Charged 31 credits · balance 1,240
```

Relay it to the user whenever it appears — it is the only signal they get about what a
generation cost, and the balance is the only warning before a run fails with
`insufficient_credits`. Do not drop it from your summary.

## Error handling

- **401** / **token missing** (non-OpenClaw): set `PRIV_TOKEN`.
- **Business `code != 0`**: read `msg` on stderr.
- **429**: rate-limited; retry later.
- **Generation timeout**: the handler caps polling at ~5 minutes; retry later if it times out.
- **Network**: verify connectivity and `MM_API_BASE_URL`.
