Files
light-heart-labs--dreamserver/ods/docs/LEMONADE-SDK-COMPAT.md
T
wehub-resource-sync 9e8f1bbeed
Dashboard / frontend (push) Failing after 0s
Dashboard / api (push) Failing after 0s
Lint PowerShell / powershell-lint (ubuntu-latest) (push) Failing after 1s
Python Lint / Lint Python with Ruff (push) Failing after 1s
ShellCheck / Lint shell scripts (push) Failing after 1s
Matrix Smoke / linux-smoke (push) Failing after 1s
Matrix Smoke / distro: cachyos (push) Failing after 15s
Matrix Smoke / distro: linux-mint-21.3 (push) Failing after 15s
Matrix Smoke / distro: debian-12 (push) Failing after 5m21s
Matrix Smoke / distro: fedora-41 (push) Failing after 4m56s
Matrix Smoke / distro: ubuntu-24.04 (push) Failing after 2m13s
Matrix Smoke / distro: rocky-9 (push) Failing after 10m39s
Matrix Smoke / distro: manjaro (push) Failing after 12m11s
Matrix Smoke / distro: opensuse-tw (push) Failing after 11m53s
Matrix Smoke / distro: archlinux (push) Failing after 20m3s
Matrix Smoke / distro: ubuntu-22.04 (push) Failing after 13m49s
Validate .env Schema / tier-1-env-validation (push) Successful in 52s
Validate .env Schema / tier-2-env-validation (push) Successful in 44s
Validate .env Schema / tier-3-env-validation (push) Successful in 52s
Validate .env Schema / tier-4-env-validation (push) Successful in 51s
Validate Extensions Catalog / Check catalog is up-to-date (push) Failing after 9m47s
Secret Scan / Scan for secrets (push) Failing after 21m4s
Validate Docker Compose / Validate Docker Compose files (push) Has been cancelled
Python Type Check / Type check with mypy (push) Has been cancelled
Validate .env Schema / tier-0-env-validation (push) Has been cancelled
Test Linux / integration-smoke (push) Has been cancelled
Lint PowerShell / powershell-lint (windows-latest) (push) Has been cancelled
Matrix Smoke / macos-smoke (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:31:33 +08:00

5.9 KiB

Lemonade SDK Compatibility

ODS's Linux installer can wrap an existing Lemonade SDK install instead of starting its own managed Lemonade runtime. This is intended for AMD Linux systems where Lemonade is already installed, configured, and serving models. The longer-term contract for making Lemonade a supported provider mode across platforms is defined in Engine Provider Modes.

Install Around Existing Lemonade

Start Lemonade first, then install ODS with:

./install.sh --use-existing-lemonade

If Lemonade is not using its default URL, pass it explicitly:

./install.sh --use-existing-lemonade --lemonade-url http://localhost:13305

When --lemonade-url is omitted, ODS checks http://localhost:13305 first, then http://localhost:8000. This covers current Lemonade Server packages and older Python SDK installs. If neither endpoint is reachable, the installer falls back to http://localhost:13305 and the Phase 12 completion check will fail with a targeted Lemonade routing error instead of declaring a false-green install.

If Lemonade requires an API key:

./install.sh --use-existing-lemonade \
  --lemonade-url http://localhost:13305 \
  --lemonade-api-key "$LEMONADE_API_KEY"

ODS will keep Lemonade unmanaged:

  • it does not install Lemonade;
  • it does not start or stop Lemonade;
  • it does not download ODS's GGUF model into data/models;
  • it routes ODS services through LiteLLM, which calls the existing Lemonade service.

This only applies to the LLM runtime. ODS's optional voice and image services are separate from Lemonade:

  • Whisper speech-to-text listens on port 9000;
  • Kokoro text-to-speech listens on port 8880;
  • ComfyUI image generation listens on port 8188.

If you choose Full Stack, ODS still enables those services by default. That is useful when ODS should own the full app stack, but it can conflict with an existing local AI setup that already runs Whisper, TTS, ComfyUI, or other services on the same ports.

To wrap an existing Lemonade install without ODS-managed voice or image services:

./install.sh --use-existing-lemonade --no-voice --no-comfyui

If you are using --all, put the opt-out flags after --all because installer flags are processed left to right:

./install.sh --use-existing-lemonade --all --no-voice --no-comfyui

If you want ODS's Whisper or ComfyUI services but need to avoid port collisions, set alternate ports before running the installer:

WHISPER_PORT=9100 COMFYUI_PORT=8190 \
  ./install.sh --use-existing-lemonade

If the installer reports that ports 9000, 8880, or 8188 are already in use, either disable the matching ODS feature or choose a different port where the installer supports it. Today, a Kokoro/TTS conflict on port 8880 should be handled with --no-voice. The port conflict is from the optional ODS service, not from Lemonade itself.

Windows AMD installs already use a separate host-managed Lemonade path. These flags are for Linux installs that should attach to a pre-existing Lemonade SDK service.

Model Selection

ODS auto-detects the first model id returned by Lemonade's /api/v1/models endpoint that does not look like an image-generation model and writes it to LEMONADE_MODEL.

Set LEMONADE_MODEL only if you want ODS to use a specific served model:

LEMONADE_MODEL=Qwen3-0.6B-GGUF ./install.sh --use-existing-lemonade

The model id should match an id returned by Lemonade's model list endpoint, for example:

curl http://localhost:13305/api/v1/models

Use a text/chat model for LEMONADE_MODEL. Image models such as Flux, SDXL, or Stable Diffusion can appear in Lemonade's model list, but they are not valid for ODS's chat/completions route.

Phase 12 verifies the selected model with a real chat completion through LiteLLM. If Lemonade is reachable from the host but not from Docker containers, if the selected model id is wrong, or if the selected model is an image/non-chat model, the installer fails there with a recovery hint instead of finishing with a broken chat path.

Linux Docker Networking

On Linux, Docker containers cannot always reach a host service that is bound only to 127.0.0.1. ODS converts a host URL such as http://localhost:13305 into the container-side URL http://host.docker.internal:13305, but Lemonade must be reachable there.

On a trusted host, configure Lemonade to bind beyond loopback:

lemonade config set host=0.0.0.0

If UFW or firewalld is active, the installer adds a scoped rule that allows ODS containers on ods-network to reach the configured Lemonade port. If that automatic rule cannot be added, allow the ods-network subnet to reach the Lemonade API port manually.

If you expose Lemonade beyond localhost, set LEMONADE_API_KEY or LEMONADE_ADMIN_API_KEY in Lemonade and pass the matching key to ODS with --lemonade-api-key.

ods doctor warns when external Lemonade is host-routed from Docker without a user-provided Lemonade API key. The installer-generated LITELLM_LEMONADE_API_KEY=sk-ods-lemonade-* value is only the key LiteLLM sends upstream; it does not prove that the Lemonade daemon requires authentication.

Managed vs External

Mode Who owns Lemonade? Default API target Model storage
Managed AMD Lemonade ODS llama-server:8080/api/v1 inside Docker ODS data/models
Existing Lemonade SDK User / OS service Auto-detected host.docker.internal:<port>/api/v1 from containers Lemonade cache

In both modes, ODS services talk to LiteLLM first. LiteLLM normalizes model routing and gives Open WebUI, Hermes, Perplexica, and other services one stable OpenAI-compatible gateway.

Diagnostics

ods doctor and the dashboard AMD runtime endpoint report external Lemonade as:

runtime: lemonade
location: host
runtimeMode: external-lemonade
managedByODS: false

Use this to distinguish Lemonade service/network issues from ODS-managed container failures.