refactor: litegraph 工作流编辑器 + pymss.graph 原生执行引擎 - #54
Open
baicai-1145 wants to merge 34 commits into
Open
Conversation
- 安装 @comfyorg/litegraph@0.17.2 + happy-dom(dev) - 新增 src/litegraph/nodeSpecs.ts: 数据驱动的 pymss comfy 节点规格(13 个节点: load_audio/batch, mss/vr/custom_separate, mss/vr_params, save_audio, ensemble, invert_phase, normalize, preview, string_concat),端口类型与 pymss/graph/nodes.py 对齐(AUDIO/STRING/PYMSS_MSS_PARAMS/PYMSS_VR_PARAMS) - 新增 src/litegraph/registerNodes.ts: 把 spec 注册成 litegraph 节点类, 继承 LGraphNode(获得 addWidget/addInput 等),serialize_widgets=true 保证 widgets_values 写入;separate 节点的 stem 输出端口动态可配 - 新增 src/litegraph/graphAdapter.ts: litegraph.serialize() -> comfy-mss JSON 的极薄适配(归一化字段/links 6-tuple),可直接被 pymss.graph.load_comfy_file 解析 - 新增 tests/_litegraphEnv.mjs + litegraphAdapter.test.mjs: happy-dom 下 跑 litegraph 构造图->serialize->适配器->pymss load_comfy_file 全链路 round-trip;5 个真实 comfy-mss fixture 全部通过 pymss 解析 阶段0验收: litegraph 在 Vue3 可用;序列化 JSON 能被 pymss.graph.load_comfy_file 解析。 阶段1验收: 节点定义+适配器完成;round-trip 测试 2/2 绿;DAG 拓扑序验证通过。
后端(python/worker_workflows.py 完全重写): - 删除 v2 graph runtime(worker_graph_workflows.py)与 pymss CLI fallback - cmd_infer_workflow / 批量模式改为 in-process 调 pymss.graph: load_comfy_file(comfy) / compile_workflow_to_dag(yaml) -> run_dag - progress_callback 映射到 task_progress 事件(done/total/message/progress) - emit 完整事件链:task_started -> task_stage(validating/separating/writing) -> task_done,与前端 STAGE_META 对齐 - 删除 test_worker_graph_workflows.py(v2 runtime 测试) - 验证: stub pymss.graph 后事件序列与 run_dag kwargs 全部正确 前端: - 新增 WorkflowNodeEditorLite.vue: @comfyorg/litegraph 画布,满足对外契约 (v-model:definition=comfy JSON / modelOptions / models / formError / canSave, emit save/close);暗色主题;节点搜索 palette;separate 节点 stem 端口 随所选模型动态生成;device/format 在保存时注入节点 widget - WorkflowNodeEditorView.vue 改用新组件:definition 直接是 comfy JSON, 去掉 v2 转换层(hydrate/build/serialize/readWorkflowGraphDefinition), save 直接存 definition(device/format 注入 extra.appDefaults) - task.ts: buildWorkflowDefinitionForRun/buildWorkflowRunConfig 改为直接 使用 comfy definition(defaults 从 extra.appDefaults 读);删除前端 批量输入 scan(交由 pymss_load_audio_batch 节点);最小本地验证代替 v2 深度验证(环/悬挂/未知节点交 pymss DAG) - registerNodes: 修复 createNode 返回 null(LGraphNode 方法不可枚举, 改用 class extends LGraphNode);separate stem 端口动态生成 - i18n: 加 workflows.addNode(en/zh);runtimeCoreUpdateInactive 加入 DORMANT_KEYS 验证: vue-tsc 全绿;npm test 157/160(3 失败中 2 已修复,1 为既有 flaky runtimeUtils 硬件测试,与本次改动无关);SSR 编译 5 个核心模块全通过
- workflowSimple.ts 完全重写: hydrate/build 直接操作 pymss YAML workflow dict (version/defaults/steps),不再经过 v2 graph schema;内联 parseModelStems 去掉对 workflowDefinition.ts 的依赖;analyzeSimpleWorkflow 始终返回 editable(simple 是源格式);保留 SimpleWorkflowReasonCode 类型兼容 - WorkflowSimpleCreator.vue: 改用新 SimpleStepDraft/SimpleDraft 类型, buildSimpleWorkflowDefinition 新签名(无 sourceDefinition),去掉 preservedUi/v2 验证,深度验证交 pymss 验证: vue-tsc 全绿; pymss.workflow.load_workflow_data + compile_workflow_to_dag 成功把 simple creator 产出的 YAML 编译成 5 节点 DAG (input_audio->mss_separate+pymss_mss_params->pymss_save_audio×2); worker stub 验证 yaml 分支事件链与 run_dag 调用正确
删除 v2 前端工具与旧画布组件:
- src/utils/{workflowGraph,workflowDefinition,workflowCanvas,comfyMssWorkflow}.ts
- src/components/workflow/WorkflowNodeEditor.vue(5962 行手写画布)
- tests/{workflowGraph,workflowCanvas,comfyMssWorkflow,workflowSimple,workflowValidation}.*
- tests/fixtures/workflow-validation.json
- package.json test 脚本移除对应条目
- i18n: 删除 96 个 v2 专属 key(旧画布/批量输入/工具节点/palette/note 等)
view 适配新格式(comfy JSON / pymss YAML):
- SeparateView: ensemble 快捷功能重写为直接构造 comfy-mss JSON
(load_audio -> N×mss_separate -> audio_ensemble -> save_audio);工作流
验证/批量输入/defaults 改为最小本地逻辑(深度验证交 pymss DAG)
- WorkflowsView: 工作流状态/概览/默认值编辑改为直接操作 definition;
comfy 导入直接存原生 JSON,导出直接 JSON.stringify;批量任务计数 stub
- stores/task.ts: 删除 withWorkflowModelParams(v2 残留)
- stores/workflow.ts: normalizeDefinition 改为 passthrough(definition 已是
comfy/yaml 原生格式,无需 v2 规范化)
验证: vue-tsc 全绿;npm test 50/51(唯一失败为既有 runtimeUtils 硬件
flaky 测试,HEAD 就红,与本次改动无关)
- WorkflowNodeEditorLite: 加 undo/redo(基于 graph.serialize 快照栈, 最多 50 步),Ctrl+Z 撤销 / Ctrl+Shift+Z 或 Ctrl+Y 重做;toolbar 加按钮 - i18n: 加 common.undo/redo(en/zh) - litegraph 自带:右键菜单、双击搜索添加节点、Delete 删节点、拖拽连线 验证: vue-tsc 全绿; npm test 50/51(唯一失败为既有 flaky)
- tests/litegraphAdapter.test.mjs: PY 默认路径改为项目根 .venv/bin/python (PYMSS_STUDIO_TEST_PYTHON 仍可覆盖);整理重复 imports - .gitignore: 忽略 .uv-cache(项目级 uv 缓存) 背景: /Volumes/data 是 SMB 挂载,从本地 APFS 缓存(UV_CACHE_DIR=/Volumes/2T) 复制带 com.apple.provenance xattr 的文件到 SMB 会 EPERM。解决: UV_CACHE_DIR 指到项目内 .uv-cache(SMB 同卷),uv venv .venv --python 3.11 && UV_CACHE_DIR=.uv-cache uv pip install -e /Volumes/data/pymss。 已验证: round-trip 测试 2/2 通过;完整套件 50/51(唯一失败为既有 runtimeUtils 硬件 flaky);torch 2.13 + MPS 可用。conda pymss 环境已删除。
按约定 pymss 开发环境用 uv 建在大容量盘: uv venv /Volumes/1T/pymss-venv && uv pip install -e /Volumes/data/pymss (实测 pymss 2.1.0 + torch 2.13.0 + mlx,fixture 解析 OK,round-trip 测试全绿)
问题(用户报告导入 testflow.json 后高级节点编辑器异常):
1. litegraph 0.17 configure() 期望 links 是对象格式
({id, origin_id, origin_slot, target_id, target_slot, type}),而 comfy/pymss
是数组格式([id,src,srcSlot,dst,dstSlot,type])。传数组导致所有 link 的 id
均为 undefined,links 互相覆盖,configure 后 37 条链接只剩 1 条。
修复: graphAdapter 新增 comfyLinksToLitegraph(),loadDefinition/
restoreSnapshot/测试统一用它转换。
2. testflow.json 用的节点类型未注册: pymss_mss_separate(带前缀 alias)和
ComfyUI builtin 节点(LoadAudio/SaveAudio/SaveAudioMP3/SaveAudioOpus/
SplitAudioChannels/JoinAudioChannels/AudioMerge 等 20 个)。litegraph
createNode 找不到类型就建空节点,后续 configure 出错。
修复: nodeSpecs 新增 BUILTIN_SPECS(全部 pymss builtin 音频/字符串节点,
端口对齐 pymss/graph/builtin_nodes.py);registerPymssNodes 对 separate
类型同时注册 pymss_ 前缀 alias;编辑器 palette 纳入 builtin 节点。
3. syncSeparateNodeStems 在 configure 后会把 JSON 加载的真实 stem 端口
(如 'vocals (Audio)')重建为占位端口,切断连线。修复: 仅当节点端口全是
占位(stem_1/stem_2)时才按模型重建。
测试: 新增 testflow.json 导入 round-trip 测试(27 节点 + 37 links 全保留,
round-trip 后 pymss 仍能解析);litegraphAdapter 3/3 绿;npm test 51/52
(唯一失败为既有 runtimeUtils flaky);vue-tsc 0 错误
litegraph 0.17 的 resize() 把 canvas.width 设为 CSS 像素,但绘制时 ctx.setTransform(devicePixelRatio,...) 乘了 dpr。Retina 屏(dpr=2)下 canvas buffer 物理尺寸只有 CSS 的一半,绘制坐标×2 后内容全挤在左上角 1/4。 修复: ResizeObserver 回调手动设置 canvas buffer 尺寸 = CSS 尺寸 × dpr, 并同步 bgcanvas 后 setDirty 触发重绘。鼠标坐标转换(getBoundingClientRect) 本来就是 CSS 空间,不受 dpr 影响,无需额外处理
上一版修复(5a0dda3)把前景 canvas.width 也乘了 dpr,导致前景节点(按 CSS 空间 1:1 绘制)只占 buffer 左上 1/4,且鼠标坐标(CSS 空间)与节点位置错位。 litegraph 0.17 的正确模型: - 前景 canvas: buffer = CSS 尺寸,节点/文字按 CSS 空间 1:1 绘制 - 背景 bgcanvas: buffer = CSS 尺寸 × dpr,drawBackCanvas 里 setTransform(dpr) 按物理分辨率绘制,drawFrontCanvas 里 drawImage(bgcanvas, ..., w/dpr, h/dpr) 缩回 CSS 尺寸合成到前景 - resize() 的 bug 是把 bgcanvas.width 设成 canvas.width(CSS 尺寸),背景 内容画不下只占左上 1/4 修复: ResizeObserver 里 canvas.width 保持 CSS 尺寸,bgcanvas.width/height 设为 CSS × dpr 并标 dirty_bgcanvas。鼠标坐标(offsetX,CSS 空间)与前景 节点位置一致,不再错位
…视为 1 前两版修复(5a0dda3/92b7098)试图从外部调 canvas/bgcanvas 尺寸,但 drawBackCanvas() 每帧强制 bgcanvas.width = canvas.width(CSS 尺寸),外部 改动被覆盖,无效。 根因(litegraph 0.17 上游 bug): - resize(): bgcanvas.width = canvas.width = CSS 尺寸 - drawBackCanvas(): ctx.setTransform(devicePixelRatio,...) 乘 dpr 绘制 → 背景内容在 CSS 尺寸 buffer 上只占左上角 1/4 - drawFrontCanvas(): drawImage(bgcanvas, w/dpr, h/dpr) 又除一次 dpr 由于 bgcanvas 尺寸被库内部强同步,外部无法修正,只能 patch 绘制方法本身: 包装 LGraphCanvas.prototype.drawBackCanvas/drawFrontCanvas,绘制期间把 window.devicePixelRatio 视为 1,让整个画布统一按 CSS 分辨率渲染。渲染区域 和鼠标坐标随之全部正确;代价是 Retina 屏下画布内容略低清(浏览器插值放大)
之前 onSearchBox=null 禁掉了 litegraph 的节点搜索框,右键菜单(删除/克隆/ 重命名/Add Node 等)虽默认开启但缺少配套样式,弹出的菜单/搜索框没有可读 样式。 - 移除 onSearchBox=null: 双击画布空白或拖线释放(shift)时弹出节点搜索框, 选中类型即在鼠标位置新建节点 - 引入 @comfyorg/litegraph/style.css: 提供搜索框(litesearchbox)与右键菜单 (litemenu)的官方样式 交互清单: 右键节点=删除/克隆/重命名/折叠等;右键空白=Add Node/Add Group; 双击空白或拖线释放=节点搜索;Delete 键=删除选中
litegraph registerNodeType() 无条件执行 base_class.category =
type.substring(0, type.lastIndexOf('/')),我们的节点 type 名(mss_separate 等)
不含 '/',category 被置为空串,覆盖了类里 static category = spec.category 的值。
getNodeTypesCategories() 用 if(type.category && ...) 过滤,空串全部跳过 →
Add Node 子菜单没有任何类别可展开。
修复: 注册后立即 cls.category = spec.category 补回。
litegraph ContextMenu 支持 autoopen 选项(pointerenter 触发子菜单展开) 但没有全局开关,默认需要点击。patch LiteGraph.ContextMenu 构造函数, 所有菜单默认 autoopen: true;子菜单通过 options.autoopen 继承。 静态方法(trigger/isCursorOverElement 等)已拷贝到包装构造函数。
报错: Command [.../runtime-envs/mlx/bin/python3.11 -m ensurepip ...] died with SIGABRT: 6 根因链条: 1. uv 管理的 macOS CPython 是 shared-library 构建(python 二进制链接 @rpath/libpython3.11.dylib) 2. macOS 上 venv 默认 symlinks=False(copies 模式),只拷贝 python 二进制 不拷 libpython dylib 3. 拷出来的 python 一执行就 dyld abort;venv 创建后的第一个子进程 ensurepip 首当其冲 → SIGABRT 4. data/runtime-envs/mlx 已有 8/14 的坏残骸(bin 里是断链 copies python), env_python.is_file()=true 跳过重建,坏 python 直接用于 pip → 下载模型 前置的 runtime 安装全挂 修复: - _create_venv(): EnvBuilder 强制 symlinks=True(symlink 不拷贝二进制, 无断链问题;env 依赖 bootstrap python 存在,本来就如此) - install_runtime 建-env 前探测现有 env python(跑 -c pass),rc!=0 则 rmtree 重建,不再信任 is_file() 验证: 用 1T uv python 实测 symlinks=True venv 的 python/ensurepip/pip 全部正常;现有 mlx env 探测 rc=-6 确认会走重建路径
上提 08edf27 无条件强制 symlinks=True,Windows(本项目正式发布目标)上 os.symlink 需要开发者模式/管理员权限,普通用户装 runtime 会直接 OSError。且官方/embedded CPython 的 copies 模式本来就正常——断链问题 只在 uv 管理的 macOS 共享库构建上存在。改为 sys.platform != 'win32'
pymss 2.1.1 的 download_model/fetch_modelscope_file_index 全链路接受 proxy= 参数(含 SOCKS 走 PySocks、aria2c 注入 --all-proxy*),宿主不再 需要 patch aria2c 命令行和 socket 层: - manifest: pymss>=2.0.15 → pymss[proxy]>=2.1.1(extra 自带 PySocks); common 删 pysocks——完整性检查不再要求借用环境装它(此前按 pymss 依赖树装的外部 venv 因缺这一个包被误判'环境不完整') - worker_proxy: 删 aria2_proxy_args(含错误的 --all-proxy-pass 参数名); parse_proxy_config 不再 eager 校验 PySocks(下载时 pymss[proxy] 负责, 缺失时报清晰的 ProxyError);新增 effective_proxy_url() 把三态配置 (system/none/custom)解析为 pymss proxy= 参数(system→getproxies, none→'' 强制直连,custom→url 原样) - worker_download/worker_infer: 删 _align_aria2_with_proxy/ _aria2_args_for_current_proxy/aria2_args 传递链,改为 proxy= effective_proxy_url() 直传;prepare_pymss_download 只保留下载器选择 与 aria2c 进度协议守卫 - worker_bootstrap: PACKAGE_IMPORT_NAMES 删 pysocks 映射 - 测试同步: Aria2ProxyAlignmentTest → EffectiveProxyUrlTest(6 用例); aria2 参数断言 → proxy 直传断言;Aria2Fallback mock 补 proxy kwarg 验证: python unittest 212 tests,前后对比新增回归 0、修复 4 个既有 error(剩余 10 个失败为 0d3bd6d 引入的 Windows 路径断言,macOS 上 历来红,不在 CI 跑);1T venv(pymss 2.1.1)实测 effective_proxy_url → download_studio_model → pymss proxy 参数全链路
对接 pymss 2.1.2 严格输入契约 + comfy-mss input_name widget: - worker_workflows: payload 新增 inputs(name->path)映射,直传 run_dag(inputs=);单文件模式不再强制要求 input(自足图/命名槽图 零输入可跑);批量模式 tasks[] 支持 inputs;删除已不存在的 input_paths 传参(BREAKING 后续) - nodeSpecs: pymss_load_audio(_batch) 增加 input_name widget (序列化末尾追加,与 comfy-mss >= 1.0.3 widget 布局对齐) - 推理页: analyzeWorkflowInputs 扫描图(input_name 槽/自足图/ 未解析 load),按槽位渲染逐槽文件选择 UI(选中的文件存 workflowSlotFiles,随任务 runConfig.workflowInputs 持久化, retry 复用);自足图免选文件直接运行;未命名 load 显示警告 - 无槽位图保持原行为(文件列表逐个任务) 验证: worker 4 场景(两槽命中/自足图/批量 inputs/错误槽名精准 报错) 1T venv pymss 2.1.2 全过; python 侧 142 passed; vue-tsc+build 绿; 前端 27+3 passed(runtimeUtils 1 例为已知 硬件探测 flaky)
根因: litegraph 0.17 的 canvas 节点操作自带 beforeChange/afterChange
包装,但 widget 编辑(setValue->callback)不通知 graph。我们 addWidget
的 callback 只写 node.properties,导致打字改 widget(如 input_name)
后 onAfterChange 不触发 -> scheduleSnap 不跑 -> undo 栈空、
definition 不更新,保存/撤销/重做按钮全灰(需再动一次画布才恢复)。
修复: widgetCallback 里显式调 node.graph?.afterChange(node)。
(graph.change() 只 setDirty 不通知,不能用)
验证: 新增 litegraphWidgets.test.mjs —— 旧 1 格图 configure ->
setValue('vocal') -> onAfterChange 触发 + 序列化 [path,vocal]
+ 重新加载 round-trip 保持;全套 32 passed
节点 27 那条提示(stepModelNotDownloaded)此前 return 进 formError 直接把保存按钮拦死,与注释'Warn (not block)'的本意相反。图是可 保存资产:模型可稍后下载/在别的机器下载/自定义模型本就不在 downloadedModels 列表,任何一种都不该阻止存图。 改为: formError 只管结构问题(空图/无输出节点/无名),模型缺失 走新增 advisory prop 黄字显示在工具栏,不阻断保存。
根因: litegraph serialize() 输出对象格式 links({id,origin_id,...}),
restoreSnapshot 把快照再过一遍 comfyLinksToLitegraph —— 该函数
只认 comfy 数组元组,对象格式全部被当非法丢弃,undo/redo 一执行
configure 就拿到空 links,连线全没(若此时保存则连图一起存坏)。
之前没暴露是因为 widget 编辑从不触发 undo 快照(198f12c 才修),
undo/redo 实际从未被真正用过。
修复: comfyLinksToLitegraph 对已是对象格式的元素原样透传,仅转换
comfy 数组元组;loadDefinition 路径(comfy JSON 导入)不受影响。
验证: 新回归测试(对象 links 透传 + configure 恢复 links.size=1);
litegraphAdapter 3 passed;build 绿
根因链:
1. 保存时 litegraphToComfy 输出 comfy 6 元组,但写成数字键对象
({0:id,1:src,...}) 而非数组(JSON 层面合法,pymss 读没问题)
2. e9ed37a 修 undo 时给 comfyLinksToLitegraph 加了'对象格式原样
透传',本意是透传 litegraph serialize 的对象 links({id,
origin_id,...});但数字键对象也被当成该格式透传
3. configure 的 LLink.create 读 .origin_id/.target_id → undefined →
37 条 links 全部叠成一条全 null 垃圾 → 重开编辑器连线全没
(保存一直正常,存盘数据完好)
修复: 三态识别 —— litegraph 对象(origin_id 有值)透传;数字键对象
按 0..5 取回元组再转换;数组元组照旧。旧 fixture(纯数组)/存盘
数据(数字键对象)/undo 快照(litegraph 对象)三条路径全覆盖。
验证: 用 data/settings/workflows.json 里真实存盘定义做回归
(27 节点 37 links configure 后 links.size=37);全套 8 passed;
build 绿
testflow 从 comfy-mss 导入,separate 节点 widget 存的是显示名 '[vocal/vocal_extraction] kimmel_unwa_ft2.ckpt';downloadedModels 列表里是裸文件名,直接比对全部 miss -> 27/28/41/46/47 五个节点 误报'模型尚未下载'(实际 model-cache downloaded=True)。 修复: 比对前用 /^\[[^\]]*\]\s*/ 剥掉注解前缀,与 pymss 运行时 的 _strip 逻辑一致。运行不受影响(pymss 本来就剥前缀)。
此前 comfy 定义走 hydrateSimpleWorkflow 拿到空 steps,概览页显示 0 步'待编辑简易工作流'。现在 analyzeComfyOverview 扫描 comfy 图: - 指标区: 分离节点数/节点数/输出节点数/连线数 - 模型区: 扫 separate 节点 widget(剥 [category] 前缀)标已下载状态 - 新增'运行时输入槽'区块: load 节点的 input_name(推理页按槽收文件) - 只读提示: comfy 图用高级编辑器改,概览仅展示 - 运行参数编辑区对 comfy 隐藏(device/format 是 YAML/保存注入概念) 验证: testflow 实际存盘数据 -> 5 分离/27 节点/7 输出/37 连线/ 3 模型/2 输入槽(audio1,audio2);build 绿
resolveWorkflowOpenMode 是 v2 清理时留的桩,永远返回 'simple' —— 列表里点 comfy 工作流(testflow)直接弹'正在编辑 简易工作流创建器', 新加的概览页(dcb5c9a)根本没机会展示。 修复: 有 nodes 列表(comfy 图)返回 'advanced' -> 关闭简易编辑器, 落到概览;有 steps 列表(pymss YAML)才开简易创建器。
第二个 v2 清理残留桩: analyzeSimpleWorkflow 永远 editable:true, 右侧面板条件 !selectedWorkflow || editable 把已选中的 comfy 图 也送进'选择一个工作流'空状态(0acacfd 的 openMode 修复只管了 入口,面板渲染条件还压在这个桩上)。 修复: nodes 列表(comfy 图)返回 editable:false(comfy_metadata), 只有 steps 列表(YAML)可简易编辑 —— editSimpleWorkflow 的早退\n守卫同向受益。
开始分离 handler 的守卫只看 inputFiles 文件列表;命名槽位图 (testflow audio1/audio2)用户把文件填在槽位里,inputFiles 为空, 被误拦。槽位图/自足图跳过该检查;store 侧 startWorkflowInference 的同类守卫在槽位/自足分支之后,本就不可达,无需改。
- graphAdapter: litegraphToComfy 的 comfy 6 元组由数字键对象改为
真数组 —— JSON.stringify 后 {"0":id} 对象会被 pymss comfy
加载器丢弃(pymss 侧已同时兼容旧数据,双保险)
- syncSeparateNodeStems: 修 hasRealOutputs 全图跳过 —— 真名口+
占位口混排的导入图(testflow 27/28/46/47)占位口永不刷新。
现占位口原位重命名为模型缺失的 stem(改 name 不动 links)
- stemsForModel: 剥 comfy-mss [category] 前缀后再匹配目录
验证: testflow 端到端 7 输出;npm build 绿。
testflow 四个 StringConcatenate 的 string_b 无输入(widget 空) -> 拼接退化为纯 audio_name -> 四个 save 同名互踩(三个 input.wav)。 原图在 comfy-mss 里用 Primitive String 类节点喂后缀,导入后缺失。 pymss 侧已加 StringConstant 节点(同 commit 于 pymss 仓库),编辑器 注册同型: 无输入、一个文本 widget、一个 STRING 输出。
modelOptions prop 一直传进编辑器但没人消费 —— nodeSpecs 里\nmodel_name combo 的 options 是静态空数组,下拉打开永远空,无法\n选模型(此前图里的模型名都是导入带进来的)。 接线: applyModelOptions 刷 spec(新建节点) + refreshNodeModelOptions\n刷实例(已加载节点);watch modelOptions 即时应用,loadDefinition/\nmodels 变化后逐节点刷新。value 为裸文件名(与目录一致);带\n[category] 前缀的旧值仍可显示,重选后存裸名(pymss 两侧都接受)。
2.1.2 收紧输入契约(显式 inputs 映射),2.1.3 含 comfy 图执行修复 (数字键 links 兼容/布局序 tie-breaker/单声道补偿/占位 stem 认领) + StringConstant 节点 —— 均为本轮工作流链路所需。venv 已同步升级。
- litegraphAdapter: PY 解释器默认从 /Volumes/2T 绝对路径改为 PYMSS_STUDIO_TEST_PYTHON > 项目 .venv/bin/python > python3, CI/他人机器可用 env 或 .venv,不再绑私人盘 - litegraphWidgets: 两个回归测试读本机 workflows.json/testflow.json 绝对路径(CI 必挂) -> 内联合成 fixture(两 load 两 save 小图), 同样覆盖数组元组/数字键对象两种 links 形态
- 当 PYMSS_STUDIO_PYTHON 为相对路径时,依次尝试基于当前工作目录和开发根目录解析 - 若解析后的绝对路径存在则返回,否则保留原始值 feat(workflow): 模型切换时自动同步分离节点输出端口 - 为 separate 节点注册 onModelNameChanged 回调,模型名称变化时自动同步输出端口 - 重构 syncSeparateNodeStems:仅在端口为空、仍为占位符或数量不匹配时重建,避免误改写真实音频端口 feat(litegraph): 字符串拼接支持内联 widget,音频合并新增运算方式 - StringConcatenate 节点的 string_a/string_b/delimiter 输入改为内联 widget,便于直接编辑 - 音频合并节点的 merge_method 新增 subtract/multiply 选项,默认值由 average 改为 add
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概述
将节点工作流编辑器整体重写为 litegraph 前端画布 + comfy-mss 原生 JSON + pymss DAG 引擎(in-process),删除自有 v2 graph runtime。
主要变更
工作流引擎
import pymss.graphin-process 执行(需 pymss >= 2.1.3),删除 v2 运行时运行时输入槽(input_name)
inputs映射传run_dag工作流页
运行时环境修复
编辑器修复:comfy 导入丢连线、widget 编辑后保存/撤销按钮不亮、重开编辑器连线丢失、模型未下载误报等(见各 commit)
测试
PYMSS_STUDIO_TEST_PYTHON或项目.venv依赖配套(已在 pymss 2.1.3 发布):pymss-project/pymss input_name 输入契约、comfy 图执行修复、StringConstant 节点