diff --git a/ai/compose.yaml b/ai/compose.yaml index e100c7e..fa5c39b 100644 --- a/ai/compose.yaml +++ b/ai/compose.yaml @@ -33,9 +33,9 @@ services: # Database configuration DATABASE_URL: postgresql://${AI_DB_USER}:${AI_DB_PASSWORD}@ai_postgres:5432/${AI_DB_NAME} - # OpenAI API configuration (for Claude via Anthropic API) - OPENAI_API_BASE_URLS: ${AI_OPENAI_API_BASE_URLS:-https://api.anthropic.com/v1} - OPENAI_API_KEYS: ${ANTHROPIC_API_KEY} + # OpenAI API configuration (pointing to LiteLLM proxy) + OPENAI_API_BASE_URLS: http://litellm:4000/v1 + OPENAI_API_KEYS: sk-1234 # Dummy key for LiteLLM proxy # WebUI configuration WEBUI_NAME: ${AI_WEBUI_NAME:-Pivoine AI} @@ -65,6 +65,7 @@ services: - ai_webui_data:/app/backend/data depends_on: - ai_postgres + - litellm networks: - compose_network labels: @@ -86,6 +87,32 @@ services: # Watchtower - 'com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}' + # LiteLLM - Proxy to convert Anthropic API to OpenAI-compatible format + litellm: + image: ghcr.io/berriai/litellm:main-latest + container_name: ${AI_COMPOSE_PROJECT_NAME}_litellm + restart: unless-stopped + environment: + TZ: ${TIMEZONE:-Europe/Berlin} + ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY} + LITELLM_MASTER_KEY: ${AI_WEBUI_SECRET_KEY} + volumes: + - ./ai/litellm-config.yaml:/app/config.yaml:ro + command: ["--config", "/app/config.yaml", "--port", "4000", "--num_workers", "1"] + networks: + - compose_network + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:4000/health || exit 1"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 20s + labels: + # No Traefik exposure - internal only + - 'traefik.enable=false' + # Watchtower + - 'com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}' + # Crawl4AI - Web scraping for LLMs (internal API, no public access) crawl4ai: image: ${AI_CRAWL4AI_IMAGE:-unclecode/crawl4ai:latest} diff --git a/ai/litellm-config.yaml b/ai/litellm-config.yaml new file mode 100644 index 0000000..3c9576e --- /dev/null +++ b/ai/litellm-config.yaml @@ -0,0 +1,29 @@ +model_list: + - model_name: claude-sonnet-4 + litellm_params: + model: anthropic/claude-sonnet-4-20250514 + api_key: ${ANTHROPIC_API_KEY} + + - model_name: claude-sonnet-4.5 + litellm_params: + model: anthropic/claude-sonnet-4-5-20250929 + api_key: ${ANTHROPIC_API_KEY} + + - model_name: claude-3-5-sonnet + litellm_params: + model: anthropic/claude-3-5-sonnet-20241022 + api_key: ${ANTHROPIC_API_KEY} + + - model_name: claude-3-opus + litellm_params: + model: anthropic/claude-3-opus-20240229 + api_key: ${ANTHROPIC_API_KEY} + + - model_name: claude-3-haiku + litellm_params: + model: anthropic/claude-3-haiku-20240307 + api_key: ${ANTHROPIC_API_KEY} + +litellm_settings: + drop_params: true + set_verbose: false