Veo Generator
Turns an already-scripted shot package into actual video. The prompting is done
by the veo-showreel-production-kit skill (STYLE BIBLE → per-shot shots/*.md);
this skill is the render step that calls the Veo 3.1 API and downloads mp4s.
It expects the layout the production kit emits:
<Project>/
.env <- (optional) per-project API key lives here
video_production/
shots/shot_*.md <- source of truth: prompt, negative, seed, aspect, refs
storyboard/*.png <- first-frame sketches + 00_world_anchor.png
renders/ <- mp4 output (created here)
Each shots/shot_NN.md already contains everything the renderer needs: the
▶ Full Veo prompt block, the ⛔ Negative prompt block, and a
Reproduction & consistency line with the seed, aspect ratio, resolution,
reference image(s) and first-frame image. The renderer parses those — it never
re-invents the prompt.
Prerequisites
- The
pi-veo CLI (this package). Runs as TypeScript via pi's jiti loader — no build step.
- ffmpeg — only needed for
--chain (seamless A→B last-frame handoff).
Declared in pi.tools and resolved via the tool registry; absent →
non-chain videos still generate.
- An API key (see below). Get one at https://aistudio.google.com/apikey.
Declared as an
env probe (GEMINI_API_KEY) in pi.tools. The registry
recognizes GEMINI_API_KEY only — the CLI's VEO_API_KEY /
GOOGLE_API_KEY aliases still work at run time but are NOT tracked in
Settings → Tools.
API key — per project or global
Resolution order, first non-empty wins:
| # |
Source |
Use |
| 1 |
--api-key <KEY> flag |
one-off |
| 2 |
VEO_API_KEY / GEMINI_API_KEY / GOOGLE_API_KEY env var |
machine-wide |
| 3 |
<Project>/.env or …/video_production/.env |
per-project key |
| 4 |
this package's .env |
global fallback |
Copy .env.example and set VEO_API_KEY=…. Never commit real keys.
Procedure
Dry-run / validate the package (no key spent):
pi-veo parse <Project>
Confirms every shot has a parseable prompt, shows seed/aspect/resolution, the
first-frame sketch, the reference image and seamless→next chaining. Add
--json for machine output, --shots 01 03A for a subset.
Plan the render (resolves key + model + outputs, still no API call):
pi-veo plan <Project>
Render (calls Veo, polls, downloads to video_production/renders/):
pi-veo render <Project>
- Test a single shot first:
--shots 01
- Cheaper/faster preview pass:
--model fast --resolution 720p
- Seamless A→B handoff (sequential, uses ffmpeg last frame):
--chain
- Render several independent shots at once:
--parallel 4
- Also attach the world-anchor as a reference image:
--with-reference
- Re-render existing clips:
--force
Already-rendered shot_NN.mp4 files are skipped unless --force, so the
command is safe to re-run / resume.
(Optional) regenerate storyboard sketches (the first-frame images) via
nano-banana, if they're missing or you changed sketch_prompts.json:
pi-veo storyboard <Project>
Assemble in post — cut the renders/*.mp4 in timecode order, lay the
official voiceover + music, bake captions, drop the logo into the reserved
space of the final shot. (Veo only makes ambient SFX — speech is forbidden in
the AUDIO LOCK on purpose.)
Notes & pitfalls
- Veo clips are ≤8s. The shot package is already split into ≤8s units; don't
merge them. Long beats are A/B pairs.
- Model IDs:
standard → veo-3.1-generate-preview, fast →
veo-3.1-fast-generate-preview. Pass a full id to --model to use another.
- Resolution
4k is Veo 3.1 preview only and is slower + pricier; use
--resolution 1080p (or 720p for cheap previews) to override the shot files.
- Parallel rendering: by default shots render one-at-a-time.
--parallel N
keeps up to N Veo operations in flight; the real ceiling is your Veo API
quota. --chain forces sequential (B needs A's rendered last frame).
- first-frame vs reference: by default the shot's own storyboard sketch is the
image-to-video first frame.
--with-reference additionally sends the
world-anchor as an asset reference; if the model rejects that combo the
renderer automatically retries without it.
- Cost: every render call spends credits. Always
parse → plan → render one
shot → then the batch.
- Gemini Developer API quirks (AI Studio key): the Developer API rejects
seed
and enhance_prompt. Use --no-seed (and leave enhance_prompt off — it's
opt-in via --enhance-prompt, Vertex only). Reproducibility then relies on the
first-frame sketches + STYLE LOCK, not the seed.
- Vertex env trap: if
GOOGLE_GENAI_USE_VERTEXAI=true / GOOGLE_CLOUD_PROJECT
are exported, the client routes to Vertex and fails. Unset them to force the
Developer API.
- Logs: each run appends to
renders/render_log.jsonl (status, seed, model,
resolution, output path, seconds) for auditing.
1---2name: veo-generator3description: Render a scripted video project into mp4 clips with the Google Veo 3.1 API. Reads a project's shot package (shots/*.md), one clip per camera cut, reusing each shot's prompt and sketch — world anchor only with `--with-reference`, seed unless `--no-seed`. Use on "render the Veo video for <project>", "generate the videos from the shot scripts", "make the clips with Veo".4---56# Veo Generator78Turns an already-scripted shot package into actual video. The **prompting** is done9by the `veo-showreel-production-kit` skill (STYLE BIBLE → per-shot `shots/*.md`);10this skill is the **render step** that calls the Veo 3.1 API and downloads mp4s.1112It expects the layout the production kit emits:1314```15<Project>/16 .env <- (optional) per-project API key lives here17 video_production/18 shots/shot_*.md <- source of truth: prompt, negative, seed, aspect, refs19 storyboard/*.png <- first-frame sketches + 00_world_anchor.png20 renders/ <- mp4 output (created here)21```2223Each `shots/shot_NN.md` already contains everything the renderer needs: the24**▶ Full Veo prompt** block, the **⛔ Negative prompt** block, and a25**Reproduction & consistency** line with the seed, aspect ratio, resolution,26reference image(s) and first-frame image. The renderer parses those — it never27re-invents the prompt.2829## Prerequisites3031- The `pi-veo` CLI (this package). Runs as TypeScript via pi's jiti loader — no build step.32- **ffmpeg** — only needed for `--chain` (seamless A→B last-frame handoff).33 Declared in `pi.tools` and resolved via the tool registry; absent →34 non-chain videos still generate.35- An API key (see below). Get one at <https://aistudio.google.com/apikey>.36 Declared as an `env` probe (`GEMINI_API_KEY`) in `pi.tools`. The registry37 recognizes `GEMINI_API_KEY` only — the CLI's `VEO_API_KEY` /38 `GOOGLE_API_KEY` aliases still work at run time but are NOT tracked in39 Settings → Tools.4041## API key — per project or global4243Resolution order, **first non-empty wins**:4445| # | Source | Use |46|---|--------|-----|47| 1 | `--api-key <KEY>` flag | one-off |48| 2 | `VEO_API_KEY` / `GEMINI_API_KEY` / `GOOGLE_API_KEY` env var | machine-wide |49| 3 | **`<Project>/.env`** or `…/video_production/.env` | **per-project key** |50| 4 | this package's `.env` | global fallback |5152Copy [`.env.example`](.env.example) and set `VEO_API_KEY=…`. Never commit real keys.5354## Procedure55561. **Dry-run / validate the package** (no key spent):57 ```bash58 pi-veo parse <Project>59 ```60 Confirms every shot has a parseable prompt, shows seed/aspect/resolution, the61 first-frame sketch, the reference image and seamless→next chaining. Add62 `--json` for machine output, `--shots 01 03A` for a subset.63642. **Plan the render** (resolves key + model + outputs, still no API call):65 ```bash66 pi-veo plan <Project>67 ```68693. **Render** (calls Veo, polls, downloads to `video_production/renders/`):70 ```bash71 pi-veo render <Project>72 ```73 - Test a single shot first: `--shots 01`74 - Cheaper/faster preview pass: `--model fast --resolution 720p`75 - Seamless A→B handoff (sequential, uses ffmpeg last frame): `--chain`76 - Render several independent shots at once: `--parallel 4`77 - Also attach the world-anchor as a reference image: `--with-reference`78 - Re-render existing clips: `--force`79 Already-rendered `shot_NN.mp4` files are **skipped** unless `--force`, so the80 command is safe to re-run / resume.81824. **(Optional) regenerate storyboard sketches** (the first-frame images) via83 nano-banana, if they're missing or you changed `sketch_prompts.json`:84 ```bash85 pi-veo storyboard <Project>86 ```87885. **Assemble in post** — cut the `renders/*.mp4` in timecode order, lay the89 official voiceover + music, bake captions, drop the logo into the reserved90 space of the final shot. (Veo only makes ambient SFX — speech is forbidden in91 the AUDIO LOCK on purpose.)9293## Notes & pitfalls9495- **Veo clips are ≤8s.** The shot package is already split into ≤8s units; don't96 merge them. Long beats are A/B pairs.97- **Model IDs:** `standard` → `veo-3.1-generate-preview`, `fast` →98 `veo-3.1-fast-generate-preview`. Pass a full id to `--model` to use another.99- **Resolution `4k`** is Veo 3.1 preview only and is slower + pricier; use100 `--resolution 1080p` (or `720p` for cheap previews) to override the shot files.101- **Parallel rendering:** by default shots render one-at-a-time. `--parallel N`102 keeps up to N Veo operations in flight; the real ceiling is your **Veo API103 quota**. `--chain` **forces sequential** (B needs A's rendered last frame).104- **first-frame vs reference:** by default the shot's own storyboard sketch is the105 image-to-video first frame. `--with-reference` *additionally* sends the106 world-anchor as an `asset` reference; if the model rejects that combo the107 renderer automatically retries without it.108- **Cost:** every render call spends credits. Always `parse` → `plan` → render one109 shot → then the batch.110- **Gemini Developer API quirks (AI Studio key):** the Developer API rejects `seed`111 and `enhance_prompt`. Use **`--no-seed`** (and leave enhance_prompt off — it's112 opt-in via `--enhance-prompt`, Vertex only). Reproducibility then relies on the113 first-frame sketches + STYLE LOCK, not the seed.114- **Vertex env trap:** if `GOOGLE_GENAI_USE_VERTEXAI=true` / `GOOGLE_CLOUD_PROJECT`115 are exported, the client routes to Vertex and fails. Unset them to force the116 Developer API.117- **Logs:** each run appends to `renders/render_log.jsonl` (status, seed, model,118 resolution, output path, seconds) for auditing.