diff --git a/.circleci/config.yml b/.circleci/config.yml index e4d6af8f0e2..2b3aecc6b24 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,6 +3,14 @@ orbs: codecov: codecov/codecov@4.0.1 node: circleci/node@5.1.0 # Add this line to declare the node orb +commands: + setup_google_dns: + steps: + - run: + name: "Configure Google DNS" + command: | + echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf + echo "nameserver 8.8.4.4" | sudo tee -a /etc/resolv.conf jobs: local_testing: @@ -15,7 +23,7 @@ jobs: steps: - checkout - + - setup_google_dns - run: name: Show git commit hash command: | @@ -134,7 +142,7 @@ jobs: steps: - checkout - + - setup_google_dns - run: name: Show git commit hash command: | @@ -234,7 +242,7 @@ jobs: steps: - checkout - + - setup_google_dns - run: name: Show git commit hash command: | @@ -334,6 +342,7 @@ jobs: steps: - checkout + - setup_google_dns - run: name: Install Dependencies command: | @@ -388,6 +397,7 @@ jobs: steps: - checkout + - setup_google_dns - run: name: Install Dependencies command: | @@ -429,6 +439,7 @@ jobs: working_directory: ~/project steps: - checkout + - setup_google_dns - run: name: Show git commit hash command: | @@ -479,7 +490,7 @@ jobs: working_directory: ~/project steps: - checkout - + - setup_google_dns - run: name: Show git commit hash command: | @@ -569,7 +580,7 @@ jobs: - litellm_proxy_unit_tests_coverage litellm_assistants_api_testing: # Runs all tests with the "assistants" keyword docker: - - image: cimg/python:3.11 + - image: cimg/python:3.13.1 auth: username: ${DOCKERHUB_USERNAME} password: ${DOCKERHUB_PASSWORD} @@ -577,6 +588,7 @@ jobs: steps: - checkout + - setup_google_dns - run: name: Install Dependencies command: | @@ -618,6 +630,7 @@ jobs: steps: - checkout + - setup_google_dns - run: name: Install Dependencies command: | @@ -654,6 +667,7 @@ jobs: steps: - checkout + - setup_google_dns - run: name: Install Dependencies command: | @@ -734,6 +748,7 @@ jobs: steps: - checkout + - setup_google_dns - run: name: Install Dependencies command: | @@ -778,6 +793,7 @@ jobs: steps: - checkout + - setup_google_dns - run: name: Install Dependencies command: | @@ -820,6 +836,7 @@ jobs: steps: - checkout + - setup_google_dns - run: name: Install Dependencies command: | @@ -866,6 +883,7 @@ jobs: steps: - checkout + - setup_google_dns - run: name: Install Dependencies command: | @@ -910,6 +928,7 @@ jobs: steps: - checkout + - setup_google_dns - run: name: Install Dependencies command: | @@ -956,6 +975,7 @@ jobs: steps: - checkout + - setup_google_dns - run: name: Install Dependencies command: | @@ -998,6 +1018,7 @@ jobs: steps: - checkout + - setup_google_dns - run: name: Install Dependencies command: | @@ -1040,6 +1061,7 @@ jobs: steps: - checkout + - setup_google_dns - run: name: Install Dependencies command: | @@ -1086,6 +1108,7 @@ jobs: steps: - checkout + - setup_google_dns - run: name: Install Dependencies command: | @@ -1118,6 +1141,7 @@ jobs: steps: - checkout + - setup_google_dns - run: name: Install Dependencies command: | @@ -1142,6 +1166,7 @@ jobs: steps: - checkout + - setup_google_dns # Install Helm - run: name: Install Helm @@ -1211,6 +1236,7 @@ jobs: steps: - checkout + - setup_google_dns - run: name: Install Dependencies command: | @@ -1247,6 +1273,7 @@ jobs: working_directory: ~/project steps: - checkout + - setup_google_dns - run: name: Install Python 3.9 command: | @@ -1321,6 +1348,7 @@ jobs: working_directory: ~/project steps: - checkout + - setup_google_dns - run: name: Install Docker CLI (In case it's not already installed) command: | @@ -1456,6 +1484,7 @@ jobs: working_directory: ~/project steps: - checkout + - setup_google_dns - run: name: Install Docker CLI (In case it's not already installed) command: | @@ -1580,6 +1609,7 @@ jobs: working_directory: ~/project steps: - checkout + - setup_google_dns - run: name: Install Docker CLI (In case it's not already installed) command: | @@ -1742,6 +1772,7 @@ jobs: working_directory: ~/project steps: - checkout + - setup_google_dns - run: name: Install Docker CLI (In case it's not already installed) command: | @@ -1853,6 +1884,7 @@ jobs: working_directory: ~/project steps: - checkout + - setup_google_dns - run: name: Install Docker CLI (In case it's not already installed) command: | @@ -1935,6 +1967,7 @@ jobs: working_directory: ~/project steps: - checkout + - setup_google_dns # Remove Docker CLI installation since it's already available in machine executor - run: name: Install Python 3.13 @@ -2032,6 +2065,7 @@ jobs: working_directory: ~/project steps: - checkout + - setup_google_dns - run: name: Install Docker CLI (In case it's not already installed) command: | @@ -2291,6 +2325,7 @@ jobs: working_directory: ~/project steps: - checkout + - setup_google_dns - run: name: Build UI command: | @@ -2405,6 +2440,7 @@ jobs: working_directory: ~/project steps: - checkout + - setup_google_dns - run: name: Build Docker image command: | @@ -2427,6 +2463,7 @@ jobs: working_directory: ~/project steps: - checkout + - setup_google_dns - run: name: Build Docker image command: | diff --git a/.github/workflows/publish-migrations.yml b/.github/workflows/publish-migrations.yml new file mode 100644 index 00000000000..8e5a67bcf85 --- /dev/null +++ b/.github/workflows/publish-migrations.yml @@ -0,0 +1,206 @@ +name: Publish Prisma Migrations + +permissions: + contents: write + pull-requests: write + +on: + push: + paths: + - 'schema.prisma' # Check root schema.prisma + branches: + - main + +jobs: + publish-migrations: + runs-on: ubuntu-latest + services: + postgres: + image: postgres:14 + env: + POSTGRES_DB: temp_db + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + ports: + - 5432:5432 + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + # Add shadow database service + postgres_shadow: + image: postgres:14 + env: + POSTGRES_DB: shadow_db + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + ports: + - 5433:5432 + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.x' + + - name: Install Dependencies + run: | + pip install prisma + pip install python-dotenv + + - name: Generate Initial Migration if None Exists + env: + DATABASE_URL: "postgresql://postgres:postgres@localhost:5432/temp_db" + DIRECT_URL: "postgresql://postgres:postgres@localhost:5432/temp_db" + SHADOW_DATABASE_URL: "postgresql://postgres:postgres@localhost:5433/shadow_db" + run: | + mkdir -p deploy/migrations + echo 'provider = "postgresql"' > deploy/migrations/migration_lock.toml + + if [ -z "$(ls -A deploy/migrations/2* 2>/dev/null)" ]; then + echo "No existing migrations found, creating baseline..." + VERSION=$(date +%Y%m%d%H%M%S) + mkdir -p deploy/migrations/${VERSION}_initial + + echo "Generating initial migration..." + # Save raw output for debugging + prisma migrate diff \ + --from-empty \ + --to-schema-datamodel schema.prisma \ + --shadow-database-url "${SHADOW_DATABASE_URL}" \ + --script > deploy/migrations/${VERSION}_initial/raw_migration.sql + + echo "Raw migration file content:" + cat deploy/migrations/${VERSION}_initial/raw_migration.sql + + echo "Cleaning migration file..." + # Clean the file + sed '/^Installing/d' deploy/migrations/${VERSION}_initial/raw_migration.sql > deploy/migrations/${VERSION}_initial/migration.sql + + # Verify the migration file + if [ ! -s deploy/migrations/${VERSION}_initial/migration.sql ]; then + echo "ERROR: Migration file is empty after cleaning" + echo "Original content was:" + cat deploy/migrations/${VERSION}_initial/raw_migration.sql + exit 1 + fi + + echo "Final migration file content:" + cat deploy/migrations/${VERSION}_initial/migration.sql + + # Verify it starts with SQL + if ! head -n 1 deploy/migrations/${VERSION}_initial/migration.sql | grep -q "^--\|^CREATE\|^ALTER"; then + echo "ERROR: Migration file does not start with SQL command or comment" + echo "First line is:" + head -n 1 deploy/migrations/${VERSION}_initial/migration.sql + echo "Full content is:" + cat deploy/migrations/${VERSION}_initial/migration.sql + exit 1 + fi + + echo "Initial migration generated at $(date -u)" > deploy/migrations/${VERSION}_initial/README.md + fi + + - name: Compare and Generate Migration + if: success() + env: + DATABASE_URL: "postgresql://postgres:postgres@localhost:5432/temp_db" + DIRECT_URL: "postgresql://postgres:postgres@localhost:5432/temp_db" + SHADOW_DATABASE_URL: "postgresql://postgres:postgres@localhost:5433/shadow_db" + run: | + # Create temporary migration workspace + mkdir -p temp_migrations + + # Copy existing migrations (will not fail if directory is empty) + cp -r deploy/migrations/* temp_migrations/ 2>/dev/null || true + + VERSION=$(date +%Y%m%d%H%M%S) + + # Generate diff against existing migrations or empty state + prisma migrate diff \ + --from-migrations temp_migrations \ + --to-schema-datamodel schema.prisma \ + --shadow-database-url "${SHADOW_DATABASE_URL}" \ + --script > temp_migrations/migration_${VERSION}.sql + + # Check if there are actual changes + if [ -s temp_migrations/migration_${VERSION}.sql ]; then + echo "Changes detected, creating new migration" + mkdir -p deploy/migrations/${VERSION}_schema_update + mv temp_migrations/migration_${VERSION}.sql deploy/migrations/${VERSION}_schema_update/migration.sql + echo "Migration generated at $(date -u)" > deploy/migrations/${VERSION}_schema_update/README.md + else + echo "No schema changes detected" + exit 0 + fi + + - name: Verify Migration + if: success() + env: + DATABASE_URL: "postgresql://postgres:postgres@localhost:5432/temp_db" + DIRECT_URL: "postgresql://postgres:postgres@localhost:5432/temp_db" + SHADOW_DATABASE_URL: "postgresql://postgres:postgres@localhost:5433/shadow_db" + run: | + # Create test database + psql "${SHADOW_DATABASE_URL}" -c 'CREATE DATABASE migration_test;' + + # Apply all migrations in order to verify + for migration in deploy/migrations/*/migration.sql; do + echo "Applying migration: $migration" + psql "${SHADOW_DATABASE_URL}" -f $migration + done + + # Add this step before create-pull-request to debug permissions + - name: Check Token Permissions + run: | + echo "Checking token permissions..." + curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + -H "Accept: application/vnd.github.v3+json" \ + https://api.github.com/repos/BerriAI/litellm/collaborators + + echo "\nChecking if token can create PRs..." + curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + -H "Accept: application/vnd.github.v3+json" \ + https://api.github.com/repos/BerriAI/litellm + + # Add this debug step before git push + - name: Debug Changed Files + run: | + echo "Files staged for commit:" + git diff --name-status --staged + + echo "\nAll changed files:" + git status + + - name: Create Pull Request + if: success() + uses: peter-evans/create-pull-request@v5 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "chore: update prisma migrations" + title: "Update Prisma Migrations" + body: | + Auto-generated migration based on schema.prisma changes. + + Generated files: + - deploy/migrations/${VERSION}_schema_update/migration.sql + - deploy/migrations/${VERSION}_schema_update/README.md + branch: feat/prisma-migration-${{ env.VERSION }} + base: main + delete-branch: true + + - name: Generate and Save Migrations + run: | + # Only add migration files + git add deploy/migrations/ + git status # Debug what's being committed + git commit -m "chore: update prisma migrations" diff --git a/docs/my-website/docs/proxy/admin_ui_sso.md b/docs/my-website/docs/proxy/admin_ui_sso.md index b7f8ddd585e..882e3df0b22 100644 --- a/docs/my-website/docs/proxy/admin_ui_sso.md +++ b/docs/my-website/docs/proxy/admin_ui_sso.md @@ -147,6 +147,11 @@ Some SSO providers require a specific redirect url for login and logout. You can - Login: `/sso/key/generate` - Logout: `` +Here's the env var to set the logout url on the proxy +```bash +PROXY_LOGOUT_URL="https://www.google.com" +``` + #### Step 3. Set `PROXY_BASE_URL` in your .env Set this in your .env (so the proxy can set the correct redirect url) diff --git a/docs/my-website/docs/proxy/config_settings.md b/docs/my-website/docs/proxy/config_settings.md index 0e85223d455..0093464d93f 100644 --- a/docs/my-website/docs/proxy/config_settings.md +++ b/docs/my-website/docs/proxy/config_settings.md @@ -479,7 +479,7 @@ router_settings: | PROXY_ADMIN_ID | Admin identifier for proxy server | PROXY_BASE_URL | Base URL for proxy service | PROXY_LOGOUT_URL | URL for logging out of the proxy service -| PROXY_MASTER_KEY | Master key for proxy authentication +| LITELLM_MASTER_KEY | Master key for proxy authentication | QDRANT_API_BASE | Base URL for Qdrant API | QDRANT_API_KEY | API key for Qdrant service | QDRANT_URL | Connection URL for Qdrant database diff --git a/litellm/__init__.py b/litellm/__init__.py index d2b51696640..a59484b0351 100644 --- a/litellm/__init__.py +++ b/litellm/__init__.py @@ -2,7 +2,7 @@ import warnings warnings.filterwarnings("ignore", message=".*conflict with protected namespace.*") -### INIT VARIABLES ########## +### INIT VARIABLES ########### import threading import os from typing import Callable, List, Optional, Dict, Union, Any, Literal, get_args diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index 3124ae26975..f9eb63ccca5 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -4595,6 +4595,28 @@ "source": "https://cloud.google.com/vertex-ai/generative-ai/docs/learn/models#gemini-2.0-flash", "supports_tool_choice": true }, + "gemini-2.0-flash-lite": { + "max_input_tokens": 1048576, + "max_output_tokens": 8192, + "max_images_per_prompt": 3000, + "max_videos_per_prompt": 10, + "max_video_length": 1, + "max_audio_length_hours": 8.4, + "max_audio_per_prompt": 1, + "max_pdf_size_mb": 50, + "input_cost_per_audio_token": 0.000000075, + "input_cost_per_token": 0.000000075, + "output_cost_per_token": 0.0000003, + "litellm_provider": "vertex_ai-language-models", + "mode": "chat", + "supports_system_messages": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_response_schema": true, + "supports_audio_output": true, + "source": "https://cloud.google.com/vertex-ai/generative-ai/docs/learn/models#gemini-2.0-flash", + "supports_tool_choice": true + }, "gemini/gemini-2.0-pro-exp-02-05": { "max_tokens": 8192, "max_input_tokens": 2097152, @@ -4658,6 +4680,28 @@ "supports_tool_choice": true, "source": "https://ai.google.dev/pricing#2_0flash" }, + "gemini/gemini-2.0-flash-lite": { + "max_input_tokens": 1048576, + "max_output_tokens": 8192, + "max_images_per_prompt": 3000, + "max_videos_per_prompt": 10, + "max_video_length": 1, + "max_audio_length_hours": 8.4, + "max_audio_per_prompt": 1, + "max_pdf_size_mb": 50, + "input_cost_per_audio_token": 0.000000075, + "input_cost_per_token": 0.000000075, + "output_cost_per_token": 0.0000003, + "litellm_provider": "gemini", + "mode": "chat", + "supports_system_messages": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_response_schema": true, + "supports_audio_output": true, + "supports_tool_choice": true, + "source": "https://ai.google.dev/gemini-api/docs/pricing#gemini-2.0-flash-lite" + }, "gemini/gemini-2.0-flash-001": { "max_tokens": 8192, "max_input_tokens": 1048576, diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 3124ae26975..f9eb63ccca5 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -4595,6 +4595,28 @@ "source": "https://cloud.google.com/vertex-ai/generative-ai/docs/learn/models#gemini-2.0-flash", "supports_tool_choice": true }, + "gemini-2.0-flash-lite": { + "max_input_tokens": 1048576, + "max_output_tokens": 8192, + "max_images_per_prompt": 3000, + "max_videos_per_prompt": 10, + "max_video_length": 1, + "max_audio_length_hours": 8.4, + "max_audio_per_prompt": 1, + "max_pdf_size_mb": 50, + "input_cost_per_audio_token": 0.000000075, + "input_cost_per_token": 0.000000075, + "output_cost_per_token": 0.0000003, + "litellm_provider": "vertex_ai-language-models", + "mode": "chat", + "supports_system_messages": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_response_schema": true, + "supports_audio_output": true, + "source": "https://cloud.google.com/vertex-ai/generative-ai/docs/learn/models#gemini-2.0-flash", + "supports_tool_choice": true + }, "gemini/gemini-2.0-pro-exp-02-05": { "max_tokens": 8192, "max_input_tokens": 2097152, @@ -4658,6 +4680,28 @@ "supports_tool_choice": true, "source": "https://ai.google.dev/pricing#2_0flash" }, + "gemini/gemini-2.0-flash-lite": { + "max_input_tokens": 1048576, + "max_output_tokens": 8192, + "max_images_per_prompt": 3000, + "max_videos_per_prompt": 10, + "max_video_length": 1, + "max_audio_length_hours": 8.4, + "max_audio_per_prompt": 1, + "max_pdf_size_mb": 50, + "input_cost_per_audio_token": 0.000000075, + "input_cost_per_token": 0.000000075, + "output_cost_per_token": 0.0000003, + "litellm_provider": "gemini", + "mode": "chat", + "supports_system_messages": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_response_schema": true, + "supports_audio_output": true, + "supports_tool_choice": true, + "source": "https://ai.google.dev/gemini-api/docs/pricing#gemini-2.0-flash-lite" + }, "gemini/gemini-2.0-flash-001": { "max_tokens": 8192, "max_input_tokens": 1048576, diff --git a/tests/local_testing/test_assistants.py b/tests/local_testing/test_assistants.py index 273972e9dd0..544523e4a02 100644 --- a/tests/local_testing/test_assistants.py +++ b/tests/local_testing/test_assistants.py @@ -67,6 +67,7 @@ async def test_get_assistants(provider, sync_mode): @pytest.mark.asyncio() @pytest.mark.flaky(retries=3, delay=1) async def test_create_delete_assistants(provider, sync_mode): + litellm.ssl_verify = False model = "gpt-4-turbo" if provider == "azure": os.environ["AZURE_API_VERSION"] = "2024-05-01-preview"