From 314780d59afab59fedda85f8f32083e9ce9c8d7f Mon Sep 17 00:00:00 2001 From: roberto Date: Tue, 3 Mar 2026 16:52:56 +0100 Subject: [PATCH] Add LLM configuration options and update deployment workflow - Introduced new API keys for Anthropic and Google in .env.example and settings.py - Updated llm.py to retrieve API keys directly from settings - Modified deploy.yaml to streamline code checkout and improve deployment process --- .env.example | 32 ++++++++++++++++++++++++-------- .gitea/workflows/deploy.yaml | 25 ++++++++++++++++++------- app/config/settings.py | 2 ++ app/core/llm.py | 4 ++-- 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/.env.example b/.env.example index af9d852..fd3b5f9 100644 --- a/.env.example +++ b/.env.example @@ -10,18 +10,34 @@ JWT_ALGORITHM=HS256 JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30 JWT_REFRESH_TOKEN_EXPIRE_DAYS=30 -# ── OpenAI ──────────────────────────────────────────────────────────────────── -OPENAI_API_KEY=sk-... +# ── LLM ─────────────────────────────────────────────────────────────────────── +# LiteLLM model identifiers — change to swap providers without code changes. +# Examples: gpt-4o, anthropic/claude-sonnet-4-20250514, gemini/gemini-pro, ollama/llama3 +OPENAI_API_KEY= +ANTHROPIC_API_KEY= +GOOGLE_API_KEY= +LLM_MODEL=gpt-4o +LLM_ROUTER_MODEL=gpt-4o-mini -# ── Stripe ──────────────────────────────────────────────────────────────────── -STRIPE_SECRET_KEY=sk_test_... -STRIPE_WEBHOOK_SECRET=whsec_... +# ── Stripe (leave empty to stub billing) ────────────────────────────────────── +STRIPE_SECRET_KEY= +STRIPE_WEBHOOK_SECRET= # ── AWS / S3 ────────────────────────────────────────────────────────────────── -S3_BUCKET=adiuva-backups +S3_BUCKET=adiuva S3_REGION=us-east-1 -AWS_ACCESS_KEY_ID=AKIA... -AWS_SECRET_ACCESS_KEY=... +S3_ENDPOINT_URL= +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +# For MinIO (homelab): S3_ENDPOINT_URL=http://minio:9000 + +# ── Vector Store ────────────────────────────────────────────────────────────── +# Pinecone is used when PINECONE_API_KEY is set; otherwise falls back to Qdrant. +PINECONE_API_KEY= +PINECONE_INDEX=adiuva +QDRANT_URL= +QDRANT_API_KEY= +# For local Qdrant (homelab): QDRANT_URL=http://qdrant:6333 # ── CORS ────────────────────────────────────────────────────────────────────── # Comma-separated list parsed by Settings (override default if needed) diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml index 4662532..ac64f1c 100644 --- a/.gitea/workflows/deploy.yaml +++ b/.gitea/workflows/deploy.yaml @@ -3,10 +3,8 @@ run-name: ${{ gitea.ref_name }} → Docker LXC on: push: - branches: [main] - tags: ['v*'] - pull_request: - branches: [main] + tags: + - 'v*' jobs: # ── 1. Run tests in an isolated Python container ────────────────── @@ -16,8 +14,15 @@ jobs: image: python:3.12-slim steps: + - name: Install git + run: apt-get update && apt-get install -y --no-install-recommends git + - name: Checkout Code - uses: actions/checkout@v4 + run: | + git clone --depth 1 --branch "${GITHUB_REF_NAME}" \ + "http://10.0.0.119:3000/${GITHUB_REPOSITORY}.git" . || \ + git clone --depth 1 "http://10.0.0.119:3000/${GITHUB_REPOSITORY}.git" . && \ + git checkout "${GITHUB_SHA}" - name: Install Dependencies run: pip install --no-cache-dir -r requirements.txt @@ -36,15 +41,21 @@ jobs: steps: - name: Checkout Code - uses: actions/checkout@v4 + run: | + cd /tmp + rm -rf adiuva-api-deploy + git clone --depth 1 "http://10.0.0.119:3000/${GITHUB_REPOSITORY}.git" adiuva-api-deploy || \ + git clone --depth 1 "http://10.0.0.119:3000/${GITHUB_REPOSITORY}.git" adiuva-api-deploy + cd adiuva-api-deploy && git checkout "${GITHUB_SHA}" 2>/dev/null || true - name: Sync to deploy directory run: | DEPLOY_DIR="/opt/adiuva-api" + SRC="/tmp/adiuva-api-deploy" mkdir -p "$DEPLOY_DIR" # Sync source, preserve .env and volumes - cp -rf app/ alembic/ alembic.ini Dockerfile docker-compose.yml requirements.txt "$DEPLOY_DIR/" + cp -rf "$SRC/app/" "$SRC/alembic/" "$SRC/alembic.ini" "$SRC/Dockerfile" "$SRC/docker-compose.yml" "$SRC/requirements.txt" "$DEPLOY_DIR/" - name: Build & restart services run: | diff --git a/app/config/settings.py b/app/config/settings.py index dde8d13..b5e181b 100644 --- a/app/config/settings.py +++ b/app/config/settings.py @@ -24,6 +24,8 @@ class Settings(BaseSettings): QDRANT_API_KEY: str = "" OPENAI_API_KEY: str = "" + ANTHROPIC_API_KEY: str = "" + GOOGLE_API_KEY: str = "" LLM_MODEL: str = "gpt-4o" LLM_ROUTER_MODEL: str = "gpt-4o-mini" diff --git a/app/core/llm.py b/app/core/llm.py index 2787d00..c6a69ea 100644 --- a/app/core/llm.py +++ b/app/core/llm.py @@ -26,9 +26,9 @@ from app.config.settings import settings def _api_key_for_model(model: str) -> str | None: """Return the most appropriate API key for the given LiteLLM model string.""" if model.startswith("anthropic/"): - return getattr(settings, "ANTHROPIC_API_KEY", None) or None + return settings.ANTHROPIC_API_KEY or None if model.startswith("gemini/") or model.startswith("google/"): - return getattr(settings, "GOOGLE_API_KEY", None) or None + return settings.GOOGLE_API_KEY or None # Default: OpenAI-compatible (covers plain model names like "gpt-4o") return settings.OPENAI_API_KEY or None