{ "$comment": "Example: real local engines, all external (the hub never launches them). Copy the entries you actually run into models.json. Nothing here is required for Phase 1. One rule matters when you copy: a relative `workflowPath` or `stepsPath` is relative to the catalog that writes it, so the same template this file reaches as `../workflows/…` is `workflows/…` from a catalog at `config/models.json`. Never write `config/workflows/…`: a catalog in `config/` would compose that into `config/config/workflows/…`.", "version": "1", "hosts": [ { "$comment": "Ollama runs as a background service the user manages. `ollama serve` owns port 11434, and every pulled model is reachable through the same OpenAI-compatible surface.", "id": "ollama", "name": "Ollama", "adapter": "openai_compatible", "runtime": { "engine": "ollama", "adapter": "openai_compatible", "endpoint": "http://127.0.0.1:11434", "path": "/v1/chat/completions" }, "health": { "kind": "http", "path": "/api/tags", "timeoutMs": 2000 }, "lifecycle": { "startable": false, "stoppable": false }, "resources": { "vramGb": 0, "ramGb": 0 }, "notes": "Set startable/stoppable to true and add a `start` command if you want the hub to launch `ollama serve` for you." }, { "$comment": "llama.cpp's server exposes an OpenAI-compatible route and is the most common hand-built local setup. `llama-server -m model.gguf -c 8192 --port 8080`.", "id": "llamacpp", "name": "llama.cpp server", "adapter": "openai_compatible", "runtime": { "engine": "llama.cpp", "adapter": "openai_compatible", "endpoint": "http://127.0.0.1:8080", "path": "/v1/chat/completions" }, "health": { "kind": "http", "path": "/health", "timeoutMs": 2000 }, "lifecycle": { "startable": false, "stoppable": false }, "resources": { "vramGb": 0, "ramGb": 0 } }, { "$comment": "Automatic1111 / Forge expose /sdapi/v1. This is a JSON-in/JSON-out HTTP engine, so it uses the http_json adapter. Base64 image data is returned inline or written to a configured output directory depending on your build.", "id": "a1111", "name": "Stable Diffusion WebUI (Forge/A1111)", "adapter": "http_json", "runtime": { "engine": "stable-diffusion-webui", "adapter": "http_json", "endpoint": "http://127.0.0.1:7860", "path": "/sdapi/v1/txt2img" }, "health": { "kind": "http", "path": "/sdapi/v1/sd-models", "timeoutMs": 3000 }, "lifecycle": { "startable": true, "stoppable": true, "startupTimeoutMs": 180000, "shutdownTimeoutMs": 20000, "idleTimeoutMs": 900000, "awaitHealthOnStart": true, "start": { "$comment": "Paths here are examples. `webui.sh`/`webui-user.bat` must be allowlisted or `allowAnyCommand` enabled, because the launcher is a shell script rather than one of the built-in engine executables.", "command": "python", "args": ["launch.py", "--api", "--listen", "--port", "7860"], "cwd": "C:/tools/stable-diffusion-webui" } }, "resources": { "vramGb": 8, "ramGb": 16, "diskGb": 12, "requiresGpu": true, "allowConcurrentInstances": false } }, { "$comment": "ComfyUI providers are configured API-format workflows only. The hub does not advertise loose checkpoints or automatically discover saved workflows. Each workflow explicitly declares capabilities, bindings to exact node inputs, and an output node/type; the graph itself is opaque.", "id": "comfyui", "name": "ComfyUI", "adapter": "comfyui", "runtime": { "engine": "comfyui", "adapter": "comfyui", "endpoint": "http://127.0.0.1:8188", "path": "/prompt" }, "$comment:adapterConfig": "Register each ComfyUI provider by explicitly listing a workflow. The example's relative workflowPath is resolved from this example catalog; use workflows/z-image-turbo.api.json when copied into config/models.json. Bindings and output selectors must match your own API-format export exactly.", "adapterConfig": { "workflows": [ { "id": "comfyui_z_image_turbo_host", "name": "Z-Image Turbo workflow (host declaration)", "workflowPath": "../workflows/z-image-turbo.api.json", "capabilities": ["text_to_image"], "bindings": { "prompt": { "node": "13", "input": "text" }, "seed": { "node": "15", "input": "seed" } }, "outputs": { "image": { "node": "18", "type": "image" } }, "priority": 10, "vramGb": 6, "tags": ["local", "gpu", "image"] } ] }, "health": { "kind": "http", "path": "/system_stats", "timeoutMs": 3000 }, "lifecycle": { "startable": false, "stoppable": false, "start": { "command": "C:/ComfyUI/venv/Scripts/python.exe", "args": ["main.py", "--listen", "127.0.0.1", "--port", "8188"], "cwd": "C:/ComfyUI/src" }, "startupTimeoutMs": 300000, "awaitHealthOnStart": true }, "resources": { "vramGb": 8, "ramGb": 16, "requiresGpu": true } }, { "$comment": "A local image-to-3D server. TRELLIS's official app is a Gradio app (`python app.py`, port 8080 by default), which is why this host uses the `three_d` adapter: that adapter speaks Gradio's queue API generically, so Hunyuan3D, Stable Fast 3D and TripoSR are configured the same way. The host-level `adapterConfig.models` tells the hub what this engine can generate; the discoverer intersects that with the routes the running app actually exposes, so a claim the engine cannot back is dropped rather than published. Set `startable`/`stoppable` to true and fill in `start` to let `start_model` launch it; note that a launcher outside `python` needs `allowAnyCommand`.", "id": "trellis", "name": "TRELLIS (image to 3D)", "adapter": "three_d", "runtime": { "engine": "trellis", "adapter": "three_d", "endpoint": "http://127.0.0.1:8080" }, "adapterConfig": { "models": [ { "id": "trellis_image_large", "name": "TRELLIS image-large", "capabilities": ["image_to_3d"], "weightsPath": "microsoft/TRELLIS-image-large", "vramGb": 12, "ramGb": 16, "requiresGpu": true, "notes": "Emits GLB directly through the app's Extract GLB call." } ] }, "health": { "kind": "http", "path": "/gradio_api/config", "timeoutMs": 3000 }, "lifecycle": { "startable": false, "stoppable": false, "start": { "command": "python", "args": ["app.py", "--host", "127.0.0.1", "--port", "8080"], "cwd": "C:/tools/TRELLIS" }, "startupTimeoutMs": 600000, "awaitHealthOnStart": true }, "resources": { "vramGb": 12, "ramGb": 16, "requiresGpu": true }, "notes": "Two-call protocol (generate, then export GLB), declared in config/workflows/three-d-trellis.gradio.json." }, { "$comment": "The same adapter against a Hugging Face `app.py` variant, to show that switching 3D engine is a catalog edit. `image_to_3d` here is a single call that already returns a mesh, so the step declaration is inline and one line long.", "id": "sf3d", "name": "Stable Fast 3D (image to 3D)", "adapter": "three_d", "runtime": { "engine": "sf3d", "adapter": "three_d", "endpoint": "http://127.0.0.1:8081" }, "adapterConfig": { "models": [ { "id": "sf3d_image_to_mesh", "name": "Stable Fast 3D", "capabilities": ["image_to_3d"], "vramGb": 6, "ramGb": 12, "requiresGpu": true, "notes": "Lighter than TRELLIS; the right default on an 8 GB card." } ] }, "health": { "kind": "http", "path": "/gradio_api/config", "timeoutMs": 3000 }, "lifecycle": { "startable": false, "stoppable": false }, "resources": { "vramGb": 6, "ramGb": 12, "requiresGpu": true } } ], "models": [ { "$comment": "The model is data. This entry adds a text model without touching any TypeScript.", "id": "ollama_llama3_8b", "name": "Llama 3 8B (Ollama)", "type": "text_generation", "version": "2024-04-18", "host": "ollama", "capabilities": ["text_to_text"], "adapterConfig": { "model": "llama3:8b", "temperature": 0.7, "maxTokens": 2048 }, "resources": { "vramGb": 6, "ramGb": 8 }, "limits": { "contextTokens": 8192 }, "priority": 10, "tags": ["local", "gpu", "text"], "notes": "Preferred general-purpose local text model. Lower priority number wins." }, { "id": "ollama_qwen25_14b", "name": "Qwen2.5 14B (Ollama)", "type": "text_generation", "version": "2024-09-19", "host": "ollama", "capabilities": ["text_to_text", "image_understanding"], "adapterConfig": { "model": "qwen2.5:14b", "temperature": 0.6 }, "resources": { "vramGb": 12, "ramGb": 16 }, "limits": { "contextTokens": 32768 }, "priority": 50, "tags": ["local", "gpu", "text"], "notes": "Larger fallback. Costs more VRAM, so it loses the tie on priority." }, { "$comment": "Two image models behind one host: this is why hosts exist. Only the differing facts are repeated.", "id": "a1111_sdxl", "name": "SDXL (WebUI)", "type": "image_generation", "version": "1.0", "host": "a1111", "capabilities": ["text_to_image", "image_to_image"], "adapterConfig": { "model": "sd_xl_base_1.0.safetensors", "steps": 30, "cfgScale": 7, "sampler": "DPM++ 2M Karras" }, "limits": { "maxWidth": 1536, "maxHeight": 1536, "resolutions": ["512x512", "768x768", "1024x1024", "1152x896"] }, "priority": 10, "tags": ["local", "gpu", "image"], "notes": "Preferred image model when a GPU is present." }, { "id": "a1111_sd15", "name": "Stable Diffusion 1.5 (WebUI)", "type": "image_generation", "version": "1.5", "host": "a1111", "capabilities": ["text_to_image", "image_to_image"], "adapterConfig": { "model": "v1-5-pruned-emaonly.safetensors", "steps": 25 }, "resources": { "vramGb": 4, "ramGb": 8 }, "limits": { "maxWidth": 1024, "maxHeight": 1024, "resolutions": ["512x512", "768x768"] }, "priority": 80, "tags": ["local", "gpu", "image", "low-vram"], "notes": "Smaller footprint. On an 8 GB card this is what routing should pick, while SDXL is rejected as too large." }, { "$comment": "Alternative static ComfyUI workflow model. This example uses a distinct id from the host workflow example; in a real catalog choose one declaration per provider rather than routing two ids to the same graph. The template path is relative to config/examples/ here, versus workflows/... from config/models.json. Explicit bindings and output metadata describe the API-format workflow.", "id": "comfyui_z_image_turbo", "name": "Z-Image Turbo (ComfyUI)", "providerKind": "workflow", "workflowId": "comfyui_z_image_turbo", "type": "image_generation", "version": "1.0.0", "host": "comfyui", "capabilities": ["text_to_image"], "adapterConfig": { "providerKind": "workflow", "workflowId": "comfyui_z_image_turbo", "workflowPath": "../workflows/z-image-turbo.api.json", "bindings": { "prompt": { "node": "13", "input": "text" }, "seed": { "node": "15", "input": "seed" } }, "outputs": { "image": { "node": "18", "type": "image" } }, "steps": 8, "cfg": 1, "sampler": "res_multistep", "scheduler": "simple", "width": 1024, "height": 1024, "filenamePrefix": "deadlock/z_image" }, "resources": { "vramGb": 6, "ramGb": 12 }, "limits": { "maxWidth": 1024, "maxHeight": 1024, "resolutions": ["512x512", "768x768", "1024x1024"] }, "priority": 10, "tags": ["local", "gpu", "image", "comfyui"], "notes": "Z-Image Turbo is step-distilled: 8 steps at cfg 1.0 is its intended operating point. The template names the checkpoint, text encoder and VAE, so those files must exist in your ComfyUI models directory." }, { "$comment": "A GPU-backed text model served by llama.cpp rather than Ollama, showing two engines feeding the same capability.", "id": "llamacpp_mistral_7b", "name": "Mistral 7B (llama.cpp)", "type": "text_generation", "version": "0.3", "host": "llamacpp", "capabilities": ["text_to_text"], "adapterConfig": { "model": "mistral-7b-instruct-v0.3.Q4_K_M.gguf", "maxTokens": 2048 }, "resources": { "vramGb": 5, "ramGb": 8 }, "limits": { "contextTokens": 32768 }, "priority": 20, "tags": ["local", "gpu", "text"], "notes": "Use when running llama-server instead of Ollama." }, { "$comment": "A 3D model. `adapterConfig.stepsPath` points at the protocol declaration in `config/workflows/`, which names the two Gradio calls and how the second one receives the first one's state — `../workflows/…` here, `workflows/…` from a catalog at `config/models.json`. The hub never shows any of this to the agent: `image_to_3d` is the whole interface.", "id": "trellis_image_large", "name": "TRELLIS image-large (image to 3D)", "type": "three_d_generation", "version": "1.0.0", "host": "trellis", "capabilities": ["image_to_3d"], "adapterConfig": { "protocol": "gradio", "stepsPath": "../workflows/three-d-trellis.gradio.json", "timeoutMs": 900000 }, "resources": { "vramGb": 12, "ramGb": 16, "diskGb": 20, "requiresGpu": true }, "priority": 10, "tags": ["local", "gpu", "3d", "gradio"], "notes": "Emits GLB. Needs the TRELLIS app running (`python app.py`) with the image-large checkpoint downloaded; the first call of a session pays for loading the weights." }, { "$comment": "The same capability from a lighter engine. Two models, one capability, and routing picks by declared resources and priority — no code knows either name.", "id": "sf3d_image_to_mesh", "name": "Stable Fast 3D (image to 3D)", "type": "three_d_generation", "version": "1.0.0", "host": "sf3d", "capabilities": ["image_to_3d"], "adapterConfig": { "protocol": "gradio", "apiName": "image_to_3d", "inputMode": "data_uri", "previewIndex": 1, "timeoutMs": 300000 }, "resources": { "vramGb": 6, "ramGb": 12, "requiresGpu": true }, "priority": 50, "tags": ["local", "gpu", "3d", "low-vram"], "notes": "Single-call engine, so the step declaration is three fields. Wins on an 8 GB card where TRELLIS is rejected as too large." } ] }