Repository navigation
Closed
Labels
area:canvasCanvas, nodes and direct manipulationCanvas, nodes and direct manipulationarea:providerModel providers and generation protocolsModel providers and generation protocolstype:bugSomething is brokenSomething is broken
Description
问题与影响
视频节点使用 MiniMax 官方 V2 的“首尾帧”模式时,依次连接两张图片,画布上两条参考连线均存在,但生成面板只显示首帧,尾帧仍为空。第二张图片未被分配为尾帧,提交时会作为 context_only 被过滤,不发送图片内容给模型,容易让用户误以为两张图片都参与了生成。
复现步骤
- 配置
minimax_video_v2协议的MiniMax-H3模型;其能力契约声明支持first_frame和last_frame。 - 在画布添加两张不同且可用的图片 A、B,以及一个空白视频节点。
- 为视频节点选择该模型,切换至“首尾帧”模式。
- 依次从 A、B 向视频节点连接参考线,不手动操作首尾帧选择器。
- 查看生成面板。填写非空提示词后,可在隔离环境用模拟模型服务检查输入快照和请求,无需调用付费服务。
预期与实际
- 预期:支持双帧的模型按连接顺序填入空闲首帧、尾帧,面板与工程保存的引用角色一致;提交时两张图片分别以对应角色发送。
- 实际:两条连线均建立,但 A 为
first_frame,B 保持reference;尾帧槽位为空。首尾帧输入策略将 B 标记为context_only,生成请求只携带 A 的图片内容。 - 临时绕过:手动在尾帧槽位选择 B。显式指定为
last_frame后,输入解析会将两张图片均标记为content。
定位与证据
检查基线:5581f19f4375950e3286678366ac0b13ad2b9cc1。本次使用 Node.js v24.14.0 运行隔离的画布命令复现,并调用现有 Python 输入策略核对发送范围;未修改用户工程、未调用远端模型。界面现象来自用户操作截图,本轮没有新增浏览器端端到端复现。
已核实的链路:
- 官方 MiniMax 能力规则 明确声明
frameRoles=['first_frame', 'last_frame']。 - 自动分配函数 却执行
if (settings.modelConfigId && field === "lastFrameNodeId") continue,将所有已配置服务模型都按仅支持首帧处理,没有读取实际帧能力。 - 引用保存映射 根据选中的槽位写入
first_frame/last_frame,未选入槽位的图片保持reference。 - 后端输入策略 将首尾帧模式中的普通图片参考标记为
context_only;任务构造 排除这些图片,不交给模型适配器。
从仓库根目录执行以下命令,可独立复现两条连线存在但尾帧未分配的状态:
node --experimental-strip-types --input-type=module <<'JS'
import { applyCommand, createDocument, createNode } from './src/canvas/model.ts';
import { generationDefaults } from './src/canvas/generationCatalog.ts';
const image = () => createNode('image', undefined, {
src: 'data:image/png;base64,fixture', assetState: 'ready',
});
const a = image(), b = image();
const target = createNode('video', undefined, { settings: {
...generationDefaults('video'), videoMode: 'first-last',
modelConfigId: 'configured-minimax',
}});
let doc = { ...createDocument(), nodes: [a, b, target] };
for (const source of [a, b]) doc = applyCommand(doc, {
type: 'add-edge', edge: {
id: crypto.randomUUID(), source: source.id, target: target.id,
},
});
const s = doc.nodes.find(n => n.id === target.id).data.settings;
console.log({ edges: doc.edges.length,
firstIsA: s.firstFrameNodeId === a.id,
last: s.lastFrameNodeId ?? null });
JS实际输出为 { edges: 2, firstIsA: true, last: null }。此脚本仅复现前端命令层,fixture 不代表真实媒体上传。
另以隔离的两个图片参考调用 reference_policy,使用官方模型的实际 inputRules,得到:
A.png first_frame content
B.png reference context_only
仅在内存中将 B 改为 last_frame 后,两张图片均为 content。对用户现有项目的只读解析也得到相同的过滤结果;该节点当时未提交新任务,因此上述发送范围是输入策略验证结果,不是一次新的远端请求抓包。
测试缺口:现有 tests/frameReferences.test.ts 可通过,但单帧适配测试 只用是否有 modelConfigId 区分能力,固化了该假设;MiniMax 浏览器测试 直接创建正确的首尾帧角色,绕过拖线后的自动分配。
验收标准
- 对契约支持首尾帧的模型,依次连接两张图片后,首帧与尾帧显示、保存角色和重新打开后的状态一致;覆盖逐张及批量连接、从参考模式切换至首尾帧。
- 通过模拟服务检查两张不同的真实图片:接受任务的输入快照与实际请求均保留正确角色及图片内容;不能仅验证缩略图或连线存在。
- 仅支持首帧的模型不会自动获得尾帧;模型不可用或能力未加载时有明确反馈。
- 手动选择、互换、清空、断线和撤销行为正确;刷新或后台同步不自动恢复用户明确清空的槽位。
- 已连接但未参与生成的图片有可见说明;已有工程不在加载时被静默改写,既有任务执行快照保持不变。
- UI 与 Agent 对同样的显式首尾帧输入遵守相同的后端校验和发送规则;新增真实拖线流程回归测试。
Metadata
Metadata
Assignees
Labels
area:canvasCanvas, nodes and direct manipulationCanvas, nodes and direct manipulationarea:providerModel providers and generation protocolsModel providers and generation protocolstype:bugSomething is brokenSomething is broken
Activity
[test] browser: connect two images to a first-last video node (#101)