The offline suite stubs the llama.cpp boundary, so it proves what the nodes send and how they handle responses, but never that inference works. Adds an opt-in real-weight script that drives the node classes themselves: - LLMLoader resolving a real GGUF through ComfyUI folder_paths, and returning before any weights load - LLMSampler generating real text, asserted deterministic for a fixed seed at temperature 0 rather than asserting on model knowledge - StructuredOutput constraining a real model to a generated JSON Schema. This is the llama.cpp grammar path, which a stub cannot verify at all. - LLMOptionalMemoryFreeSimple releasing a real llama.cpp allocation Verified against ggml-org/Qwen3.5-0.8B-GGUF (563 MB, Q4_0) on Metal with llama-cpp-python 0.3.34: all checks pass. Also extracts tests/_bootstrap.py. Four of the six manual scripts imported the package only when the checkout directory was named ComfyUI_VLM_nodes, which conftest.py already notes is not safe for worktrees named after a branch. All six now share one helper.
51 lines
1.6 KiB
Python
51 lines
1.6 KiB
Python
"""Make this checkout importable from the manual smoke scripts.
|
|
|
|
The manual scripts run as `python tests/manual_*.py`, outside pytest, so they
|
|
do not get `conftest.py`. Without this they only import when the checkout
|
|
directory happens to be named `ComfyUI_VLM_nodes`, which is true in a normal
|
|
ComfyUI install but not in a git worktree named after a feature branch.
|
|
|
|
Usage, before importing anything from the package:
|
|
|
|
from _bootstrap import bootstrap
|
|
|
|
bootstrap()
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import importlib.util
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
PACKAGE = "ComfyUI_VLM_nodes"
|
|
REPOSITORY = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def bootstrap() -> None:
|
|
"""Put the repository and ComfyUI on sys.path, then load this checkout."""
|
|
|
|
for candidate in (
|
|
REPOSITORY.parent,
|
|
REPOSITORY.parent / "ComfyUI",
|
|
REPOSITORY.parents[1],
|
|
):
|
|
if candidate.exists():
|
|
sys.path.insert(0, str(candidate))
|
|
|
|
if PACKAGE in sys.modules or REPOSITORY.name == PACKAGE:
|
|
return
|
|
|
|
# Load this checkout explicitly so the script can never pass by silently
|
|
# importing a sibling clone with the canonical directory name.
|
|
specification = importlib.util.spec_from_file_location(
|
|
PACKAGE,
|
|
REPOSITORY / "__init__.py",
|
|
submodule_search_locations=[str(REPOSITORY)],
|
|
)
|
|
if specification is None or specification.loader is None:
|
|
raise RuntimeError(f"Could not load package from {REPOSITORY}.")
|
|
package = importlib.util.module_from_spec(specification)
|
|
sys.modules[PACKAGE] = package
|
|
specification.loader.exec_module(package)
|