Skip to main content
IMP uses LiteLLM as its unified gateway to LLM providers. All model calls — chat completions, embeddings, reranking, OCR, and image generation — go through the LiteLLM proxy running on port 4000. LiteLLM also serves as the source of truth for budget tracking and spend logging. The proxy is also reachable externally through the LiteLLM gateway (/litellm/{project}/v1/...), which lets callers use any model in the model_list directly from an OpenAI-compatible SDK.

Role in the stack

Enabling LiteLLM

Set EXULU_USE_LITELLM=true and LITELLM_MASTER_KEY in your environment. Without LITELLM_MASTER_KEY, the backend throws at startup and refuses to start.

Supervisor lifecycle

The backend spawns LiteLLM as a child process. You do not run LiteLLM separately.
Startup sequence:
  1. Backend sets EXULU_USE_LITELLM=truestartLiteLLMSupervisor() is called.
  2. The Python venv binary at ee/python/.venv/bin/litellm is spawned with --config <path> --port 4000 --host 127.0.0.1.
  3. The supervisor polls http://127.0.0.1:4000/health/liveliness every 200 ms.
  4. If LiteLLM is not ready within 90 seconds, the supervisor kills the child and respawns.
  5. After 5 consecutive crashes, the supervisor gives up and sets state given_up. LiteLLM-dependent features fail at runtime with a clear error. Fix the config and restart the backend.
Crash backoff. On each crash the supervisor waits before respawning: 1 s → 2 s → 4 s → 8 s → 16 s, capped at 30 s. Shutdown. On SIGTERM or SIGINT, the backend sends SIGTERM to the LiteLLM child and gives it 5 seconds to exit cleanly before sending SIGKILL. Worker client mode. Worker containers do not spawn their own LiteLLM process. They connect to the backend’s proxy on port 4000. This is configured automatically by enableLiteLLMClientMode() in the worker boot path.

Config file

LiteLLM is configured via config.litellm.yaml. The default path is ./config.litellm.yaml in the working directory from which the backend is run. Override with LITELLM_CONFIG_PATH.

Annotated example

The following is a trimmed excerpt from the example repo’s config.litellm.yaml, showing the model_info fields IMP reads:

model_info fields IMP reads

Dedicated database requirement

LiteLLM tracks spend, keys, and budgets in Postgres. On startup, IMP runs prisma db push against LITELLM_DATABASE_URL to keep the LiteLLM schema up to date.
LITELLM_DATABASE_URL must point to a dedicated Postgres database — not the same database as POSTGRES_DB_NAME. If both point at the same database, prisma db push would drop every table that is not in LiteLLM’s schema, destroying all IMP application data.IMP detects this at startup, prints a loud warning banner, skips LiteLLM database setup, and continues booting. LiteLLM-dependent features (model routing, budget tracking, spend logging) will fail at runtime. This misconfiguration is not fatal at boot — check startup logs for the warning banner.Create a dedicated LiteLLM database:
Then set:
IMP also skips the push with a warning if the database already contains non-LiteLLM-prefixed tables, to prevent accidentally overwriting an unrelated schema.

Admin UI

The LiteLLM admin dashboard is accessible at /litellm-admin on the backend’s port. Navigate to:
Log in with the LITELLM_MASTER_KEY. The admin UI lets you manage virtual keys, view spend, set budgets, and monitor model health without editing config.litellm.yaml.

Configuration reference

Operational notes

Config missing at startup. If config.litellm.yaml does not exist when the backend starts, the supervisor logs an error and sets state given_up — LiteLLM is not started. Place the config file and restart the backend. Python venv. LiteLLM runs from a Python virtual environment bundled with @exulu/backend at ee/python/.venv. The venv is built during the Docker image build step (docker compose build). If the venv is absent, the supervisor logs an error and skips startup. DEBUG env var conflict. The backend strips the DEBUG variable from the child process environment and pins it to "false". LiteLLM’s click-based CLI reads DEBUG as a boolean flag; Node’s debug package convention (e.g. DEBUG=http-proxy-middleware*) would crash the LiteLLM process. Worker port 4000. Port 4000 is published on the backend container so that worker containers can reach the proxy over the Docker network. Workers connect to http://<backend-container>:4000 using LITELLM_HOST=<backend-host>.