Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions data/research/comfy-contract-resolution.v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"publishesTemplates": false,
"researchOnly": true
},
"contentHash": "sha256:425d20ad21a3c8b86d66d7e254f65be47a98999758f5ffdf71e0ea79c8725214",
"contentHash": "sha256:ed9cf2796b2d9468d520e85f79ac834ffc2a18cadd17dff8ce00de23fc797d81",
"contractKind": "non_executable_comfy_contract_resolution_ledger",
"resolutions": [
{
Expand Down Expand Up @@ -16499,14 +16499,14 @@
"sha256": "sha256:d743007946b424026f86f0890bf7926953ad4808512b91018d100b4ea2940c75"
},
"templateAuthoringSpecs": {
"contentHash": "sha256:f7b2e5cdf11ffe88f38d298357d48641275c69d240ff13cf6b3d39eee3cdc522",
"contentHash": "sha256:25433f08dc2d43521b16c1b6ab53e9d0dfaeb78a1e794fee7c1695df65fa0dea",
"path": "data/template-authoring-specs.v1.json",
"sha256": "sha256:b4fa65929304f22cba6f6d13bb138f7188d49115f81a859b29b9b603614d2f4b"
"sha256": "sha256:17ff9c9bbe8b7283c8ff960699d4f1cbe6baae15aaa8e487328ded4601359321"
},
"upstreamCoverage": {
"contentHash": "sha256:a7d36b205241f21d4067de7cc3b877c2c29538d3e2a2d965c03d670b9135f9ca",
"contentHash": "sha256:ed25c084c7fb0be603cc00e79e49d3b6dc53b053c88cd2bcd97711811eb239d1",
"path": "data/upstream-coverage.v1.json",
"sha256": "sha256:6f5d0b3551c5c4c8e4f109947c8527c23f9c04d7d595ed134e2d8c82a6005cf0"
"sha256": "sha256:bfd3e3c6a565549bea2b7d545f78b89eda39129b14213f4323e73c94c8acfb83"
},
"workflowManifest": {
"path": "data/workflow-library-manifest.json",
Expand Down
10 changes: 5 additions & 5 deletions data/research/comfy-evidence-resolution.v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"presentationMediaHints"
]
},
"contentHash": "sha256:f7fc575517953e6a7c0296851e9dde211de498a92aca36696867a50512f0634c",
"contentHash": "sha256:f18ffca9fe31ed2690729c1dad6cf4d82959a4f9b45c02b2336467c078cdc9a8",
"contractKind": "non_executable_comfy_evidence_resolution_ledger",
"resolutions": [
{
Expand Down Expand Up @@ -7483,14 +7483,14 @@
"sha256": "sha256:d743007946b424026f86f0890bf7926953ad4808512b91018d100b4ea2940c75"
},
"templateAuthoringSpecs": {
"contentHash": "sha256:f7b2e5cdf11ffe88f38d298357d48641275c69d240ff13cf6b3d39eee3cdc522",
"contentHash": "sha256:25433f08dc2d43521b16c1b6ab53e9d0dfaeb78a1e794fee7c1695df65fa0dea",
"path": "data/template-authoring-specs.v1.json",
"sha256": "sha256:b4fa65929304f22cba6f6d13bb138f7188d49115f81a859b29b9b603614d2f4b"
"sha256": "sha256:17ff9c9bbe8b7283c8ff960699d4f1cbe6baae15aaa8e487328ded4601359321"
},
"upstreamCoverage": {
"contentHash": "sha256:a7d36b205241f21d4067de7cc3b877c2c29538d3e2a2d965c03d670b9135f9ca",
"contentHash": "sha256:ed25c084c7fb0be603cc00e79e49d3b6dc53b053c88cd2bcd97711811eb239d1",
"path": "data/upstream-coverage.v1.json",
"sha256": "sha256:6f5d0b3551c5c4c8e4f109947c8527c23f9c04d7d595ed134e2d8c82a6005cf0"
"sha256": "sha256:bfd3e3c6a565549bea2b7d545f78b89eda39129b14213f4323e73c94c8acfb83"
},
"workflowManifest": {
"path": "data/workflow-library-manifest.json",
Expand Down
6 changes: 3 additions & 3 deletions data/template-authoring-specs.v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
"selectsInputAssets": false,
"studioVisible": false
},
"contentHash": "sha256:f7b2e5cdf11ffe88f38d298357d48641275c69d240ff13cf6b3d39eee3cdc522",
"contentHash": "sha256:25433f08dc2d43521b16c1b6ab53e9d0dfaeb78a1e794fee7c1695df65fa0dea",
"contractKind": "non_public_template_authoring_spec_ledger",
"schemaVersion": 1,
"sources": {
"candidateContracts": {
"contentHash": "sha256:419ecd358329d4ee720c319bb634598870f8cd463fd3f832f0f23ff1b7818679",
"contentHash": "sha256:27df3a3e7b79a359a8333700983f334398a6317ee0427784204f5edc5682f331",
"path": "data/template-candidate-contracts.v1.json",
"sha256": "sha256:61546d67c49ea8dfc089522fb222a6a024750fb11aea22df3274cbbf41da2e05"
"sha256": "sha256:144696f2c50db52b6b958d92b6b2fca4e366a4137d16f96dd29ec0d1abeb22ba"
},
"workflowManifest": {
"path": "data/workflow-library-manifest.json",
Expand Down
6 changes: 3 additions & 3 deletions data/template-candidate-contracts.v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"qualificationMetadataMeaning": "exact_manifest_binding_not_candidate_evidence",
"studioVisible": false
},
"contentHash": "sha256:419ecd358329d4ee720c319bb634598870f8cd463fd3f832f0f23ff1b7818679",
"contentHash": "sha256:27df3a3e7b79a359a8333700983f334398a6317ee0427784204f5edc5682f331",
"contractKind": "non_public_template_candidate_contract_ledger",
"contracts": [
{
Expand Down Expand Up @@ -6687,9 +6687,9 @@
"sha256": "sha256:f278e24ed314a1ab997b5521cc4c8b9576c67cdbbe76e19ffa3ce58a4593dc0e"
},
"upstreamCoverage": {
"contentHash": "sha256:a7d36b205241f21d4067de7cc3b877c2c29538d3e2a2d965c03d670b9135f9ca",
"contentHash": "sha256:ed25c084c7fb0be603cc00e79e49d3b6dc53b053c88cd2bcd97711811eb239d1",
"path": "data/upstream-coverage.v1.json",
"sha256": "sha256:6f5d0b3551c5c4c8e4f109947c8527c23f9c04d7d595ed134e2d8c82a6005cf0"
"sha256": "sha256:bfd3e3c6a565549bea2b7d545f78b89eda39129b14213f4323e73c94c8acfb83"
},
"workflowManifest": {
"path": "data/workflow-library-manifest.json",
Expand Down
4 changes: 2 additions & 2 deletions data/upstream-coverage.v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -2339,7 +2339,7 @@
"status": "executable"
}
],
"contentHash": "sha256:a7d36b205241f21d4067de7cc3b877c2c29538d3e2a2d965c03d670b9135f9ca",
"contentHash": "sha256:ed25c084c7fb0be603cc00e79e49d3b6dc53b053c88cd2bcd97711811eb239d1",
"diffusersPipelines": [
{
"artifactReviews": [],
Expand Down Expand Up @@ -8667,7 +8667,7 @@
},
"qualificationBoundary": "Executable means source/graph admission only; it does not imply live output, Auto, Gallery, hardware, license, or release qualification.",
"templateBundle": "web/assets/studio-templates.js",
"templateBundleSha256": "e554ddc034cb069918936aae7641bf08345d86c5d3670494dee7e13739c570b8",
"templateBundleSha256": "015acbe27676173560cb135be77e5681f9cef766ab8f29fc0f0494840ad0275b",
"transformers": {
"productionRuntime": {
"byteSize": 11625234,
Expand Down
29 changes: 29 additions & 0 deletions docs/workflow-authoring-ux.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,35 @@ conditioning or audio operations. Whole-pipeline routes expose Generate/Edit
operations instead; those nodes do not claim independently replaceable denoising.
Qwen-Image 2.1 uses its supported whole-pipeline route at the reviewed Diffusers pin.

## Group nodes into a reusable Block

Select nodes and choose **Create block**. New definitions use Block V2 and can
contain existing Blocks such as Encode Inputs. Their nested contents, values and
crossing connections are retained. Existing saved definitions are not rewritten.
Creation errors appear inside the dialog. Public sockets and controls remain
available; the dialog lets you choose controls and rename ports.

Connection validation follows executable nodes inside containers. A loader and
denoiser grouped around an external encoder can exchange values without creating
an execution cycle. Required input checks also inspect these internal nodes; a
missing model connection blocks Run and identifies the affected node or Block.

When changing a model inside a Block, the change preview may retire untouched,
automatically derived outputs that the new route cannot provide and nobody uses.
Connected outputs, configured interfaces and preview bindings remain protected.
Incompatible contracts require repair before the change can be applied.

Scalar inputs declared with an editor (text, number, toggle or choices) retain
both their editor and optional socket. A connection supplies the execution value
and disables the literal editor; disconnecting restores the saved fallback.
The source is shown when available. Model and media inputs retain their sockets.

For a custom graph using Auto memory, **Graph ready · Auto check at Run** means
static graph checks passed. Run checks the exact backend resource plan before
submission. Use **Resources → Check Auto execution plan** to inspect it earlier.
Installed model files alone do not qualify a recipe; Custom memory retains your
chosen settings without claiming Auto qualification.

## Change the model

### Guidance control visibility
Expand Down
10 changes: 9 additions & 1 deletion modiff/workflow_auto_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,15 @@ def _build_workflow_auto_plan(
"Use a covered batch size or select Expert."
if form.get("batchSize", 1) > 1 else None
)
raise ValueError(plan.get("blockingReason") or batch_reason or "No accepted recipe preserves this graph's model, precision and requested workload.")
reason = plan.get("blockingReason") or batch_reason or (
"No accepted recipe preserves this graph's model, precision and requested workload. "
f"Requested {repo}, {form['dtype']}, {form['quantizationMode']} quantization, "
f"{form.get('width', 'default')}x{form.get('height', 'default')}, "
f"{form.get('steps', 'default')} steps. "
"Installed model files do not establish Auto resource qualification. "
"Review the model's resource recipes or select Custom memory to keep your settings."
)
raise ValueError(reason)
candidate = candidates[0]
envelope = candidate.get("requirements", {})
requirements = envelope
Expand Down
1 change: 1 addition & 0 deletions modules/ModularDiffusers/embeddings.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class EncodePrompt(NodeBase):
params = {
"text_encoders": {
"label": "Text Encoders *",
"required": True,
"type": "diffusers_auto_models",
"display": "input",
"onSignal": "update_node",
Expand Down
8 changes: 8 additions & 0 deletions tests/test_required_encoder_contract.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""The registry must expose the model dependency before graph execution."""
from modules.ModularDiffusers.embeddings import EncodePrompt


def test_prompt_encoder_requires_models_but_accepts_inline_prompt():
assert EncodePrompt.params['text_encoders']['required'] is True
assert EncodePrompt.params['text_encoders']['display'] == 'input'
assert not EncodePrompt.params['prompt_input'].get('required', False)
15 changes: 15 additions & 0 deletions tests/test_workflow_auto_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,3 +629,18 @@ def test_owner_retention_normalizes_numeric_hardware_values(setup):
result = plan(graph(two=True))
assert result['canAutoRun']
assert result['schedule'] is None


def test_unqualified_recipe_explains_installed_files_are_not_auto_proof(setup):
plan, candidate, _, _ = setup
candidate['canAutoRun'] = False
g = graph()
before = deepcopy(g)
result = plan(g)
assert not result['canAutoRun']
message = ' '.join(result['issues'])
assert 'Installed model files do not establish Auto resource qualification' in message
assert 'test/model' in message
assert 'bfloat16' in message
assert 'Custom memory' in message
assert g == before
2 changes: 1 addition & 1 deletion web/assets/AlertDialog.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading