Fix GGUF workflow compatibility and release v1.0.4

This commit is contained in:
Your Name
2026-05-16 12:46:38 +02:00
parent 4815f3bc24
commit c091b30faf
4 changed files with 86 additions and 7 deletions
+12 -6
View File
@@ -1498,18 +1498,20 @@ class ThinkingLLM_QwenVL_GGUF_Advanced(QwenVLGGUFBase):
"frame_count": ("INT", {"default": 16, "min": 1, "max": 64}),
"ctx": ("INT", {"default": 32768, "min": 1024, "max": 262144, "step": 512}),
"n_batch": ("INT", {"default": 512, "min": 64, "max": 32768, "step": 64}),
"n_ubatch": ("INT", {"default": 512, "min": 32, "max": 32768, "step": 32, "tooltip": "Physical batch size. Keep at or below n_batch. Lower values can help throughput or memory stability depending on the backend."}),
"gpu_layers": ("INT", {"default": -1, "min": -1, "max": 200}),
"image_max_tokens": ("INT", {"default": 4096, "min": 256, "max": 1024000, "step": 256}),
"top_k": ("INT", {"default": 20, "min": 0, "max": 32768}),
"pool_size": ("INT", {"default": 4194304, "min": 1048576, "max": 10485760, "step": 524288}),
"keep_model_loaded": ("BOOLEAN", {"default": False}),
"seed": ("INT", {"default": 1, "min": 1, "max": 2**32 - 1}),
"legacy_seed_mode": (["fixed", "randomize", "increment", "decrement"], {"default": "fixed", "tooltip": "Legacy workflow compatibility only. This widget is ignored by current ThinkingLLM logic."}),
"legacy_unload_after_run": ("BOOLEAN", {"default": False, "tooltip": "Legacy workflow compatibility only. Model unloading is controlled by keep_model_loaded."}),
"n_ubatch": ("INT", {"default": 512, "min": 32, "max": 32768, "step": 32, "tooltip": "Physical batch size. Keep at or below n_batch. Lower values can help throughput or memory stability depending on the backend."}),
"n_threads": ("INT", {"default": 0, "min": 0, "max": 256, "tooltip": "CPU generation threads. Set 0 to let llama.cpp choose."}),
"n_threads_batch": ("INT", {"default": 0, "min": 0, "max": 256, "tooltip": "CPU prompt/batch threads. Set 0 to let llama.cpp choose."}),
"flash_attn": ("BOOLEAN", {"default": True, "tooltip": "Enable flash attention when the installed llama.cpp backend supports it."}),
"offload_kqv": ("BOOLEAN", {"default": True, "tooltip": "Keep K/Q/V and KV-cache related work on GPU when supported."}),
"ctx_checkpoints": ("INT", {"default": 0, "min": 0, "max": 32, "tooltip": "Checkpoint count for multimodal context handling. JamePeng docs recommend 0 for single-turn ComfyUI-style multimodal runs."}),
"keep_model_loaded": ("BOOLEAN", {"default": False}),
"seed": ("INT", {"default": 1, "min": 1, "max": 2**32 - 1}),
"keep_last_prompt": ("BOOLEAN", {"default": False, "tooltip": "Keep the last generated prompt instead of creating a new one"}),
"stream_tokens_to_terminal": ("BOOLEAN", {"default": False, "tooltip": "Print every generated token live to the ComfyUI terminal/console"}),
"enable_thinking": ("BOOLEAN", {"default": True, "tooltip": "Enable model reasoning/thinking when the backend supports it: True=allow thinking, False=force direct answer. Even when enabled, easy prompts may still get a direct answer, and this node automatically disables thinking when there is not enough output budget left for useful reasoning. For non-Qwen GGUF models this is advisory."}),
@@ -1542,18 +1544,20 @@ class ThinkingLLM_QwenVL_GGUF_Advanced(QwenVLGGUFBase):
frame_count,
ctx,
n_batch,
n_ubatch,
gpu_layers,
image_max_tokens,
top_k,
pool_size,
keep_model_loaded,
seed,
legacy_seed_mode,
legacy_unload_after_run,
n_ubatch,
n_threads,
n_threads_batch,
flash_attn,
offload_kqv,
ctx_checkpoints,
keep_model_loaded,
seed,
keep_last_prompt,
image=None,
video=None,
@@ -1562,6 +1566,8 @@ class ThinkingLLM_QwenVL_GGUF_Advanced(QwenVLGGUFBase):
stream_tokens_to_terminal=False,
enable_thinking=True,
):
_ = legacy_seed_mode
_ = legacy_unload_after_run
result = self.run(
model_name=model_name,
preset_prompt=preset_prompt,
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "ComfyUI-ThinkingLLM"
description = "A multimodal ComfyUI AI node with Qwen3.5, Qwen3-VL, Qwen2.5-VL, Qwen3, and Gemma 4 integrations. Features live thinking in the terminal to see what the LLM is doing in real time."
version = "1.0.3"
version = "1.0.4"
license = {file = "LICENSE"}
dependencies = ["transformers>=5.2.0", "torch", "huggingface-hub", "hf_xet", "psutil", "numpy", "Pillow", "opencv-python", "bitsandbytes", "accelerate", "sentencepiece", "tiktoken", "llama-cpp-python"]
+63
View File
@@ -9,6 +9,7 @@ plain shell without ML dependencies.
import ast
import importlib.util
import inspect
import json
import os
import re
@@ -428,6 +429,68 @@ class TestLegacyNodeNameCompatibility(unittest.TestCase):
self.assertIn(node_type, resolved_types)
class TestGGUFAdvancedWorkflowCompatibility(unittest.TestCase):
LEGACY_REQUIRED_PREFIX = [
"model_name",
"device",
"preset_prompt",
"custom_prompt",
"max_tokens",
"temperature",
"top_p",
"repetition_penalty",
"frame_count",
"ctx",
"n_batch",
"gpu_layers",
"image_max_tokens",
"top_k",
"pool_size",
"keep_model_loaded",
"seed",
]
def _load_gguf_advanced_class(self):
package = load_thinkingllm_loader_subset(["AILab_QwenVL_GGUF.py"])
return package.NODE_CLASS_MAPPINGS["ThinkingLLM_QwenVL_GGUF_Advanced"]
def test_gguf_advanced_required_widgets_preserve_legacy_order(self):
node_cls = self._load_gguf_advanced_class()
required_keys = list(node_cls.INPUT_TYPES()["required"].keys())
self.assertEqual(
required_keys[: len(self.LEGACY_REQUIRED_PREFIX)],
self.LEGACY_REQUIRED_PREFIX,
)
self.assertEqual(
required_keys[len(self.LEGACY_REQUIRED_PREFIX): len(self.LEGACY_REQUIRED_PREFIX) + 2],
["legacy_seed_mode", "legacy_unload_after_run"],
)
self.assertGreater(required_keys.index("n_ubatch"), required_keys.index("legacy_unload_after_run"))
def test_gguf_advanced_process_signature_matches_required_widget_order(self):
node_cls = self._load_gguf_advanced_class()
signature = inspect.signature(node_cls.process)
parameter_names = [
name
for name, parameter in signature.parameters.items()
if name != "self" and parameter.kind in (inspect.Parameter.POSITIONAL_OR_KEYWORD, inspect.Parameter.KEYWORD_ONLY)
]
expected_prefix = self.LEGACY_REQUIRED_PREFIX + [
"legacy_seed_mode",
"legacy_unload_after_run",
"n_ubatch",
"n_threads",
"n_threads_batch",
"flash_attn",
"offload_kqv",
"ctx_checkpoints",
"keep_last_prompt",
]
self.assertEqual(parameter_names[: len(expected_prefix)], expected_prefix)
class _GlobalCheck(ast.NodeVisitor):
def __init__(self):
self.found = False
+10
View File
@@ -1,5 +1,15 @@
# ComfyUI-QwenVL Update Log
## Version 1.0.4 (2026/05/16) — GGUF Workflow Compatibility Fix
### Fixed
- Restored legacy widget ordering compatibility for `ThinkingLLM_QwenVL_GGUF_Advanced` so older saved workflows no longer shift values into the wrong advanced GGUF fields.
- Added compatibility shims for deprecated legacy fields (`seed_mode` and `unload_after_run`) so old workflows deserialize cleanly without affecting current runtime behavior.
- Added regression tests that lock the advanced GGUF widget order and `process()` signature alignment.
### Validation
- Local regression suite passes: `python tests/test_new_features.py`
## Version 2.2.5-local-locked (2026/05/14) — Complete Feature Parity
### 🎯 All 6 Nodes Now Have: