@ninkch/dsh-infinite-canvas 0.18.3 → 0.18.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -47,6 +47,18 @@ The Settings panel — data root, Craft status (12/12 ready), skills, text model
47
47
 
48
48
  ![Settings (EN UI)](./docs/images/panel-settings-en.png)
49
49
 
50
+ ## Work beside the chat
51
+
52
+ The canvas is not a separate window you have to switch to. It opens as a **tab in the Harness right pane**, so you can talk to the agent on the left and storyboard on the right **at the same time** — ask for a change in chat and watch the nodes update in place.
53
+
54
+ 1. Open the right pane (**开始 / Start**) and click the **无限画布 / Infinite Canvas** card.
55
+ 2. The canvas opens as a tab beside the conversation; the same projects, nodes and assets as the full-page panel.
56
+ 3. Drag the pane wider, or use the pane's fullscreen button, when you need more room.
57
+
58
+ ![Infinite Canvas as a right-pane tab](./docs/images/harness-right-pane.png)
59
+
60
+ > One live canvas at a time (shared node graph and generation state): opening it in the pane while the full-page panel is also open **moves** the canvas rather than duplicating it — the other side shows a "move the canvas here" button.
61
+
50
62
  ## How it works
51
63
 
52
64
  ```mermaid
package/README.zh-CN.md CHANGED
@@ -47,6 +47,18 @@
47
47
 
48
48
  ![设置页签](./docs/images/panel-settings-zh.png)
49
49
 
50
+ ## 在对话旁边工作
51
+
52
+ 画布不是必须切过去的另一个窗口——它可以作为 **Harness 右侧面板里的一个页签**打开,左边对话、右边分镜,**同时进行**:在对话里提要求,右边节点实时跟着变。
53
+
54
+ 1. 打开右侧面板(**开始**),点击 **无限画布** 卡片。
55
+ 2. 画布以页签形式出现在对话右侧,与全屏面板共享同一批项目、节点与资产。
56
+ 3. 需要更大空间时,把右栏拖宽,或用右栏的全屏按钮。
57
+
58
+ ![无限画布作为右侧面板页签](./docs/images/harness-right-pane.png)
59
+
60
+ > 同一时刻只有一个画布实例(共享节点图与生成状态):在右栏打开时若全屏面板也开着,画布会**被移动到右栏**而不是复制一份——另一侧显示「把画布切换到这里」按钮。
61
+
50
62
  ## 工作方式
51
63
 
52
64
  ```mermaid
@@ -50,7 +50,8 @@ B:……
50
50
  绑定几张参考图就写几个 [图N]。
51
51
  - **【主体】**中央大幅全身立绘(正面站姿):体型写量化并加反例(如「约 3 公斤、肩高 20 厘米;
52
52
  不是中型犬,不是萨摩耶/银狐/柴犬」——易混淆品种必须显式排除)、毛色毛发、五官、四肢尾巴,
53
- 以及固定配饰的完整描述。
53
+ 以及固定配饰的完整描述。**并声明姿态是自然空手站立**:四肢自然着地 / 下垂,口部闭合或自然吐舌,
54
+ **不抱、不拿、不叼、不踩、不坐任何外物**。
54
55
  - **【主图下方·三视图(必须项)】**正面/侧面/背面三格全身站姿——同一角色只换角度,
55
56
  交代侧背形态(后续视频一致性靠它)。
56
57
  - **【右侧窄栏·自上而下分块;每块内容全图只出现一次】**
@@ -59,11 +60,14 @@ B:……
59
60
  ③ 表情格:6 个头部小头像分两行(每行 3 个),每个下方只标两字表情名。
60
61
  - **【文字规则】**图内文字极少:只保留两三个字的短标签,黑色细体、笔画清楚、字要写大;
61
62
  不写任何大标题、说明段或长句。
62
- - **【画面白名单】**明确写出「画面中只有这一只角色和上述分格内容;没有人物、没有其他动物、
63
- 没有乐器、没有文字水印」——反幻觉白名单实测能压住乱入元素。
63
+ - **【画面白名单】**反幻觉白名单,逐类点名,实测能压住乱入元素:
64
+ 「画面中**只有这一只角色本体与它的固定配饰**(如 项圈 / 挂牌),以及上述分格内容;
65
+ **没有任何被抱、被拿、被叼、被踩或被坐着的物品**——纸箱、包裹、篮子、玩具、食物、乐器、器材、
66
+ 道具、家具一律不出现;没有人物、没有其他动物、没有场景陈设、没有文字水印。」
64
67
 
65
68
  要点:**每块内容全图只出现一次**(配饰在配饰格画过,主图描述就不再重复强调它);
66
- 反例约束有效——易混淆的品种 / 风格务必写进【主体】的排除句。
69
+ **外物是最常见的乱入**("抱着纸箱""叼着玩具""踩着道具"),必须在【主体】声明空手姿态、
70
+ 并在【画面白名单】里逐类点名排除;反例约束同样有效——易混淆的品种 / 风格务必写进【主体】的排除句。
67
71
 
68
72
  ### 道具设定图(横竖皆可——按道具特性选,不限制)
69
73
  - **画幅选择**:长条形/单件道具(剑、箫、杖)竖版更能展示完整形态;
@@ -173,6 +177,76 @@ B:……
173
177
 
174
178
  ## 四、视频提示词规范
175
179
 
180
+ ### 多镜头视频:系统自动用「参考生成」结构化格式(不要手写机械拼装)
181
+
182
+ 分镜表驱动的视频生成(视频节点连了分镜表)**由画布自动组装结构化提示词**,格式对齐 MiniMax H3 /
183
+ 优云智算优化后的协议——**机械拼装(风格 + [图N] 绑定 + 镜头列表 + 设定集全文)会让模型把台词、
184
+ 场景、人物判错**(实测:台词被当画外音、场景串镜)。自动生成的六段结构:
185
+
186
+ ```text
187
+ subject_definitions: <Subject N> 是 <Picture M>… 中的 实体名:外观要点 ← 素材↔主体绑定
188
+ summary: [参考生成] 共 N 镜、总时长 X 秒:从…开始,到…结束;主体:…
189
+ retention_analysis: <Subject N>(出现于 [Shot a]、[Shot b]):fully_preserved —— 保持…
190
+ detailed_description: 风格:…(设定集风格)
191
+ [Shot 1] 00:00.000 起(镜头标题):画面;运镜/动作:…;台词:<Subject 2>(S1)
192
+ 用5–6 岁男孩奶音,尾音上扬说:<d>[Chinese] 为什么呀?</d>;音效:…
193
+ overall_soundscape: 各镜音效合并
194
+ non_diegetic_music: 仅当显式给出(节点扩展参数 {"music":"…"})时输出,绝不臆造
195
+ ```
196
+
197
+ 要点(这也解释了它为什么能音画同步):
198
+
199
+ - **<Picture N> ↔ <Subject N> ↔ 实体名** 三级绑定:参考图不再只是"[图N] 角色:某某",
200
+ 而是模型能引用的主体;镜头正文里的实体名会被替换成 `<Subject N>`(长名优先匹配)。
201
+ - **台词绑定到主体**:`<Subject N>(S1)用<音色>说:<d>[Chinese] 台词</d>`——说话人编号全局唯一,
202
+ 首次出现带音色描述,因此口型/音色/台词三者不会错配。
203
+ - **绝对时间轴**:每镜标注 `00:MM:SS.mmm 起`,模型据此切镜与对齐口型。
204
+ - **前置条件(必须满足,否则格式退化)**:
205
+ 1. 分镜表每镜有 `dialogue`(角色名 + 台词逐字)——台词只能来自这里;
206
+ 2. 设定集条目描述里带「**外观:**…」与「**声音:**…」两个字段(前者进主体定义,后者进台词音色);
207
+ 3. 参考图已连到视频节点(无参考图时自动回退普通提示词)。
208
+ - **手写覆盖**:节点提示词里若含 `subject_definitions`,画布原样发送,不做二次加工(高级用法)。
209
+
210
+ ### 分镜衔接:分段生成能不能接上,全看这四件事
211
+
212
+ 短剧一集必然切成多段生成(模型单次有时长上限),而**每段是独立采样的——模型看不到上一段最后发生了什么**。
213
+ 所以"接不上"不是模型笨,是分镜里没写接点。分镜表镜头除 visual/motion 外还有四个衔接字段
214
+ (画布「分镜衔接」开关打开时,AI 自动写;也可手写):
215
+
216
+ | 字段 | 写什么 | 硬规则 |
217
+ |---|---|---|
218
+ | `tail` 接点尾态 | 本镜**最后一刻**的状态:姿势停在哪个动作的中途、朝向、视线落点、手持物、位置关系 | **必须是"动作进行中"**,绝不允许写"已完成/站定/看向"——切在静止定格,下一镜没东西可接 |
219
+ | `cam` 运镜延续 | 本镜的运镜方向 + 速度,写成下一镜能接着走的形式("右移横移,匀速,未停") | 相邻镜**禁止反向运镜**;要反向就改遮挡/过肩/特写插入 |
220
+ | `start` 起始态 | 仅第 1 镜或非续帧镜头需要 | 续帧镜头不写(自动承接上一镜 tail) |
221
+ | `seg` 段落类型 | `continuation` 续帧(默认)/ `scene_change` 换场 / `new_character` 新角色入场 / `closeup` 特写插入 / `opening` 首段 | 决定生成时走哪条链路(见下) |
222
+
223
+ **方向要分清(这是最容易写错的地方)**:每镜的 `tail` / `cam` 描述的是**本镜自己的结尾**,
224
+ 它们是留给**下一镜**的「接点」;而每一镜开头「承接上镜结尾」引用的,是**上一镜**的 `tail`。
225
+ 两个方向别混:写本镜时想"我演到哪、怎么交给下一镜",而不是"我该从哪开始"。
226
+ 旧分镜若没写 `tail`,系统会退到上一镜的 `motion` 并**明确标注"按最后动作推断"**——这是兜底,不是等价物;
227
+ 要真的接得上,`tail` 必须手写或由 AI 写出。
228
+
229
+ 配套的拆分纪律:
230
+
231
+ - **一镜只做一个主动作**:转身+走路+推镜塞进一镜,模型只执行前半段,下一镜必然对不上。
232
+ - **一段一运镜**:又推又横移又摇 = 下段没法延续。
233
+ - **大位移拆镜**:人物横移超过画面 1/4、或走位大改,再拆一镜(换景别接)。
234
+ - **轴线一致**:两人对话,男左女右在相邻镜必须保持,不得越轴。
235
+ - **时长按节拍切 4–6 秒**,别按模型单次最大时长怼满——段越长,中间漂移概率越高、首尾帧差越大越容易崩。
236
+
237
+ 生成端的自动调度(画布已实现,无需手写提示词):
238
+
239
+ 1. **续帧段(`seg: continuation`)** → 自动取上一段的**尾帧**作为本段首帧(不是"最后一帧",而是在片尾多帧里选"动作进行中、清晰、不抖"的一帧)。**只有这一段类型会接力尾帧。**
240
+ 2. **首帧与参考图互斥时**(多数厂商如此)→ 尾帧降级为第 1 张参考图 + 提示词软锚定("第 1 帧必须与 [图1] 一致"),
241
+ 节点上会显示「接缝通过 / 接缝偏跳」,偏跳就打回重生成或改「硬首帧」模式(硬首帧放弃参考图,画面绝对承接)。
242
+ 3. **换场段(`seg: scene_change`)** → 不接尾帧,直接按场景参考建立空间。
243
+ 4. **新角色入场段(`seg: new_character`)** → 不接上段尾帧(首尾帧图里没有他就锁不住他),走参考图模式,要求从画面内自然进入。
244
+ 5. **特写/细节插入段(`seg: closeup`)** → 允许跳切,不要求画面连续(接缝阈值放宽到 0.15)。
245
+ 6. 生成后**自动接缝校验**:本段首帧 vs 上段尾帧的相似度,同场续帧 0.55、跨场换景/新角色 0.35、特写插入 0.15,
246
+ 不达标在节点上告警(不静默),并建议调低运动幅度重生成。
247
+
248
+ > 一句话:**角色一致性靠参考图,剧情衔接靠尾帧接力 + 接点尾态;剪辑端只是兜底,救不回没写接点的分镜。**
249
+
176
250
  ### 导演简报六组件(顺序即权重:构图在前,质感在后)
177
251
  **场景(环境+光线)→ 主体(身份+细节)→ 动作(一次一个节拍)→ 运镜(机位+镜头+速度)→ 音频(音乐+音效+环境)→ 节奏/风格(时长+情绪+调色)**
178
252
 
@@ -78,6 +78,16 @@ description: 用无限画布(Infinite Canvas)做短剧/视频创作时使用
78
78
  台词**绝不能**处理成画外音/旁白——成片里人嘴闭着、声音飘在背景,就是这个错误。
79
79
  视频提示词会自动带上该约束(画面内开口、口型与台词同步);发现分镜把有台词的镜头写成背影/空镜,
80
80
  必须重新生成该分镜。
81
+ 15. **分段接戏的四个字段必须写(`tail`/`cam`/`start`/`seg`)。** 一集切成多段生成时,每段是独立采样的、
82
+ 看不到上一段——接不上的根因是分镜没写接点,不是模型笨。AI 拆镜默认会写(`cont` 开关默认开);
83
+ 用 `canvas_update_node` 改 `shots` 时**必须保留/补齐这四个字段**:
84
+ `tail` 是"动作进行中"的尾态(不要写"已完成/站定")、`cam` 可被下一镜延续(相邻镜不反向)、
85
+ `start` 只在非续帧镜头写、`seg` 取值**只能是** `opening` / `continuation` / `scene_change` /
86
+ `new_character` / `closeup`(写 `cut`/`insert` 会被归一化为 `closeup`)。
87
+ **只有 `continuation` 才接力尾帧**:`scene_change` 换场、`new_character` 新角色入场都不接上段画面,
88
+ `closeup` 特写插入允许跳切(接缝阈值 0.15)。续帧段由画布自动做尾帧接力
89
+ (`tailpick` → 下段 `frame`,或沿 `tail→prev` 链自动取上一段尾帧)并做接缝校验;
90
+ **不要**为了"接上"去复制上一段的画面描述(重演 = 白花钱且更跳)。
81
91
 
82
92
  ## 二、标准工作流(对话填提示词+连线+触发,生成由节点完成)
83
93
 
@@ -117,16 +127,33 @@ description: 用无限画布(Infinite Canvas)做短剧/视频创作时使用
117
127
  - **【跨段连贯:分镜承接 + 尾帧 → 首帧】**连贯分两层,先文本后画面:
118
128
  **①分镜承接(文本层,先做)**:上一分镜表 `tail` → 本分镜表 `prev`(见硬约束 13 / 工作流第 3 步),
119
129
  让分镜第 1 镜从上一场尾镜的最后一个动作继续、重叠 ≤0.2s、背景声连续;
120
- **②画面承接(视频层,后做)**:每个视频节点生成完成后会**自动提取尾帧**并挂到 `last` 输出端口。
121
- 多场视频按顺序串联:上一视频节点的 `last` 端口 → 下一视频节点的 `frame` 端口
122
- (`canvas_connect({ projectId, fromNode: 上一段, toNode: 下一段, fromPort: 'last', toPort: 'frame' })`)。
130
+ **②画面承接(视频层,后做)**:每个视频节点生成完成后会**自动提取尾帧**,挂两个输出口:
131
+ `last`=真·最后一帧(画面结尾原样),`tailpick`=片尾若干帧里选出的**最佳选帧**
132
+ (动作进行中、清晰、不抖——机械取最后一帧常落在动作顶点/运动模糊/抖动上,接缝必跳)。
133
+ 两者都是 **image 类型**,只能连到 `frame`(或 `ref`)输入口。
134
+ 多场视频按顺序串联时优先用 `tailpick`:
135
+ `canvas_connect({ projectId, fromNode: 上一段, toNode: 下一段, fromPort: 'tailpick', toPort: 'frame' })`;
136
+ 该视频还没生成过(没有选帧)时才退到 `fromPort: 'last'`。
123
137
  第一段的 `frame` 用开场定帧图(若生成了首帧关键图)或留空。
124
- **【衔接模式】**下一段视频节点若有 frame 连线,节点上有「衔接」下拉三选一:
125
- **参考图融合**(默认:尾帧降级为第 1 张参考图,保留实体参考图,衔接为软约束)、
138
+ **自动续帧(标准用法通常不需要手动连线)**:视频节点连着分镜表、且分镜第 1 镜的 `seg` 是
139
+ `continuation`(默认)时,即使没连 frame,画布也会**自动取上一段视频的尾帧作为本段首帧**
140
+ (节点上显示「🔗 自动取上一段尾帧作首帧」)。它按三条路找「上一段」:frame 连线 →
141
+ 同一分镜表的其它视频段 → **沿分镜表 `tail→prev` 承接链向上游找那一场所连的视频**
142
+ (所以「一场一个分镜表 + 一场一个视频」的标准布局下,**只要按第 3 步连好 `tail→prev`,
143
+ 自动续帧就可用**)。不想要时把视频节点「衔接」设为「忽略首帧」,或把该镜 `seg` 改成 `scene_change`,
144
+ 或关掉分镜表的「分镜衔接」开关(`cont: false`)。
145
+ **【衔接模式】**视频节点上的「衔接」下拉三选一(**始终可见**,不是有连线才出现):
146
+ **参考图融合**(默认:尾帧降级为第 1 张参考图,保留实体参考图,衔接为软约束——提示词会用
147
+ `frameAnchorText` 写明"第 1 帧必须与 [图1] 一致,只允许往后运动")、
126
148
  **硬首帧(弃参考图)**(用真首帧参数,画面绝对承接——网关禁止首帧与参考图混用)、
127
- **忽略首帧**。需要画面严格承接选「硬首帧」,新实体参考图占主导选「参考图融合」。
128
- **按顺序触发**:上一段 `canvas_node_status` 为 done 后再连线、再触发下一段
129
- (连线可以提前建好——frame 在下一段真正运行时才解析)。
149
+ **忽略首帧**。需要画面严格承接且不需要实体参考图时选「硬首帧」;要保住角色/场景参考图选「参考图融合」。
150
+ **接缝校验**:续帧段生成后自动比对「本段首帧 vs 上段尾帧」相似度,节点上显示
151
+ 「✓ 接缝通过 / ⚠ 接缝偏跳 N」;偏跳时建议调低运动幅度重生成或改「硬首帧」。
152
+ 阈值随段落类型放宽:同场续帧(`continuation`)0.55 / 跨场换景(`scene_change`)与新角色入场
153
+ (`new_character`)0.35 / 特写插入(`closeup`)0.15。
154
+ **按顺序触发**:上一段 `canvas_node_status` 为 done 后再触发下一段(自动续帧要读上一段成片)。
155
+ 分镜表节点上的「铺开到画布」按钮会**自动把上一段的 `tailpick`/`last` 接到本段 `frame`**
156
+ (按上面同一条「找上一段」规则),所以铺开 → 逐段按顺序生成即可,通常不必手工连 frame。
130
157
  - **【声音一致(可选)】**视频接口配置里的「生成同步音频」勾选后才发送 `generate_audio:true`——
131
158
  模型生成**自带音轨**的视频(对白/环境声与画面同步);不勾 = 无声视频(声音另行 TTS 配音)。
132
159
  要让同一角色**跨视频保持音色**:用视频/成片节点的「提取声音参考」按钮——
@@ -136,15 +163,31 @@ description: 用无限画布(Infinite Canvas)做短剧/视频创作时使用
136
163
  模型生成的对白将向参考音色对齐(携带声音参考时会自动强制开启同步音频)。
137
164
  时间窗归属靠分镜的 `dialogue` 标注(对白逐字来自剧本、按镜头分配,一镜尽量单说话人);
138
165
  分镜缺少台词标注时按钮会降级为手动模式并提示重新生成分镜。
139
- - 触发:`canvas_run_node` → 轮询;整段视频一次生成完成
166
+ - 触发:`canvas_generate_node({ projectId, nodeId, waitSeconds })` 一次等到终态(画布需打开);
167
+ 多镜头视频**整段一次生成**完成。
168
+ - **【提示词是自动结构化的,不要手写机械拼装】**视频节点连着分镜表时,画布会把
169
+ 分镜 + 参考图 + 设定集自动组装成厂商「参考生成」格式(`subject_definitions` /
170
+ `summary` / `retention_analysis` / `detailed_description`(含 `<Subject N>`、(S1) 说话人、
171
+ `<d>[Chinese] 台词</d>`、绝对时间轴)/ `overall_soundscape` / 非叙事音乐)——
172
+ 这是音画同步与台词不错配的关键。你只需保证三件事:
173
+ ① 分镜每镜的 `dialogue` 有「角色名 + 逐字台词」(台词只从这里来);
174
+ ② 设定集条目描述里带「**外观:**…」与「**声音:**…」(前者进主体定义、后者进台词音色);
175
+ ③ 参考图已连到视频节点(无参考图时会回退成普通提示词)。细节见 `canvas-craft` 第四节。
176
+ 需要手工覆盖时,在节点提示词里写含 `subject_definitions` 的完整结构,画布会原样发送。
177
+ **分镜衔接字段会自动进提示词**:每镜 `tail`(接点尾态)→「承接上镜结尾:…」、
178
+ `cam`(运镜延续)→「运镜延续:…(方向与速度保持)」、`seg` → 段落类型行;
179
+ 首帧接力则追加首帧锚定行与 `continuity:` 段。**你不必(也不要)把这些手工拼进提示词**,
180
+ 只需在分镜 `shots` 里把字段写对;分镜表节点「分镜衔接」开关(`cont`)默认开,
181
+ 关掉后 AI 拆镜不再产出这四个字段(留给人工写)。
140
182
  5. **生成角色/场景/道具参考图**:为设定集里的每个条目创建 image-gen 节点
141
183
  (命名规范「角色-<名> 设定图」/「场景-<名> 设定图」/「道具-<名> 设定图」),
142
184
  **prompt 必须按 `canvas-craft`「资产设定图版式」一节的排版模板写详细版式提示词,
143
185
  禁止只写一句三视图/外观关键词**——信息量不足,撑不起后续视频的角色一致性。要点(完整模板见 canvas-craft):
144
186
  - **角色设定图**(16:9 横版):按 canvas-craft 的「六段式」结构写——【总起】(版式/背景/风格/
145
- 全格一致)→【身份锚】(参考图=唯一形象事实,忽略照片配饰)→【主体】(量化体型+反例排除)→
146
- 【三视图·必须项】→【右侧窄栏:脸部特写 / 配饰格 / 表情两行×3,每格只标两字标签,
147
- 每块内容全图只出现一次】→【文字规则 + 画面白名单】
187
+ 全格一致)→【身份锚】(参考图=唯一形象事实,忽略照片配饰)→【主体】(量化体型+反例排除+
188
+ **声明空手自然站立:不抱/不拿/不叼/不踩/不坐任何外物**)→【三视图·必须项】→
189
+ 【右侧窄栏:脸部特写 / 配饰格 / 表情两行×3,每格只标两字标签,每块内容全图只出现一次】→
190
+ 【文字规则 + 画面白名单(**逐类点名排除外物**:纸箱/包裹/玩具/食物/乐器/器材/道具/家具一律不出现)】
148
191
  - **道具设定图**(横竖皆可,按道具特性选):顶部道具名大标题(≤6 字);中央主图(斜 45° 悬浮+氛围光);
149
192
  细节特写 2–3 格(格内无文字);侧栏侧视图;底部圆形色卡 3–5 枚(色名 ≤3 字)
150
193
  - **场景设定图**(主图+环绕小图):一张主场景大图占主体,周边环绕补充小图(多角度 / 其他时间段 / 细节格,3–6 张各配 ≤6 字短标注)——大致参考不强约束
@@ -208,14 +251,28 @@ description: 用无限画布(Infinite Canvas)做短剧/视频创作时使用
208
251
 
209
252
  1. **文本类(剧本 / 分镜)**:可由你直接生成完整正文,用
210
253
  `canvas_write_node({ projectId, nodeId, text: 完整正文, target: 'output' })` 写入;
211
- 也可让画布用它自己配置的模型生成:`canvas_run_node({ projectId, nodeId })`。
254
+ 也可让画布用它自己配置的模型生成:`canvas_generate_node({ projectId, nodeId, waitSeconds })`。
212
255
  2. **图片 / 视频**:只能由画布生成(使用用户在画布设置里配置的图片/视频接口):
213
- `canvas_run_node({ projectId, nodeId })` 触发 → `canvas_node_status` 轮询直到 `status` 变为
214
- `done`(成功)或 `error`(失败,读 `error` 字段并向用户说明)。
215
- 3. **模型为空/报错时**:`canvas_node_status` 会给出错误文本(例如"模型未返回文本")——
216
- 如实转达,并建议用户在画布设置里更换文本模型;**不要谎报已生成**。
217
- 4. **生成需要时间**:图片/视频可能几十秒到数分钟。触发后用 `canvas_node_status` 间隔轮询
218
- (建议 ≥10 秒一次),不要反复触发同一个节点。
256
+ `canvas_generate_node({ projectId, nodeId, waitSeconds })` 触发并等待(等价于点节点上的生成按钮;
257
+ 图片约 30–120s、视频数分钟),或只触发不等待:`waitSeconds: 0` → 再用 `canvas_node_status` 轮询。
258
+ **执行前提:画布页面处于打开状态**(运行请求由画布轮询消费);等待超时≠失败,继续查状态即可。
259
+ 3. **改节点内容用 `canvas_update_node`,绝不删节点重建**:读现状用 `canvas_node_status`
260
+ (它会返回生成节点的对话框提示词 `prompt`、比例/清晰度/时长/分辨率、衔接模式、历史产物 id 等),
261
+ 改内容用 `canvas_update_node({ projectId, nodeId, patch: { prompt: '……', ratio: '9:16', duration: 5 } })`——
262
+ 可改字段:prompt / idea / output / text / script / requirement / shots / label / ratio / size /
263
+ duration / resolution / frameMode / count / imageModel / videoModel / model。
264
+ 节点 id、类型、坐标、尺寸等结构字段不可改。**用户改提示词、换参数、重生成,全程不需要删节点。**
265
+ 4. **模型为空/报错时**:`canvas_node_status` 会给出错误文本(例如"模型未返回文本")——
266
+ 如实转达,并建议用户在画布设置里更换文本/图片/视频模型;**不要谎报已生成**。
267
+ 5. **生成需要时间**:图片/视频可能几十秒到数分钟。用 `canvas_generate_node` 的 `waitSeconds`
268
+ 一次等到终态(推荐),或触发后间隔轮询 `canvas_node_status`(建议 ≥10 秒一次),不要反复触发同一节点。
269
+ 6. **节点上的 `genWarn` 字段必须转达**:参考素材超出厂商上限被截断、厂商忽略参数等事实都会写在这里——
270
+ 如实告诉用户,绝不忽略(例如"参考图 12 张超过该厂商上限 9 张,本次只用了前 9 张")。
271
+ 视频节点的 `genWarn` 还会带**衔接相关事实**:「已自动取上一段尾帧作为本段首帧」「接缝校验未通过:…」——
272
+ 接缝告警要明确建议"调低运动幅度重生成 或 改硬首帧",不要轻描淡写。
273
+ 7. **衔接状态也在节点上**:`chainFrom`(`'wired'`=首帧来自 frame 连线 / 节点 id=自动取上一段尾帧)、
274
+ `seam`(`{ ok, sim, thr, note }` 接缝校验结果)、`tailPickMeta`(`{ t, score }` 最佳选帧的时间点与得分)。
275
+ `canvas_node_status` 会带出这些字段;汇报成片质量时一并说明。
219
276
 
220
277
  ## 五、生成参数来源(不要臆造参数)
221
278