@xiaohhhh1/canvas-agent 0.4.85 → 0.4.87

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.
@@ -16,15 +16,15 @@
16
16
 
17
17
  - 用户要求打开带货任务时,调用 `open_flow_c_website`,不要输出或询问 Local URL、连接令牌。
18
18
  - 网站把脚本任务交给本机 Codex 后,使用 `flow_c_get_script_task` 读取完整、服务器持久化的任务,再用 `flow_c_submit_script_chunk` 每次回传 1–30 条。不要要求用户复制 JSON、选择交接文件或把短期令牌发到聊天中。
19
- - 大批量脚本按本机助手指定的序号分段创作;批量大小不能成为降低质量、缩短脚本或套用模板的理由。每条都必须独立构思、符合目标市场自然语言习惯、保持紧凑但清晰可说完的 10 秒节奏。
20
- - 三种制作方式 `storyboard`、`visual-storyboard`、`first-frame-chain` 共用完全相同、与媒体模式无关的脚本层:同一套爆款蓝图/带货形式库选择、商品适配、目标地区当地化、口播、完整脚本和局部 0–10 秒段。制作方式及分镜布局不得进入脚本创作提示,不得据此重写、过滤、重选或简化脚本。
21
- - 10 秒仍走原有单段结构。只有任务明确给出 20 30 秒时,才先写一份完整总脚本,再拆成 23 个各自从 0–10 秒计时、可独立生成的段落;同人物同场景用 `continue` 并固定人物、服装、音色身份、场景、光线与商品状态,明确换人物或场景才用 `reset`。音色身份需详细到年龄、音高、音质、语速、口音、停连和说话习惯,情绪随剧情变化,整体仍保持快节奏。
19
+ - 大批量脚本按本机助手指定的序号分段创作;批量大小不能成为降低质量、缩短脚本或套用模板的理由。每条都必须独立构思、符合目标市场自然语言习惯、保持在当前任务每段时长内清晰可说完的紧凑节奏。
20
+ - 三种制作方式 `storyboard`、`visual-storyboard`、`first-frame-chain` 共用完全相同、与媒体模式无关的脚本层:同一套爆款蓝图/带货形式库选择、商品适配、目标地区当地化、口播、完整脚本和局部 0–segmentSeconds 秒段。制作方式及分镜布局不得进入脚本创作提示,不得据此重写、过滤、重选或简化脚本。
21
+ - 以任务已持久化的 `video_model_key` 确定模型,读取任务给出的或该模型定义的 `segmentSeconds`;不能继承当前对话的模型,也不能只按总时长猜测分段。Omni 的 10/20/30 秒分别为 1/2/3 个局部 0–10 秒段,旧 Omni 单段结构保持;Seedance Mini/Fast 的 15/30 秒分别为 1/2 个局部 0–15 秒段。单段沿用独立脚本结构;多段一次写出完整总脚本及对应独立局部脚本,每段都从 0 开始。同人物同场景用 `continue` 并固定人物、服装、音色身份、场景、光线与商品状态,明确换人物或场景才用 `reset`。音色身份需详细到年龄、音高、音质、语速、口音、停连和说话习惯,情绪随剧情变化,整体仍保持快节奏。历史任务按其已保存模型、分段与提示版本恢复,不迁移或重写已完成分段。
22
22
  - 写脚本和回传草案不创建付费任务。只有客户在网站审阅并确认费用后,中心服务才可开始故事板和视频生成。
23
23
 
24
24
  - 用户明确选择流程 C 时,必须新建独立画布、清单和归档目录,不得混用流程 A 或 B 的资产。
25
25
  - 脚本定稿后才按已持久化制作方式分流媒体控制:`storyboard` 使用同一局部脚本和原始同 SKU 商品图生成 9:16 `director-table-scripted-v1` 导演总表;`first-frame-chain` 使用同一局部脚本生成干净 9:16 首帧,并按既有首帧/尾帧连续控制执行。
26
26
  - 新 `visual-storyboard` 使用同一局部脚本和原始同 SKU 商品图生成原生横向 16:9 `visual-storyboard-landscape-v2` 纯视觉分镜图。镜头按时间行优先排列(从左到右,再到下一排):1–4 镜单排;5–8 镜为 3+2、3+3、4+3、4+4 的平衡两排。每排铺满且每格都是真实镜头,不得添加空白、占位格、连续性小块、元数据栏、技术块、脚本、标签、时间码或字幕;镜头景别、镜头、运镜、动作和切点保持原脚本不变,关键内容放在竖屏安全核心。已持久化 `visual-storyboard-adaptive-v1` 仍按原 9:16 历史合同恢复,不得升级或重解释为 v2。
27
- - Omni 成片在三种制作方式下始终是单一全屏竖向 9:16。纯视觉 v2 按同一行优先顺序把横板每格重建为完整动态镜头,禁止把横板、网格、接缝、边框、空白、分屏、画中画、联系表或幻灯片渲染进成片;20/30 秒仍逐段生成后只做 stream-copy 无损拼接。
27
+ - Omni 与 Seedance 成片在三种制作方式下始终是单一全屏竖向 9:16。纯视觉 v2 按同一行优先顺序把横板每格重建为完整动态镜头,禁止把横板、网格、接缝、边框、空白、分屏、画中画、联系表或幻灯片渲染进成片;多段任务按已保存的模型和每段时长逐段生成后只做 stream-copy 无损拼接,不混合不同模型或不同时长的分段。
28
28
  - 原始商品图是唯一商品标准:每一格都必须保持颜色、外形、文字或 Logo、比例、部件和数量一致。分镜通过逐格检查前,严禁提交视频任务。
29
29
  - 视频阶段必须按已持久化制作方式提供控制图和原始商品图:导演总表与纯视觉分镜图固定为 `[当前故事板, ...原商品图]`;首帧模式沿用其首帧/尾帧引用合同。技术失败、超时、明显商品不一致或明显分镜错误时按中心既有有界策略处理;提示词、参考图或平台合规问题才暂停等待用户修改。
30
30
  - 未配置流程 C 的第三方视频接口时,只能完成分镜准备和验收,明确说明“待管理员配置视频接口”,不得假装已提交或产生扣费。
@@ -1134,18 +1134,33 @@ export class WorkflowManager {
1134
1134
  record.market = batch.market;
1135
1135
  const deliveries = batch.deliveries || [];
1136
1136
  let cursor = 0;
1137
+ let failed = false;
1138
+ let firstFailure;
1137
1139
  const workers = Array.from({ length: Math.min(4, deliveries.length) }, async () => {
1138
- while (cursor < deliveries.length) {
1139
- const delivery = deliveries[cursor++];
1140
- await this.saveDelivery(batch, delivery);
1141
- if (!record.downloadedOrdinals.includes(delivery.ordinal))
1142
- record.downloadedOrdinals.push(delivery.ordinal);
1143
- record.message = `正在保存本批全部成片:${record.downloadedOrdinals.length}/${deliveries.length}`;
1144
- record.updatedAt = now();
1145
- this.save();
1140
+ try {
1141
+ while (!failed && cursor < deliveries.length) {
1142
+ const delivery = deliveries[cursor++];
1143
+ await this.saveDelivery(batch, delivery);
1144
+ if (!record.downloadedOrdinals.includes(delivery.ordinal))
1145
+ record.downloadedOrdinals.push(delivery.ordinal);
1146
+ record.message = `正在保存本批全部成片:${record.downloadedOrdinals.length}/${deliveries.length}`;
1147
+ record.updatedAt = now();
1148
+ this.save();
1149
+ }
1150
+ }
1151
+ catch (error) {
1152
+ if (!failed) {
1153
+ failed = true;
1154
+ firstFailure = error;
1155
+ }
1156
+ throw error;
1146
1157
  }
1147
1158
  });
1148
- await Promise.all(workers);
1159
+ // A retry must not unlink a .part file still owned by an earlier
1160
+ // writer. Stop admission on failure and drain all admitted writers.
1161
+ await Promise.allSettled(workers);
1162
+ if (failed)
1163
+ throw firstFailure;
1149
1164
  record.downloadedOrdinals.sort((a, b) => a - b);
1150
1165
  const finished = ["completed", "cancelled", "failed"].includes(batch.status);
1151
1166
  record.status = finished && record.downloadedOrdinals.length >= (batch.deliveries?.length || 0) ? "complete" : "waiting";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiaohhhh1/canvas-agent",
3
- "version": "0.4.85",
3
+ "version": "0.4.87",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",