feat(image-list)!: replace fixed Start extras with growable value_N slots

Distributed Image List Start no longer has reference_image, text,
strength, seed or per-slot mode dropdowns. It now takes images, mask and
up to 10 generic value_N inputs (IMAGE, MASK, STRING, INT, FLOAT,
BOOLEAN) that grow via native V3 Autogrow, each with a matching output.

- One value is shared by every image; one per image pairs in order; any
  other count fails before dispatch. Only images is split into frames.
- Outputs are declared up front (image, mask, item_index, context,
  value_1..value_10). web/imageListStart.js hides unused value outputs,
  mirrors input types, and follows Autogrow compaction so downstream
  links keep their value.
- Image-list protocol bumped to v2; older workers fail preflight.

Breaking: saved workflows using the old Start inputs must recreate Start.
This commit is contained in:
Robert Wojciechowski
2026-10-13 09:18:50 +11:00
parent 8653e34254
commit dcddf23db2
15 changed files with 664 additions and 171 deletions
+3 -3
View File
@@ -168,7 +168,7 @@ class _FakeSession:
def _valid_capability():
return {
"supported": True,
"protocol_version": 1,
"protocol_version": 2,
"node_ids": ["DistributedImageListStart", "DistributedImageListEnd"],
}
@@ -418,7 +418,7 @@ class DispatchSelectionTests(unittest.IsolatedAsyncioTestCase):
await dispatch.preflight_image_list_workers(workers, require_idle=True)
async def test_image_list_preflight_fails_closed_for_malformed_capabilities(self):
malformed = {"supported": True, "protocol_version": 1, "node_ids": None}
malformed = {"supported": True, "protocol_version": 2, "node_ids": None}
session = _FakeSession({("worker", "capabilities"): (200, malformed)})
async def fake_session():
@@ -432,7 +432,7 @@ class DispatchSelectionTests(unittest.IsolatedAsyncioTestCase):
async def test_image_list_preflight_fails_closed_for_incompatible_protocol(self):
incompatible = _valid_capability()
incompatible["protocol_version"] = 2
incompatible["protocol_version"] = 1
session = _FakeSession({("worker", "capabilities"): (200, incompatible)})
async def fake_session():