diff --git a/.env.dev b/.env.dev new file mode 100644 index 00000000..a5393f15 --- /dev/null +++ b/.env.dev @@ -0,0 +1,27 @@ +# Dev environment overlay โ sourced AFTER .env to override prod values +# Secrets are inherited from .env; only env-specific config is set here. + +# Pod identity +POD_NAME="dev-router-pod" + +# Public URLs +BASEURL="dev.vendeuvre.lan" +BASE_URL="dev.vendeuvre.lan" +PUBLIC_BASE_URL="https://dev.vendeuvre.lan/llm-routing" + +# Dev port assignments (+10 offset from production) +ROUTER_PORT="5010" +LITELLM_PORT="4010" +LANGFUSE_WEB_PORT="3011" +LANGFUSE_WORKER_PORT="3040" +POSTGRES_PORT="5442" +VALKEY_CACHE_PORT="6389" +VALKEY_LF_PORT="6390" +CLICKHOUSE_HTTP_PORT="8133" +CLICKHOUSE_TCP_PORT="9010" +CLICKHOUSE_INTERSERVER_PORT="9019" +MINIO_S3_PORT="9012" +MINIO_CONSOLE_PORT="9011" + +# Dev uses locally-built router image (for testing code changes) +ROUTER_IMAGE="localhost/llm-routing-dev:latest" diff --git a/.gitignore b/.gitignore index 5ccf9013..41daa843 100644 --- a/.gitignore +++ b/.gitignore @@ -4,13 +4,9 @@ # Exclude Podman runtime file generated dynamically at startup pod-run.yaml -# Exclude persistent database and cache storages -postgres-data/ -langfuse-data/ -valkey-data/ -clickhouse-data/ -minio-data/ -redis-lf-data/ +# Exclude persistent database and cache storages (all under data/) +data/ + # Exclude auto-generated backups backups/ @@ -36,7 +32,5 @@ router/free_models_roster.json workdirs/ pr_description.txt -# Dataset work in progress -data/ .cache/ test_output*.log diff --git a/litellm/config.yaml b/litellm/config.yaml index 195712f5..b204f9cc 100644 --- a/litellm/config.yaml +++ b/litellm/config.yaml @@ -12,7 +12,7 @@ litellm_settings: cache_params: host: 127.0.0.1 mode: default - port: 6379 + port: VALKEY_CACHE_PORT_PLACEHOLDER ttl: 3600 type: redis caching_backend: redis @@ -77,7 +77,7 @@ model_list: is_public_model_group: true - litellm_params: model: openai/llm-routing-ollama - api_base: http://127.0.0.1:5000/v1 + api_base: http://127.0.0.1:ROUTER_PORT_PLACEHOLDER/v1 api_key: os.environ/LITELLM_MASTER_KEY request_timeout: 120 model_name: llm-routing-ollama @@ -237,7 +237,7 @@ model_list: redis_settings: redis_host: 127.0.0.1 - redis_port: 6379 + redis_port: VALKEY_CACHE_PORT_PLACEHOLDER router_settings: allowed_fails: 0 cooldown_time: 300 diff --git a/litellm/entrypoint.py b/litellm/entrypoint.py index 65520978..b8755d44 100644 --- a/litellm/entrypoint.py +++ b/litellm/entrypoint.py @@ -17,7 +17,7 @@ if line and not line.startswith("#") and "=" in line: key, _, val = line.partition("=") val = val.strip().strip('"').strip("'") - os.environ[key] = val + os.environ.setdefault(key, val) # Load Gemini OAuth token from credentials JSON creds_path = "/config/gemini_auth/oauth_creds.json" @@ -46,9 +46,10 @@ def check_tcp_port(ip: str, port: int) -> bool: return False max_wait = 60 -print(f"๐ Waiting for PostgreSQL on :5432 (max {max_wait}s)...") +postgres_port = int(os.environ.get("POSTGRES_PORT", "5432")) +print(f"๐ Waiting for PostgreSQL on :{postgres_port} (max {max_wait}s)...") for i in range(max_wait): - if check_tcp_port("127.0.0.1", 5432): + if check_tcp_port("127.0.0.1", postgres_port): print(f"โ PostgreSQL ready after {i+1}s") break time.sleep(1) @@ -127,5 +128,6 @@ def _serialize_dt(dt): # Start LiteLLM Proxy import litellm from litellm.proxy.proxy_cli import run_server -sys.argv = ["litellm", "--config", "/app/config.yaml", "--port", "4000"] +litellm_port = os.environ.get("LITELLM_PORT", os.environ.get("PORT", "4000")) +sys.argv = ["litellm", "--config", "/app/config.yaml", "--port", litellm_port] run_server() diff --git a/pod.yaml b/pod.yaml index a76bfcbb..c871aabf 100644 --- a/pod.yaml +++ b/pod.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: Pod metadata: - name: agent-router-pod + name: POD_NAME_PLACEHOLDER spec: containers: # Valkey Cache โ LiteLLM response cache (exact-match & semantic) @@ -9,19 +9,29 @@ spec: - valkey-server - --bind - 127.0.0.1 + - --port + - 'VALKEY_CACHE_PORT_PLACEHOLDER' - --loglevel - warning - image: docker.io/valkey/valkey:9.1.0-alpine + image: docker.io/valkey/valkey:9.1.0 livenessProbe: - tcpSocket: - port: 6379 + exec: + command: + - valkey-cli + - -p + - 'VALKEY_CACHE_PORT_PLACEHOLDER' + - ping initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 2 name: valkey-cache readinessProbe: - tcpSocket: - port: 6379 + exec: + command: + - valkey-cli + - -p + - 'VALKEY_CACHE_PORT_PLACEHOLDER' + - ping initialDelaySeconds: 2 periodSeconds: 5 timeoutSeconds: 2 @@ -34,28 +44,34 @@ spec: - /app/entrypoint.py env: - name: DATABASE_URL - value: postgresql://postgres:POSTGRES_PASSWORD_ENCODED_PLACEHOLDER@127.0.0.1:5432/postgres + value: postgresql://postgres:POSTGRES_PASSWORD_ENCODED_PLACEHOLDER@127.0.0.1:POSTGRES_PORT_PLACEHOLDER/postgres - name: STORE_MODEL_IN_DB value: 'True' - name: LITELLM_LOG value: INFO - name: LANGFUSE_HOST - value: http://127.0.0.1:3001 + value: http://127.0.0.1:LANGFUSE_WEB_PORT_PLACEHOLDER - name: LITELLM_MASTER_KEY value: LITELLM_MASTER_KEY_PLACEHOLDER - name: OLLAMA_API_KEY value: OLLAMA_API_KEY_PLACEHOLDER - name: SERVER_ROOT_PATH - value: SERVER_ROOT_PATH_PLACEHOLDER + value: /llm-routing/litellm - name: PROXY_BASE_URL value: PROXY_BASE_URL_PLACEHOLDER + - name: PORT + value: 'LITELLM_PORT_PLACEHOLDER' + - name: LITELLM_PORT + value: 'LITELLM_PORT_PLACEHOLDER' + - name: POSTGRES_PORT + value: 'POSTGRES_PORT_PLACEHOLDER' image: ghcr.io/berriai/litellm:v1.91.1 livenessProbe: exec: command: - python3 - -c - - import urllib.request; urllib.request.urlopen('http://localhost:4000/health/liveness') + - import urllib.request; urllib.request.urlopen('http://localhost:LITELLM_PORT_PLACEHOLDER/ping') initialDelaySeconds: 240 periodSeconds: 15 timeoutSeconds: 5 @@ -65,16 +81,16 @@ spec: command: - python3 - -c - - import urllib.request; urllib.request.urlopen('http://localhost:4000/health/readiness') + - import urllib.request; urllib.request.urlopen('http://localhost:LITELLM_PORT_PLACEHOLDER/health/readiness') initialDelaySeconds: 45 periodSeconds: 10 timeoutSeconds: 5 volumeMounts: - mountPath: /app/config.yaml - name: litellm-config + name: litellm-rendered subPath: config.yaml - mountPath: /app/entrypoint.py - name: litellm-config + name: litellm-rendered subPath: entrypoint.py - mountPath: /config/.env name: env-file @@ -83,7 +99,7 @@ spec: name: gemini-secrets # LLM Triage Router โ classification + routing gateway - args: - - set -a && . /config/.env && set +a && exec uvicorn main:app --host 0.0.0.0 --port 5000 --log-level ${LOG_LEVEL:-warning} + - set -a && . /config/.env && set +a && LITELLM_PORT=LITELLM_PORT_PLACEHOLDER VALKEY_CACHE_PORT=VALKEY_CACHE_PORT_PLACEHOLDER exec uvicorn main:app --host 0.0.0.0 --port ROUTER_PORT_PLACEHOLDER --log-level ${LOG_LEVEL:-warning} command: - /bin/sh - -c @@ -93,7 +109,7 @@ spec: - name: LITELLM_CONFIG_PATH value: /config/litellm_dir/config.yaml - name: DATABASE_URL - value: postgresql://postgres:POSTGRES_PASSWORD_ENCODED_PLACEHOLDER@127.0.0.1:5432/postgres + value: postgresql://postgres:POSTGRES_PASSWORD_ENCODED_PLACEHOLDER@127.0.0.1:POSTGRES_PORT_PLACEHOLDER/postgres - name: DBUS_SESSION_BUS_ADDRESS value: unix:path=RUN_USER_PLACEHOLDER/bus - name: LITELLM_MASTER_KEY @@ -103,22 +119,26 @@ spec: - name: LANGFUSE_SECRET_KEY value: LANGFUSE_SECRET_KEY_PLACEHOLDER - name: LANGFUSE_HOST - value: http://127.0.0.1:3001 + value: http://127.0.0.1:LANGFUSE_WEB_PORT_PLACEHOLDER - name: OLLAMA_API_KEY value: OLLAMA_API_KEY_PLACEHOLDER - name: PUBLIC_BASE_URL value: PUBLIC_BASE_URL_PLACEHOLDER - name: ROUTING_DOMAIN value: ROUTING_DOMAIN_PLACEHOLDER + - name: LITELLM_PORT + value: 'LITELLM_PORT_PLACEHOLDER' + - name: VALKEY_CACHE_PORT + value: 'VALKEY_CACHE_PORT_PLACEHOLDER' - name: LOG_LEVEL value: info - image: localhost/llm-triage-router:latest + image: ROUTER_IMAGE_PLACEHOLDER livenessProbe: exec: command: - python3 - -c - - import urllib.request; urllib.request.urlopen('http://localhost:5000/metrics') + - import urllib.request; urllib.request.urlopen('http://localhost:ROUTER_PORT_PLACEHOLDER/metrics') initialDelaySeconds: 20 periodSeconds: 15 timeoutSeconds: 5 @@ -128,7 +148,7 @@ spec: command: - python3 - -c - - import urllib.request; urllib.request.urlopen('http://localhost:5000/metrics') + - import urllib.request; urllib.request.urlopen('http://localhost:ROUTER_PORT_PLACEHOLDER/metrics') initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 5 @@ -136,7 +156,7 @@ spec: - mountPath: /config/router_dir name: router-config - mountPath: /config/litellm_dir - name: litellm-config + name: litellm-rendered - mountPath: /app/data name: dataset-data - mountPath: /config/gemini_auth @@ -167,6 +187,8 @@ spec: value: langfuse - name: PGDATA value: /var/lib/postgresql/data/pg18 + - name: PGPORT + value: 'POSTGRES_PORT_PLACEHOLDER' image: docker.io/pgvector/pgvector:0.8.3-pg18 livenessProbe: exec: @@ -174,6 +196,8 @@ spec: - pg_isready - -U - postgres + - -p + - 'POSTGRES_PORT_PLACEHOLDER' initialDelaySeconds: 15 periodSeconds: 10 timeoutSeconds: 5 @@ -184,6 +208,8 @@ spec: - pg_isready - -U - postgres + - -p + - 'POSTGRES_PORT_PLACEHOLDER' initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 5 @@ -203,6 +229,10 @@ spec: exec: command: - clickhouse-client + - --host + - 127.0.0.1 + - --port + - 'CLICKHOUSE_TCP_PORT_PLACEHOLDER' - --user - clickhouse - --password @@ -217,6 +247,10 @@ spec: exec: command: - clickhouse-client + - --host + - 127.0.0.1 + - --port + - 'CLICKHOUSE_TCP_PORT_PLACEHOLDER' - --user - clickhouse - --password @@ -230,23 +264,32 @@ spec: volumeMounts: - mountPath: /var/lib/clickhouse name: clickhouse-storage + - mountPath: /etc/clickhouse-server/config.d/port-override.xml + name: clickhouse-port-config + subPath: port-override.xml # Valkey LF โ Langfuse v3 BullMQ job queue - command: - redis-server - --bind - 127.0.0.1 - --port - - '6380' + - 'VALKEY_LF_PORT_PLACEHOLDER' - --requirepass - REDIS_AUTH_PLACEHOLDER - --maxmemory-policy - noeviction - --loglevel - warning - image: docker.io/valkey/valkey:9.1.0-alpine + image: docker.io/valkey/valkey:9.1.0 livenessProbe: - tcpSocket: - port: 6380 + exec: + command: + - valkey-cli + - -p + - "VALKEY_LF_PORT_PLACEHOLDER" + - -a + - REDIS_AUTH_PLACEHOLDER + - ping initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 2 @@ -256,7 +299,7 @@ spec: command: - valkey-cli - -p - - "6380" + - "VALKEY_LF_PORT_PLACEHOLDER" - -a - REDIS_AUTH_PLACEHOLDER - ping @@ -269,11 +312,11 @@ spec: # Langfuse Web โ observability dashboard - env: - name: DATABASE_URL - value: postgresql://postgres:POSTGRES_PASSWORD_ENCODED_PLACEHOLDER@127.0.0.1:5432/langfuse + value: postgresql://postgres:POSTGRES_PASSWORD_ENCODED_PLACEHOLDER@127.0.0.1:POSTGRES_PORT_PLACEHOLDER/langfuse - name: NEXTAUTH_SECRET value: NEXTAUTH_SECRET_PLACEHOLDER - name: NEXTAUTH_URL - value: NEXTAUTH_URL_PLACEHOLDER + value: http://localhost:LANGFUSE_WEB_PORT_PLACEHOLDER - name: SALT value: SALT_PLACEHOLDER - name: ENCRYPTION_KEY @@ -281,7 +324,7 @@ spec: - name: HOSTNAME value: 0.0.0.0 - name: PORT - value: '3001' + value: 'LANGFUSE_WEB_PORT_PLACEHOLDER' - name: TELEMETRY_ENABLED value: 'false' - name: LANGFUSE_S3_EVENT_UPLOAD_BUCKET @@ -293,13 +336,13 @@ spec: - name: LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY value: MINIO_PASSWORD_PLACEHOLDER - name: LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT - value: http://127.0.0.1:9002 + value: http://127.0.0.1:MINIO_S3_PORT_PLACEHOLDER - name: S3_FORCE_PATH_STYLE value: 'true' - name: CLICKHOUSE_URL - value: http://127.0.0.1:8123 + value: http://127.0.0.1:CLICKHOUSE_HTTP_PORT_PLACEHOLDER - name: CLICKHOUSE_MIGRATION_URL - value: clickhouse://127.0.0.1:9000 + value: clickhouse://127.0.0.1:CLICKHOUSE_TCP_PORT_PLACEHOLDER - name: CLICKHOUSE_USER value: clickhouse - name: CLICKHOUSE_PASSWORD @@ -309,7 +352,7 @@ spec: - name: REDIS_HOST value: 127.0.0.1 - name: REDIS_PORT - value: '6380' + value: 'VALKEY_LF_PORT_PLACEHOLDER' - name: REDIS_AUTH value: REDIS_AUTH_PLACEHOLDER - name: LANGFUSE_INIT_ORG_ID @@ -334,7 +377,7 @@ spec: - -q - -O - /dev/null - - http://127.0.0.1:3001/api/health + - http://127.0.0.1:LANGFUSE_WEB_PORT_PLACEHOLDER/api/health initialDelaySeconds: 240 periodSeconds: 15 timeoutSeconds: 5 @@ -346,16 +389,16 @@ spec: - -q - -O - /dev/null - - http://127.0.0.1:3001/api/health + - http://127.0.0.1:LANGFUSE_WEB_PORT_PLACEHOLDER/api/health initialDelaySeconds: 15 periodSeconds: 10 timeoutSeconds: 5 # Langfuse Worker โ background job processor - env: - name: DATABASE_URL - value: postgresql://postgres:POSTGRES_PASSWORD_ENCODED_PLACEHOLDER@127.0.0.1:5432/langfuse + value: postgresql://postgres:POSTGRES_PASSWORD_ENCODED_PLACEHOLDER@127.0.0.1:POSTGRES_PORT_PLACEHOLDER/langfuse - name: CLICKHOUSE_URL - value: http://127.0.0.1:8123 + value: http://127.0.0.1:CLICKHOUSE_HTTP_PORT_PLACEHOLDER - name: CLICKHOUSE_USER value: clickhouse - name: CLICKHOUSE_PASSWORD @@ -365,13 +408,13 @@ spec: - name: REDIS_HOST value: 127.0.0.1 - name: REDIS_PORT - value: '6380' + value: 'VALKEY_LF_PORT_PLACEHOLDER' - name: REDIS_AUTH value: REDIS_AUTH_PLACEHOLDER - name: HOSTNAME value: 0.0.0.0 - name: PORT - value: '3030' + value: 'LANGFUSE_WORKER_PORT_PLACEHOLDER' - name: TELEMETRY_ENABLED value: 'false' - name: LANGFUSE_S3_EVENT_UPLOAD_BUCKET @@ -383,7 +426,7 @@ spec: - name: S3_FORCE_PATH_STYLE value: 'true' - name: LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT - value: http://127.0.0.1:9002 + value: http://127.0.0.1:MINIO_S3_PORT_PLACEHOLDER - name: LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY value: MINIO_PASSWORD_PLACEHOLDER - name: LANGFUSE_LOG_LEVEL @@ -404,9 +447,9 @@ spec: - --quiet - /data - --address - - ":9002" + - ":MINIO_S3_PORT_PLACEHOLDER" - --console-address - - ":9001" + - ":MINIO_CONSOLE_PORT_PLACEHOLDER" env: - name: MINIO_ROOT_USER value: MINIO_USER_PLACEHOLDER @@ -416,7 +459,7 @@ spec: livenessProbe: httpGet: path: /minio/health/live - port: 9002 + port: MINIO_S3_PORT_PLACEHOLDER initialDelaySeconds: 10 periodSeconds: 15 timeoutSeconds: 5 @@ -424,7 +467,7 @@ spec: readinessProbe: httpGet: path: /minio/health/ready - port: 9002 + port: MINIO_S3_PORT_PLACEHOLDER initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 5 @@ -435,25 +478,27 @@ spec: restartPolicy: Always volumes: - hostPath: - path: WORKDIR_PLACEHOLDER/valkey-data + path: DATA_ROOT_PLACEHOLDER/valkey-data name: valkey-storage - hostPath: - path: WORKDIR_PLACEHOLDER/litellm - name: litellm-config + path: DATA_ROOT_PLACEHOLDER/litellm-rendered + type: DirectoryOrCreate + name: litellm-rendered - hostPath: - path: WORKDIR_PLACEHOLDER/router + path: DATA_ROOT_PLACEHOLDER/router-rendered + type: DirectoryOrCreate name: router-config - hostPath: - path: WORKDIR_PLACEHOLDER/postgres-data + path: DATA_ROOT_PLACEHOLDER/postgres-data name: postgres-storage - hostPath: - path: WORKDIR_PLACEHOLDER/clickhouse-data + path: DATA_ROOT_PLACEHOLDER/clickhouse-data name: clickhouse-storage - hostPath: - path: WORKDIR_PLACEHOLDER/redis-lf-data + path: DATA_ROOT_PLACEHOLDER/redis-lf-data name: redis-lf-storage - hostPath: - path: WORKDIR_PLACEHOLDER/minio-data + path: DATA_ROOT_PLACEHOLDER/minio-data name: minio-storage - hostPath: path: HOME_PLACEHOLDER/.gemini @@ -477,6 +522,10 @@ spec: path: WORKDIR_PLACEHOLDER name: env-file - hostPath: - path: WORKDIR_PLACEHOLDER/data + path: DATA_ROOT_PLACEHOLDER/datasets type: DirectoryOrCreate name: dataset-data + - hostPath: + path: DATA_ROOT_PLACEHOLDER/clickhouse-config + type: DirectoryOrCreate + name: clickhouse-port-config diff --git a/router/config.yaml b/router/config.yaml index 80b42939..a30ed2ad 100644 --- a/router/config.yaml +++ b/router/config.yaml @@ -34,26 +34,26 @@ classification_rules: # The api_key placeholder is resolved at runtime by main.py:788. backends: - name: "agent-simple-core" - api_base: "http://127.0.0.1:4000/v1" + api_base: "http://127.0.0.1:LITELLM_PORT_PLACEHOLDER/v1" api_key: "DYNAMIC_LITELLM_MASTER_KEY_PLACEHOLDER" - name: "agent-medium-core" - api_base: "http://127.0.0.1:4000/v1" + api_base: "http://127.0.0.1:LITELLM_PORT_PLACEHOLDER/v1" api_key: "DYNAMIC_LITELLM_MASTER_KEY_PLACEHOLDER" - name: "agent-complex-core" - api_base: "http://127.0.0.1:4000/v1" + api_base: "http://127.0.0.1:LITELLM_PORT_PLACEHOLDER/v1" api_key: "DYNAMIC_LITELLM_MASTER_KEY_PLACEHOLDER" - name: "agent-reasoning-core" - api_base: "http://127.0.0.1:4000/v1" + api_base: "http://127.0.0.1:LITELLM_PORT_PLACEHOLDER/v1" api_key: "DYNAMIC_LITELLM_MASTER_KEY_PLACEHOLDER" - name: "agent-advanced-core" - api_base: "http://127.0.0.1:4000/v1" + api_base: "http://127.0.0.1:LITELLM_PORT_PLACEHOLDER/v1" api_key: "DYNAMIC_LITELLM_MASTER_KEY_PLACEHOLDER" - name: "ollama-deepseek-v4-pro" - api_base: "http://127.0.0.1:4000/v1" + api_base: "http://127.0.0.1:LITELLM_PORT_PLACEHOLDER/v1" api_key: "DYNAMIC_LITELLM_MASTER_KEY_PLACEHOLDER" - name: "ollama-deepseek-v4-flash" - api_base: "http://127.0.0.1:4000/v1" + api_base: "http://127.0.0.1:LITELLM_PORT_PLACEHOLDER/v1" api_key: "DYNAMIC_LITELLM_MASTER_KEY_PLACEHOLDER" - name: "openrouter-auto" - api_base: "http://127.0.0.1:4000/v1" + api_base: "http://127.0.0.1:LITELLM_PORT_PLACEHOLDER/v1" api_key: "DYNAMIC_LITELLM_MASTER_KEY_PLACEHOLDER" diff --git a/router/main.py b/router/main.py index 7b8df8d9..6ca2e7c3 100644 --- a/router/main.py +++ b/router/main.py @@ -23,9 +23,9 @@ from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator, RootModel from typing import Dict, Optional, Union -LITELLM_URL = (os.getenv("LITELLM_ADMIN_URL") or "http://127.0.0.1:4000").rstrip("/") +LITELLM_URL = (os.getenv("LITELLM_ADMIN_URL") or f"http://127.0.0.1:{os.getenv('LITELLM_PORT', '4000')}").rstrip("/") LLAMA_SERVER_URL = (os.getenv("LLAMA_SERVER_URL") or "http://127.0.0.1:8080").rstrip("/") -LANGFUSE_HOST = (os.getenv("LANGFUSE_HOST") or "http://127.0.0.1:3001").rstrip("/") +LANGFUSE_HOST = (os.getenv("LANGFUSE_HOST") or f"http://127.0.0.1:{os.getenv('LANGFUSE_WEB_PORT', '3001')}").rstrip("/") GEMINI_OAUTH_CREDS_PATH = "/config/gemini_auth/oauth_creds.json" @@ -41,6 +41,10 @@ _redis_last_init_attempt = 0.0 _REDIS_RETRY_INTERVAL_SECONDS = 5.0 +def _valkey_port() -> str: + """Resolve the Valkey cache port from env, preferring VALKEY_CACHE_PORT.""" + return os.getenv("VALKEY_CACHE_PORT") or os.getenv("VALKEY_PORT", "6379") + def get_redis(): """Lazily initialize and return the async Redis/Valkey client. Returns None if connection fails or is disabled (non-fatal fallback).""" @@ -57,7 +61,7 @@ def get_redis(): logger.info("Valkey client initialized from URL") else: host = os.getenv("VALKEY_HOST", "127.0.0.1") - port = int(os.getenv("VALKEY_PORT", "6379")) + port = int(_valkey_port()) _redis_client = aioredis.Redis(host=host, port=port, decode_responses=True, socket_timeout=1.0) logger.info(f"Valkey client initialized at {host}:{port}") except Exception as e: @@ -1590,7 +1594,7 @@ def get_pie_chart_gradient() -> str: @app.api_route("/v1/memory{path:path}", methods=["GET", "POST", "DELETE", "PUT"]) async def proxy_memory(request: Request, path: str = ""): """Proxies memory API calls to the LiteLLM gateway on port 4000.""" - litellm_base = "http://127.0.0.1:4000/v1/memory" + litellm_base = f"http://127.0.0.1:{os.getenv('LITELLM_PORT', '4000')}/v1/memory" # Resolve the destination URL url = f"{litellm_base}{path}" @@ -2666,10 +2670,10 @@ async def get_dashboard_data(): llamacpp, ) = await asyncio.gather( asyncio.wait_for(sync_cooldowns_from_valkey(), timeout=2.0), - check_tcp_port("127.0.0.1", 6379), - check_http_endpoint("http://127.0.0.1:4000/"), + check_tcp_port("127.0.0.1", int(_valkey_port())), + check_http_endpoint(f"http://127.0.0.1:{os.getenv('LITELLM_PORT', '4000')}/"), check_http_endpoint("http://127.0.0.1:8080/health"), - check_http_endpoint("http://127.0.0.1:3001"), + check_http_endpoint(f"http://127.0.0.1:{os.getenv('LANGFUSE_WEB_PORT', '3001')}"), get_gemini_oauth_status(), asyncio.wait_for(get_best_free_model(), timeout=5.0), asyncio.to_thread(get_goose_sessions), @@ -3867,7 +3871,7 @@ async def get_dashboard(request: Request):