From b31589064aaa4cebfe24e19514eb3b7218cce00e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deniz=20=C5=9Eafak?= Date: Wed, 18 Mar 2026 01:28:26 +0300 Subject: [PATCH] Fix jobs preview fallback priority when text and images coexist --- comfy_execution/jobs.py | 18 ++++++++++++------ tests/execution/test_jobs.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/comfy_execution/jobs.py b/comfy_execution/jobs.py index fcd7ef735..b2e691470 100644 --- a/comfy_execution/jobs.py +++ b/comfy_execution/jobs.py @@ -223,11 +223,13 @@ def get_outputs_summary(outputs: dict) -> tuple[int, Optional[dict]]: Preview priority (matching frontend): 1. type="output" with previewable media - 2. Any previewable media + 2. Any non-text previewable media + 3. Text preview fallback """ count = 0 preview_output = None fallback_preview = None + text_fallback_preview = None for node_id, node_outputs in outputs.items(): if not isinstance(node_outputs, dict): @@ -256,8 +258,8 @@ def get_outputs_summary(outputs: dict) -> tuple[int, Optional[dict]]: 'nodeId': node_id, 'mediaType': media_type } - if fallback_preview is None: - fallback_preview = enriched + if text_fallback_preview is None: + text_fallback_preview = enriched continue # normalize_output_item returned a dict (e.g. 3D file) item = normalized @@ -276,10 +278,14 @@ def get_outputs_summary(outputs: dict) -> tuple[int, Optional[dict]]: enriched['mediaType'] = media_type if item.get('type') == 'output': preview_output = enriched - elif fallback_preview is None: - fallback_preview = enriched + elif media_type != 'text': + # Prefer non-text media (images/video/audio/3d) over text fallback. + if fallback_preview is None: + fallback_preview = enriched + elif text_fallback_preview is None: + text_fallback_preview = enriched - return count, preview_output or fallback_preview + return count, preview_output or fallback_preview or text_fallback_preview def apply_sorting(jobs: list[dict], sort_by: str, sort_order: str) -> list[dict]: diff --git a/tests/execution/test_jobs.py b/tests/execution/test_jobs.py index 814af5c13..895c0006e 100644 --- a/tests/execution/test_jobs.py +++ b/tests/execution/test_jobs.py @@ -136,6 +136,37 @@ class TestGetOutputsSummary: count, preview = get_outputs_summary(outputs) assert preview['filename'] == 'temp1.png' + def test_text_preview_does_not_override_image_fallback(self): + """Text output should not take precedence over image fallback previews.""" + outputs = { + 'node1': { + 'text': ['debug text from PreviewAny'] + }, + 'node2': { + 'images': [ + {'filename': 'temp1.png', 'type': 'temp'} + ] + } + } + count, preview = get_outputs_summary(outputs) + assert count == 2 + assert preview is not None + assert preview['mediaType'] == 'images' + assert preview['filename'] == 'temp1.png' + + def test_text_fallback_used_when_only_text_exists(self): + """Text preview should still be used when no non-text previewable outputs exist.""" + outputs = { + 'node1': { + 'text': ['debug text from PreviewAny'] + } + } + count, preview = get_outputs_summary(outputs) + assert count == 1 + assert preview is not None + assert preview['mediaType'] == 'text' + assert preview['content'] == 'debug text from PreviewAny' + def test_non_previewable_media_types_counted_but_no_preview(self): """Non-previewable media types should be counted but not used as preview.""" outputs = {