fix: limit workflow models to metadata enrichment#12990
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (9)
💤 Files with no reviewable changes (2)
🚧 Files skipped from review as they are similar to previous changes (5)
📝 WalkthroughWalkthrough
ChangesMissing Model Enrichment Simplification
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 6 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (6 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🎨 Storybook: ✅ Built — View Storybook🎭 Playwright: ❌ 1665 passed, 1 failed · 3 flaky❌ Failed Tests📊 Browser Reports
📦 Bundle: 7.45 MB gzip 🟢 -705 BDetailsSummary
Category Glance App Entry Points — 46.7 kB (baseline 46.7 kB) • ⚪ 0 BMain entry bundles and manifests
Status: 1 added / 1 removed Graph Workspace — 1.25 MB (baseline 1.25 MB) • ⚪ 0 BGraph editor runtime, canvas, workflow orchestration
Status: 1 added / 1 removed Views & Navigation — 95.3 kB (baseline 95.3 kB) • ⚪ 0 BTop-level views, pages, and routed surfaces
Status: 9 added / 9 removed / 3 unchanged Panels & Settings — 525 kB (baseline 525 kB) • ⚪ 0 BConfiguration panels, inspectors, and settings screens
Status: 11 added / 11 removed / 15 unchanged User & Accounts — 19.9 kB (baseline 19.9 kB) • ⚪ 0 BAuthentication, profile, and account management bundles
Status: 6 added / 6 removed / 3 unchanged Editors & Dialogs — 112 kB (baseline 112 kB) • ⚪ 0 BModals, dialogs, drawers, and in-app editors
Status: 4 added / 4 removed / 1 unchanged UI Components — 57.2 kB (baseline 57.2 kB) • ⚪ 0 BReusable component library chunks
Status: 5 added / 5 removed / 8 unchanged Data & Services — 266 kB (baseline 266 kB) • ⚪ 0 BStores, services, APIs, and repositories
Status: 13 added / 13 removed / 3 unchanged Utilities & Hooks — 3.32 MB (baseline 3.32 MB) • 🟢 -2.75 kBHelpers, composables, and utility bundles
Status: 14 added / 14 removed / 16 unchanged Vendor & Third-Party — 15.3 MB (baseline 15.3 MB) • ⚪ 0 BExternal libraries and shared vendor chunks Status: 16 unchanged Other — 10.4 MB (baseline 10.4 MB) • ⚪ 0 BBundles that do not match a named category
Status: 62 added / 62 removed / 89 unchanged ⚡ Performance Report
Show regressions
All metrics
Historical variance (last 15 runs)
Trend (last 15 commits on main)
Raw data{
"timestamp": "2026-06-19T08:43:44.419Z",
"gitSha": "398760f07a50f7a52df79d8a776199ba1a526a32",
"branch": "jaeone/models-metadata-only",
"measurements": [
{
"name": "canvas-idle",
"durationMs": 2021.5619999999888,
"styleRecalcs": 9,
"styleRecalcDurationMs": 8.219999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 418.12200000000007,
"heapDeltaBytes": -1689428,
"heapUsedBytes": 56751764,
"domNodes": 18,
"jsHeapTotalBytes": 24903680,
"scriptDurationMs": 22.5,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-idle",
"durationMs": 2050.483999999983,
"styleRecalcs": 9,
"styleRecalcDurationMs": 7.908999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 383.73799999999994,
"heapDeltaBytes": -1680016,
"heapUsedBytes": 56969632,
"domNodes": 18,
"jsHeapTotalBytes": 25165824,
"scriptDurationMs": 16.32,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-mouse-sweep",
"durationMs": 1996.0820000000012,
"styleRecalcs": 79,
"styleRecalcDurationMs": 50.888,
"layouts": 12,
"layoutDurationMs": 4.366,
"taskDurationMs": 943.412,
"heapDeltaBytes": -13553124,
"heapUsedBytes": 54774952,
"domNodes": -239,
"jsHeapTotalBytes": 21671936,
"scriptDurationMs": 132.3,
"eventListeners": -199,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-mouse-sweep",
"durationMs": 1777.2699999999872,
"styleRecalcs": 74,
"styleRecalcDurationMs": 37.498000000000005,
"layouts": 12,
"layoutDurationMs": 3.6760000000000006,
"taskDurationMs": 750.9129999999999,
"heapDeltaBytes": -7384224,
"heapUsedBytes": 51053300,
"domNodes": 57,
"jsHeapTotalBytes": 26738688,
"scriptDurationMs": 119.01599999999999,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1758.4420000000023,
"styleRecalcs": 32,
"styleRecalcDurationMs": 18.281,
"layouts": 6,
"layoutDurationMs": 0.732,
"taskDurationMs": 352.67,
"heapDeltaBytes": 98248,
"heapUsedBytes": 68134932,
"domNodes": -216,
"jsHeapTotalBytes": 13807616,
"scriptDurationMs": 20.303,
"eventListeners": -184,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1707.899999999995,
"styleRecalcs": 30,
"styleRecalcDurationMs": 16.619000000000003,
"layouts": 6,
"layoutDurationMs": 0.678,
"taskDurationMs": 306.64399999999995,
"heapDeltaBytes": 1586896,
"heapUsedBytes": 59992188,
"domNodes": 77,
"jsHeapTotalBytes": 25952256,
"scriptDurationMs": 19.201000000000004,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "dom-widget-clipping",
"durationMs": 551.6879999999844,
"styleRecalcs": 11,
"styleRecalcDurationMs": 6.711999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 339.23199999999997,
"heapDeltaBytes": 6855716,
"heapUsedBytes": 65365236,
"domNodes": 18,
"jsHeapTotalBytes": 19136512,
"scriptDurationMs": 55.980000000000004,
"eventListeners": 0,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "dom-widget-clipping",
"durationMs": 626.7990000000054,
"styleRecalcs": 12,
"styleRecalcDurationMs": 9.023000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 392.135,
"heapDeltaBytes": -24150528,
"heapUsedBytes": 45118632,
"domNodes": -311,
"jsHeapTotalBytes": 5681152,
"scriptDurationMs": 53.467999999999996,
"eventListeners": -203,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-idle",
"durationMs": 2003.9140000000089,
"styleRecalcs": 11,
"styleRecalcDurationMs": 9.62,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 510.332,
"heapDeltaBytes": -9428076,
"heapUsedBytes": 61927976,
"domNodes": 22,
"jsHeapTotalBytes": 9842688,
"scriptDurationMs": 85.977,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66999999999998,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "large-graph-idle",
"durationMs": 2041.2640000000124,
"styleRecalcs": 9,
"styleRecalcDurationMs": 8.555,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 566.5600000000001,
"heapDeltaBytes": -9385840,
"heapUsedBytes": 62445820,
"domNodes": 18,
"jsHeapTotalBytes": 10104832,
"scriptDurationMs": 103.1,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-pan",
"durationMs": 2051.8429999999626,
"styleRecalcs": 68,
"styleRecalcDurationMs": 19.830000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1007.0920000000001,
"heapDeltaBytes": 10228272,
"heapUsedBytes": 82898464,
"domNodes": 18,
"jsHeapTotalBytes": 12115968,
"scriptDurationMs": 353.14300000000003,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-pan",
"durationMs": 2110.5380000000196,
"styleRecalcs": 69,
"styleRecalcDurationMs": 21.744,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1066.6030000000003,
"heapDeltaBytes": 9597704,
"heapUsedBytes": 82482332,
"domNodes": 18,
"jsHeapTotalBytes": 9494528,
"scriptDurationMs": 378.672,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-zoom",
"durationMs": 3071.7390000000364,
"styleRecalcs": 66,
"styleRecalcDurationMs": 21.318,
"layouts": 60,
"layoutDurationMs": 8.334999999999999,
"taskDurationMs": 1266.4189999999999,
"heapDeltaBytes": 12853240,
"heapUsedBytes": 67510352,
"domNodes": 16,
"jsHeapTotalBytes": 6553600,
"scriptDurationMs": 476.378,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-zoom",
"durationMs": 3077.4599999999737,
"styleRecalcs": 63,
"styleRecalcDurationMs": 17.434,
"layouts": 60,
"layoutDurationMs": 8.165000000000001,
"taskDurationMs": 1316.904,
"heapDeltaBytes": 13236700,
"heapUsedBytes": 67286936,
"domNodes": -293,
"jsHeapTotalBytes": 786432,
"scriptDurationMs": 515.9549999999999,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "minimap-idle",
"durationMs": 2001.7879999999764,
"styleRecalcs": 10,
"styleRecalcDurationMs": 9.290999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 500.25600000000003,
"heapDeltaBytes": -9252308,
"heapUsedBytes": 64313040,
"domNodes": 20,
"jsHeapTotalBytes": 7483392,
"scriptDurationMs": 79.807,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "minimap-idle",
"durationMs": 2001.9909999999754,
"styleRecalcs": 10,
"styleRecalcDurationMs": 9.344999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 510.227,
"heapDeltaBytes": -9143776,
"heapUsedBytes": 64248952,
"domNodes": 20,
"jsHeapTotalBytes": 7221248,
"scriptDurationMs": 84.481,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 581.7000000000121,
"styleRecalcs": 46,
"styleRecalcDurationMs": 13.794,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 387.26099999999997,
"heapDeltaBytes": 7494056,
"heapUsedBytes": 66222608,
"domNodes": 18,
"jsHeapTotalBytes": 18087936,
"scriptDurationMs": 125.84299999999999,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 593.9280000000053,
"styleRecalcs": 46,
"styleRecalcDurationMs": 11.08,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 378.31399999999996,
"heapDeltaBytes": 7673804,
"heapUsedBytes": 66245052,
"domNodes": 18,
"jsHeapTotalBytes": 19660800,
"scriptDurationMs": 131.113,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.663333333333338,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "subgraph-idle",
"durationMs": 1989.8839999999893,
"styleRecalcs": 9,
"styleRecalcDurationMs": 8.908,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 365.47200000000004,
"heapDeltaBytes": -2717652,
"heapUsedBytes": 56053352,
"domNodes": 18,
"jsHeapTotalBytes": 24903680,
"scriptDurationMs": 13.963999999999997,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "subgraph-idle",
"durationMs": 2006.0809999999947,
"styleRecalcs": 10,
"styleRecalcDurationMs": 10.242999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 372.004,
"heapDeltaBytes": -2748524,
"heapUsedBytes": 55894560,
"domNodes": 20,
"jsHeapTotalBytes": 24641536,
"scriptDurationMs": 14.185,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1675.7649999999842,
"styleRecalcs": 75,
"styleRecalcDurationMs": 36.888,
"layouts": 16,
"layoutDurationMs": 4.404,
"taskDurationMs": 640.557,
"heapDeltaBytes": 15378804,
"heapUsedBytes": 73926816,
"domNodes": 60,
"jsHeapTotalBytes": 25165824,
"scriptDurationMs": 88.709,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1698.1030000000032,
"styleRecalcs": 75,
"styleRecalcDurationMs": 37.887,
"layouts": 16,
"layoutDurationMs": 4.805,
"taskDurationMs": 652.6809999999999,
"heapDeltaBytes": -4997316,
"heapUsedBytes": 62936412,
"domNodes": 63,
"jsHeapTotalBytes": 21757952,
"scriptDurationMs": 89.749,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-transition-enter",
"durationMs": 967.2570000000178,
"styleRecalcs": 15,
"styleRecalcDurationMs": 29.164,
"layouts": 4,
"layoutDurationMs": 12.629000000000001,
"taskDurationMs": 743.3420000000002,
"heapDeltaBytes": 2497500,
"heapUsedBytes": 78186872,
"domNodes": 13833,
"jsHeapTotalBytes": 17301504,
"scriptDurationMs": 29.116000000000003,
"eventListeners": 2527,
"totalBlockingTimeMs": 146,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "viewport-pan-sweep",
"durationMs": 8206.575999999985,
"styleRecalcs": 253,
"styleRecalcDurationMs": 62.21900000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 3717.556,
"heapDeltaBytes": -3724300,
"heapUsedBytes": 67757124,
"domNodes": 24,
"jsHeapTotalBytes": 16310272,
"scriptDurationMs": 1237.7530000000002,
"eventListeners": 20,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "viewport-pan-sweep",
"durationMs": 8156.210999999928,
"styleRecalcs": 250,
"styleRecalcDurationMs": 62.095000000000006,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 3760.199,
"heapDeltaBytes": -4154072,
"heapUsedBytes": 67328836,
"domNodes": 18,
"jsHeapTotalBytes": 16048128,
"scriptDurationMs": 1222.126,
"eventListeners": 20,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "vue-large-graph-idle",
"durationMs": 13825.283000000014,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 13807.479000000001,
"heapDeltaBytes": -28202920,
"heapUsedBytes": 169895516,
"domNodes": -3302,
"jsHeapTotalBytes": 19632128,
"scriptDurationMs": 593.337,
"eventListeners": -16471,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.220000000000073,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "vue-large-graph-idle",
"durationMs": 13516.651999999907,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 13501.775000000001,
"heapDeltaBytes": -30929348,
"heapUsedBytes": 170000580,
"domNodes": -3302,
"jsHeapTotalBytes": 19632128,
"scriptDurationMs": 574.1820000000001,
"eventListeners": -16472,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.223333333333237,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-pan",
"durationMs": 16295.200999999963,
"styleRecalcs": 89,
"styleRecalcDurationMs": 22.650000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 16272.282000000001,
"heapDeltaBytes": -39457900,
"heapUsedBytes": 157154956,
"domNodes": -3302,
"jsHeapTotalBytes": 19107840,
"scriptDurationMs": 909.1870000000001,
"eventListeners": -16467,
"totalBlockingTimeMs": 10,
"frameDurationMs": 17.219999999999953,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "vue-large-graph-pan",
"durationMs": 15714.31300000006,
"styleRecalcs": 78,
"styleRecalcDurationMs": 21.581000000000017,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 15692.57,
"heapDeltaBytes": -39355524,
"heapUsedBytes": 169797920,
"domNodes": -3300,
"jsHeapTotalBytes": 19107840,
"scriptDurationMs": 918.2470000000001,
"eventListeners": -16474,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.776666666666642,
"p95FrameDurationMs": 16.80000000000291
},
{
"name": "workflow-execution",
"durationMs": 449.4109999999978,
"styleRecalcs": 17,
"styleRecalcDurationMs": 22.817999999999998,
"layouts": 4,
"layoutDurationMs": 1.2239999999999998,
"taskDurationMs": 113.404,
"heapDeltaBytes": 5429976,
"heapUsedBytes": 65216536,
"domNodes": 168,
"jsHeapTotalBytes": 3407872,
"scriptDurationMs": 16.758000000000003,
"eventListeners": 69,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "workflow-execution",
"durationMs": 451.21800000003986,
"styleRecalcs": 17,
"styleRecalcDurationMs": 22.485,
"layouts": 4,
"layoutDurationMs": 1.2030000000000003,
"taskDurationMs": 112.707,
"heapDeltaBytes": 4923392,
"heapUsedBytes": 71786884,
"domNodes": 157,
"jsHeapTotalBytes": 4718592,
"scriptDurationMs": 17.266999999999996,
"eventListeners": 69,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66666666666665,
"p95FrameDurationMs": 16.700000000000728
}
]
} |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/platform/missingModel/missingModelScan.test.ts (1)
899-975: ⚡ Quick winAdd an ancestor-bypassed subgraph regression test for enrichment.
Current cases only cover nodes whose own mode is muted/bypassed. Please add a
case where a node is mode0but lives under a bypassed/muted container and
shares model name with an active branch; assert that nourl/hashenrichment
leaks from the inactive branch.As per coding guidelines, “Write tests for all changes, especially bug fixes to catch future regressions.”
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/missingModel/missingModelScan.test.ts` around lines 899 - 975, Add a new test case after the "does not enrich from bypassed node metadata" test to verify that enrichWithEmbeddedMetadata does not leak metadata from an ancestor-bypassed subgraph. Create a ComfyWorkflowJSON graph structure with two branches: one with a muted/bypassed container node that has properties containing model metadata, and an active node inside that container with mode 0 referencing the same model name. Include a second active branch with a node that also references the same model name but without the metadata. Call enrichWithEmbeddedMetadata with candidates matching the model name and assert that the result[0].url remains undefined, confirming no enrichment occurs from the bypassed ancestor container.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/platform/missingModel/missingModelScan.ts`:
- Around line 219-220: The collectEmbeddedModels function currently includes all
embedded models without checking if they are within inactive ancestor subgraphs,
allowing metadata from muted or bypassed ancestors to be applied to active
candidates during enrichment. Either gate the collectEmbeddedModels collection
to exclude models in inactive ancestor subgraphs by checking ancestor activity
status, or restore source-bound matching using nodeId and widgetName during the
enrichment process (in the enrichment loop around lines 246-257) instead of
relying on global name and directory matching. This will prevent inactive branch
metadata from polluting active candidate download suggestions.
---
Nitpick comments:
In `@src/platform/missingModel/missingModelScan.test.ts`:
- Around line 899-975: Add a new test case after the "does not enrich from
bypassed node metadata" test to verify that enrichWithEmbeddedMetadata does not
leak metadata from an ancestor-bypassed subgraph. Create a ComfyWorkflowJSON
graph structure with two branches: one with a muted/bypassed container node that
has properties containing model metadata, and an active node inside that
container with mode 0 referencing the same model name. Include a second active
branch with a node that also references the same model name but without the
metadata. Call enrichWithEmbeddedMetadata with candidates matching the model
name and assert that the result[0].url remains undefined, confirming no
enrichment occurs from the bypassed ancestor container.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: b93e0791-b20a-4f28-a2f3-5185dbfa0ae6
📒 Files selected for processing (7)
src/platform/missingModel/__fixtures__/activeSubgraphUnmatchedModel.jsonsrc/platform/missingModel/__fixtures__/bypassedSubgraphUnmatchedModel.jsonsrc/platform/missingModel/missingModelPipeline.test.tssrc/platform/missingModel/missingModelPipeline.tssrc/platform/missingModel/missingModelScan.test.tssrc/platform/missingModel/missingModelScan.tssrc/platform/missingModel/types.ts
💤 Files with no reviewable changes (2)
- src/platform/missingModel/fixtures/activeSubgraphUnmatchedModel.json
- src/platform/missingModel/fixtures/bypassedSubgraphUnmatchedModel.json
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## main #12990 +/- ##
==========================================
+ Coverage 76.17% 76.27% +0.09%
==========================================
Files 1572 1573 +1
Lines 88813 100749 +11936
Branches 26647 30380 +3733
==========================================
+ Hits 67655 76842 +9187
- Misses 20497 23116 +2619
- Partials 661 791 +130
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 309 files with indirect coverage changes 🚀 New features to boost your workflow:
|
14befac to
e452895
Compare
|
Deployment failed with the following error: Learn More: https://vercel.com/uy-tieu-s-projects?upgradeToPro=build-rate-limit |
e452895 to
490cfd7
Compare
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Summary
This PR intentionally narrows workflow-embedded model metadata handling so root-level
models[]and node-level embedded model metadata can enrich existing missing-model candidates, but can no longer create new candidates by themselves.Why this PR exists
ADR 0009, Subgraph promoted widgets use linked inputs, changes promoted value ownership for subgraphs. That design was implemented by #12197, Subgraph Link Only Promotion (ADR 0009).
Under ADR 0009, a promoted widget is represented as a standard linked
SubgraphInputon the hostSubgraphNode. The host boundary owns the promoted value identity through the host node locator plusSubgraphInput.name. The interior source widget remains the provider of schema, type, options, tooltip, defaults, diagnostics, and migration metadata, but it is not the persistence owner of the promoted value.This PR is a preparatory cleanup discovered while working on the missing model detection follow-up required by that ADR 0009 / #12197 behavior. The follow-up needs missing model detection to respect the new subgraph promoted-widget ownership model. While reviewing that path, we found that the existing embedded model metadata fallback in
enrichWithEmbeddedMetadatawas doing more than metadata enrichment.The important finding was that this fallback was not just attaching metadata to candidates that had already been detected from live node widgets. It could also synthesize brand-new
MissingModelCandidateentries from workflow JSON metadata, including root-levelmodels[]entries, when no live candidate existed.That behavior is inaccurate for the missing model system for two reasons.
First, the normal missing model lifecycle is anchored to a real node/widget binding. A candidate found from a COMBO or asset widget has a concrete
nodeId + widgetNamereference. That reference is what lets the UI surface the error, cache it as a pending warning, and later clear or resolve it when the underlying node/widget value is fixed. A root-levelmodels[]entry does not reliably provide that anchor. If metadata-only fallback creates a candidate without a real live widget reference, the resulting error can be detected but cannot reliably travel through the existing clearing path. In practice, that can become an effectively unremovable missing model warning unless the user downloads exactly the same model referenced by the stale metadata.Second, a missing model error is meant to mean that a model-selecting widget on an active node references a value that is not available. Workflow JSON metadata by itself is not the same source of truth. If a model only appears in root workflow metadata, or appears in node metadata that is not represented by an active COMBO or asset widget candidate, that is a different kind of state from the existing missing model error model. Treating that metadata as a candidate creates a second, less reliable detector that is not aligned with the scan/clear lifecycle.
This is especially important before the ADR 0009 missing-model follow-up. With linked-input promoted widgets, the host promoted value is the value that matters. The interior source widget may still carry stale or default metadata, and it must not become a second source of truth for missing model errors. A detection path that can create candidates directly from workflow metadata would make it harder to reason about which value actually produced the warning.
For those reasons, this PR removes metadata-only candidate synthesis and keeps embedded metadata in the role it can perform safely: metadata enrichment. If the live widget/asset scan produces a candidate, embedded metadata may fill in
directory,url,hash, andhashType. If no live candidate exists, the metadata is not enough to create a missing model warning.This PR is intended to land before the child PR that updates runtime missing model detection for ADR 0009 linked-input promoted widgets.
Changes
enrichWithEmbeddedMetadatato enriching existing candidates instead of creating fallback candidates from unmatched rootmodels[]or embedded model metadata.enrichWithEmbeddedMetadata.modelStore.loadModelFolders()path from the missing model pipeline, since embedded metadata no longer performs installed-model fallback detection.EmbeddedModelWithSource, source node/widget fields, and widget-name lookup) that only existed to support metadata-only synthesis.Review Focus
Please focus on whether the candidate lifecycle now has a single source of truth: live COMBO/asset widget scanning creates candidates, while workflow metadata only enriches those candidates.
The intended behavioral change is that a model present only in workflow-level metadata, with no active node widget candidate referencing it, no longer appears as a missing model. This avoids surfacing warnings that cannot be cleared through the normal
nodeId + widgetNamepath.The expected retained behavior is that active widget-referenced missing models are still detected by
scanAllModelCandidates, and metadata from rootmodels[]or nodeproperties.modelsstill supplies download-related fields for those live candidates.Screenshots (if applicable)
Not applicable. This is a detection/pipeline behavior change covered by unit tests.
Validation
pnpm test:unit src/platform/missingModel/missingModelScan.test.ts src/platform/missingModel/missingModelPipeline.test.tspnpm exec eslint src/platform/missingModel/missingModelScan.ts src/platform/missingModel/missingModelScan.test.ts src/platform/missingModel/missingModelPipeline.ts src/platform/missingModel/missingModelPipeline.test.ts src/platform/missingModel/types.tspnpm exec oxfmt --check src/platform/missingModel/missingModelScan.ts src/platform/missingModel/missingModelScan.test.ts src/platform/missingModel/missingModelPipeline.ts src/platform/missingModel/missingModelPipeline.test.ts src/platform/missingModel/types.tspnpm typecheckknip --cache