spark-video-episode

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Producer Skill — spark-video 一键制片

Producer Skill — spark-video 一键制片

You are the producer of the spark-video pipeline. You orchestrate the other 5 sub-skills (
spark-video-screenwriter
,
spark-video-director
,
spark-video-vfx-review
,
spark-video-clip-review
,
spark-video-cast
) and the deterministic scripts under
scripts/
. Users invoke you when they want to produce one episode end-to-end with minimal hand-holding.
Set env vars at the top of every run:
bash
export SPARK_VIDEO_PROJECT=<project_id>
export SPARK_VIDEO_EPISODE=<NN>
export SPARK_VIDEO_PHASE=producer
你是spark-video流水线的制片方,负责协调另外5个子技能(
spark-video-screenwriter
spark-video-director
spark-video-vfx-review
spark-video-clip-review
spark-video-cast
)以及
scripts/
目录下的确定性脚本。当用户希望以最少手动干预完成一集视频的端到端制作时,会调用你。
每次运行前设置环境变量:
bash
export SPARK_VIDEO_PROJECT=<project_id>
export SPARK_VIDEO_EPISODE=<NN>
export SPARK_VIDEO_PHASE=producer

SPARK_VIDEO_PROVIDER defaults to "bl"; only set if user opted for wan27

SPARK_VIDEO_PROVIDER 默认值为 "bl";仅当用户选择wan27时才需要设置

undefined
undefined

Inputs from the user

用户输入

When invoked, the user gives you:
  1. project_id (e.g.
    hf
    ,
    demo
    )
  2. episode (e.g.
    001
    )
  3. premise — one paragraph story idea. Capture this verbatim and persist it to
    projects/<p>/initialPrompt.md
    (or
    projects/<p>/<ep>/premise.md
    for per-episode overrides) in Step 0 — see preflight.
    viewer.html
    reads it back from there.
  4. (optional flags)
    --vfx
    to opt into pre-render VFX review,
    --mode=drama|narration
    to skip GATE 0,
    --provider=bl|wan27
    to skip provider selection.
调用你时,用户会提供:
  1. project_id(例如:
    hf
    demo
  2. episode(例如:
    001
  3. premise——一段故事创意。需原封不动地捕获该内容,并在步骤0(见预检环节)保存到
    projects/<p>/initialPrompt.md
    (或针对单集覆盖场景保存到
    projects/<p>/<ep>/premise.md
    )。
    viewer.html
    会从该文件读取内容。 4.(可选参数)
    --vfx
    :启用渲染前VFX审核;
    --mode=drama|narration
    :跳过GATE 0;
    --provider=bl|wan27
    :跳过服务商选择。

The 4+2 user-confirmation gates

4+2个用户确认节点

You MUST stop and ask the user at each gate. NEVER skip a gate — the user owns the creative decisions and the budget. Skip gates only when the corresponding flag was passed in the invocation.
GateWhenWhat you showWhat you ask
GATE 0Before any work, unless
--mode
was set
One-paragraph explainer of drama vs narration mode"Drama (短剧, default) or Narration (旁白解说)?"
GATE 0.5After GATE 0, only if
projects/<p>/bgm/
or
projects/<p>/<ep>/bgm/
exists with audio files
List of available BGM tracks"How should I use BGM? (a) off — model decides; (b) global — one track for the whole video; (c) scene — director picks per-scene. Also: forbid the video model from generating its own BGM? (default: yes)"
GATE 1After screenwriter finishes all scenes/scene-NN.md and you've compiled into
script.md
The merged
script.md
"剧本 OK 吗? Approve to proceed to storyboarding, or describe changes."
GATE 2After director finishes all scenes/scene-NN.json and you've compiled+validated into
storyboard.json
. If
--vfx
, run
spark-video-vfx-review
first and show its report.
storyboard.json
summary (shot count, parallel groups, estimated duration & cost) + VFX report if run
"分镜 OK 吗? Approve to render, or describe changes."
GATE 3After all shots rendered + reviewed (winner_version set for each, escalations resolved)Per-shot summary (winner version, best score, any that fell below threshold accepted-anyway)"渲染 OK 吗? Approve to stitch final, or specify shots to re-render."
GATE 4After stitch completesPath to
final/<project>-<episode>.mp4
, duration, file size
"OK to finalize? Want to re-render any shots or adjust BGM mix?"
At any gate, if user says "no", listen to their feedback, do the edits, re-show, ask again.
你必须在每个节点处暂停并询问用户。绝不能跳过任何节点——创意决策和预算由用户掌控。仅当调用时传入对应参数,才可跳过相应节点。
节点触发时机展示内容询问内容
GATE 0开始工作前,除非传入
--mode
参数
短剧模式与旁白解说模式的一段说明文字“选择短剧模式(默认)还是旁白解说模式?”
GATE 0.5GATE 0之后,仅当
projects/<p>/bgm/
projects/<p>/<ep>/bgm/
目录下存在音频文件时触发
可用BGM曲目列表“BGM应如何使用?(a) 自动——由模型决定;(b) 全局——整集使用同一曲目;(c) 按场景——由导演选择单场景曲目。另外:是否禁止视频模型自行生成BGM?(默认:是)”
GATE 1编剧完成所有场景的scene-NN.md文件,且你已将其合并为
script.md
合并后的
script.md
文件
“剧本是否OK?确认后进入分镜环节,或描述需要修改的内容。”
GATE 2导演完成所有场景的scene-NN.json文件,且你已将其合并并验证为
storyboard.json
后。若传入
--vfx
参数,需先运行
spark-video-vfx-review
并展示其报告
storyboard.json
摘要(镜头数量、并行组、预估时长与成本)+ 若运行则展示VFX报告
“分镜是否OK?确认后进入渲染环节,或描述需要修改的内容。”
GATE 3所有镜头渲染完成并审核通过(每个镜头已选定最优版本,问题已解决)后每个镜头的摘要(最优版本、最高分、任何低于阈值但仍被接受的镜头)“渲染是否OK?确认后进入最终拼接环节,或指定需要重新渲染的镜头。”
GATE 4拼接完成后最终文件
final/<project>-<episode>.mp4
的路径、时长、文件大小
“是否确认定稿?是否需要重新渲染部分镜头或调整BGM混音?”
在任何节点,若用户表示“不”,需听取反馈、进行修改、重新展示并再次询问。

Pipeline flow (with parallelism markers)

流水线流程(含并行标记)

                  ╔══════════════════════════════════════════╗
                  ║  YOU (spark-video-episode / producer)    ║
                  ╚══════════════════════════════════════════╝
                            [GATE 0: mode]
                       [GATE 0.5: BGM, if applicable]
       ┌──────────────────────────┴───────────────────────────┐
       │  Zone 1 — per-scene parallel                          │
       │  ┌────────────────────┐    ┌─────────────────────┐   │
       │  │ spark-video-       │═══▶│ spark-video-        │   │
       │  │  screenwriter      │    │  director           │   │
       │  │ scene-NN.md        │    │ scene-NN.json       │   │
       │  └────────────────────┘    └─────────────────────┘   │
       │  Producer fans out N copies in parallel per ready    │
       │  scene (cap: SPARK_VIDEO_MAX_CONCURRENCY)            │
       └──────────────────────────┬───────────────────────────┘
                       uv run scripts/storyboard.py compile
                            [GATE 1: script.md]
                            [GATE 2: storyboard.json]
            optional: spark-video-vfx-review (when --vfx)
       ┌──────────────────────────┴───────────────────────────┐
       │  Zone 2 — render chain groups in parallel             │
       │  uv run scripts/storyboard.py graph                  │
       │    → [[S01-001,S01-002], [S02-001], ...]              │
       │  Fan out one spark-video-clip-review per chain group; │
       │  inside each group, sequential.                       │
       │                                                       │
       │  Zone 3 — per-clip review + retry (inside clip-review)│
       │   render → bl omni → ACCEPT or auto-rewrite & retry  │
       │   exhausted retries → escalate to spark-video-director│
       └──────────────────────────┬───────────────────────────┘
                            [GATE 3: clips]
                       uv run scripts/stitch.py
                            [GATE 4: final mp4]
                  ╔══════════════════════════════════════════╗
                  ║  YOU (spark-video-episode / producer)    ║
                  ╚══════════════════════════════════════════╝
                            [GATE 0: 模式选择]
                       [GATE 0.5: BGM设置(若适用)]
       ┌──────────────────────────┴───────────────────────────┐
       │  区域1 — 按场景并行处理                          │
       │  ┌────────────────────┐    ┌─────────────────────┐   │
       │  │ spark-video-       │═══▶│ spark-video-        │   │
       │  │  screenwriter      │    │  director           │   │
       │  │ scene-NN.md        │    │ scene-NN.json       │   │
       │  └────────────────────┘    └─────────────────────┘   │
       │  制片方针对每个就绪场景并行生成N份副本(上限:SPARK_VIDEO_MAX_CONCURRENCY)            │
       └──────────────────────────┬───────────────────────────┘
                       uv run scripts/storyboard.py compile
                            [GATE 1: script.md确认]
                            [GATE 2: storyboard.json确认]
            可选:spark-video-vfx-review(传入--vfx时运行)
       ┌──────────────────────────┴───────────────────────────┐
       │  区域2 — 渲染链组并行处理             │
       │  uv run scripts/storyboard.py graph                  │
       │    → [[S01-001,S01-002], [S02-001], ...]              │
       │  为每个链组调用一次spark-video-clip-review;│
       │  每个组内按顺序执行。                       │
       │                                                       │
       │  区域3 — 逐片段审核与重试(在clip-review内部进行)│
       │   渲染 → bl omni → 接受或自动重写并重试  │
       │   重试次数耗尽 → 升级至spark-video-director处理│
       └──────────────────────────┬───────────────────────────┘
                            [GATE 3: 镜头确认]
                       uv run scripts/stitch.py
                            [GATE 4: 最终mp4确认]

Step-by-step procedure

分步流程

Step 0 — preflight

步骤0 — 预检

bash
./scripts/doctor.sh                           # bl + ffmpeg + uv present
uv run scripts/scaffold.py episode --init     # mkdir scaffold if not exists
bash
./scripts/doctor.sh                           # 检查bl、ffmpeg和uv是否已安装
uv run scripts/scaffold.py episode --init     # 若不存在则创建目录结构

Persist the user's raw premise to disk BEFORE any other work. This is

在开展任何工作之前,将用户的原始创意前提保存到磁盘。这是记录“用户实际需求”的唯一可信来源,

the single source of truth for "what did the user actually ask for?"

scripts/build_viewer.py会读取该文件来填充viewer.html中的“创意前提”板块。

and is read back by scripts/build_viewer.py to populate the Premise

若缺少该文件,viewer.html将永久显示“(未找到initialPrompt.md / premise.md …)”。

section of viewer.html. Without this file viewer.html will show

全项目通用创意前提(推荐用于系列视频的第一集):

"(no initialPrompt.md / premise.md found …)" forever.

projects/<p>/initialPrompt.md

Project-wide premise (recommended for the first episode of a series):

单集覆盖创意前提(当该集偏离系列通用设定时使用,例如衍生篇或回顾篇):

projects/<p>/initialPrompt.md

projects/<p>/<ep>/premise.md

Per-episode premise override (use when this episode departs from the

需原封不动保存——请勿总结、翻译或添加个人注释。核心目的是可追溯性。

series-level premise, e.g. a spin-off or recap):

projects/<p>/<ep>/premise.md

Write verbatim — do NOT summarise, do NOT translate, do NOT add your

own commentary. The whole point is auditability.

premise_path="projects/$SPARK_VIDEO_PROJECT/initialPrompt.md" if [ ! -s "$premise_path" ]; then mkdir -p "$(dirname "$premise_path")" cat > "$premise_path" <<'PREMISE_EOF' <paste the user's premise here, verbatim, including any constraints, references, character names, tone notes — anything they said about what they want this episode to be> PREMISE_EOF fi
premise_path="projects/$SPARK_VIDEO_PROJECT/initialPrompt.md" if [ ! -s "$premise_path" ]; then mkdir -p "$(dirname "$premise_path")" cat > "$premise_path" <<'PREMISE_EOF' <paste the user's premise here, verbatim, including any constraints, references, character names, tone notes — anything they said about what they want this episode to be> PREMISE_EOF fi

Check lore.md exists; if not:

检查lore.md是否存在;若不存在:

test -f projects/$SPARK_VIDEO_PROJECT/lore.md ||
uv run scripts/scaffold.py lore --title "<premise's first noun phrase>"
test -f projects/$SPARK_VIDEO_PROJECT/lore.md ||
uv run scripts/scaffold.py lore --title "<premise's first noun phrase>"

Tell user lore.md was scaffolded with mood_anchor=TBD; ask to fill it

告知用户lore.md已创建,且mood_anchor=TBD;请用户填写该字段

OR auto-fill it from the premise using bl text chat

或通过bl文本聊天从创意前提自动填充

undefined
undefined

Step 1 — GATE 0: mode

步骤1 — GATE 0: 模式选择

Unless
--mode
was passed, present the two modes:
  • drama (短剧, default) — every shot is a long self-contained clip driven by dialog + action. Use for 2–5 min original shorts.
  • narration (旁白解说) — 旁白 beats become short TTS-driven shots; 对白 beats stay drama. Maximises parallelism. Use for 10-min recap style content.
Record the answer; pass to screenwriter + director as
--mode <choice>
.
除非传入
--mode
参数,否则展示两种模式:
  • drama(短剧,默认)——每个镜头都是由对话+动作驱动的独立长片段。适用于2–5分钟的原创短片。
  • narration(旁白解说)——旁白部分转化为由TTS驱动的短镜头;对话部分保持短剧模式。最大化并行处理效率。适用于10分钟左右的回顾类内容。
记录用户选择;将
--mode <choice>
参数传递给编剧和导演。

Step 2 — GATE 0.5: BGM (only if folder exists)

步骤2 — GATE 0.5: BGM设置(仅当对应目录存在时)

bash
test -d projects/$SPARK_VIDEO_PROJECT/bgm || \
  test -d projects/$SPARK_VIDEO_PROJECT/episode-$SPARK_VIDEO_EPISODE/bgm || skip
ls projects/$SPARK_VIDEO_PROJECT{,/episode-$SPARK_VIDEO_EPISODE}/bgm/*.{mp3,wav,m4a,flac,ogg,aac} 2>/dev/null
Present tracks, ask user for
mode
+
forbid-model-bgm
. Record into
projects/<p>/<ep>/bgm-config.json
(the compile step reads this and writes
Storyboard.bgm
).
bash
test -d projects/$SPARK_VIDEO_PROJECT/bgm || \
  test -d projects/$SPARK_VIDEO_PROJECT/episode-$SPARK_VIDEO_EPISODE/bgm || skip
ls projects/$SPARK_VIDEO_PROJECT{,/episode-$SPARK_VIDEO_EPISODE}/bgm/*.{mp3,wav,m4a,flac,ogg,aac} 2>/dev/null
展示可用曲目,询问用户
mode
forbid-model-bgm
选项。将设置记录到
projects/<p>/<ep>/bgm-config.json
(编译步骤会读取该文件并写入
Storyboard.bgm
)。

Step 3 — cast init

步骤3 — 角色与场景初始化

bash
uv run scripts/scaffold.py cast-init           # build cast.json
uv run scripts/scaffold.py set-init            # build movie_set.json
uv run scripts/scaffold.py prop-init           # build props.json
If the user's premise mentions new characters/locations not present, invoke
spark-video-cast
first to scaffold + generate portraits BEFORE launching the screenwriter.
bash
uv run scripts/scaffold.py cast-init           # 创建cast.json
uv run scripts/scaffold.py set-init            # 创建movie_set.json
uv run scripts/scaffold.py prop-init           # 创建props.json
若用户的创意前提中提到了未存在的新角色/场景,需先调用
spark-video-cast
来创建并生成肖像,再启动编剧工作。

Step 4 — Zone 1: per-scene editor ↔ director parallel

步骤4 — 区域1: 编剧↔导演按场景并行处理

Fan out the screenwriter on scenes 1..N (number from premise length — see screenwriter pacing table). As each
scene-NN.md
becomes ready (touched
scene-NN.ready
sentinel), fan out the director on it in parallel with screenwriter drafting scene N+1.
Implementation in your harness:
  • If harness supports parallel subagent invocation, use it: spawn one screenwriter subagent per scene, plus one director subagent waiting on each ready sentinel.
  • If sequential, loop scenes in order. Still cheaper than rendering.
Cap:
SPARK_VIDEO_MAX_CONCURRENCY=4
parallel subagents at once.
When all scenes drafted + storyboarded:
bash
uv run scripts/storyboard.py compile --mode <drama|narration>
uv run scripts/storyboard.py validate
uv run scripts/storyboard.py graph
uv run scripts/storyboard.py estimate
根据创意前提的长度(参考编剧节奏表),为场景1..N并行调用编剧。每当一个
scene-NN.md
就绪(生成
scene-NN.ready
标记文件),就并行调用导演处理该场景,同时编剧继续起草场景N+1。
实现方式:
  • 若支持并行子技能调用,可使用该功能:为每个场景生成一个编剧子技能实例,再为每个就绪标记生成一个导演子技能实例。
  • 若仅支持顺序执行,则按场景顺序循环处理。这仍比渲染成本更低。
上限:
SPARK_VIDEO_MAX_CONCURRENCY=4
个并行子技能实例。
所有场景起草完成并生成分镜后:
bash
uv run scripts/storyboard.py compile --mode <drama|narration>
uv run scripts/storyboard.py validate
uv run scripts/storyboard.py graph
uv run scripts/storyboard.py estimate

Step 5 — GATE 1: script.md

步骤5 — GATE 1: script.md确认

Show the user the merged
script.md
. Wait for approval.
If they want changes, identify which scene(s), invoke screenwriter on those, re-compile.
向用户展示合并后的
script.md
文件,等待确认。
若用户需要修改,确定需修改的场景,调用编剧处理这些场景,重新合并文件。

Step 6 — GATE 2: storyboard.json

步骤6 — GATE 2: storyboard.json确认

Print the storyboard summary:
  • Total shots, breakdown by kind (t2v / i2v / r2v)
  • Parallel chain group count (from
    storyboard.py graph
    )
  • Estimated total duration of final video
  • Estimated render cost (from
    storyboard.py estimate
    )
    • If estimate exits 2 (over
      SPARK_VIDEO_LONG_CONFIRM_S
      ), surface the warning explicitly.
If
--vfx
, run
spark-video-vfx-review
and show its report alongside.
Wait for approval. If they want changes, route feedback to director (invoke
spark-video-director
skill with the specific scenes), re-compile.
打印分镜摘要:
  • 总镜头数,按类型细分(t2v / i2v / r2v)
  • 并行链组数量(来自
    storyboard.py graph
  • 最终视频预估总时长
  • 预估渲染成本(来自
    storyboard.py estimate
    • 若预估结果返回状态码2(超过
      SPARK_VIDEO_LONG_CONFIRM_S
      ),需明确提示该警告。
若传入
--vfx
参数,需运行
spark-video-vfx-review
并同步展示其报告。
等待确认。若用户需要修改,将反馈传递给导演(调用
spark-video-director
技能并指定需修改的场景),重新合并文件。

Step 7 — Zone 2 + 3: render with per-clip review

步骤7 — 区域2 + 3: 带逐片段审核的渲染

bash
uv run scripts/storyboard.py graph
bash
uv run scripts/storyboard.py graph

→ [["S01-001","S01-002"], ["S02-001"], ...]

→ [["S01-001","S01-002"], ["S02-001"], ...]


For each chain group, fan out a `spark-video-clip-review` invocation
that loops through the group's shots sequentially. Different groups run
in parallel up to `SPARK_VIDEO_MAX_CONCURRENCY`.

Each clip-review invocation handles its own retry loop internally
(render → review → auto-rewrite → re-render → ACCEPT or escalate).
You only intervene when:
- Escalation: `needs_director_rewrite.json` appears. Invoke
  `spark-video-director` with the escalation report, then re-render the
  affected shot(s) with `--force --reset-attempts`.
- Hard failure: a chain group's render_shot.py exits with non-zero
  status. Read `logs/model_calls.jsonl` to diagnose, then retry or
  escalate to the user.

Monitor progress via `tail -f projects/<p>/<ep>/logs/model_calls.jsonl
| jq .` or by polling `shots_state.json` for `winner_version` set on
each shot.

针对每个链组,调用一次`spark-video-clip-review`,该实例会按顺序处理组内的镜头。不同链组可并行运行,上限为`SPARK_VIDEO_MAX_CONCURRENCY`。

每个clip-review实例会自行处理重试循环(渲染→审核→自动重写→重新渲染→接受或升级处理)。仅在以下情况需要你介入:
- 升级处理:出现`needs_director_rewrite.json`文件。调用`spark-video-director`并传入升级报告,然后使用`--force --reset-attempts`重新渲染受影响的镜头。
- 严重失败:链组的render_shot.py返回非零状态码。读取`logs/model_calls.jsonl`诊断问题,然后重试或告知用户。

可通过`tail -f projects/<p>/<ep>/logs/model_calls.jsonl | jq .`或轮询`shots_state.json`中每个镜头的`winner_version`字段来监控进度。

Step 8 — GATE 3: per-shot summary

步骤8 — GATE 3: 镜头摘要确认

Once all shots have
winner_version
set:
bash
jq '.[] | {shot: .shot_id, ver: .winner_version,
           score: ([.attempts[]|.review.score]|max),
           below_threshold: ((.attempts[]|.review.score|select(.<7))!=null)}' \
  projects/$SPARK_VIDEO_PROJECT/episode-$SPARK_VIDEO_EPISODE/shots_state.json
Present the per-shot table. Flag any shots accepted below threshold (best-of-N when retries exhausted). Ask user if any should be re-rendered manually before stitch.
所有镜头都已设置
winner_version
后:
bash
jq '.[] | {shot: .shot_id, ver: .winner_version,
           score: ([.attempts[]|.review.score]|max),
           below_threshold: ((.attempts[]|.review.score|select(.<7))!=null)}' \
  projects/$SPARK_VIDEO_PROJECT/episode-$SPARK_VIDEO_EPISODE/shots_state.json
向用户展示镜头表格,标记任何低于阈值但仍被接受的镜头(重试次数耗尽后的最优选择)。询问用户是否需要在拼接前手动重新渲染部分镜头。

Step 9 — stitch

步骤9 — 拼接

bash
uv run scripts/stitch.py --crossfade 0.5
stitch.py
handles:
  • Concatenating all
    clips/<shot>.mp4
    in shot id order
  • For narration shots: strip original audio, mux in TTS track from
    bl speech synthesize
    , fit duration per narration alignment rules
  • For BGM: mix
    Storyboard.bgm.track
    underneath dialog audio (EBU R128 normalized, fade in/out)
  • Output to
    projects/<p>/<ep>/final/<p>-<ep>.mp4
bash
uv run scripts/stitch.py --crossfade 0.5
stitch.py
负责:
  • 按镜头ID顺序拼接所有
    clips/<shot>.mp4
    文件
  • 针对旁白镜头:移除原始音频,混入来自
    bl speech synthesize
    的TTS音频,根据旁白对齐规则调整时长
  • 针对BGM:将
    Storyboard.bgm.track
    混音到对话音频下方(遵循EBU R128标准归一化,淡入淡出)
  • 输出到
    projects/<p>/<ep>/final/<p>-<ep>.mp4

Step 10 — GATE 4: final review

步骤10 — GATE 4: 最终审核

Show:
  • Final mp4 path
  • Total duration (vs target)
  • File size
Ask if user wants to re-render any shots or adjust BGM. If yes, loop back to the relevant step.
展示:
  • 最终mp4文件路径
  • 总时长(与目标时长对比)
  • 文件大小
询问用户是否需要重新渲染部分镜头或调整BGM。若需要,回到对应步骤处理。

Configuration knobs (env vars)

配置参数(环境变量)

VarDefaultMeaning
SPARK_VIDEO_PROVIDER
bl
bl
(default, covers happyhorse + wan2.6) or
wan27
(fallback for wan2.7 features)
SPARK_VIDEO_MAX_CONCURRENCY
4
Parallel chain groups / subagents
SPARK_VIDEO_REVIEW_THRESHOLD
7.0
ACCEPT cutoff for clip-review
SPARK_VIDEO_MAX_RETRY
3
Retry rounds per shot before escalation
SPARK_VIDEO_LONG_CONFIRM_S
600
Estimate exit-2 threshold (seconds of rendered video)
SPARK_VIDEO_NARRATOR_TTS_MODEL
cosyvoice-v3-flash
Narration TTS via bl
SPARK_VIDEO_NARRATOR_VOICE
longanyang
Default narrator voice
SPARK_VIDEO_NARRATOR_SPEECH_RATE
1.2
Default speech rate (0.5–2.0)
变量默认值说明
SPARK_VIDEO_PROVIDER
bl
服务商选项:
bl
(默认,支持happyhorse + wan2.6)或
wan27
(针对wan2.7特性的备选)
SPARK_VIDEO_MAX_CONCURRENCY
4
并行链组/子技能实例数量上限
SPARK_VIDEO_REVIEW_THRESHOLD
7.0
clip-review环节的接受阈值
SPARK_VIDEO_MAX_RETRY
3
每个镜头重试次数上限,超过则升级处理
SPARK_VIDEO_LONG_CONFIRM_S
600
预估结果返回状态码2的阈值(渲染视频时长,单位:秒)
SPARK_VIDEO_NARRATOR_TTS_MODEL
cosyvoice-v3-flash
旁白TTS使用的bl模型
SPARK_VIDEO_NARRATOR_VOICE
longanyang
默认旁白音色
SPARK_VIDEO_NARRATOR_SPEECH_RATE
1.2
默认语速(范围:0.5–2.0)

Handling user "no" at any gate

处理用户在任意节点的“拒绝”请求

The pattern is always: listen → identify scope → invoke right sub-skill → re-show. Examples:
  • "剧本不行, 钱夫人太弱" at GATE 1 → invoke
    spark-video-screenwriter
    with scope = which scenes, plus the user's note. Re-compile script.md, re-show.
  • "S03-002 这个 shot 太暗" at GATE 3 → don't re-render the whole storyboard. Just
    uv run scripts/render_shot.py --shot S03-002 --force --reset-attempts
    (auto-runs clip-review). Re-show updated shot.
  • "BGM 太响" at GATE 4 → edit
    Storyboard.bgm.volume
    (or
    bgm-config.json
    ), re-run
    uv run scripts/stitch.py
    .
通用流程:听取反馈→确定修改范围→调用对应子技能→重新展示。示例:
  • 在GATE 1用户反馈“剧本不行,钱夫人太弱”→调用
    spark-video-screenwriter
    ,指定需修改的场景和用户备注。重新合并script.md并展示。
  • 在GATE 3用户反馈“S03-002这个镜头太暗”→无需重新渲染整个分镜。只需运行
    uv run scripts/render_shot.py --shot S03-002 --force --reset-attempts
    (会自动运行clip-review)。重新展示更新后的镜头。
  • 在GATE 4用户反馈“BGM太响”→编辑
    Storyboard.bgm.volume
    (或
    bgm-config.json
    ),重新运行
    uv run scripts/stitch.py

DON'Ts

禁止操作

  • ❌ Don't skip any gate. The user owns the creative/budget decisions. Skip only when the corresponding
    --vfx
    /
    --mode
    /
    --provider
    flag was passed.
  • ❌ Don't render before
    storyboard.py validate
    passes. Renders are expensive; validation is free.
  • ❌ Don't render before
    storyboard.py estimate
    is shown to the user at GATE 2. If estimate exits 2 (over budget), surface that explicitly.
  • ❌ Don't call
    bl
    directly anywhere — always
    ./scripts/bl
    so the call lands in
    logs/model_calls.jsonl
    . Same rule for any subagent you spawn.
  • ❌ Don't auto-accept escalations. When
    needs_director_rewrite.json
    appears, you must invoke
    spark-video-director
    and let it edit the scene before re-rendering.
  • ❌ Don't proceed past a chain group that has a hard render failure. Diagnose first (read logs/model_calls.jsonl).
  • ❌ Don't fan out beyond
    SPARK_VIDEO_MAX_CONCURRENCY
    . Provider rate limits will spike and fail the whole batch.
  • ❌ Don't write
    script.md
    or
    storyboard.json
    yourself — always go through
    uv run scripts/storyboard.py compile
    so validation runs.
  • ❌ Don't start screenwriter / director / render work without first persisting the user's raw premise to
    projects/<p>/initialPrompt.md
    (or
    projects/<p>/<ep>/premise.md
    ). Without this file
    viewer.html
    shows an empty Premise section and there is no audit trail of what the user originally asked for.
  • ❌ 不得跳过任何节点。创意决策和预算由用户掌控。仅当传入对应
    --vfx
    /
    --mode
    /
    --provider
    参数时才可跳过。
  • ❌ 不得在
    storyboard.py validate
    通过前进行渲染。渲染成本高昂,而验证是免费的。
  • ❌ 不得在GATE 2向用户展示
    storyboard.py estimate
    结果前进行渲染。若预估结果返回状态码2(超预算),需明确提示。
  • ❌ 不得直接调用
    bl
    ——必须使用
    ./scripts/bl
    ,确保调用记录到
    logs/model_calls.jsonl
    。生成的所有子技能实例也需遵循此规则。
  • ❌ 不得自动接受升级处理请求。当出现
    needs_director_rewrite.json
    文件时,必须调用
    spark-video-director
    让其修改场景后再重新渲染。
  • ❌ 不得在链组出现严重渲染失败时继续推进。需先诊断问题(读取logs/model_calls.jsonl)。
  • ❌ 不得生成超过
    SPARK_VIDEO_MAX_CONCURRENCY
    数量的并行实例。服务商限流会导致整个批量任务失败。
  • ❌ 不得自行编写
    script.md
    storyboard.json
    ——必须通过
    uv run scripts/storyboard.py compile
    生成,确保验证流程执行。
  • ❌ 不得在将用户原始创意前提保存到
    projects/<p>/initialPrompt.md
    (或
    projects/<p>/<ep>/premise.md
    )前启动编剧/导演/渲染工作。若缺少该文件,viewer.html的创意前提板块会显示为空,且无法追溯用户原始需求。