feat: expose workflow execution modes in editor

This commit is contained in:
2026-04-07 11:10:58 +02:00
parent f9d4da52b9
commit 26046fb2d6
7 changed files with 147 additions and 16 deletions
@@ -171,7 +171,10 @@ def build_preset_workflow_config(
"version": 1,
"nodes": nodes,
"edges": edges,
"ui": {"preset": preset_type},
"ui": {
"preset": preset_type,
"execution_mode": "legacy",
},
}
@@ -214,7 +217,10 @@ def _canonicalize_legacy_custom_config(raw: dict[str, Any]) -> dict[str, Any]:
"version": 1,
"nodes": nodes,
"edges": edges,
"ui": {"preset": "custom"},
"ui": {
"preset": "custom",
"execution_mode": "legacy",
},
}
@@ -225,6 +231,11 @@ def canonicalize_workflow_config(raw: dict[str, Any]) -> dict[str, Any]:
if "version" in raw and "nodes" in raw:
normalized = deepcopy(raw)
normalized.setdefault("edges", [])
ui = normalized.get("ui")
if not isinstance(ui, dict):
ui = {}
normalized["ui"] = dict(ui)
normalized["ui"].setdefault("execution_mode", "legacy")
return normalized
workflow_type = raw.get("type")
@@ -13,6 +13,7 @@ def test_build_preset_workflow_config_creates_canonical_dag():
assert config["version"] == 1
assert config["ui"]["preset"] == "still"
assert config["ui"]["execution_mode"] == "legacy"
assert [node["step"] for node in config["nodes"]] == [
"order_line_setup",
"resolve_template",
@@ -34,6 +35,7 @@ def test_canonicalize_workflow_config_migrates_legacy_preset():
assert canonical["version"] == 1
assert canonical["ui"]["preset"] == "turntable"
assert canonical["ui"]["execution_mode"] == "legacy"
assert any(node["step"] == "blender_turntable" for node in canonical["nodes"])
@@ -76,6 +78,7 @@ def test_canonicalize_legacy_custom_config_preserves_edges():
canonical = canonicalize_workflow_config(legacy)
assert canonical["ui"]["preset"] == "custom"
assert canonical["ui"]["execution_mode"] == "legacy"
assert canonical["edges"] == [{"id": "e1", "from": "input", "to": "render"}]
@@ -91,3 +94,19 @@ def test_extract_runtime_workflow_converts_resolution_to_dimensions():
assert params["width"] == 1920
assert params["height"] == 1080
assert "resolution" not in params
def test_canonicalize_workflow_config_defaults_execution_mode_for_canonical_configs():
canonical = canonicalize_workflow_config(
{
"version": 1,
"nodes": [
{"id": "setup", "step": "order_line_setup", "params": {}},
],
"edges": [],
"ui": {"preset": "custom"},
}
)
assert canonical["ui"]["preset"] == "custom"
assert canonical["ui"]["execution_mode"] == "legacy"
@@ -45,3 +45,40 @@ async def test_node_definitions_endpoint_returns_registry(client, auth_headers):
)
assert blender_still["node_type"] == "renderNode"
assert blender_still["defaults"]["render_engine"] == "cycles"
@pytest.mark.asyncio
async def test_workflow_crud_roundtrip_preserves_execution_mode(client, auth_headers):
create_response = await client.post(
"/api/workflows",
headers=auth_headers,
json={
"name": "Shadow Workflow",
"config": {
"version": 1,
"ui": {
"preset": "custom",
"execution_mode": "shadow",
},
"nodes": [
{
"id": "setup",
"step": StepName.ORDER_LINE_SETUP.value,
"params": {},
}
],
"edges": [],
},
"is_active": True,
},
)
assert create_response.status_code == 201
created = create_response.json()
assert created["config"]["ui"]["execution_mode"] == "shadow"
get_response = await client.get(f"/api/workflows/{created['id']}", headers=auth_headers)
assert get_response.status_code == 200
fetched = get_response.json()
assert fetched["config"]["ui"]["execution_mode"] == "shadow"