comfyui: add model discovery and actionable error messages

- Client queries ComfyUI /object_info to discover installed models
  (checkpoints, diffusion models, VAE, CLIP, LoRAs)
- Each tool declares its required models and checks them on execute()
- get_status() returns DEGRADED when server is up but models are missing
- Clear error messages tell the user exactly which models to download
- When COMFYUI_SERVER_URL is not set, error message tells the user to
  configure it in .env instead of silently failing on localhost:8188
- 8 new tests covering URL config, error messages, and model requirements

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
martimramos
2026-04-17 00:08:45 +01:00
committed by Alastair Beal
parent 6ec2bbb090
commit e3947e1f11
5 changed files with 225 additions and 12 deletions
+23 -4
View File
@@ -30,6 +30,10 @@ _WORKFLOWS = Path(__file__).resolve().parent.parent / "_comfyui" / "workflows"
_OUTPUT_NODE = "3"
_REQUIRED_MODELS = [
"ace_step_v1_3.5b.safetensors",
]
class ComfyUIMusic(BaseTool):
name = "comfyui_music"
@@ -117,9 +121,12 @@ class ComfyUIMusic(BaseTool):
self._client = ComfyUIClient()
def get_status(self) -> ToolStatus:
if self._client.is_available():
return ToolStatus.AVAILABLE
return ToolStatus.UNAVAILABLE
if not self._client.is_available():
return ToolStatus.UNAVAILABLE
_, missing = self._client.check_models(_REQUIRED_MODELS)
if missing:
return ToolStatus.DEGRADED
return ToolStatus.AVAILABLE
def estimate_cost(self, inputs: dict[str, Any]) -> float:
return 0.0
@@ -132,9 +139,21 @@ class ComfyUIMusic(BaseTool):
if not self._client.is_available():
return ToolResult(
success=False,
error="ComfyUI server not reachable. " + self.install_instructions,
error=self._client.unavailable_reason(),
)
if not inputs.get("workflow_json"):
_, missing = self._client.check_models(_REQUIRED_MODELS)
if missing:
return ToolResult(
success=False,
error=(
f"ComfyUI server is running but missing required models: "
f"{', '.join(missing)}.\n"
f"Download them to your ComfyUI checkpoints directory."
),
)
start = time.time()
seed = inputs.get("seed") or ComfyUIClient.random_seed()
duration = inputs.get("duration", 30.0)