Files
Artificial-Sweetener-Simple…/tests/test_external_llm_prompt_node.py
T

103 lines
3.2 KiB
Python

# SimpleSyrup - workflow-focused ComfyUI extensions for image generation
# Copyright (C) 2026 Artificial Sweetener and contributors
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Tests for the legacy External LLM Prompt node."""
from __future__ import annotations
from simple_syrup.nodes.external_llm_prompt import ExternalLLMPrompt
from simple_syrup.services.external_llm_prompt_service import CONFIGURE_EXTERNAL_LLM
class FakeExternalLLMService:
"""Service double for node tests."""
def model_choices(self) -> list[str]:
"""Return deterministic model choices."""
return ["model-a"]
def generate(
self,
model: str,
system_prompt: str,
user_prompt: str,
max_tokens: int = 1024,
reasoning_effort: str = "default",
image: object | None = None,
) -> str:
"""Return a deterministic response."""
return (
f"{model}:{system_prompt}:{user_prompt}:"
f"{max_tokens}:{reasoning_effort}:{image}"
)
def test_external_llm_prompt_input_types_are_cached_and_single_line() -> None:
"""The node exposes cached model choices and single-line prompt widgets."""
original_service = ExternalLLMPrompt._service
ExternalLLMPrompt._service = FakeExternalLLMService() # type: ignore[assignment]
try:
input_types = ExternalLLMPrompt.INPUT_TYPES()
finally:
ExternalLLMPrompt._service = original_service
inputs = input_types["required"]
assert inputs["model"][0] == ["model-a"]
assert inputs["model"][1]["default"] == "model-a"
assert inputs["system_prompt"][0] == "STRING"
assert inputs["system_prompt"][1]["multiline"] is False
assert inputs["user_prompt"][0] == "STRING"
assert inputs["user_prompt"][1]["multiline"] is False
assert inputs["max_tokens"][0] == "INT"
assert inputs["max_tokens"][1]["default"] == 1024
assert inputs["max_tokens"][1]["min"] == 1
assert inputs["max_tokens"][1]["max"] == 32768
assert inputs["reasoning_effort"][0] == [
"default",
"high",
"medium",
"low",
"off",
]
assert inputs["reasoning_effort"][1]["default"] == "default"
assert input_types["optional"]["image"][0] == "IMAGE"
def test_external_llm_prompt_output_contract() -> None:
"""The node returns one named STRING output."""
assert ExternalLLMPrompt.RETURN_TYPES == ("STRING",)
assert ExternalLLMPrompt.RETURN_NAMES == ("response",)
assert ExternalLLMPrompt.FUNCTION == "generate"
def test_external_llm_prompt_executes_service() -> None:
"""Node execution delegates to the prompt service."""
node = ExternalLLMPrompt()
original_service = node._service
node._service = FakeExternalLLMService() # type: ignore[assignment]
try:
result = node.generate(
"model-a",
"system",
"user",
128,
"off",
image="image",
)
finally:
node._service = original_service
assert result == ("model-a:system:user:128:off:image",)
def test_external_llm_prompt_sentinel_constant_matches_plan() -> None:
"""The setup sentinel is stable for dropdown fallback behavior."""
assert CONFIGURE_EXTERNAL_LLM == "Configure external LLM endpoint"