# 画布节点模型设计

这份文档定义 cinema_agent 的画布节点分类、新建方式和连线规则。目标不是做通用媒体画布，而是把短剧制作中的“资产 → 分镜 → 视频 → 拼接/审片”组织成可视化、可审计、可由 Agent 自动操作的工作流。

---

## 1. 产品定位：短剧生产管线画布

cinema_agent 是**短剧生产管线（pipeline manifest）**：

- 一个 Session = 一部短片，有固定的生产语义。
- 主管线是：**锚定资产 → 分镜板 → 镜头视频 → 拼接输出**。
- 用户/Agent 不需要自由拼装任意图，而是围绕剧情、角色、镜头、参考素材和输出版本不断迭代。
- 画布是**审阅台 + 调试台 + 人工接管面**，不是纯设计 surface。

这决定了节点和交互的取舍：节点不是“媒体类型标签”，而是生产管线中的语义角色。

---

## 2. 节点分类

### Tier 1 — 锚（Anchor，手动创建）

跨镜复用的“身份单位”。Seedream/Seedance 可把这些图当 reference image 或文本锚，帮助锁定人物、场景、道具和视觉风格。

| 节点 | 作用 | 视觉 | 必须的字段 |
|---|---|---|---|
| **角色锚** Character | 跨镜复用同一张脸/同一角色设定 | 琥珀色边框 | `name` `prompt` `mediaUrl` |
| **场景锚** Scene | 跨镜复用同一个空间/环境 | 蓝色边框 | 同上 |
| **道具锚** Prop | 跨镜复用同一件物 | 粉色边框 | 同上 |
| **风格锚** Style | 跨镜统一视觉风格 | 紫色边框 | 主要靠 prompt 文字 |

> Tier 1 是用户主动写“这部短剧里的恒常元素”，量级 0–10 个/session，避免无限增长。

### Tier 2 — 镜头管线（每个 shot 派生）

| 节点 | 作用 | 视觉 | 数量 |
|---|---|---|---|
| **分镜板** Storyboard | Seedream grid / 草图，作为镜头视频参考 | 紫色 | 按需显示，通常跟 shot 关联 |
| **镜头视频** Shot Video | Seedance 输出 | 蓝色 | 1:1 跟 shot |

### Tier 3 — 输出（可多个）

| 节点 | 作用 | 视觉 | 数量 |
|---|---|---|---|
| **拼接** Stitch | ffmpeg concat 出完整片或局部版本 | 绿色 | 一个 session 可有多个，每个有独立 playlist / 输出 / 终审 |

### Tier 4 — 自由参考/处理节点

| 节点 | 作用 |
|---|---|
| 参考视频 | 上传后可分析镜头表，也可绑定到某个 Shot 作为 reference_video |
| 视频处理 | 对参考视频做裁剪、加速、采样拼接等派生处理 |
| 未来：文本 / 音频 / 任意参考图 | 作为辅助素材，不污染主管线语义 |

---

## 3. 怎么新建

| 节点 | 当前入口 | 语义 |
|---|---|---|
| 角色锚 | 顶部按钮 / 右键空白菜单 / 拖图片 | 手动创建可复用角色资产 |
| 场景锚 | 顶部按钮 / 右键空白菜单 / 拖图片 | 手动创建可复用场景资产 |
| 道具/风格锚 | 右键菜单/后续入口 | 手动创建可复用辅助资产 |
| 镜头视频 | 右键空白菜单“分镜镜头” / 顶部 `+ 分镜` | 追加一个 shot，后续可启用分镜板 |
| 拼接 | 右键空白菜单“拼接节点” / 自动显示 legacy 输出 | 创建一个独立输出 playlist |
| 参考视频 | 右键菜单上传 / 拖视频 / 顶部上传视频 | 上传后进入参考视频分析与绑定流程 |

### 右键菜单示意

```text
新建节点
├── 角色锚        C
├── 场景锚        S
├── 分镜镜头      N
├── 拼接节点      J
├── 上传图 → 角色 U
├── 上传图 → 场景 V
└── 上传参考视频  R
```

---

## 4. 连线规则

| 起点 | 终点 | 是否合法 | 含义 | 写回字段 |
|---|---|---|---|---|
| 锚（角色/场景/道具/风格） | 分镜板 | ✅ | 该分镜板出图时使用这个锚作为参考 | `shot.assetIds` / storyboard refs |
| 锚 | 镜头视频 | ✅ | 该镜头视频生成时使用这个锚作为角色/场景/风格参考 | `shot.assetIds` |
| 分镜板 | 镜头视频 | ✅ | 该 storyboard grid 作为视频参考输入 | `shot.subShotStoryboardAssetIds` |
| 参考视频 / 视频处理 | 镜头视频 | ✅ | 该视频作为 Seedance reference_video | `shot.referenceVideoAssetId` / `referenceClipUrl` |
| 镜头视频 | 镜头视频 | ✅ | 上游镜头视频作为下游 reference_video | `shot.referenceVideoFromShotId` |
| 镜头视频 | 拼接 | ✅ | 加入某个拼接节点的 playlist | `stitchJob.shotIds` 或 legacy `session.stitchShotIds` |
| 拼接 | 任意 | ❌ | 输出节点不驱动上游 | — |

### 反向操作（删连线）

- 删 **锚→分镜/视频** = 从对应 shot 的参考列表移除。
- 删 **分镜板→镜头视频** = 从 `subShotStoryboardAssetIds` 移除。
- 删 **参考视频→镜头视频** = 清掉 `referenceVideoAssetId` 和 `referenceClipUrl`。
- 删 **镜头视频→拼接** = 从对应拼接节点的 `shotIds` 中移除。
- 删节点 = 调用对应实体删除/隐藏逻辑，并写入撤销栈。

---

## 5. 用户交互模型

| 手势 | 动作 | 影响 |
|---|---|---|
| 单击节点 | 选中 + 打开 Inspector | 不写数据 |
| 右键空白 | 弹“新建节点”菜单 | 选中后创建节点/上传素材 |
| 双击空白 | 回到全景视图 | 仅 UI |
| 拖节点 | 重排位置 | UI 状态，刷新后按派生布局回流 |
| 拖文件入画布 | 上传 → 自动建对应参考/锚节点 | 写 asset |
| 从 handle 拉线 | 建立语义依赖 | 写 shot / session / stitch job |
| 删除线 | 移除语义依赖 | 写回对应字段 |
| 删除节点 | 删除/隐藏实体，支持撤销 | 写 store + undo stack |

### Inspector 三档动作

- **审阅档**（无外部副作用）：预览组装 prompt、看上次 prompt、看历史。
- **保存档**（写 db 不调外部）：保存 raw prompt / draft / 角色描述 / playlist。
- **生成档**（调外部 API + 消耗 token/算力）：重新出图、重新出片、拼接、VLM 审片。

---

## 6. 设计边界

| 主题 | 取舍 |
|---|---|
| 节点类型 | 按短剧生产语义分层，而不是无限扩展媒体类型 |
| 任意拉线 | 允许会写回明确字段的连接；没有语义的连接直接拒绝 |
| 资产库 | 锚天然就是资产；派生节点保留审计历史，不默认进入全局资产库 |
| 工作流模板 | 后续可做 session/subgraph 模板，当前优先稳定节点语义 |
| 重型 3D 预演 | 作为外部工具输入的截图/视频，不在本项目内实现完整 3D 导演台 |

---

## 7. 探索 feature 的语义槽位

| 探索 feature | 挂在哪 |
|---|---|
| 抠图 / 重绘 / 扩图 | 锚节点 Inspector |
| 一键风格库 | 风格锚 Inspector 的“风格预设”下拉 |
| 多机位九宫格 / 角色三视图 | 锚节点 Inspector 的快捷生成工具 |
| 视频高清放大 / 慢动作 | 镜头视频或视频处理节点 Inspector |
| 参考视频分析（拆 shot） | 参考视频节点 Inspector |
| 文本节点 / 音频节点 | Tier 4 自由参考节点 |
| 外部 3D/摄影预演截图 | 拖文件入画布走 Tier 4 |
| 多模型切换器 | 全局顶部条 + 每个生成节点 Inspector 顶部下拉 |

> 铁律：新功能要么挂在已有节点的 Inspector 里，要么进入 Tier 4 自由参考层。不要轻易新增主管线节点类型。