diff --git a/.github/workflows/ghcr_carto_deploy.yaml b/.github/workflows/ghcr_carto_deploy.yaml new file mode 100644 index 000000000000..404bce14dfde --- /dev/null +++ b/.github/workflows/ghcr_carto_deploy.yaml @@ -0,0 +1,105 @@ +name: Deploy CartoDB Docker Image +on: + push: + branches: + - main + - dev + paths: + - "litellm/**" + - "docker/**" + - ".github/workflows/ghcr_carto_deploy.yaml" + pull_request: + branches: + - main + - dev + paths: + - "litellm/**" + - "docker/**" + - ".github/workflows/ghcr_carto_deploy.yaml" + + workflow_dispatch: + inputs: + ref: + description: "Branch or full commit SHA to build" + default: "main" + tag: + description: "Extra tag (e.g., v1.2.3). Leave blank for none." + required: true + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + DOCKER_GIT_REVISION_SHA: ${{ github.event.inputs.ref || github.sha }} + CHANNEL: ${{ github.ref_name || 'manual' }} + +jobs: + # print commit hash, tag, and release type + print: + runs-on: ubuntu-latest + steps: + - run: | + echo "Ref : ${{ github.event.inputs.ref || github.ref }}" + echo "Tag : ${{ github.event.inputs.tag }}" + echo "Channel : ${{ env.CHANNEL }}" + echo "DOCKER_GIT_REVISION_SHA: ${{ env.DOCKER_GIT_REVISION_SHA }}" + + build-and-push-image-non_root: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.ref || github.sha }} + + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Configure tags + id: tag-config + run: | + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + # For workflow_dispatch: only use the input tag (now required) + echo "tags=type=raw,value=${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT + else + # For push/pull_request: use channel-latest and just SHA + echo "tags=type=raw,value=${{ env.CHANNEL }}-latest" >> $GITHUB_OUTPUT + echo "tags<> $GITHUB_OUTPUT + echo "type=raw,value=${{ env.DOCKER_GIT_REVISION_SHA }}" >> $GITHUB_OUTPUT + if [ -n "${{ github.event.inputs.tag }}" ]; then + echo "type=raw,value=${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT + fi + echo "EOF" >> $GITHUB_OUTPUT + fi + + - name: Extract metadata for tags & labels + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-non_root + tags: | + ${{ steps.tag-config.outputs.tags }} + + # Configure multi platform Docker builds + - name: Set up QEMU + uses: docker/setup-qemu-action@e0e4588fad221d38ee467c0bffd91115366dc0c5 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@edfb0fe6204400c56fbfd3feba3fe9ad1adfa345 + + - name: Build and push non_root Docker image + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: . + file: ./docker/Dockerfile.non_root + push: true + cache-from: type=gha + cache-to: type=gha,mode=max + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + platforms: linux/amd64, #linux/arm64 diff --git a/.github/workflows/ghcr_deploy.yml b/.github/workflows/ghcr_deploy.yml deleted file mode 100644 index cc40d1ac0c04..000000000000 --- a/.github/workflows/ghcr_deploy.yml +++ /dev/null @@ -1,440 +0,0 @@ -# this workflow is triggered by an API call when there is a new PyPI release of LiteLLM -name: Build, Publish LiteLLM Docker Image. New Release -on: - workflow_dispatch: - inputs: - tag: - description: "The tag version you want to build" - release_type: - description: "The release type you want to build. Can be 'latest', 'stable', 'dev', 'rc'" - type: string - default: "latest" - commit_hash: - description: "Commit hash" - required: true - -# Defines two custom environment variables for the workflow. Used for the Container registry domain, and a name for the Docker image that this workflow builds. -env: - REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} - CHART_NAME: litellm-helm - -# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu. -jobs: - # print commit hash, tag, and release type - print: - runs-on: ubuntu-latest - steps: - - run: | - echo "Commit hash: ${{ github.event.inputs.commit_hash }}" - echo "Tag: ${{ github.event.inputs.tag }}" - echo "Release type: ${{ github.event.inputs.release_type }}" - docker-hub-deploy: - if: github.repository == 'BerriAI/litellm' - runs-on: ubuntu-latest - steps: - - - name: Checkout - uses: actions/checkout@v4 - with: - ref: ${{ github.event.inputs.commit_hash }} - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push - uses: docker/build-push-action@v5 - with: - context: . - push: true - tags: litellm/litellm:${{ github.event.inputs.tag || 'latest' }} - - - name: Build and push litellm-database image - uses: docker/build-push-action@v5 - with: - context: . - push: true - file: ./docker/Dockerfile.database - tags: litellm/litellm-database:${{ github.event.inputs.tag || 'latest' }} - - - name: Build and push litellm-spend-logs image - uses: docker/build-push-action@v5 - with: - context: . - push: true - file: ./litellm-js/spend-logs/Dockerfile - tags: litellm/litellm-spend_logs:${{ github.event.inputs.tag || 'latest' }} - - - name: Build and push litellm-non_root image - uses: docker/build-push-action@v5 - with: - context: . - push: true - file: ./docker/Dockerfile.non_root - tags: litellm/litellm-non_root:${{ github.event.inputs.tag || 'latest' }} - build-and-push-image: - runs-on: ubuntu-latest - # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. - permissions: - contents: read - packages: write - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - ref: ${{ github.event.inputs.commit_hash }} - # Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here. - - name: Log in to the Container registry - uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - # This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels. - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - # Configure multi platform Docker builds - - name: Set up QEMU - uses: docker/setup-qemu-action@e0e4588fad221d38ee467c0bffd91115366dc0c5 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@edfb0fe6204400c56fbfd3feba3fe9ad1adfa345 - # This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages. - # It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository. - # It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step. - - name: Build and push Docker image - uses: docker/build-push-action@4976231911ebf5f32aad765192d35f942aa48cb8 - with: - context: . - push: true - tags: | - ${{ steps.meta.outputs.tags }}-${{ github.event.inputs.tag || 'latest' }}, - ${{ steps.meta.outputs.tags }}-${{ github.event.inputs.release_type }} - ${{ (github.event.inputs.release_type == 'stable' || github.event.inputs.release_type == 'rc') && format('{0}/berriai/litellm:main-{1}', env.REGISTRY, github.event.inputs.tag) || '' }}, - ${{ github.event.inputs.release_type == 'stable' && format('{0}/berriai/litellm:main-stable', env.REGISTRY) || '' }}, - ${{ (github.event.inputs.release_type == 'stable' || github.event.inputs.release_type == 'rc') && format('{0}/berriai/litellm:{1}', env.REGISTRY, github.event.inputs.tag) || '' }}, - labels: ${{ steps.meta.outputs.labels }} - platforms: local,linux/amd64,linux/arm64,linux/arm64/v8 - - build-and-push-image-ee: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - ref: ${{ github.event.inputs.commit_hash }} - - - name: Log in to the Container registry - uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata (tags, labels) for EE Dockerfile - id: meta-ee - uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee - # Configure multi platform Docker builds - - name: Set up QEMU - uses: docker/setup-qemu-action@e0e4588fad221d38ee467c0bffd91115366dc0c5 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@edfb0fe6204400c56fbfd3feba3fe9ad1adfa345 - - - name: Build and push EE Docker image - uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 - with: - context: . - file: Dockerfile - push: true - tags: | - ${{ steps.meta-ee.outputs.tags }}-${{ github.event.inputs.tag || 'latest' }}, - ${{ steps.meta-ee.outputs.tags }}-${{ github.event.inputs.release_type }} - ${{ (github.event.inputs.release_type == 'stable' || github.event.inputs.release_type == 'rc') && format('{0}/berriai/litellm-ee:main-{1}', env.REGISTRY, github.event.inputs.tag) || '' }}, - ${{ github.event.inputs.release_type == 'stable' && format('{0}/berriai/litellm-ee:main-stable', env.REGISTRY) || '' }} - labels: ${{ steps.meta-ee.outputs.labels }} - platforms: local,linux/amd64,linux/arm64,linux/arm64/v8 - - build-and-push-image-database: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - ref: ${{ github.event.inputs.commit_hash }} - - - name: Log in to the Container registry - uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata (tags, labels) for database Dockerfile - id: meta-database - uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-database - # Configure multi platform Docker builds - - name: Set up QEMU - uses: docker/setup-qemu-action@e0e4588fad221d38ee467c0bffd91115366dc0c5 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@edfb0fe6204400c56fbfd3feba3fe9ad1adfa345 - - - name: Build and push Database Docker image - uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 - with: - context: . - file: ./docker/Dockerfile.database - push: true - tags: | - ${{ steps.meta-database.outputs.tags }}-${{ github.event.inputs.tag || 'latest' }}, - ${{ steps.meta-database.outputs.tags }}-${{ github.event.inputs.release_type }} - ${{ (github.event.inputs.release_type == 'stable' || github.event.inputs.release_type == 'rc') && format('{0}/berriai/litellm-database:main-{1}', env.REGISTRY, github.event.inputs.tag) || '' }}, - ${{ github.event.inputs.release_type == 'stable' && format('{0}/berriai/litellm-database:main-stable', env.REGISTRY) || '' }} - labels: ${{ steps.meta-database.outputs.labels }} - platforms: local,linux/amd64,linux/arm64,linux/arm64/v8 - - build-and-push-image-non_root: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - ref: ${{ github.event.inputs.commit_hash }} - - - name: Log in to the Container registry - uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata (tags, labels) for non_root Dockerfile - id: meta-non_root - uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-non_root - # Configure multi platform Docker builds - - name: Set up QEMU - uses: docker/setup-qemu-action@e0e4588fad221d38ee467c0bffd91115366dc0c5 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@edfb0fe6204400c56fbfd3feba3fe9ad1adfa345 - - - name: Build and push non_root Docker image - uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 - with: - context: . - file: ./docker/Dockerfile.non_root - push: true - tags: | - ${{ steps.meta-non_root.outputs.tags }}-${{ github.event.inputs.tag || 'latest' }}, - ${{ steps.meta-non_root.outputs.tags }}-${{ github.event.inputs.release_type }} - ${{ (github.event.inputs.release_type == 'stable' || github.event.inputs.release_type == 'rc') && format('{0}/berriai/litellm-non_root:main-{1}', env.REGISTRY, github.event.inputs.tag) || '' }}, - ${{ github.event.inputs.release_type == 'stable' && format('{0}/berriai/litellm-non_root:main-stable', env.REGISTRY) || '' }} - labels: ${{ steps.meta-non_root.outputs.labels }} - platforms: local,linux/amd64,linux/arm64,linux/arm64/v8 - - build-and-push-image-spend-logs: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - ref: ${{ github.event.inputs.commit_hash }} - - - name: Log in to the Container registry - uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata (tags, labels) for spend-logs Dockerfile - id: meta-spend-logs - uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-spend_logs - # Configure multi platform Docker builds - - name: Set up QEMU - uses: docker/setup-qemu-action@e0e4588fad221d38ee467c0bffd91115366dc0c5 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@edfb0fe6204400c56fbfd3feba3fe9ad1adfa345 - - - name: Build and push Database Docker image - uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 - with: - context: . - file: ./litellm-js/spend-logs/Dockerfile - push: true - tags: | - ${{ steps.meta-spend-logs.outputs.tags }}-${{ github.event.inputs.tag || 'latest' }}, - ${{ steps.meta-spend-logs.outputs.tags }}-${{ github.event.inputs.release_type }} - ${{ (github.event.inputs.release_type == 'stable' || github.event.inputs.release_type == 'rc') && format('{0}/berriai/litellm-spend_logs:main-{1}', env.REGISTRY, github.event.inputs.tag) || '' }}, - ${{ github.event.inputs.release_type == 'stable' && format('{0}/berriai/litellm-spend_logs:main-stable', env.REGISTRY) || '' }} - platforms: local,linux/amd64,linux/arm64,linux/arm64/v8 - - build-and-push-helm-chart: - if: github.event.inputs.release_type != 'dev' - needs: [docker-hub-deploy, build-and-push-image, build-and-push-image-database] - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Log in to the Container registry - uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: lowercase github.repository_owner - run: | - echo "REPO_OWNER=`echo ${{github.repository_owner}} | tr '[:upper:]' '[:lower:]'`" >>${GITHUB_ENV} - - - name: Get LiteLLM Latest Tag - id: current_app_tag - shell: bash - run: | - LATEST_TAG=$(git describe --tags --exclude "*dev*" --abbrev=0) - if [ -z "${LATEST_TAG}" ]; then - echo "latest_tag=latest" | tee -a $GITHUB_OUTPUT - else - echo "latest_tag=${LATEST_TAG}" | tee -a $GITHUB_OUTPUT - fi - - - name: Get last published chart version - id: current_version - shell: bash - run: | - CHART_LIST=$(helm show chart oci://${{ env.REGISTRY }}/${{ env.REPO_OWNER }}/${{ env.CHART_NAME }} 2>/dev/null || true) - if [ -z "${CHART_LIST}" ]; then - echo "current-version=0.1.0" | tee -a $GITHUB_OUTPUT - else - printf '%s' "${CHART_LIST}" | grep '^version:' | awk 'BEGIN{FS=":"}{print "current-version="$2}' | tr -d " " | tee -a $GITHUB_OUTPUT - fi - env: - HELM_EXPERIMENTAL_OCI: '1' - - # Automatically update the helm chart version one "patch" level - - name: Bump release version - id: bump_version - uses: christian-draeger/increment-semantic-version@1.1.0 - with: - current-version: ${{ steps.current_version.outputs.current-version || '0.1.0' }} - version-fragment: 'bug' - - - uses: ./.github/actions/helm-oci-chart-releaser - with: - name: ${{ env.CHART_NAME }} - repository: ${{ env.REPO_OWNER }} - tag: ${{ github.event.inputs.chartVersion || steps.bump_version.outputs.next-version || '0.1.0' }} - app_version: ${{ steps.current_app_tag.outputs.latest_tag }} - path: deploy/charts/${{ env.CHART_NAME }} - registry: ${{ env.REGISTRY }} - registry_username: ${{ github.actor }} - registry_password: ${{ secrets.GITHUB_TOKEN }} - update_dependencies: true - - release: - name: "New LiteLLM Release" - needs: [docker-hub-deploy, build-and-push-image, build-and-push-image-database] - - runs-on: "ubuntu-latest" - - steps: - - name: Display version - run: echo "Current version is ${{ github.event.inputs.tag }}" - - name: "Set Release Tag" - run: echo "RELEASE_TAG=${{ github.event.inputs.tag }}" >> $GITHUB_ENV - - name: Display release tag - run: echo "RELEASE_TAG is $RELEASE_TAG" - - name: "Create release" - uses: "actions/github-script@v6" - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - script: | - const commitHash = "${{ github.event.inputs.commit_hash}}"; - console.log("Commit Hash:", commitHash); // Add this line for debugging - try { - const response = await github.rest.repos.createRelease({ - draft: false, - generate_release_notes: true, - target_commitish: commitHash, - name: process.env.RELEASE_TAG, - owner: context.repo.owner, - prerelease: false, - repo: context.repo.repo, - tag_name: process.env.RELEASE_TAG, - }); - - core.exportVariable('RELEASE_ID', response.data.id); - core.exportVariable('RELEASE_UPLOAD_URL', response.data.upload_url); - } catch (error) { - core.setFailed(error.message); - } - - name: Fetch Release Notes - id: release-notes - uses: actions/github-script@v6 - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - script: | - try { - const response = await github.rest.repos.getRelease({ - owner: context.repo.owner, - repo: context.repo.repo, - release_id: process.env.RELEASE_ID, - }); - const formattedBody = JSON.stringify(response.data.body).slice(1, -1); - return formattedBody; - } catch (error) { - core.setFailed(error.message); - } - env: - RELEASE_ID: ${{ env.RELEASE_ID }} - - name: Github Releases To Discord - env: - WEBHOOK_URL: ${{ secrets.WEBHOOK_URL }} - REALEASE_TAG: ${{ env.RELEASE_TAG }} - RELEASE_NOTES: ${{ steps.release-notes.outputs.result }} - run: | - curl -H "Content-Type: application/json" -X POST -d '{ - "content": "New LiteLLM release '"${RELEASE_TAG}"'", - "username": "Release Changelog", - "avatar_url": "https://cdn.discordapp.com/avatars/487431320314576937/bd64361e4ba6313d561d54e78c9e7171.png", - "embeds": [ - { - "title": "Changelog for LiteLLM '"${RELEASE_TAG}"'", - "description": "'"${RELEASE_NOTES}"'", - "color": 2105893 - } - ] - }' $WEBHOOK_URL - diff --git a/.github/workflows/ghcr_deploy.yml.txt b/.github/workflows/ghcr_deploy.yml.txt new file mode 100644 index 000000000000..2e25d80bd9ec --- /dev/null +++ b/.github/workflows/ghcr_deploy.yml.txt @@ -0,0 +1,438 @@ +# this workflow is triggered by an API call when there is a new PyPI release of LiteLLM +name: Build, Publish LiteLLM Docker Image. New Release +on: {} + # workflow_dispatch: + # inputs: + # tag: + # description: "The tag version you want to build" + # release_type: + # description: "The release type you want to build. Can be 'latest', 'stable', 'dev', 'rc'" + # type: string + # default: "latest" + # commit_hash: + # description: "Commit hash" + # required: true + +# Defines two custom environment variables for the workflow. Used for the Container registry domain, and a name for the Docker image that this workflow builds. +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu. +jobs: + # print commit hash, tag, and release type + print: + runs-on: ubuntu-latest + steps: + - run: | + echo "Commit hash: ${{ github.event.inputs.commit_hash }}" + echo "Tag: ${{ github.event.inputs.tag }}" + echo "Release type: ${{ github.event.inputs.release_type }}" + # docker-hub-deploy: + # if: github.repository == 'cartod/litellm' + # runs-on: ubuntu-latest + # steps: + # - + # name: Checkout + # uses: actions/checkout@v4 + # with: + # ref: ${{ github.event.inputs.commit_hash }} + # - + # name: Set up QEMU + # uses: docker/setup-qemu-action@v3 + # - + # name: Set up Docker Buildx + # uses: docker/setup-buildx-action@v3 + # - + # name: Login to Docker Hub + # uses: docker/login-action@v3 + # with: + # username: ${{ secrets.DOCKERHUB_USERNAME }} + # password: ${{ secrets.DOCKERHUB_TOKEN }} + # - + # name: Build and push + # uses: docker/build-push-action@v5 + # with: + # context: . + # push: true + # tags: litellm/litellm:${{ github.event.inputs.tag || 'latest' }} + # - + # name: Build and push litellm-database image + # uses: docker/build-push-action@v5 + # with: + # context: . + # push: true + # file: ./docker/Dockerfile.database + # tags: litellm/litellm-database:${{ github.event.inputs.tag || 'latest' }} + # - + # name: Build and push litellm-spend-logs image + # uses: docker/build-push-action@v5 + # with: + # context: . + # push: true + # file: ./litellm-js/spend-logs/Dockerfile + # tags: litellm/litellm-spend_logs:${{ github.event.inputs.tag || 'latest' }} + # - + # name: Build and push litellm-non_root image + # uses: docker/build-push-action@v5 + # with: + # context: . + # push: true + # file: ./docker/Dockerfile.non_root + # tags: litellm/litellm-non_root:${{ github.event.inputs.tag || 'latest' }} + # build-and-push-image: + # runs-on: ubuntu-latest + # # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. + # permissions: + # contents: read + # packages: write + # steps: + # - name: Checkout repository + # uses: actions/checkout@v4 + # with: + # ref: ${{ github.event.inputs.commit_hash }} + # # Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here. + # - name: Log in to the Container registry + # uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + # with: + # registry: ${{ env.REGISTRY }} + # username: ${{ github.actor }} + # password: ${{ secrets.GITHUB_TOKEN }} + # # This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels. + # - name: Extract metadata (tags, labels) for Docker + # id: meta + # uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + # with: + # images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + # # Configure multi platform Docker builds + # - name: Set up QEMU + # uses: docker/setup-qemu-action@e0e4588fad221d38ee467c0bffd91115366dc0c5 + # - name: Set up Docker Buildx + # uses: docker/setup-buildx-action@edfb0fe6204400c56fbfd3feba3fe9ad1adfa345 + # # This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages. + # # It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository. + # # It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step. + # - name: Build and push Docker image + # uses: docker/build-push-action@4976231911ebf5f32aad765192d35f942aa48cb8 + # with: + # context: . + # push: true + # tags: | + # ${{ steps.meta.outputs.tags }}-${{ github.event.inputs.tag || 'latest' }}, + # ${{ steps.meta.outputs.tags }}-${{ github.event.inputs.release_type }} + # ${{ (github.event.inputs.release_type == 'stable' || github.event.inputs.release_type == 'rc') && format('{0}/berriai/litellm:main-{1}', env.REGISTRY, github.event.inputs.tag) || '' }}, + # ${{ github.event.inputs.release_type == 'stable' && format('{0}/berriai/litellm:main-stable', env.REGISTRY) || '' }}, + # ${{ (github.event.inputs.release_type == 'stable' || github.event.inputs.release_type == 'rc') && format('{0}/berriai/litellm:{1}', env.REGISTRY, github.event.inputs.tag) || '' }}, + # labels: ${{ steps.meta.outputs.labels }} + # platforms: local,linux/amd64,linux/arm64,linux/arm64/v8 + + # build-and-push-image-ee: + # runs-on: ubuntu-latest + # permissions: + # contents: read + # packages: write + # steps: + # - name: Checkout repository + # uses: actions/checkout@v4 + # with: + # ref: ${{ github.event.inputs.commit_hash }} + + # - name: Log in to the Container registry + # uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + # with: + # registry: ${{ env.REGISTRY }} + # username: ${{ github.actor }} + # password: ${{ secrets.GITHUB_TOKEN }} + + # - name: Extract metadata (tags, labels) for EE Dockerfile + # id: meta-ee + # uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + # with: + # images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee + # # Configure multi platform Docker builds + # - name: Set up QEMU + # uses: docker/setup-qemu-action@e0e4588fad221d38ee467c0bffd91115366dc0c5 + # - name: Set up Docker Buildx + # uses: docker/setup-buildx-action@edfb0fe6204400c56fbfd3feba3fe9ad1adfa345 + + # - name: Build and push EE Docker image + # uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + # with: + # context: . + # file: Dockerfile + # push: true + # tags: | + # ${{ steps.meta-ee.outputs.tags }}-${{ github.event.inputs.tag || 'latest' }}, + # ${{ steps.meta-ee.outputs.tags }}-${{ github.event.inputs.release_type }} + # ${{ (github.event.inputs.release_type == 'stable' || github.event.inputs.release_type == 'rc') && format('{0}/berriai/litellm-ee:main-{1}', env.REGISTRY, github.event.inputs.tag) || '' }}, + # ${{ github.event.inputs.release_type == 'stable' && format('{0}/berriai/litellm-ee:main-stable', env.REGISTRY) || '' }} + # labels: ${{ steps.meta-ee.outputs.labels }} + # platforms: local,linux/amd64,linux/arm64,linux/arm64/v8 + + # build-and-push-image-database: + # runs-on: ubuntu-latest + # permissions: + # contents: read + # packages: write + # steps: + # - name: Checkout repository + # uses: actions/checkout@v4 + # with: + # ref: ${{ github.event.inputs.commit_hash }} + + # - name: Log in to the Container registry + # uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + # with: + # registry: ${{ env.REGISTRY }} + # username: ${{ github.actor }} + # password: ${{ secrets.GITHUB_TOKEN }} + + # - name: Extract metadata (tags, labels) for database Dockerfile + # id: meta-database + # uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + # with: + # images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-database + # # Configure multi platform Docker builds + # - name: Set up QEMU + # uses: docker/setup-qemu-action@e0e4588fad221d38ee467c0bffd91115366dc0c5 + # - name: Set up Docker Buildx + # uses: docker/setup-buildx-action@edfb0fe6204400c56fbfd3feba3fe9ad1adfa345 + + # - name: Build and push Database Docker image + # uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + # with: + # context: . + # file: ./docker/Dockerfile.database + # push: true + # tags: | + # ${{ steps.meta-database.outputs.tags }}-${{ github.event.inputs.tag || 'latest' }}, + # ${{ steps.meta-database.outputs.tags }}-${{ github.event.inputs.release_type }} + # ${{ (github.event.inputs.release_type == 'stable' || github.event.inputs.release_type == 'rc') && format('{0}/berriai/litellm-database:main-{1}', env.REGISTRY, github.event.inputs.tag) || '' }}, + # ${{ github.event.inputs.release_type == 'stable' && format('{0}/berriai/litellm-database:main-stable', env.REGISTRY) || '' }} + # labels: ${{ steps.meta-database.outputs.labels }} + # platforms: local,linux/amd64,linux/arm64,linux/arm64/v8 + + build-and-push-image-non_root: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.commit_hash }} + + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for non_root Dockerfile + id: meta-non_root + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-non_root + # Configure multi platform Docker builds + - name: Set up QEMU + uses: docker/setup-qemu-action@e0e4588fad221d38ee467c0bffd91115366dc0c5 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@edfb0fe6204400c56fbfd3feba3fe9ad1adfa345 + + - name: Build and push non_root Docker image + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: . + file: ./docker/Dockerfile.non_root + push: true + tags: | + ${{ steps.meta-non_root.outputs.tags }}-${{ github.event.inputs.tag || 'latest' }}, + ${{ steps.meta-non_root.outputs.tags }}-${{ github.event.inputs.release_type }} + ${{ (github.event.inputs.release_type == 'stable' || github.event.inputs.release_type == 'rc') && format('{0}/berriai/litellm-non_root:main-{1}', env.REGISTRY, github.event.inputs.tag) || '' }}, + ${{ github.event.inputs.release_type == 'stable' && format('{0}/CartoDB/litellm-non_root:main-stable', env.REGISTRY) || '' }} + labels: ${{ steps.meta-non_root.outputs.labels }} + platforms: local,linux/amd64,linux/arm64,linux/arm64/v8 + + # build-and-push-image-spend-logs: + # runs-on: ubuntu-latest + # permissions: + # contents: read + # packages: write + # steps: + # - name: Checkout repository + # uses: actions/checkout@v4 + # with: + # ref: ${{ github.event.inputs.commit_hash }} + + # - name: Log in to the Container registry + # uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + # with: + # registry: ${{ env.REGISTRY }} + # username: ${{ github.actor }} + # password: ${{ secrets.GITHUB_TOKEN }} + + # - name: Extract metadata (tags, labels) for spend-logs Dockerfile + # id: meta-spend-logs + # uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + # with: + # images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-spend_logs + # # Configure multi platform Docker builds + # - name: Set up QEMU + # uses: docker/setup-qemu-action@e0e4588fad221d38ee467c0bffd91115366dc0c5 + # - name: Set up Docker Buildx + # uses: docker/setup-buildx-action@edfb0fe6204400c56fbfd3feba3fe9ad1adfa345 + + # - name: Build and push Database Docker image + # uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + # with: + # context: . + # file: ./litellm-js/spend-logs/Dockerfile + # push: true + # tags: | + # ${{ steps.meta-spend-logs.outputs.tags }}-${{ github.event.inputs.tag || 'latest' }}, + # ${{ steps.meta-spend-logs.outputs.tags }}-${{ github.event.inputs.release_type }} + # ${{ (github.event.inputs.release_type == 'stable' || github.event.inputs.release_type == 'rc') && format('{0}/CartoDB/litellm-spend_logs:main-{1}', env.REGISTRY, github.event.inputs.tag) || '' }}, + # ${{ github.event.inputs.release_type == 'stable' && format('{0}/CartoDB/litellm-spend_logs:main-stable', env.REGISTRY) || '' }} + # platforms: local,linux/amd64,linux/arm64,linux/arm64/v8 + + # build-and-push-helm-chart: + # if: github.event.inputs.release_type != 'dev' + # needs: [docker-hub-deploy, build-and-push-image, build-and-push-image-database] + # runs-on: ubuntu-latest + # steps: + # - name: Checkout repository + # uses: actions/checkout@v4 + # with: + # fetch-depth: 0 + + # - name: Log in to the Container registry + # uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + # with: + # registry: ${{ env.REGISTRY }} + # username: ${{ github.actor }} + # password: ${{ secrets.GITHUB_TOKEN }} + + # - name: lowercase github.repository_owner + # run: | + # echo "REPO_OWNER=`echo ${{github.repository_owner}} | tr '[:upper:]' '[:lower:]'`" >>${GITHUB_ENV} + + # - name: Get LiteLLM Latest Tag + # id: current_app_tag + # shell: bash + # run: | + # LATEST_TAG=$(git describe --tags --exclude "*dev*" --abbrev=0) + # if [ -z "${LATEST_TAG}" ]; then + # echo "latest_tag=latest" | tee -a $GITHUB_OUTPUT + # else + # echo "latest_tag=${LATEST_TAG}" | tee -a $GITHUB_OUTPUT + # fi + + # - name: Get last published chart version + # id: current_version + # shell: bash + # run: | + # CHART_LIST=$(helm show chart oci://${{ env.REGISTRY }}/${{ env.REPO_OWNER }}/${{ env.CHART_NAME }} 2>/dev/null || true) + # if [ -z "${CHART_LIST}" ]; then + # echo "current-version=0.1.0" | tee -a $GITHUB_OUTPUT + # else + # printf '%s' "${CHART_LIST}" | grep '^version:' | awk 'BEGIN{FS=":"}{print "current-version="$2}' | tr -d " " | tee -a $GITHUB_OUTPUT + # fi + # env: + # HELM_EXPERIMENTAL_OCI: '1' + + # # Automatically update the helm chart version one "patch" level + # - name: Bump release version + # id: bump_version + # uses: christian-draeger/increment-semantic-version@1.1.0 + # with: + # current-version: ${{ steps.current_version.outputs.current-version || '0.1.0' }} + # version-fragment: 'bug' + + # - uses: ./.github/actions/helm-oci-chart-releaser + # with: + # name: ${{ env.CHART_NAME }} + # repository: ${{ env.REPO_OWNER }} + # tag: ${{ github.event.inputs.chartVersion || steps.bump_version.outputs.next-version || '0.1.0' }} + # app_version: ${{ steps.current_app_tag.outputs.latest_tag }} + # path: deploy/charts/${{ env.CHART_NAME }} + # registry: ${{ env.REGISTRY }} + # registry_username: ${{ github.actor }} + # registry_password: ${{ secrets.GITHUB_TOKEN }} + # update_dependencies: true + + # release: + # name: "New LiteLLM Release" + # needs: [docker-hub-deploy, build-and-push-image, build-and-push-image-database] + + # runs-on: "ubuntu-latest" + + # steps: + # - name: Display version + # run: echo "Current version is ${{ github.event.inputs.tag }}" + # - name: "Set Release Tag" + # run: echo "RELEASE_TAG=${{ github.event.inputs.tag }}" >> $GITHUB_ENV + # - name: Display release tag + # run: echo "RELEASE_TAG is $RELEASE_TAG" + # - name: "Create release" + # uses: "actions/github-script@v6" + # with: + # github-token: "${{ secrets.GITHUB_TOKEN }}" + # script: | + # const commitHash = "${{ github.event.inputs.commit_hash}}"; + # console.log("Commit Hash:", commitHash); // Add this line for debugging + # try { + # const response = await github.rest.repos.createRelease({ + # draft: false, + # generate_release_notes: true, + # target_commitish: commitHash, + # name: process.env.RELEASE_TAG, + # owner: context.repo.owner, + # prerelease: false, + # repo: context.repo.repo, + # tag_name: process.env.RELEASE_TAG, + # }); + + # core.exportVariable('RELEASE_ID', response.data.id); + # core.exportVariable('RELEASE_UPLOAD_URL', response.data.upload_url); + # } catch (error) { + # core.setFailed(error.message); + # } + # - name: Fetch Release Notes + # id: release-notes + # uses: actions/github-script@v6 + # with: + # github-token: "${{ secrets.GITHUB_TOKEN }}" + # script: | + # try { + # const response = await github.rest.repos.getRelease({ + # owner: context.repo.owner, + # repo: context.repo.repo, + # release_id: process.env.RELEASE_ID, + # }); + # const formattedBody = JSON.stringify(response.data.body).slice(1, -1); + # return formattedBody; + # } catch (error) { + # core.setFailed(error.message); + # } + # env: + # RELEASE_ID: ${{ env.RELEASE_ID }} + # - name: Github Releases To Discord + # env: + # WEBHOOK_URL: ${{ secrets.WEBHOOK_URL }} + # REALEASE_TAG: ${{ env.RELEASE_TAG }} + # RELEASE_NOTES: ${{ steps.release-notes.outputs.result }} + # run: | + # curl -H "Content-Type: application/json" -X POST -d '{ + # "content": "New LiteLLM release '"${RELEASE_TAG}"'", + # "username": "Release Changelog", + # "avatar_url": "https://cdn.discordapp.com/avatars/487431320314576937/bd64361e4ba6313d561d54e78c9e7171.png", + # "embeds": [ + # { + # "title": "Changelog for LiteLLM '"${RELEASE_TAG}"'", + # "description": "'"${RELEASE_NOTES}"'", + # "color": 2105893 + # } + # ] + # }' $WEBHOOK_URL diff --git a/.github/workflows/ghcr_helm_deploy.yml b/.github/workflows/ghcr_helm_deploy.yml.txt similarity index 95% rename from .github/workflows/ghcr_helm_deploy.yml rename to .github/workflows/ghcr_helm_deploy.yml.txt index f78dc6f0f3f4..2e4ae69da637 100644 --- a/.github/workflows/ghcr_helm_deploy.yml +++ b/.github/workflows/ghcr_helm_deploy.yml.txt @@ -1,10 +1,10 @@ # this workflow is triggered by an API call when there is a new PyPI release of LiteLLM name: Build, Publish LiteLLM Helm Chart. New Release -on: - workflow_dispatch: - inputs: - chartVersion: - description: "Update the helm chart's version to this" +on: {} + # workflow_dispatch: + # inputs: + # chartVersion: + # description: "Update the helm chart's version to this" # Defines two custom environment variables for the workflow. Used for the Container registry domain, and a name for the Docker image that this workflow builds. env: diff --git a/.github/workflows/helm_unit_test.yml b/.github/workflows/helm_unit_test.yml.txt similarity index 90% rename from .github/workflows/helm_unit_test.yml rename to .github/workflows/helm_unit_test.yml.txt index c4b83af70a15..c9311c34429a 100644 --- a/.github/workflows/helm_unit_test.yml +++ b/.github/workflows/helm_unit_test.yml.txt @@ -1,10 +1,7 @@ name: Helm unit test -on: - pull_request: - push: - branches: - - main +on: {} + # workflow_dispatch: jobs: unit-test: diff --git a/.github/workflows/llm-translation-testing.yml b/.github/workflows/llm-translation-testing.yml index 7fda37a66dcb..c2bf8b68bfd6 100644 --- a/.github/workflows/llm-translation-testing.yml +++ b/.github/workflows/llm-translation-testing.yml @@ -7,10 +7,7 @@ on: description: 'Release candidate tag/version' required: true type: string - push: - tags: - - 'v*-rc*' # Triggers on release candidate tags like v1.0.0-rc1 - + jobs: run-llm-translation-tests: runs-on: ubuntu-latest diff --git a/.github/workflows/load_test.yml b/.github/workflows/load_test.yml index cdaffa328c94..e3732587e189 100644 --- a/.github/workflows/load_test.yml +++ b/.github/workflows/load_test.yml @@ -1,10 +1,6 @@ name: Test Locust Load Test on: - workflow_run: - workflows: ["Build, Publish LiteLLM Docker Image. New Release"] - types: - - completed workflow_dispatch: jobs: diff --git a/.github/workflows/read_pyproject_version.yml b/.github/workflows/read_pyproject_version.yml.txt similarity index 100% rename from .github/workflows/read_pyproject_version.yml rename to .github/workflows/read_pyproject_version.yml.txt diff --git a/.gitignore b/.gitignore index aa973201fd15..8480465915be 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,10 @@ litellm_uuid.txt __pycache__/ *.pyc bun.lockb +# Build artifacts +dist/ +build/ +*.egg-info/ **/.DS_Store .aider* litellm_results.jsonl diff --git a/APSCHEDULER_MEMORY_LEAK_FIX.md b/APSCHEDULER_MEMORY_LEAK_FIX.md new file mode 100644 index 000000000000..2171a17fd24c --- /dev/null +++ b/APSCHEDULER_MEMORY_LEAK_FIX.md @@ -0,0 +1,106 @@ +# APScheduler Memory Leak Fix + +## Problem Summary +The LiteLLM proxy server was experiencing critical memory leaks during startup, causing crashes with memory allocations exceeding 35GB. Memray analysis revealed the issue originated from APScheduler's internal functions. + +## Root Cause Analysis + +### Memory Leak Sources (from Memray stats): +1. `normalize()` function: **6.872GB allocated** +2. `_apply_jitter()` function: **6.542GB allocated** +3. `get_next_fire_time()` functions: **6.173GB combined** +4. `_get_run_times()` function: **2.946GB allocated** + +Total: **35.230GB allocated** with **483,180,019 allocations** + +### Contributing Factors: +1. **Jitter Parameter**: The `jitter` parameter in job scheduling caused excessive memory allocations in APScheduler's normalize() function +2. **Very Frequent Intervals**: Jobs running every 10 seconds generated massive calculation overhead +3. **Missed Run Calculations**: APScheduler computing backlogs of missed runs during startup +4. **Job Rescheduling**: Resetting jobs to "now" triggered recalculation of thousands of missed executions + +## Implemented Solution + +### Key Changes: + +#### 1. Removed Jitter Parameters +- **Before**: All jobs used `jitter` parameter (ranging from 2-3600 seconds) +- **After**: Removed all `jitter` parameters, using random offsets in intervals instead +- **Impact**: Eliminates the primary memory leak source in `_apply_jitter()` and `normalize()` + +#### 2. Increased Minimum Job Intervals +- **Before**: Some jobs ran every 10 seconds +- **After**: Minimum interval increased to 30 seconds +- **Impact**: Reduces frequency of APScheduler calculations by 3x + +#### 3. Enhanced Scheduler Configuration +```python +scheduler = AsyncIOScheduler( + job_defaults={ + "coalesce": True, # Collapse missed runs + "misfire_grace_time": 3600, # Increased from 120 to 3600 seconds + "max_instances": 1, # Prevent concurrent executions + "replace_existing": True, # Always replace existing jobs + }, + jobstores={'default': MemoryJobStore()}, + executors={'default': AsyncIOExecutor()}, + timezone=None # Disable timezone calculations +) +``` + +#### 4. Removed Job Rescheduling on Startup +- **Before**: All jobs were reset to `next_run_time=now` on startup +- **After**: Jobs start naturally with `misfire_grace_time` handling any backlogs +- **Impact**: Prevents massive backlog calculations + +#### 5. Updated Default Constants +- `PROXY_BATCH_WRITE_AT`: Increased from 10 to 30 seconds default + +## Files Modified +1. `litellm/proxy/proxy_server.py`: + - Updated `initialize_scheduled_background_jobs()` method + - Removed all `jitter` parameters from job scheduling + - Added memory-optimized scheduler configuration + - Increased job intervals + +2. `litellm/constants.py`: + - Updated `PROXY_BATCH_WRITE_AT` default from 10 to 30 seconds + +## Deployment Notes + +### Environment Variables (Optional Overrides) +If you need to adjust intervals, use these environment variables: +- `PROXY_BATCH_WRITE_AT`: Minimum 30 seconds recommended +- `PROXY_BUDGET_RESCHEDULER_MIN_TIME`: Default 597 seconds +- `PROXY_BUDGET_RESCHEDULER_MAX_TIME`: Default 605 seconds +- `PROXY_BATCH_POLLING_INTERVAL`: Default 3600 seconds + +### Testing Recommendations +1. Monitor memory usage during proxy startup using: + ```bash + python -m memray run --output memray.bin litellm --config config.yaml + python -m memray stats memray.bin + ``` + +2. Verify scheduled jobs are running: + - Check logs for "APScheduler started with memory leak prevention settings" + - Monitor job execution timestamps + +3. Load test with multiple proxy instances to ensure job distribution works without jitter + +### Rollback Plan +If issues occur, rollback by: +1. Reverting the code changes +2. Setting `PROXY_BATCH_WRITE_AT=10` to restore original interval +3. Note: The memory leak will return with rollback + +## Performance Impact +- **Memory**: Dramatic reduction from 35GB to expected <1GB during startup +- **CPU**: Reduced computational overhead from jitter calculations +- **Job Timing**: Slightly less random distribution (using interval offsets instead of jitter) +- **Reliability**: Improved stability, no more OOM crashes during startup + +## Future Improvements +1. Consider migrating away from APScheduler to a simpler scheduling solution +2. Implement job queuing with external scheduler (Redis/Celery) +3. Add memory monitoring and alerts for scheduler operations \ No newline at end of file diff --git a/REDIS_SESSION_PATCH.md b/REDIS_SESSION_PATCH.md new file mode 100644 index 000000000000..6db774944e56 --- /dev/null +++ b/REDIS_SESSION_PATCH.md @@ -0,0 +1,255 @@ +# Redis Session Patch for LiteLLM Issue #12364 + +## Overview +This is a **temporary patch** to fix the Responses API conversation context timing issue while waiting for the official fix from LiteLLM maintainers. + +**Problem**: Conversation context fails on consecutive requests due to 10-second batch processing delay. +**Solution**: Immediate Redis storage with database fallback. + +## Strategy + +### Core Principle: Minimal, Non-Breaking Changes +- **Redis-first**: Store session data immediately in Redis after response generation +- **Database fallback**: Keep existing batch processing as backup (resilient to Redis failures) +- **Patch approach**: Minimal code changes, clearly marked as temporary fix +- **Zero breaking changes**: Existing functionality preserved + +### Architecture +``` +Request → Response Generated → [PATCH] Store in Redis immediately → Return Response + ↓ +Later Request → [PATCH] Check Redis first → Found? Use immediately + ↓ + Not found? → Use existing database/enterprise logic +``` + +## Implementation + +### Files to Modify + +#### 1. `/litellm/responses/litellm_completion_transformation/transformation.py` + +**Add Redis helper functions** (at the end of file): + +```python +# ============================================================================= +# PATCH: Redis Session Storage for Issue #12364 +# This is a temporary fix for conversation context timing issues +# TODO: Remove when upstream fixes batch processing timing +# ============================================================================= + +async def _patch_store_session_in_redis(response_id: str, session_id: str, messages: List[Dict]): + """PATCH: Store session immediately in Redis to avoid batch processing delay""" + try: + from litellm.proxy.proxy_server import redis_client + import json + + if redis_client is None: + return # No Redis - graceful fallback to existing logic + + session_data = { + "messages": messages, + "session_id": session_id, + "timestamp": datetime.utcnow().isoformat() + } + + # Store with 24-hour TTL + await redis_client.setex( + f"litellm_patch:session:{response_id}", + 86400, # 24 hours + json.dumps(session_data) + ) + + except Exception: + # PATCH: Silent fail - don't break existing functionality + pass + +async def _patch_get_session_from_redis(previous_response_id: str) -> Optional[Dict]: + """PATCH: Get session from Redis if available""" + try: + from litellm.proxy.proxy_server import redis_client + import json + + if redis_client is None: + return None + + # Decode response ID to get actual request ID + actual_request_id = ResponsesAPIRequestUtils.decode_previous_response_id_to_original_previous_response_id( + previous_response_id + ) + + # Get session data from Redis + session_json = await redis_client.get(f"litellm_patch:session:{actual_request_id}") + + if session_json: + return json.loads(session_json) + + return None + + except Exception: + # PATCH: Silent fail - fallback to existing logic + return None +``` + +**Modify `async_responses_api_session_handler`** (replace existing function): + +```python +@staticmethod +async def async_responses_api_session_handler( + previous_response_id: str, + litellm_completion_request: dict, +) -> dict: + """ + Async hook to get the chain of previous input and output pairs and return a list of Chat Completion messages + + PATCH: Added Redis-first lookup to fix conversation context timing issues + """ + + # PATCH: Try Redis first for immediate availability + redis_session = await _patch_get_session_from_redis(previous_response_id) + if redis_session: + _messages = litellm_completion_request.get("messages") or [] + session_messages = redis_session.get("messages") or [] + litellm_completion_request["messages"] = session_messages + _messages + litellm_completion_request["litellm_trace_id"] = redis_session.get("session_id") + return litellm_completion_request + + # PATCH: Fallback to existing enterprise/database logic + if _ENTERPRISE_ResponsesSessionHandler is not None: + chat_completion_session = ChatCompletionSession( + messages=[], litellm_session_id=None + ) + if previous_response_id: + chat_completion_session = await _ENTERPRISE_ResponsesSessionHandler.get_chat_completion_message_history_for_previous_response_id( + previous_response_id=previous_response_id + ) + _messages = litellm_completion_request.get("messages") or [] + session_messages = chat_completion_session.get("messages") or [] + litellm_completion_request["messages"] = session_messages + _messages + litellm_completion_request[ + "litellm_trace_id" + ] = chat_completion_session.get("litellm_session_id") + + return litellm_completion_request +``` + +#### 2. `/litellm/responses/litellm_completion_transformation/handler.py` + +**Modify `async_response_api_handler`** (add one line after response generation): + +```python +async def async_response_api_handler( + self, + litellm_completion_request: dict, + request_input: Union[str, ResponseInputParam], + responses_api_request: ResponsesAPIOptionalRequestParams, + **kwargs, +) -> Union[ResponsesAPIResponse, BaseResponsesAPIStreamingIterator]: + + previous_response_id: Optional[str] = responses_api_request.get( + "previous_response_id" + ) + if previous_response_id: + litellm_completion_request = await LiteLLMCompletionResponsesConfig.async_responses_api_session_handler( + previous_response_id=previous_response_id, + litellm_completion_request=litellm_completion_request, + ) + + acompletion_args = {} + acompletion_args.update(kwargs) + acompletion_args.update(litellm_completion_request) + + litellm_completion_response: Union[ + ModelResponse, litellm.CustomStreamWrapper + ] = await litellm.acompletion( + **acompletion_args, + ) + + if isinstance(litellm_completion_response, ModelResponse): + responses_api_response: ResponsesAPIResponse = ( + LiteLLMCompletionResponsesConfig.transform_chat_completion_response_to_responses_api_response( + chat_completion_response=litellm_completion_response, + request_input=request_input, + responses_api_request=responses_api_request, + ) + ) + + # PATCH: Store session immediately in Redis to avoid batch processing delay + if responses_api_response.id: + session_id = kwargs.get("litellm_trace_id") or str(uuid.uuid4()) + current_messages = litellm_completion_request.get("messages", []) + await LiteLLMCompletionResponsesConfig._patch_store_session_in_redis( + response_id=responses_api_response.id, + session_id=session_id, + messages=current_messages + ) + + return responses_api_response + + elif isinstance(litellm_completion_response, litellm.CustomStreamWrapper): + return LiteLLMCompletionStreamingIterator( + litellm_custom_stream_wrapper=litellm_completion_response, + request_input=request_input, + responses_api_request=responses_api_request, + ) +``` + +## Required Imports + +Add to top of `/litellm/responses/litellm_completion_transformation/transformation.py`: + +```python +# PATCH: Additional imports for Redis session storage +from datetime import datetime +import uuid +from typing import Optional, Dict, List +``` + +## Configuration + +**Optional**: Add environment variable control (add to proxy server config): + +```python +# PATCH: Redis session storage configuration +REDIS_SESSION_PATCH_ENABLED = os.getenv("REDIS_SESSION_PATCH_ENABLED", "true").lower() == "true" +REDIS_SESSION_PATCH_TTL = int(os.getenv("REDIS_SESSION_PATCH_TTL", "86400")) # 24 hours +``` + +## Testing + +### Verification Steps +1. **Before patch**: Two consecutive requests fail without 10-second delay +2. **After patch**: Two consecutive requests work immediately +3. **Redis failure**: Still works (falls back to existing logic) +4. **Different models**: Works with Gemini, Claude, etc. + +### Test Commands +```bash +# Test 1: Immediate consecutive requests (should work) +curl -X POST http://localhost:4000/v1/responses -d '{"model": "gemini-pro", "input": "Who is Michael Jordan?"}' +# Get response_id from above, then immediately: +curl -X POST http://localhost:4000/v1/responses -d '{"model": "gemini-pro", "input": "Tell me more about him", "previous_response_id": "RESPONSE_ID"}' + +# Test 2: Redis failure resilience +# Stop Redis, test should still work (with database fallback) +``` + +## Rollback Plan + +To remove the patch: +1. Remove the `_patch_*` functions from `transformation.py` +2. Revert `async_responses_api_session_handler` to original version +3. Remove the Redis storage line from `handler.py` +4. Clear Redis keys: `redis-cli DEL litellm_patch:session:*` + +## Notes + +- **Minimal impact**: Only 3 small changes to existing files +- **Graceful degradation**: Works without Redis, falls back to existing logic +- **Temporary**: Designed to be easily removed when upstream fixes the issue +- **Performance**: Redis lookup is faster than database batch processing +- **Memory**: 24-hour TTL prevents Redis memory bloat + +--- + +**This is a temporary patch. Monitor LiteLLM releases for official fix and remove this patch when resolved.** \ No newline at end of file diff --git a/RESPONSES_API_TEST_README.md b/RESPONSES_API_TEST_README.md new file mode 100644 index 000000000000..3adcaddd9469 --- /dev/null +++ b/RESPONSES_API_TEST_README.md @@ -0,0 +1,100 @@ +# LiteLLM Responses API Testing + +This repository contains fixes for the LiteLLM Responses API, specifically addressing tool format transformation issues. + +## Quick Start + +### Prerequisites +1. Python 3.x +2. Redis (for session management) + +### Setup + +```bash +# 1. Install Redis +# macOS: +brew install redis +brew services start redis + +# Linux: +sudo apt-get install redis-server +sudo systemctl start redis + +# 2. Install LiteLLM with proxy support +pip install -e ".[proxy]" + +# 3. Verify Redis is running +redis-cli ping # Should return PONG +``` + +### Configuration + +1. Edit `responses_api_config.yaml` and add your API keys: + - `YOUR_ANTHROPIC_API_KEY` - Get from https://console.anthropic.com/ + - `YOUR_DEEPSEEK_API_KEY` - Get from https://platform.deepseek.com/ + - `YOUR_GOOGLE_API_KEY` - Get from https://aistudio.google.com/apikey + +### Running the Test + +```bash +# Terminal 1: Start the proxy +litellm --config responses_api_config.yaml --port 4000 + +# Terminal 2: Run the test +python test_responses_api.py +``` + +## What This Tests + +The test suite validates: + +1. **Basic Responses** - Verifies each provider can return responses +2. **Session Management** - Tests context retention across multiple requests using Redis +3. **Streaming** - Validates streaming responses work correctly + +## Expected Results + +✅ **Working Features:** +- Basic request/response for all providers +- Session management with context retention (Claude, DeepSeek, Gemini) +- Response ID generation and session linking + +⚠️ **Known Limitations:** +- Some providers may have varying context retention capabilities +- Streaming support varies by provider + +## Fixes Included + +This repository includes a fix for the Responses API tool format transformation issue in: +- `litellm/responses/litellm_completion_transformation/transformation.py` + +The fix ensures tools are properly transformed from the nested Responses API format to the format expected by the Chat Completions API. + +## Troubleshooting + +### Redis Issues +```bash +# Check Redis is running +redis-cli ping + +# Monitor Redis activity +redis-cli MONITOR + +# Check stored sessions +redis-cli keys "litellm_patch:session:*" +``` + +### Proxy Issues +```bash +# Run with verbose logging +litellm --config responses_api_config.yaml --port 4000 --debug + +# Check proxy health +curl http://localhost:4000/health +``` + +## Files + +- `test_responses_api.py` - Comprehensive test suite +- `responses_api_config.yaml` - Proxy configuration +- This README \ No newline at end of file diff --git a/deploy/migrations/20251030013554_initial/README.md b/deploy/migrations/20251030013554_initial/README.md new file mode 100644 index 000000000000..219a9a1d91f3 --- /dev/null +++ b/deploy/migrations/20251030013554_initial/README.md @@ -0,0 +1 @@ +Initial migration generated at Thu Oct 30 01:36:02 UTC 2025 diff --git a/deploy/migrations/20251030013554_initial/migration.sql b/deploy/migrations/20251030013554_initial/migration.sql new file mode 100644 index 000000000000..15dc3e1ff2b2 --- /dev/null +++ b/deploy/migrations/20251030013554_initial/migration.sql @@ -0,0 +1,723 @@ +-- CreateEnum +CREATE TYPE "JobStatus" AS ENUM ('ACTIVE', 'INACTIVE'); + +-- CreateTable +CREATE TABLE "LiteLLM_BudgetTable" ( + "budget_id" TEXT NOT NULL, + "max_budget" DOUBLE PRECISION, + "soft_budget" DOUBLE PRECISION, + "max_parallel_requests" INTEGER, + "tpm_limit" BIGINT, + "rpm_limit" BIGINT, + "model_max_budget" JSONB, + "budget_duration" TEXT, + "budget_reset_at" TIMESTAMP(3), + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_BudgetTable_pkey" PRIMARY KEY ("budget_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_CredentialsTable" ( + "credential_id" TEXT NOT NULL, + "credential_name" TEXT NOT NULL, + "credential_values" JSONB NOT NULL, + "credential_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_CredentialsTable_pkey" PRIMARY KEY ("credential_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ProxyModelTable" ( + "model_id" TEXT NOT NULL, + "model_name" TEXT NOT NULL, + "litellm_params" JSONB NOT NULL, + "model_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_ProxyModelTable_pkey" PRIMARY KEY ("model_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_OrganizationTable" ( + "organization_id" TEXT NOT NULL, + "organization_alias" TEXT NOT NULL, + "budget_id" TEXT NOT NULL, + "metadata" JSONB NOT NULL DEFAULT '{}', + "models" TEXT[], + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "model_spend" JSONB NOT NULL DEFAULT '{}', + "object_permission_id" TEXT, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_OrganizationTable_pkey" PRIMARY KEY ("organization_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ModelTable" ( + "id" SERIAL NOT NULL, + "aliases" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_ModelTable_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_TeamTable" ( + "team_id" TEXT NOT NULL, + "team_alias" TEXT, + "organization_id" TEXT, + "object_permission_id" TEXT, + "admins" TEXT[], + "members" TEXT[], + "members_with_roles" JSONB NOT NULL DEFAULT '{}', + "metadata" JSONB NOT NULL DEFAULT '{}', + "max_budget" DOUBLE PRECISION, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "models" TEXT[], + "max_parallel_requests" INTEGER, + "tpm_limit" BIGINT, + "rpm_limit" BIGINT, + "budget_duration" TEXT, + "budget_reset_at" TIMESTAMP(3), + "blocked" BOOLEAN NOT NULL DEFAULT false, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "model_spend" JSONB NOT NULL DEFAULT '{}', + "model_max_budget" JSONB NOT NULL DEFAULT '{}', + "team_member_permissions" TEXT[] DEFAULT ARRAY[]::TEXT[], + "model_id" INTEGER, + + CONSTRAINT "LiteLLM_TeamTable_pkey" PRIMARY KEY ("team_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_UserTable" ( + "user_id" TEXT NOT NULL, + "user_alias" TEXT, + "team_id" TEXT, + "sso_user_id" TEXT, + "organization_id" TEXT, + "object_permission_id" TEXT, + "password" TEXT, + "teams" TEXT[] DEFAULT ARRAY[]::TEXT[], + "user_role" TEXT, + "max_budget" DOUBLE PRECISION, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "user_email" TEXT, + "models" TEXT[], + "metadata" JSONB NOT NULL DEFAULT '{}', + "max_parallel_requests" INTEGER, + "tpm_limit" BIGINT, + "rpm_limit" BIGINT, + "budget_duration" TEXT, + "budget_reset_at" TIMESTAMP(3), + "allowed_cache_controls" TEXT[] DEFAULT ARRAY[]::TEXT[], + "model_spend" JSONB NOT NULL DEFAULT '{}', + "model_max_budget" JSONB NOT NULL DEFAULT '{}', + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "LiteLLM_UserTable_pkey" PRIMARY KEY ("user_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ObjectPermissionTable" ( + "object_permission_id" TEXT NOT NULL, + "mcp_servers" TEXT[] DEFAULT ARRAY[]::TEXT[], + "mcp_access_groups" TEXT[] DEFAULT ARRAY[]::TEXT[], + "mcp_tool_permissions" JSONB, + "vector_stores" TEXT[] DEFAULT ARRAY[]::TEXT[], + + CONSTRAINT "LiteLLM_ObjectPermissionTable_pkey" PRIMARY KEY ("object_permission_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_MCPServerTable" ( + "server_id" TEXT NOT NULL, + "server_name" TEXT, + "alias" TEXT, + "description" TEXT, + "url" TEXT, + "transport" TEXT NOT NULL DEFAULT 'sse', + "auth_type" TEXT, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT, + "mcp_info" JSONB DEFAULT '{}', + "mcp_access_groups" TEXT[], + "allowed_tools" TEXT[] DEFAULT ARRAY[]::TEXT[], + "extra_headers" TEXT[] DEFAULT ARRAY[]::TEXT[], + "status" TEXT DEFAULT 'unknown', + "last_health_check" TIMESTAMP(3), + "health_check_error" TEXT, + "command" TEXT, + "args" TEXT[] DEFAULT ARRAY[]::TEXT[], + "env" JSONB DEFAULT '{}', + + CONSTRAINT "LiteLLM_MCPServerTable_pkey" PRIMARY KEY ("server_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_VerificationToken" ( + "token" TEXT NOT NULL, + "key_name" TEXT, + "key_alias" TEXT, + "soft_budget_cooldown" BOOLEAN NOT NULL DEFAULT false, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "expires" TIMESTAMP(3), + "models" TEXT[], + "aliases" JSONB NOT NULL DEFAULT '{}', + "config" JSONB NOT NULL DEFAULT '{}', + "user_id" TEXT, + "team_id" TEXT, + "permissions" JSONB NOT NULL DEFAULT '{}', + "max_parallel_requests" INTEGER, + "metadata" JSONB NOT NULL DEFAULT '{}', + "blocked" BOOLEAN, + "tpm_limit" BIGINT, + "rpm_limit" BIGINT, + "max_budget" DOUBLE PRECISION, + "budget_duration" TEXT, + "budget_reset_at" TIMESTAMP(3), + "allowed_cache_controls" TEXT[] DEFAULT ARRAY[]::TEXT[], + "allowed_routes" TEXT[] DEFAULT ARRAY[]::TEXT[], + "model_spend" JSONB NOT NULL DEFAULT '{}', + "model_max_budget" JSONB NOT NULL DEFAULT '{}', + "budget_id" TEXT, + "organization_id" TEXT, + "object_permission_id" TEXT, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT, + "rotation_count" INTEGER DEFAULT 0, + "auto_rotate" BOOLEAN DEFAULT false, + "rotation_interval" TEXT, + "last_rotation_at" TIMESTAMP(3), + "key_rotation_at" TIMESTAMP(3), + + CONSTRAINT "LiteLLM_VerificationToken_pkey" PRIMARY KEY ("token") +); + +-- CreateTable +CREATE TABLE "LiteLLM_EndUserTable" ( + "user_id" TEXT NOT NULL, + "alias" TEXT, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "allowed_model_region" TEXT, + "default_model" TEXT, + "budget_id" TEXT, + "blocked" BOOLEAN NOT NULL DEFAULT false, + + CONSTRAINT "LiteLLM_EndUserTable_pkey" PRIMARY KEY ("user_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_TagTable" ( + "tag_name" TEXT NOT NULL, + "description" TEXT, + "models" TEXT[], + "model_info" JSONB, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "budget_id" TEXT, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "LiteLLM_TagTable_pkey" PRIMARY KEY ("tag_name") +); + +-- CreateTable +CREATE TABLE "LiteLLM_Config" ( + "param_name" TEXT NOT NULL, + "param_value" JSONB, + + CONSTRAINT "LiteLLM_Config_pkey" PRIMARY KEY ("param_name") +); + +-- CreateTable +CREATE TABLE "LiteLLM_SpendLogs" ( + "request_id" TEXT NOT NULL, + "call_type" TEXT NOT NULL, + "api_key" TEXT NOT NULL DEFAULT '', + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "total_tokens" INTEGER NOT NULL DEFAULT 0, + "prompt_tokens" INTEGER NOT NULL DEFAULT 0, + "completion_tokens" INTEGER NOT NULL DEFAULT 0, + "startTime" TIMESTAMP(3) NOT NULL, + "endTime" TIMESTAMP(3) NOT NULL, + "completionStartTime" TIMESTAMP(3), + "model" TEXT NOT NULL DEFAULT '', + "model_id" TEXT DEFAULT '', + "model_group" TEXT DEFAULT '', + "custom_llm_provider" TEXT DEFAULT '', + "api_base" TEXT DEFAULT '', + "user" TEXT DEFAULT '', + "metadata" JSONB DEFAULT '{}', + "cache_hit" TEXT DEFAULT '', + "cache_key" TEXT DEFAULT '', + "request_tags" JSONB DEFAULT '[]', + "team_id" TEXT, + "end_user" TEXT, + "requester_ip_address" TEXT, + "messages" JSONB DEFAULT '{}', + "response" JSONB DEFAULT '{}', + "session_id" TEXT, + "status" TEXT, + "mcp_namespaced_tool_name" TEXT, + "proxy_server_request" JSONB DEFAULT '{}', + + CONSTRAINT "LiteLLM_SpendLogs_pkey" PRIMARY KEY ("request_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ErrorLogs" ( + "request_id" TEXT NOT NULL, + "startTime" TIMESTAMP(3) NOT NULL, + "endTime" TIMESTAMP(3) NOT NULL, + "api_base" TEXT NOT NULL DEFAULT '', + "model_group" TEXT NOT NULL DEFAULT '', + "litellm_model_name" TEXT NOT NULL DEFAULT '', + "model_id" TEXT NOT NULL DEFAULT '', + "request_kwargs" JSONB NOT NULL DEFAULT '{}', + "exception_type" TEXT NOT NULL DEFAULT '', + "exception_string" TEXT NOT NULL DEFAULT '', + "status_code" TEXT NOT NULL DEFAULT '', + + CONSTRAINT "LiteLLM_ErrorLogs_pkey" PRIMARY KEY ("request_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_UserNotifications" ( + "request_id" TEXT NOT NULL, + "user_id" TEXT NOT NULL, + "models" TEXT[], + "justification" TEXT NOT NULL, + "status" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_UserNotifications_pkey" PRIMARY KEY ("request_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_TeamMembership" ( + "user_id" TEXT NOT NULL, + "team_id" TEXT NOT NULL, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "budget_id" TEXT, + + CONSTRAINT "LiteLLM_TeamMembership_pkey" PRIMARY KEY ("user_id","team_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_OrganizationMembership" ( + "user_id" TEXT NOT NULL, + "organization_id" TEXT NOT NULL, + "user_role" TEXT, + "spend" DOUBLE PRECISION DEFAULT 0.0, + "budget_id" TEXT, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "LiteLLM_OrganizationMembership_pkey" PRIMARY KEY ("user_id","organization_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_InvitationLink" ( + "id" TEXT NOT NULL, + "user_id" TEXT NOT NULL, + "is_accepted" BOOLEAN NOT NULL DEFAULT false, + "accepted_at" TIMESTAMP(3), + "expires_at" TIMESTAMP(3) NOT NULL, + "created_at" TIMESTAMP(3) NOT NULL, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_InvitationLink_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_AuditLog" ( + "id" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "changed_by" TEXT NOT NULL DEFAULT '', + "changed_by_api_key" TEXT NOT NULL DEFAULT '', + "action" TEXT NOT NULL, + "table_name" TEXT NOT NULL, + "object_id" TEXT NOT NULL, + "before_value" JSONB, + "updated_values" JSONB, + + CONSTRAINT "LiteLLM_AuditLog_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_DailyUserSpend" ( + "id" TEXT NOT NULL, + "user_id" TEXT, + "date" TEXT NOT NULL, + "api_key" TEXT NOT NULL, + "model" TEXT, + "model_group" TEXT, + "custom_llm_provider" TEXT, + "mcp_namespaced_tool_name" TEXT, + "prompt_tokens" BIGINT NOT NULL DEFAULT 0, + "completion_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_read_input_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_creation_input_tokens" BIGINT NOT NULL DEFAULT 0, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "api_requests" BIGINT NOT NULL DEFAULT 0, + "successful_requests" BIGINT NOT NULL DEFAULT 0, + "failed_requests" BIGINT NOT NULL DEFAULT 0, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_DailyUserSpend_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_DailyTeamSpend" ( + "id" TEXT NOT NULL, + "team_id" TEXT, + "date" TEXT NOT NULL, + "api_key" TEXT NOT NULL, + "model" TEXT, + "model_group" TEXT, + "custom_llm_provider" TEXT, + "mcp_namespaced_tool_name" TEXT, + "prompt_tokens" BIGINT NOT NULL DEFAULT 0, + "completion_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_read_input_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_creation_input_tokens" BIGINT NOT NULL DEFAULT 0, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "api_requests" BIGINT NOT NULL DEFAULT 0, + "successful_requests" BIGINT NOT NULL DEFAULT 0, + "failed_requests" BIGINT NOT NULL DEFAULT 0, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_DailyTeamSpend_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_DailyTagSpend" ( + "id" TEXT NOT NULL, + "tag" TEXT, + "date" TEXT NOT NULL, + "api_key" TEXT NOT NULL, + "model" TEXT, + "model_group" TEXT, + "custom_llm_provider" TEXT, + "mcp_namespaced_tool_name" TEXT, + "prompt_tokens" BIGINT NOT NULL DEFAULT 0, + "completion_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_read_input_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_creation_input_tokens" BIGINT NOT NULL DEFAULT 0, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "api_requests" BIGINT NOT NULL DEFAULT 0, + "successful_requests" BIGINT NOT NULL DEFAULT 0, + "failed_requests" BIGINT NOT NULL DEFAULT 0, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_DailyTagSpend_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_CronJob" ( + "cronjob_id" TEXT NOT NULL, + "pod_id" TEXT NOT NULL, + "status" "JobStatus" NOT NULL DEFAULT 'INACTIVE', + "last_updated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "ttl" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_CronJob_pkey" PRIMARY KEY ("cronjob_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ManagedFileTable" ( + "id" TEXT NOT NULL, + "unified_file_id" TEXT NOT NULL, + "file_object" JSONB, + "model_mappings" JSONB NOT NULL, + "flat_model_file_ids" TEXT[] DEFAULT ARRAY[]::TEXT[], + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) NOT NULL, + "updated_by" TEXT, + + CONSTRAINT "LiteLLM_ManagedFileTable_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ManagedObjectTable" ( + "id" TEXT NOT NULL, + "unified_object_id" TEXT NOT NULL, + "model_object_id" TEXT NOT NULL, + "file_object" JSONB NOT NULL, + "file_purpose" TEXT NOT NULL, + "status" TEXT, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) NOT NULL, + "updated_by" TEXT, + + CONSTRAINT "LiteLLM_ManagedObjectTable_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ManagedVectorStoresTable" ( + "vector_store_id" TEXT NOT NULL, + "custom_llm_provider" TEXT NOT NULL, + "vector_store_name" TEXT, + "vector_store_description" TEXT, + "vector_store_metadata" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + "litellm_credential_name" TEXT, + "litellm_params" JSONB, + + CONSTRAINT "LiteLLM_ManagedVectorStoresTable_pkey" PRIMARY KEY ("vector_store_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_GuardrailsTable" ( + "guardrail_id" TEXT NOT NULL, + "guardrail_name" TEXT NOT NULL, + "litellm_params" JSONB NOT NULL, + "guardrail_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_GuardrailsTable_pkey" PRIMARY KEY ("guardrail_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_PromptTable" ( + "id" TEXT NOT NULL, + "prompt_id" TEXT NOT NULL, + "litellm_params" JSONB NOT NULL, + "prompt_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_PromptTable_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_HealthCheckTable" ( + "health_check_id" TEXT NOT NULL, + "model_name" TEXT NOT NULL, + "model_id" TEXT, + "status" TEXT NOT NULL, + "healthy_count" INTEGER NOT NULL DEFAULT 0, + "unhealthy_count" INTEGER NOT NULL DEFAULT 0, + "error_message" TEXT, + "response_time_ms" DOUBLE PRECISION, + "details" JSONB, + "checked_by" TEXT, + "checked_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_HealthCheckTable_pkey" PRIMARY KEY ("health_check_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_SearchToolsTable" ( + "search_tool_id" TEXT NOT NULL, + "search_tool_name" TEXT NOT NULL, + "litellm_params" JSONB NOT NULL, + "search_tool_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_SearchToolsTable_pkey" PRIMARY KEY ("search_tool_id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_CredentialsTable_credential_name_key" ON "LiteLLM_CredentialsTable"("credential_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_TeamTable_model_id_key" ON "LiteLLM_TeamTable"("model_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_UserTable_sso_user_id_key" ON "LiteLLM_UserTable"("sso_user_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_SpendLogs_startTime_idx" ON "LiteLLM_SpendLogs"("startTime"); + +-- CreateIndex +CREATE INDEX "LiteLLM_SpendLogs_end_user_idx" ON "LiteLLM_SpendLogs"("end_user"); + +-- CreateIndex +CREATE INDEX "LiteLLM_SpendLogs_session_id_idx" ON "LiteLLM_SpendLogs"("session_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_OrganizationMembership_user_id_organization_id_key" ON "LiteLLM_OrganizationMembership"("user_id", "organization_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_date_idx" ON "LiteLLM_DailyUserSpend"("date"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_user_id_idx" ON "LiteLLM_DailyUserSpend"("user_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_api_key_idx" ON "LiteLLM_DailyUserSpend"("api_key"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_model_idx" ON "LiteLLM_DailyUserSpend"("model"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_mcp_namespaced_tool_name_idx" ON "LiteLLM_DailyUserSpend"("mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_DailyUserSpend_user_id_date_api_key_model_custom_ll_key" ON "LiteLLM_DailyUserSpend"("user_id", "date", "api_key", "model", "custom_llm_provider", "mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_date_idx" ON "LiteLLM_DailyTeamSpend"("date"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_team_id_idx" ON "LiteLLM_DailyTeamSpend"("team_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_api_key_idx" ON "LiteLLM_DailyTeamSpend"("api_key"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_model_idx" ON "LiteLLM_DailyTeamSpend"("model"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_mcp_namespaced_tool_name_idx" ON "LiteLLM_DailyTeamSpend"("mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_DailyTeamSpend_team_id_date_api_key_model_custom_ll_key" ON "LiteLLM_DailyTeamSpend"("team_id", "date", "api_key", "model", "custom_llm_provider", "mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_date_idx" ON "LiteLLM_DailyTagSpend"("date"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_tag_idx" ON "LiteLLM_DailyTagSpend"("tag"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_api_key_idx" ON "LiteLLM_DailyTagSpend"("api_key"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_model_idx" ON "LiteLLM_DailyTagSpend"("model"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_mcp_namespaced_tool_name_idx" ON "LiteLLM_DailyTagSpend"("mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_DailyTagSpend_tag_date_api_key_model_custom_llm_pro_key" ON "LiteLLM_DailyTagSpend"("tag", "date", "api_key", "model", "custom_llm_provider", "mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_ManagedFileTable_unified_file_id_key" ON "LiteLLM_ManagedFileTable"("unified_file_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_ManagedFileTable_unified_file_id_idx" ON "LiteLLM_ManagedFileTable"("unified_file_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_ManagedObjectTable_unified_object_id_key" ON "LiteLLM_ManagedObjectTable"("unified_object_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_ManagedObjectTable_model_object_id_key" ON "LiteLLM_ManagedObjectTable"("model_object_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_ManagedObjectTable_unified_object_id_idx" ON "LiteLLM_ManagedObjectTable"("unified_object_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_ManagedObjectTable_model_object_id_idx" ON "LiteLLM_ManagedObjectTable"("model_object_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_GuardrailsTable_guardrail_name_key" ON "LiteLLM_GuardrailsTable"("guardrail_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_PromptTable_prompt_id_key" ON "LiteLLM_PromptTable"("prompt_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_HealthCheckTable_model_name_idx" ON "LiteLLM_HealthCheckTable"("model_name"); + +-- CreateIndex +CREATE INDEX "LiteLLM_HealthCheckTable_checked_at_idx" ON "LiteLLM_HealthCheckTable"("checked_at"); + +-- CreateIndex +CREATE INDEX "LiteLLM_HealthCheckTable_status_idx" ON "LiteLLM_HealthCheckTable"("status"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_SearchToolsTable_search_tool_name_key" ON "LiteLLM_SearchToolsTable"("search_tool_name"); + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationTable" ADD CONSTRAINT "LiteLLM_OrganizationTable_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationTable" ADD CONSTRAINT "LiteLLM_OrganizationTable_object_permission_id_fkey" FOREIGN KEY ("object_permission_id") REFERENCES "LiteLLM_ObjectPermissionTable"("object_permission_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TeamTable" ADD CONSTRAINT "LiteLLM_TeamTable_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "LiteLLM_OrganizationTable"("organization_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TeamTable" ADD CONSTRAINT "LiteLLM_TeamTable_model_id_fkey" FOREIGN KEY ("model_id") REFERENCES "LiteLLM_ModelTable"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TeamTable" ADD CONSTRAINT "LiteLLM_TeamTable_object_permission_id_fkey" FOREIGN KEY ("object_permission_id") REFERENCES "LiteLLM_ObjectPermissionTable"("object_permission_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_UserTable" ADD CONSTRAINT "LiteLLM_UserTable_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "LiteLLM_OrganizationTable"("organization_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_UserTable" ADD CONSTRAINT "LiteLLM_UserTable_object_permission_id_fkey" FOREIGN KEY ("object_permission_id") REFERENCES "LiteLLM_ObjectPermissionTable"("object_permission_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_VerificationToken" ADD CONSTRAINT "LiteLLM_VerificationToken_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_VerificationToken" ADD CONSTRAINT "LiteLLM_VerificationToken_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "LiteLLM_OrganizationTable"("organization_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_VerificationToken" ADD CONSTRAINT "LiteLLM_VerificationToken_object_permission_id_fkey" FOREIGN KEY ("object_permission_id") REFERENCES "LiteLLM_ObjectPermissionTable"("object_permission_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_EndUserTable" ADD CONSTRAINT "LiteLLM_EndUserTable_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TagTable" ADD CONSTRAINT "LiteLLM_TagTable_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TeamMembership" ADD CONSTRAINT "LiteLLM_TeamMembership_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationMembership" ADD CONSTRAINT "LiteLLM_OrganizationMembership_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "LiteLLM_UserTable"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationMembership" ADD CONSTRAINT "LiteLLM_OrganizationMembership_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "LiteLLM_OrganizationTable"("organization_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationMembership" ADD CONSTRAINT "LiteLLM_OrganizationMembership_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_InvitationLink" ADD CONSTRAINT "LiteLLM_InvitationLink_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "LiteLLM_UserTable"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_InvitationLink" ADD CONSTRAINT "LiteLLM_InvitationLink_created_by_fkey" FOREIGN KEY ("created_by") REFERENCES "LiteLLM_UserTable"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_InvitationLink" ADD CONSTRAINT "LiteLLM_InvitationLink_updated_by_fkey" FOREIGN KEY ("updated_by") REFERENCES "LiteLLM_UserTable"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE; + diff --git a/deploy/migrations/20251030013554_initial/raw_migration.sql b/deploy/migrations/20251030013554_initial/raw_migration.sql new file mode 100644 index 000000000000..dfc585189d16 --- /dev/null +++ b/deploy/migrations/20251030013554_initial/raw_migration.sql @@ -0,0 +1,724 @@ +Installing Prisma CLI +-- CreateEnum +CREATE TYPE "JobStatus" AS ENUM ('ACTIVE', 'INACTIVE'); + +-- CreateTable +CREATE TABLE "LiteLLM_BudgetTable" ( + "budget_id" TEXT NOT NULL, + "max_budget" DOUBLE PRECISION, + "soft_budget" DOUBLE PRECISION, + "max_parallel_requests" INTEGER, + "tpm_limit" BIGINT, + "rpm_limit" BIGINT, + "model_max_budget" JSONB, + "budget_duration" TEXT, + "budget_reset_at" TIMESTAMP(3), + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_BudgetTable_pkey" PRIMARY KEY ("budget_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_CredentialsTable" ( + "credential_id" TEXT NOT NULL, + "credential_name" TEXT NOT NULL, + "credential_values" JSONB NOT NULL, + "credential_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_CredentialsTable_pkey" PRIMARY KEY ("credential_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ProxyModelTable" ( + "model_id" TEXT NOT NULL, + "model_name" TEXT NOT NULL, + "litellm_params" JSONB NOT NULL, + "model_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_ProxyModelTable_pkey" PRIMARY KEY ("model_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_OrganizationTable" ( + "organization_id" TEXT NOT NULL, + "organization_alias" TEXT NOT NULL, + "budget_id" TEXT NOT NULL, + "metadata" JSONB NOT NULL DEFAULT '{}', + "models" TEXT[], + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "model_spend" JSONB NOT NULL DEFAULT '{}', + "object_permission_id" TEXT, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_OrganizationTable_pkey" PRIMARY KEY ("organization_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ModelTable" ( + "id" SERIAL NOT NULL, + "aliases" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_ModelTable_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_TeamTable" ( + "team_id" TEXT NOT NULL, + "team_alias" TEXT, + "organization_id" TEXT, + "object_permission_id" TEXT, + "admins" TEXT[], + "members" TEXT[], + "members_with_roles" JSONB NOT NULL DEFAULT '{}', + "metadata" JSONB NOT NULL DEFAULT '{}', + "max_budget" DOUBLE PRECISION, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "models" TEXT[], + "max_parallel_requests" INTEGER, + "tpm_limit" BIGINT, + "rpm_limit" BIGINT, + "budget_duration" TEXT, + "budget_reset_at" TIMESTAMP(3), + "blocked" BOOLEAN NOT NULL DEFAULT false, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "model_spend" JSONB NOT NULL DEFAULT '{}', + "model_max_budget" JSONB NOT NULL DEFAULT '{}', + "team_member_permissions" TEXT[] DEFAULT ARRAY[]::TEXT[], + "model_id" INTEGER, + + CONSTRAINT "LiteLLM_TeamTable_pkey" PRIMARY KEY ("team_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_UserTable" ( + "user_id" TEXT NOT NULL, + "user_alias" TEXT, + "team_id" TEXT, + "sso_user_id" TEXT, + "organization_id" TEXT, + "object_permission_id" TEXT, + "password" TEXT, + "teams" TEXT[] DEFAULT ARRAY[]::TEXT[], + "user_role" TEXT, + "max_budget" DOUBLE PRECISION, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "user_email" TEXT, + "models" TEXT[], + "metadata" JSONB NOT NULL DEFAULT '{}', + "max_parallel_requests" INTEGER, + "tpm_limit" BIGINT, + "rpm_limit" BIGINT, + "budget_duration" TEXT, + "budget_reset_at" TIMESTAMP(3), + "allowed_cache_controls" TEXT[] DEFAULT ARRAY[]::TEXT[], + "model_spend" JSONB NOT NULL DEFAULT '{}', + "model_max_budget" JSONB NOT NULL DEFAULT '{}', + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "LiteLLM_UserTable_pkey" PRIMARY KEY ("user_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ObjectPermissionTable" ( + "object_permission_id" TEXT NOT NULL, + "mcp_servers" TEXT[] DEFAULT ARRAY[]::TEXT[], + "mcp_access_groups" TEXT[] DEFAULT ARRAY[]::TEXT[], + "mcp_tool_permissions" JSONB, + "vector_stores" TEXT[] DEFAULT ARRAY[]::TEXT[], + + CONSTRAINT "LiteLLM_ObjectPermissionTable_pkey" PRIMARY KEY ("object_permission_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_MCPServerTable" ( + "server_id" TEXT NOT NULL, + "server_name" TEXT, + "alias" TEXT, + "description" TEXT, + "url" TEXT, + "transport" TEXT NOT NULL DEFAULT 'sse', + "auth_type" TEXT, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT, + "mcp_info" JSONB DEFAULT '{}', + "mcp_access_groups" TEXT[], + "allowed_tools" TEXT[] DEFAULT ARRAY[]::TEXT[], + "extra_headers" TEXT[] DEFAULT ARRAY[]::TEXT[], + "status" TEXT DEFAULT 'unknown', + "last_health_check" TIMESTAMP(3), + "health_check_error" TEXT, + "command" TEXT, + "args" TEXT[] DEFAULT ARRAY[]::TEXT[], + "env" JSONB DEFAULT '{}', + + CONSTRAINT "LiteLLM_MCPServerTable_pkey" PRIMARY KEY ("server_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_VerificationToken" ( + "token" TEXT NOT NULL, + "key_name" TEXT, + "key_alias" TEXT, + "soft_budget_cooldown" BOOLEAN NOT NULL DEFAULT false, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "expires" TIMESTAMP(3), + "models" TEXT[], + "aliases" JSONB NOT NULL DEFAULT '{}', + "config" JSONB NOT NULL DEFAULT '{}', + "user_id" TEXT, + "team_id" TEXT, + "permissions" JSONB NOT NULL DEFAULT '{}', + "max_parallel_requests" INTEGER, + "metadata" JSONB NOT NULL DEFAULT '{}', + "blocked" BOOLEAN, + "tpm_limit" BIGINT, + "rpm_limit" BIGINT, + "max_budget" DOUBLE PRECISION, + "budget_duration" TEXT, + "budget_reset_at" TIMESTAMP(3), + "allowed_cache_controls" TEXT[] DEFAULT ARRAY[]::TEXT[], + "allowed_routes" TEXT[] DEFAULT ARRAY[]::TEXT[], + "model_spend" JSONB NOT NULL DEFAULT '{}', + "model_max_budget" JSONB NOT NULL DEFAULT '{}', + "budget_id" TEXT, + "organization_id" TEXT, + "object_permission_id" TEXT, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT, + "rotation_count" INTEGER DEFAULT 0, + "auto_rotate" BOOLEAN DEFAULT false, + "rotation_interval" TEXT, + "last_rotation_at" TIMESTAMP(3), + "key_rotation_at" TIMESTAMP(3), + + CONSTRAINT "LiteLLM_VerificationToken_pkey" PRIMARY KEY ("token") +); + +-- CreateTable +CREATE TABLE "LiteLLM_EndUserTable" ( + "user_id" TEXT NOT NULL, + "alias" TEXT, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "allowed_model_region" TEXT, + "default_model" TEXT, + "budget_id" TEXT, + "blocked" BOOLEAN NOT NULL DEFAULT false, + + CONSTRAINT "LiteLLM_EndUserTable_pkey" PRIMARY KEY ("user_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_TagTable" ( + "tag_name" TEXT NOT NULL, + "description" TEXT, + "models" TEXT[], + "model_info" JSONB, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "budget_id" TEXT, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "LiteLLM_TagTable_pkey" PRIMARY KEY ("tag_name") +); + +-- CreateTable +CREATE TABLE "LiteLLM_Config" ( + "param_name" TEXT NOT NULL, + "param_value" JSONB, + + CONSTRAINT "LiteLLM_Config_pkey" PRIMARY KEY ("param_name") +); + +-- CreateTable +CREATE TABLE "LiteLLM_SpendLogs" ( + "request_id" TEXT NOT NULL, + "call_type" TEXT NOT NULL, + "api_key" TEXT NOT NULL DEFAULT '', + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "total_tokens" INTEGER NOT NULL DEFAULT 0, + "prompt_tokens" INTEGER NOT NULL DEFAULT 0, + "completion_tokens" INTEGER NOT NULL DEFAULT 0, + "startTime" TIMESTAMP(3) NOT NULL, + "endTime" TIMESTAMP(3) NOT NULL, + "completionStartTime" TIMESTAMP(3), + "model" TEXT NOT NULL DEFAULT '', + "model_id" TEXT DEFAULT '', + "model_group" TEXT DEFAULT '', + "custom_llm_provider" TEXT DEFAULT '', + "api_base" TEXT DEFAULT '', + "user" TEXT DEFAULT '', + "metadata" JSONB DEFAULT '{}', + "cache_hit" TEXT DEFAULT '', + "cache_key" TEXT DEFAULT '', + "request_tags" JSONB DEFAULT '[]', + "team_id" TEXT, + "end_user" TEXT, + "requester_ip_address" TEXT, + "messages" JSONB DEFAULT '{}', + "response" JSONB DEFAULT '{}', + "session_id" TEXT, + "status" TEXT, + "mcp_namespaced_tool_name" TEXT, + "proxy_server_request" JSONB DEFAULT '{}', + + CONSTRAINT "LiteLLM_SpendLogs_pkey" PRIMARY KEY ("request_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ErrorLogs" ( + "request_id" TEXT NOT NULL, + "startTime" TIMESTAMP(3) NOT NULL, + "endTime" TIMESTAMP(3) NOT NULL, + "api_base" TEXT NOT NULL DEFAULT '', + "model_group" TEXT NOT NULL DEFAULT '', + "litellm_model_name" TEXT NOT NULL DEFAULT '', + "model_id" TEXT NOT NULL DEFAULT '', + "request_kwargs" JSONB NOT NULL DEFAULT '{}', + "exception_type" TEXT NOT NULL DEFAULT '', + "exception_string" TEXT NOT NULL DEFAULT '', + "status_code" TEXT NOT NULL DEFAULT '', + + CONSTRAINT "LiteLLM_ErrorLogs_pkey" PRIMARY KEY ("request_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_UserNotifications" ( + "request_id" TEXT NOT NULL, + "user_id" TEXT NOT NULL, + "models" TEXT[], + "justification" TEXT NOT NULL, + "status" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_UserNotifications_pkey" PRIMARY KEY ("request_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_TeamMembership" ( + "user_id" TEXT NOT NULL, + "team_id" TEXT NOT NULL, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "budget_id" TEXT, + + CONSTRAINT "LiteLLM_TeamMembership_pkey" PRIMARY KEY ("user_id","team_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_OrganizationMembership" ( + "user_id" TEXT NOT NULL, + "organization_id" TEXT NOT NULL, + "user_role" TEXT, + "spend" DOUBLE PRECISION DEFAULT 0.0, + "budget_id" TEXT, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "LiteLLM_OrganizationMembership_pkey" PRIMARY KEY ("user_id","organization_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_InvitationLink" ( + "id" TEXT NOT NULL, + "user_id" TEXT NOT NULL, + "is_accepted" BOOLEAN NOT NULL DEFAULT false, + "accepted_at" TIMESTAMP(3), + "expires_at" TIMESTAMP(3) NOT NULL, + "created_at" TIMESTAMP(3) NOT NULL, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_InvitationLink_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_AuditLog" ( + "id" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "changed_by" TEXT NOT NULL DEFAULT '', + "changed_by_api_key" TEXT NOT NULL DEFAULT '', + "action" TEXT NOT NULL, + "table_name" TEXT NOT NULL, + "object_id" TEXT NOT NULL, + "before_value" JSONB, + "updated_values" JSONB, + + CONSTRAINT "LiteLLM_AuditLog_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_DailyUserSpend" ( + "id" TEXT NOT NULL, + "user_id" TEXT, + "date" TEXT NOT NULL, + "api_key" TEXT NOT NULL, + "model" TEXT, + "model_group" TEXT, + "custom_llm_provider" TEXT, + "mcp_namespaced_tool_name" TEXT, + "prompt_tokens" BIGINT NOT NULL DEFAULT 0, + "completion_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_read_input_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_creation_input_tokens" BIGINT NOT NULL DEFAULT 0, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "api_requests" BIGINT NOT NULL DEFAULT 0, + "successful_requests" BIGINT NOT NULL DEFAULT 0, + "failed_requests" BIGINT NOT NULL DEFAULT 0, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_DailyUserSpend_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_DailyTeamSpend" ( + "id" TEXT NOT NULL, + "team_id" TEXT, + "date" TEXT NOT NULL, + "api_key" TEXT NOT NULL, + "model" TEXT, + "model_group" TEXT, + "custom_llm_provider" TEXT, + "mcp_namespaced_tool_name" TEXT, + "prompt_tokens" BIGINT NOT NULL DEFAULT 0, + "completion_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_read_input_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_creation_input_tokens" BIGINT NOT NULL DEFAULT 0, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "api_requests" BIGINT NOT NULL DEFAULT 0, + "successful_requests" BIGINT NOT NULL DEFAULT 0, + "failed_requests" BIGINT NOT NULL DEFAULT 0, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_DailyTeamSpend_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_DailyTagSpend" ( + "id" TEXT NOT NULL, + "tag" TEXT, + "date" TEXT NOT NULL, + "api_key" TEXT NOT NULL, + "model" TEXT, + "model_group" TEXT, + "custom_llm_provider" TEXT, + "mcp_namespaced_tool_name" TEXT, + "prompt_tokens" BIGINT NOT NULL DEFAULT 0, + "completion_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_read_input_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_creation_input_tokens" BIGINT NOT NULL DEFAULT 0, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "api_requests" BIGINT NOT NULL DEFAULT 0, + "successful_requests" BIGINT NOT NULL DEFAULT 0, + "failed_requests" BIGINT NOT NULL DEFAULT 0, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_DailyTagSpend_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_CronJob" ( + "cronjob_id" TEXT NOT NULL, + "pod_id" TEXT NOT NULL, + "status" "JobStatus" NOT NULL DEFAULT 'INACTIVE', + "last_updated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "ttl" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_CronJob_pkey" PRIMARY KEY ("cronjob_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ManagedFileTable" ( + "id" TEXT NOT NULL, + "unified_file_id" TEXT NOT NULL, + "file_object" JSONB, + "model_mappings" JSONB NOT NULL, + "flat_model_file_ids" TEXT[] DEFAULT ARRAY[]::TEXT[], + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) NOT NULL, + "updated_by" TEXT, + + CONSTRAINT "LiteLLM_ManagedFileTable_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ManagedObjectTable" ( + "id" TEXT NOT NULL, + "unified_object_id" TEXT NOT NULL, + "model_object_id" TEXT NOT NULL, + "file_object" JSONB NOT NULL, + "file_purpose" TEXT NOT NULL, + "status" TEXT, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) NOT NULL, + "updated_by" TEXT, + + CONSTRAINT "LiteLLM_ManagedObjectTable_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ManagedVectorStoresTable" ( + "vector_store_id" TEXT NOT NULL, + "custom_llm_provider" TEXT NOT NULL, + "vector_store_name" TEXT, + "vector_store_description" TEXT, + "vector_store_metadata" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + "litellm_credential_name" TEXT, + "litellm_params" JSONB, + + CONSTRAINT "LiteLLM_ManagedVectorStoresTable_pkey" PRIMARY KEY ("vector_store_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_GuardrailsTable" ( + "guardrail_id" TEXT NOT NULL, + "guardrail_name" TEXT NOT NULL, + "litellm_params" JSONB NOT NULL, + "guardrail_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_GuardrailsTable_pkey" PRIMARY KEY ("guardrail_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_PromptTable" ( + "id" TEXT NOT NULL, + "prompt_id" TEXT NOT NULL, + "litellm_params" JSONB NOT NULL, + "prompt_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_PromptTable_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_HealthCheckTable" ( + "health_check_id" TEXT NOT NULL, + "model_name" TEXT NOT NULL, + "model_id" TEXT, + "status" TEXT NOT NULL, + "healthy_count" INTEGER NOT NULL DEFAULT 0, + "unhealthy_count" INTEGER NOT NULL DEFAULT 0, + "error_message" TEXT, + "response_time_ms" DOUBLE PRECISION, + "details" JSONB, + "checked_by" TEXT, + "checked_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_HealthCheckTable_pkey" PRIMARY KEY ("health_check_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_SearchToolsTable" ( + "search_tool_id" TEXT NOT NULL, + "search_tool_name" TEXT NOT NULL, + "litellm_params" JSONB NOT NULL, + "search_tool_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_SearchToolsTable_pkey" PRIMARY KEY ("search_tool_id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_CredentialsTable_credential_name_key" ON "LiteLLM_CredentialsTable"("credential_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_TeamTable_model_id_key" ON "LiteLLM_TeamTable"("model_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_UserTable_sso_user_id_key" ON "LiteLLM_UserTable"("sso_user_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_SpendLogs_startTime_idx" ON "LiteLLM_SpendLogs"("startTime"); + +-- CreateIndex +CREATE INDEX "LiteLLM_SpendLogs_end_user_idx" ON "LiteLLM_SpendLogs"("end_user"); + +-- CreateIndex +CREATE INDEX "LiteLLM_SpendLogs_session_id_idx" ON "LiteLLM_SpendLogs"("session_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_OrganizationMembership_user_id_organization_id_key" ON "LiteLLM_OrganizationMembership"("user_id", "organization_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_date_idx" ON "LiteLLM_DailyUserSpend"("date"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_user_id_idx" ON "LiteLLM_DailyUserSpend"("user_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_api_key_idx" ON "LiteLLM_DailyUserSpend"("api_key"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_model_idx" ON "LiteLLM_DailyUserSpend"("model"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_mcp_namespaced_tool_name_idx" ON "LiteLLM_DailyUserSpend"("mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_DailyUserSpend_user_id_date_api_key_model_custom_ll_key" ON "LiteLLM_DailyUserSpend"("user_id", "date", "api_key", "model", "custom_llm_provider", "mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_date_idx" ON "LiteLLM_DailyTeamSpend"("date"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_team_id_idx" ON "LiteLLM_DailyTeamSpend"("team_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_api_key_idx" ON "LiteLLM_DailyTeamSpend"("api_key"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_model_idx" ON "LiteLLM_DailyTeamSpend"("model"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_mcp_namespaced_tool_name_idx" ON "LiteLLM_DailyTeamSpend"("mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_DailyTeamSpend_team_id_date_api_key_model_custom_ll_key" ON "LiteLLM_DailyTeamSpend"("team_id", "date", "api_key", "model", "custom_llm_provider", "mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_date_idx" ON "LiteLLM_DailyTagSpend"("date"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_tag_idx" ON "LiteLLM_DailyTagSpend"("tag"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_api_key_idx" ON "LiteLLM_DailyTagSpend"("api_key"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_model_idx" ON "LiteLLM_DailyTagSpend"("model"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_mcp_namespaced_tool_name_idx" ON "LiteLLM_DailyTagSpend"("mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_DailyTagSpend_tag_date_api_key_model_custom_llm_pro_key" ON "LiteLLM_DailyTagSpend"("tag", "date", "api_key", "model", "custom_llm_provider", "mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_ManagedFileTable_unified_file_id_key" ON "LiteLLM_ManagedFileTable"("unified_file_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_ManagedFileTable_unified_file_id_idx" ON "LiteLLM_ManagedFileTable"("unified_file_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_ManagedObjectTable_unified_object_id_key" ON "LiteLLM_ManagedObjectTable"("unified_object_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_ManagedObjectTable_model_object_id_key" ON "LiteLLM_ManagedObjectTable"("model_object_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_ManagedObjectTable_unified_object_id_idx" ON "LiteLLM_ManagedObjectTable"("unified_object_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_ManagedObjectTable_model_object_id_idx" ON "LiteLLM_ManagedObjectTable"("model_object_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_GuardrailsTable_guardrail_name_key" ON "LiteLLM_GuardrailsTable"("guardrail_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_PromptTable_prompt_id_key" ON "LiteLLM_PromptTable"("prompt_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_HealthCheckTable_model_name_idx" ON "LiteLLM_HealthCheckTable"("model_name"); + +-- CreateIndex +CREATE INDEX "LiteLLM_HealthCheckTable_checked_at_idx" ON "LiteLLM_HealthCheckTable"("checked_at"); + +-- CreateIndex +CREATE INDEX "LiteLLM_HealthCheckTable_status_idx" ON "LiteLLM_HealthCheckTable"("status"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_SearchToolsTable_search_tool_name_key" ON "LiteLLM_SearchToolsTable"("search_tool_name"); + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationTable" ADD CONSTRAINT "LiteLLM_OrganizationTable_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationTable" ADD CONSTRAINT "LiteLLM_OrganizationTable_object_permission_id_fkey" FOREIGN KEY ("object_permission_id") REFERENCES "LiteLLM_ObjectPermissionTable"("object_permission_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TeamTable" ADD CONSTRAINT "LiteLLM_TeamTable_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "LiteLLM_OrganizationTable"("organization_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TeamTable" ADD CONSTRAINT "LiteLLM_TeamTable_model_id_fkey" FOREIGN KEY ("model_id") REFERENCES "LiteLLM_ModelTable"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TeamTable" ADD CONSTRAINT "LiteLLM_TeamTable_object_permission_id_fkey" FOREIGN KEY ("object_permission_id") REFERENCES "LiteLLM_ObjectPermissionTable"("object_permission_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_UserTable" ADD CONSTRAINT "LiteLLM_UserTable_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "LiteLLM_OrganizationTable"("organization_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_UserTable" ADD CONSTRAINT "LiteLLM_UserTable_object_permission_id_fkey" FOREIGN KEY ("object_permission_id") REFERENCES "LiteLLM_ObjectPermissionTable"("object_permission_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_VerificationToken" ADD CONSTRAINT "LiteLLM_VerificationToken_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_VerificationToken" ADD CONSTRAINT "LiteLLM_VerificationToken_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "LiteLLM_OrganizationTable"("organization_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_VerificationToken" ADD CONSTRAINT "LiteLLM_VerificationToken_object_permission_id_fkey" FOREIGN KEY ("object_permission_id") REFERENCES "LiteLLM_ObjectPermissionTable"("object_permission_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_EndUserTable" ADD CONSTRAINT "LiteLLM_EndUserTable_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TagTable" ADD CONSTRAINT "LiteLLM_TagTable_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TeamMembership" ADD CONSTRAINT "LiteLLM_TeamMembership_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationMembership" ADD CONSTRAINT "LiteLLM_OrganizationMembership_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "LiteLLM_UserTable"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationMembership" ADD CONSTRAINT "LiteLLM_OrganizationMembership_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "LiteLLM_OrganizationTable"("organization_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationMembership" ADD CONSTRAINT "LiteLLM_OrganizationMembership_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_InvitationLink" ADD CONSTRAINT "LiteLLM_InvitationLink_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "LiteLLM_UserTable"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_InvitationLink" ADD CONSTRAINT "LiteLLM_InvitationLink_created_by_fkey" FOREIGN KEY ("created_by") REFERENCES "LiteLLM_UserTable"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_InvitationLink" ADD CONSTRAINT "LiteLLM_InvitationLink_updated_by_fkey" FOREIGN KEY ("updated_by") REFERENCES "LiteLLM_UserTable"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE; + diff --git a/deploy/migrations/20251030013602_schema_update/README.md b/deploy/migrations/20251030013602_schema_update/README.md new file mode 100644 index 000000000000..eb3733788ebd --- /dev/null +++ b/deploy/migrations/20251030013602_schema_update/README.md @@ -0,0 +1 @@ +Migration generated at Thu Oct 30 01:36:03 UTC 2025 diff --git a/deploy/migrations/20251030013602_schema_update/migration.sql b/deploy/migrations/20251030013602_schema_update/migration.sql new file mode 100644 index 000000000000..2f725d838066 --- /dev/null +++ b/deploy/migrations/20251030013602_schema_update/migration.sql @@ -0,0 +1,2 @@ +-- This is an empty migration. + diff --git a/deploy/migrations/migration_lock.toml b/deploy/migrations/migration_lock.toml new file mode 100644 index 000000000000..2fe25d87cc30 --- /dev/null +++ b/deploy/migrations/migration_lock.toml @@ -0,0 +1 @@ +provider = "postgresql" diff --git a/docker/Dockerfile.non_root b/docker/Dockerfile.non_root index 4178724e6e4e..e8a59dd08f86 100644 --- a/docker/Dockerfile.non_root +++ b/docker/Dockerfile.non_root @@ -19,7 +19,13 @@ COPY . . # Build Admin UI RUN chmod +x docker/build_admin_ui.sh && ./docker/build_admin_ui.sh -# Build package and wheel dependencies +# Build litellm-proxy-extras package first (includes new migrations) +RUN cd litellm-proxy-extras && \ + rm -rf dist/* && \ + python -m build && \ + cd .. + +# Build main package and wheel dependencies RUN rm -rf dist/* && python -m build && \ pip install dist/*.whl && \ pip wheel --no-cache-dir --wheel-dir=/wheels/ -r requirements.txt diff --git a/enterprise/dist/litellm_enterprise-0.1.1-py3-none-any.whl b/enterprise/dist/litellm_enterprise-0.1.1-py3-none-any.whl deleted file mode 100644 index d9a8ef41e62a..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.1-py3-none-any.whl and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.1.tar.gz b/enterprise/dist/litellm_enterprise-0.1.1.tar.gz deleted file mode 100644 index 98cf132b213d..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.1.tar.gz and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.10-py3-none-any.whl b/enterprise/dist/litellm_enterprise-0.1.10-py3-none-any.whl deleted file mode 100644 index 473ff736e3a5..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.10-py3-none-any.whl and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.10.tar.gz b/enterprise/dist/litellm_enterprise-0.1.10.tar.gz deleted file mode 100644 index e28ee65c3892..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.10.tar.gz and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.11-py3-none-any.whl b/enterprise/dist/litellm_enterprise-0.1.11-py3-none-any.whl deleted file mode 100644 index 3dece3053d25..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.11-py3-none-any.whl and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.11.tar.gz b/enterprise/dist/litellm_enterprise-0.1.11.tar.gz deleted file mode 100644 index 02b62c3ddac8..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.11.tar.gz and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.12-py3-none-any.whl b/enterprise/dist/litellm_enterprise-0.1.12-py3-none-any.whl deleted file mode 100644 index 9f72a920141b..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.12-py3-none-any.whl and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.12.tar.gz b/enterprise/dist/litellm_enterprise-0.1.12.tar.gz deleted file mode 100644 index cbaeff7d77e6..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.12.tar.gz and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.13-py3-none-any.whl b/enterprise/dist/litellm_enterprise-0.1.13-py3-none-any.whl deleted file mode 100644 index e9f350030b98..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.13-py3-none-any.whl and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.13.tar.gz b/enterprise/dist/litellm_enterprise-0.1.13.tar.gz deleted file mode 100644 index bde63337ab30..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.13.tar.gz and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.15-py3-none-any.whl b/enterprise/dist/litellm_enterprise-0.1.15-py3-none-any.whl deleted file mode 100644 index 99381c7f65de..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.15-py3-none-any.whl and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.15.tar.gz b/enterprise/dist/litellm_enterprise-0.1.15.tar.gz deleted file mode 100644 index 794a6a1b870a..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.15.tar.gz and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.17-py3-none-any.whl b/enterprise/dist/litellm_enterprise-0.1.17-py3-none-any.whl deleted file mode 100644 index 9c2856b4652e..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.17-py3-none-any.whl and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.17.tar.gz b/enterprise/dist/litellm_enterprise-0.1.17.tar.gz deleted file mode 100644 index 92d4a6ee92fb..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.17.tar.gz and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.19-py3-none-any.whl b/enterprise/dist/litellm_enterprise-0.1.19-py3-none-any.whl deleted file mode 100644 index 5b48b65e4d22..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.19-py3-none-any.whl and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.19.tar.gz b/enterprise/dist/litellm_enterprise-0.1.19.tar.gz deleted file mode 100644 index 2f99960bdeb9..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.19.tar.gz and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.2-py3-none-any.whl b/enterprise/dist/litellm_enterprise-0.1.2-py3-none-any.whl deleted file mode 100644 index 1f75e0f1b5ca..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.2-py3-none-any.whl and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.2.tar.gz b/enterprise/dist/litellm_enterprise-0.1.2.tar.gz deleted file mode 100644 index b6fa4dd5f7b8..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.2.tar.gz and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.3-py3-none-any.whl b/enterprise/dist/litellm_enterprise-0.1.3-py3-none-any.whl deleted file mode 100644 index 7b5cb8565665..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.3-py3-none-any.whl and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.3.tar.gz b/enterprise/dist/litellm_enterprise-0.1.3.tar.gz deleted file mode 100644 index d5ac9f26a47d..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.3.tar.gz and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.4-py3-none-any.whl b/enterprise/dist/litellm_enterprise-0.1.4-py3-none-any.whl deleted file mode 100644 index f862a55b18b2..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.4-py3-none-any.whl and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.4.tar.gz b/enterprise/dist/litellm_enterprise-0.1.4.tar.gz deleted file mode 100644 index bf1b3ec57c11..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.4.tar.gz and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.5-py3-none-any.whl b/enterprise/dist/litellm_enterprise-0.1.5-py3-none-any.whl deleted file mode 100644 index 661638db3f9f..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.5-py3-none-any.whl and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.5.tar.gz b/enterprise/dist/litellm_enterprise-0.1.5.tar.gz deleted file mode 100644 index 2808574ddac6..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.5.tar.gz and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.6-py3-none-any.whl b/enterprise/dist/litellm_enterprise-0.1.6-py3-none-any.whl deleted file mode 100644 index c212c7e5a3d6..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.6-py3-none-any.whl and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.6.tar.gz b/enterprise/dist/litellm_enterprise-0.1.6.tar.gz deleted file mode 100644 index 698a9da2095d..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.6.tar.gz and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.7-py3-none-any.whl b/enterprise/dist/litellm_enterprise-0.1.7-py3-none-any.whl deleted file mode 100644 index 248e1ca294d9..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.7-py3-none-any.whl and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.7.tar.gz b/enterprise/dist/litellm_enterprise-0.1.7.tar.gz deleted file mode 100644 index 7c28d3a36aff..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.7.tar.gz and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.8-py3-none-any.whl b/enterprise/dist/litellm_enterprise-0.1.8-py3-none-any.whl deleted file mode 100644 index b9470dca4680..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.8-py3-none-any.whl and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.8.tar.gz b/enterprise/dist/litellm_enterprise-0.1.8.tar.gz deleted file mode 100644 index f233be2be8f9..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.8.tar.gz and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.9-py3-none-any.whl b/enterprise/dist/litellm_enterprise-0.1.9-py3-none-any.whl deleted file mode 100644 index eb4b9d1083b4..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.9-py3-none-any.whl and /dev/null differ diff --git a/enterprise/dist/litellm_enterprise-0.1.9.tar.gz b/enterprise/dist/litellm_enterprise-0.1.9.tar.gz deleted file mode 100644 index 748ed2150efd..000000000000 Binary files a/enterprise/dist/litellm_enterprise-0.1.9.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.0-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.0-py3-none-any.whl deleted file mode 100644 index 1aff64ef5852..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.0-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.0.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.0.tar.gz deleted file mode 100644 index 0bdf82816311..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.0.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.1-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.1-py3-none-any.whl deleted file mode 100644 index e2583935a4cf..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.1-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.1.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.1.tar.gz deleted file mode 100644 index c9111dd9c360..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.1.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.12-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.12-py3-none-any.whl deleted file mode 100644 index 29fea44cf277..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.12-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.12.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.12.tar.gz deleted file mode 100644 index 7e156b25884d..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.12.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.14-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.14-py3-none-any.whl deleted file mode 100644 index a40f07acf744..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.14-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.14.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.14.tar.gz deleted file mode 100644 index 382e20f6b50e..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.14.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.15-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.15-py3-none-any.whl deleted file mode 100644 index 1b8ba5f63d4a..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.15-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.15.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.15.tar.gz deleted file mode 100644 index 1f207ac381ff..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.15.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.17-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.17-py3-none-any.whl deleted file mode 100644 index 5e64ad7733a1..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.17-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.17.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.17.tar.gz deleted file mode 100644 index 49183ba24f2b..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.17.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.18-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.18-py3-none-any.whl deleted file mode 100644 index 42621943a0e0..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.18-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.18.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.18.tar.gz deleted file mode 100644 index 9b83e532a846..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.18.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.19-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.19-py3-none-any.whl deleted file mode 100644 index 1506322a02d2..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.19-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.19.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.19.tar.gz deleted file mode 100644 index 3deaee390f8f..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.19.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.2-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.2-py3-none-any.whl deleted file mode 100644 index a034034c24e9..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.2-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.2.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.2.tar.gz deleted file mode 100644 index b3157d42cdd9..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.2.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.20-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.20-py3-none-any.whl deleted file mode 100644 index 60d9d8130aa1..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.20-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.20.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.20.tar.gz deleted file mode 100644 index 1f01d5067e91..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.20.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.21-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.21-py3-none-any.whl deleted file mode 100644 index 8602cd14ed65..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.21-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.21.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.21.tar.gz deleted file mode 100644 index 2074d2256fa5..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.21.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.3-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.3-py3-none-any.whl deleted file mode 100644 index 12f72a933f9a..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.3-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.3.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.3.tar.gz deleted file mode 100644 index 590be316287a..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.3.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.4-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.4-py3-none-any.whl deleted file mode 100644 index 498d0941ed87..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.4-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.4.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.4.tar.gz deleted file mode 100644 index 80920457bf86..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.4.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.7-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.7-py3-none-any.whl deleted file mode 100644 index cf7b2a1953dc..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.7-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.7.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.7.tar.gz deleted file mode 100644 index 5934d5dfb90d..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.7.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.8-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.8-py3-none-any.whl deleted file mode 100644 index b4a2ca73d266..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.8-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.8.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.8.tar.gz deleted file mode 100644 index a254112d2b4e..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.1.8.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.1-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.1-py3-none-any.whl deleted file mode 100644 index 30da05bb8aab..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.1-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.1.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.1.tar.gz deleted file mode 100644 index 8b802f0d37e5..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.1.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.10-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.10-py3-none-any.whl deleted file mode 100644 index a0ffa5e7d398..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.10-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.10.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.10.tar.gz deleted file mode 100644 index f8985cb47edc..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.10.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.14-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.14-py3-none-any.whl deleted file mode 100644 index fc160319c07a..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.14-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.14.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.14.tar.gz deleted file mode 100644 index b5d3f317b967..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.14.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.2-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.2-py3-none-any.whl deleted file mode 100644 index 15aef8728fd5..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.2-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.2.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.2.tar.gz deleted file mode 100644 index 66342f3bdbcc..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.2.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.4-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.4-py3-none-any.whl deleted file mode 100644 index 429a22432cee..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.4-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.4.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.4.tar.gz deleted file mode 100644 index 7837e491db7c..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.4.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.5-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.5-py3-none-any.whl deleted file mode 100644 index ec9728a9dc78..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.5-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.5.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.5.tar.gz deleted file mode 100644 index 2d07b68338d5..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.5.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.7-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.7-py3-none-any.whl deleted file mode 100644 index a6cc10e3df1d..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.7-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.7.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.7.tar.gz deleted file mode 100644 index 107d05d477ce..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.7.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.8-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.8-py3-none-any.whl deleted file mode 100644 index e7a8b94b8e45..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.8-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.8.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.8.tar.gz deleted file mode 100644 index 638fe607e711..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.8.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.9-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.9-py3-none-any.whl deleted file mode 100644 index eb2863d483c8..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.9-py3-none-any.whl and /dev/null differ diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.9.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.9.tar.gz deleted file mode 100644 index 0f2deee1f6d9..000000000000 Binary files a/litellm-proxy-extras/dist/litellm_proxy_extras-0.2.9.tar.gz and /dev/null differ diff --git a/litellm-proxy-extras/litellm_proxy_extras/migrations/20250930000000_fix_mcp_server_name_column/migration.sql b/litellm-proxy-extras/litellm_proxy_extras/migrations/20250930000000_fix_mcp_server_name_column/migration.sql new file mode 100644 index 000000000000..ae6cacaaa579 --- /dev/null +++ b/litellm-proxy-extras/litellm_proxy_extras/migrations/20250930000000_fix_mcp_server_name_column/migration.sql @@ -0,0 +1,51 @@ +-- Emergency fix for MCP server_name column issue +-- This migration ensures the server_name column exists regardless of previous migration state +-- Safe to run multiple times - it's idempotent + +DO $$ +BEGIN + -- Check if table exists first + IF EXISTS ( + SELECT FROM information_schema.tables + WHERE table_schema = 'public' + AND table_name = 'LiteLLM_MCPServerTable' + ) THEN + -- If server_name doesn't exist but alias does, rename it + IF NOT EXISTS ( + SELECT FROM information_schema.columns + WHERE table_name = 'LiteLLM_MCPServerTable' + AND column_name = 'server_name' + ) AND EXISTS ( + SELECT FROM information_schema.columns + WHERE table_name = 'LiteLLM_MCPServerTable' + AND column_name = 'alias' + ) THEN + RAISE NOTICE 'Renaming alias to server_name...'; + ALTER TABLE "LiteLLM_MCPServerTable" RENAME COLUMN "alias" TO "server_name"; + END IF; + + -- Ensure server_name column exists (in case it was never there) + IF NOT EXISTS ( + SELECT FROM information_schema.columns + WHERE table_name = 'LiteLLM_MCPServerTable' + AND column_name = 'server_name' + ) THEN + RAISE NOTICE 'Adding server_name column...'; + ALTER TABLE "LiteLLM_MCPServerTable" ADD COLUMN "server_name" TEXT; + END IF; + + -- Ensure alias column exists (for backward compatibility) + IF NOT EXISTS ( + SELECT FROM information_schema.columns + WHERE table_name = 'LiteLLM_MCPServerTable' + AND column_name = 'alias' + ) THEN + RAISE NOTICE 'Adding alias column for backward compatibility...'; + ALTER TABLE "LiteLLM_MCPServerTable" ADD COLUMN "alias" TEXT; + END IF; + + RAISE NOTICE 'MCP server_name column fix completed successfully'; + ELSE + RAISE NOTICE 'LiteLLM_MCPServerTable does not exist, skipping fix'; + END IF; +END $$; diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 938c8979d2ca..c0d36c1c5cf2 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -85,6 +85,8 @@ def showwarning(message, category, filename, lineno, file=None, line=None): import orjson import yaml # type: ignore from apscheduler.schedulers.asyncio import AsyncIOScheduler + from apscheduler.jobstores.memory import MemoryJobStore + from apscheduler.executors.asyncio import AsyncIOExecutor except ImportError as e: raise ImportError(f"Missing dependency {e}. Run `pip install 'litellm[proxy]'`") @@ -4164,6 +4166,8 @@ async def initialize_scheduled_background_jobs( "spend_report_frequency must be specified in days, e.g., '1d', '7d'" ) + from datetime import datetime, timedelta + scheduler.add_job( proxy_logging_obj.slack_alerting_instance.send_weekly_spend_report, "interval", diff --git a/litellm/responses/litellm_completion_transformation/handler.py b/litellm/responses/litellm_completion_transformation/handler.py index 7e0b4cfa2437..5ee6770e9296 100644 --- a/litellm/responses/litellm_completion_transformation/handler.py +++ b/litellm/responses/litellm_completion_transformation/handler.py @@ -5,6 +5,8 @@ from typing import Any, Coroutine, Dict, Optional, Union import litellm +# PATCH: Additional imports for Redis session storage +import uuid from litellm.responses.litellm_completion_transformation.streaming_iterator import ( LiteLLMCompletionStreamingIterator, ) @@ -127,6 +129,16 @@ async def async_response_api_handler( ) ) + # PATCH: Store session immediately in Redis to avoid batch processing delay + if responses_api_response.id: + session_id = kwargs.get("litellm_trace_id") or str(uuid.uuid4()) + current_messages = litellm_completion_request.get("messages", []) + await LiteLLMCompletionResponsesConfig._patch_store_session_in_redis( + response_id=responses_api_response.id, + session_id=session_id, + messages=current_messages + ) + return responses_api_response elif isinstance(litellm_completion_response, litellm.CustomStreamWrapper): diff --git a/litellm/responses/litellm_completion_transformation/streaming_iterator.py b/litellm/responses/litellm_completion_transformation/streaming_iterator.py index 7c79c575a5bd..eee65c89f76a 100644 --- a/litellm/responses/litellm_completion_transformation/streaming_iterator.py +++ b/litellm/responses/litellm_completion_transformation/streaming_iterator.py @@ -442,6 +442,7 @@ def _transform_chat_completion_chunk_to_response_api_chunk( ): reasoning_content = chunk.choices[0].delta.reasoning_content + encoded_chunk_id = self._encode_chunk_id(chunk.id) return ReasoningSummaryTextDeltaEvent( type=ResponsesAPIStreamEvents.REASONING_SUMMARY_TEXT_DELTA, item_id=f"rs_{hash(str(reasoning_content))}", @@ -516,9 +517,60 @@ def _emit_response_completed_event( litellm_metadata=self.litellm_metadata, ) + responses_api_response = LiteLLMCompletionResponsesConfig.transform_chat_completion_response_to_responses_api_response( + request_input=self.request_input, + chat_completion_response=litellm_model_response, + responses_api_request=self.responses_api_request, + ) + + # PATCH: Store session immediately in Redis for streaming responses + # This ensures the session is available for subsequent requests + if responses_api_response.id: + # Store the completed event to be used in async context + self.response_completed_event = ResponseCompletedEvent( + type=ResponsesAPIStreamEvents.RESPONSE_COMPLETED, + response=responses_api_response, + ) + return self.response_completed_event + return ResponseCompletedEvent( type=ResponsesAPIStreamEvents.RESPONSE_COMPLETED, response=encoded_response, ) else: return None + + async def _store_session_in_redis(self, response_completed_event: ResponseCompletedEvent): + """ + PATCH: Store session in Redis for streaming responses + This fixes the issue where Redis sessions weren't created for streaming requests + """ + try: + response = response_completed_event.response + if response and response.id: + # Get the session ID from metadata or from the completion request + session_id = (self.litellm_completion_request.get("litellm_trace_id") or + self.litellm_metadata.get("litellm_trace_id") or + str(uuid.uuid4())) + + # Get the full messages from the completion request (includes history) + messages = self.litellm_completion_request.get("messages", []).copy() + + # Add the assistant response to the messages + if response.output and len(response.output) > 0: + output_item = response.output[0] + if output_item.content and len(output_item.content) > 0: + content_item = output_item.content[0] + if hasattr(content_item, "text"): + messages.append({"role": "assistant", "content": content_item.text}) + + # Store session in Redis + await LiteLLMCompletionResponsesConfig._patch_store_session_in_redis( + response_id=response.id, + session_id=session_id, + messages=messages + ) + except Exception: + # Silently fail - Redis storage is a patch for timing issues + # and shouldn't break the streaming response + pass diff --git a/litellm/responses/litellm_completion_transformation/transformation.py b/litellm/responses/litellm_completion_transformation/transformation.py index e021f4c16d14..726357c9ba0d 100644 --- a/litellm/responses/litellm_completion_transformation/transformation.py +++ b/litellm/responses/litellm_completion_transformation/transformation.py @@ -4,6 +4,10 @@ from typing import Any, Dict, List, Literal, Optional, Tuple, Union, cast +# PATCH: Additional imports for Redis session storage +from datetime import datetime +import json + from openai.types.responses.tool_param import FunctionToolParam from typing_extensions import TypedDict @@ -207,6 +211,8 @@ async def async_responses_api_session_handler( ) -> dict: """ Async hook to get the chain of previous input and output pairs and return a list of Chat Completion messages + + PATCH: Added Redis-first lookup to fix conversation context timing issues """ chat_completion_session = ChatCompletionSession( messages=[], litellm_session_id=None diff --git a/responses_api_config.yaml b/responses_api_config.yaml new file mode 100644 index 000000000000..a16bebaccda3 --- /dev/null +++ b/responses_api_config.yaml @@ -0,0 +1,36 @@ +# LiteLLM Responses API Test Configuration +# This config includes multiple providers for testing the Responses API + +model_list: + # Anthropic Claude + - model_name: claude-3-5-sonnet + litellm_params: + model: claude-3-5-sonnet-20241022 + api_key: YOUR_ANTHROPIC_API_KEY # Replace with your key + + # DeepSeek + - model_name: deepseek-chat + litellm_params: + model: deepseek-chat + api_key: YOUR_DEEPSEEK_API_KEY # Replace with your key + api_base: https://api.deepseek.com + + # Google Gemini + - model_name: gemini-2.0-flash + litellm_params: + model: gemini/gemini-2.0-flash-exp + api_key: YOUR_GOOGLE_API_KEY # Replace with your key + +# LiteLLM settings +litellm_settings: + set_verbose: false # Set to true for debugging + cache: true # REQUIRED for Responses API session management + cache_params: + type: "redis" + host: "localhost" + port: 6379 + # password: "" # Uncomment if Redis requires password + +# General settings +general_settings: + master_key: sk-test-key-1234 # API key for accessing the proxy \ No newline at end of file diff --git a/temp_migrations/20251030013554_initial/README.md b/temp_migrations/20251030013554_initial/README.md new file mode 100644 index 000000000000..219a9a1d91f3 --- /dev/null +++ b/temp_migrations/20251030013554_initial/README.md @@ -0,0 +1 @@ +Initial migration generated at Thu Oct 30 01:36:02 UTC 2025 diff --git a/temp_migrations/20251030013554_initial/migration.sql b/temp_migrations/20251030013554_initial/migration.sql new file mode 100644 index 000000000000..15dc3e1ff2b2 --- /dev/null +++ b/temp_migrations/20251030013554_initial/migration.sql @@ -0,0 +1,723 @@ +-- CreateEnum +CREATE TYPE "JobStatus" AS ENUM ('ACTIVE', 'INACTIVE'); + +-- CreateTable +CREATE TABLE "LiteLLM_BudgetTable" ( + "budget_id" TEXT NOT NULL, + "max_budget" DOUBLE PRECISION, + "soft_budget" DOUBLE PRECISION, + "max_parallel_requests" INTEGER, + "tpm_limit" BIGINT, + "rpm_limit" BIGINT, + "model_max_budget" JSONB, + "budget_duration" TEXT, + "budget_reset_at" TIMESTAMP(3), + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_BudgetTable_pkey" PRIMARY KEY ("budget_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_CredentialsTable" ( + "credential_id" TEXT NOT NULL, + "credential_name" TEXT NOT NULL, + "credential_values" JSONB NOT NULL, + "credential_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_CredentialsTable_pkey" PRIMARY KEY ("credential_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ProxyModelTable" ( + "model_id" TEXT NOT NULL, + "model_name" TEXT NOT NULL, + "litellm_params" JSONB NOT NULL, + "model_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_ProxyModelTable_pkey" PRIMARY KEY ("model_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_OrganizationTable" ( + "organization_id" TEXT NOT NULL, + "organization_alias" TEXT NOT NULL, + "budget_id" TEXT NOT NULL, + "metadata" JSONB NOT NULL DEFAULT '{}', + "models" TEXT[], + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "model_spend" JSONB NOT NULL DEFAULT '{}', + "object_permission_id" TEXT, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_OrganizationTable_pkey" PRIMARY KEY ("organization_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ModelTable" ( + "id" SERIAL NOT NULL, + "aliases" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_ModelTable_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_TeamTable" ( + "team_id" TEXT NOT NULL, + "team_alias" TEXT, + "organization_id" TEXT, + "object_permission_id" TEXT, + "admins" TEXT[], + "members" TEXT[], + "members_with_roles" JSONB NOT NULL DEFAULT '{}', + "metadata" JSONB NOT NULL DEFAULT '{}', + "max_budget" DOUBLE PRECISION, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "models" TEXT[], + "max_parallel_requests" INTEGER, + "tpm_limit" BIGINT, + "rpm_limit" BIGINT, + "budget_duration" TEXT, + "budget_reset_at" TIMESTAMP(3), + "blocked" BOOLEAN NOT NULL DEFAULT false, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "model_spend" JSONB NOT NULL DEFAULT '{}', + "model_max_budget" JSONB NOT NULL DEFAULT '{}', + "team_member_permissions" TEXT[] DEFAULT ARRAY[]::TEXT[], + "model_id" INTEGER, + + CONSTRAINT "LiteLLM_TeamTable_pkey" PRIMARY KEY ("team_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_UserTable" ( + "user_id" TEXT NOT NULL, + "user_alias" TEXT, + "team_id" TEXT, + "sso_user_id" TEXT, + "organization_id" TEXT, + "object_permission_id" TEXT, + "password" TEXT, + "teams" TEXT[] DEFAULT ARRAY[]::TEXT[], + "user_role" TEXT, + "max_budget" DOUBLE PRECISION, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "user_email" TEXT, + "models" TEXT[], + "metadata" JSONB NOT NULL DEFAULT '{}', + "max_parallel_requests" INTEGER, + "tpm_limit" BIGINT, + "rpm_limit" BIGINT, + "budget_duration" TEXT, + "budget_reset_at" TIMESTAMP(3), + "allowed_cache_controls" TEXT[] DEFAULT ARRAY[]::TEXT[], + "model_spend" JSONB NOT NULL DEFAULT '{}', + "model_max_budget" JSONB NOT NULL DEFAULT '{}', + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "LiteLLM_UserTable_pkey" PRIMARY KEY ("user_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ObjectPermissionTable" ( + "object_permission_id" TEXT NOT NULL, + "mcp_servers" TEXT[] DEFAULT ARRAY[]::TEXT[], + "mcp_access_groups" TEXT[] DEFAULT ARRAY[]::TEXT[], + "mcp_tool_permissions" JSONB, + "vector_stores" TEXT[] DEFAULT ARRAY[]::TEXT[], + + CONSTRAINT "LiteLLM_ObjectPermissionTable_pkey" PRIMARY KEY ("object_permission_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_MCPServerTable" ( + "server_id" TEXT NOT NULL, + "server_name" TEXT, + "alias" TEXT, + "description" TEXT, + "url" TEXT, + "transport" TEXT NOT NULL DEFAULT 'sse', + "auth_type" TEXT, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT, + "mcp_info" JSONB DEFAULT '{}', + "mcp_access_groups" TEXT[], + "allowed_tools" TEXT[] DEFAULT ARRAY[]::TEXT[], + "extra_headers" TEXT[] DEFAULT ARRAY[]::TEXT[], + "status" TEXT DEFAULT 'unknown', + "last_health_check" TIMESTAMP(3), + "health_check_error" TEXT, + "command" TEXT, + "args" TEXT[] DEFAULT ARRAY[]::TEXT[], + "env" JSONB DEFAULT '{}', + + CONSTRAINT "LiteLLM_MCPServerTable_pkey" PRIMARY KEY ("server_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_VerificationToken" ( + "token" TEXT NOT NULL, + "key_name" TEXT, + "key_alias" TEXT, + "soft_budget_cooldown" BOOLEAN NOT NULL DEFAULT false, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "expires" TIMESTAMP(3), + "models" TEXT[], + "aliases" JSONB NOT NULL DEFAULT '{}', + "config" JSONB NOT NULL DEFAULT '{}', + "user_id" TEXT, + "team_id" TEXT, + "permissions" JSONB NOT NULL DEFAULT '{}', + "max_parallel_requests" INTEGER, + "metadata" JSONB NOT NULL DEFAULT '{}', + "blocked" BOOLEAN, + "tpm_limit" BIGINT, + "rpm_limit" BIGINT, + "max_budget" DOUBLE PRECISION, + "budget_duration" TEXT, + "budget_reset_at" TIMESTAMP(3), + "allowed_cache_controls" TEXT[] DEFAULT ARRAY[]::TEXT[], + "allowed_routes" TEXT[] DEFAULT ARRAY[]::TEXT[], + "model_spend" JSONB NOT NULL DEFAULT '{}', + "model_max_budget" JSONB NOT NULL DEFAULT '{}', + "budget_id" TEXT, + "organization_id" TEXT, + "object_permission_id" TEXT, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT, + "rotation_count" INTEGER DEFAULT 0, + "auto_rotate" BOOLEAN DEFAULT false, + "rotation_interval" TEXT, + "last_rotation_at" TIMESTAMP(3), + "key_rotation_at" TIMESTAMP(3), + + CONSTRAINT "LiteLLM_VerificationToken_pkey" PRIMARY KEY ("token") +); + +-- CreateTable +CREATE TABLE "LiteLLM_EndUserTable" ( + "user_id" TEXT NOT NULL, + "alias" TEXT, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "allowed_model_region" TEXT, + "default_model" TEXT, + "budget_id" TEXT, + "blocked" BOOLEAN NOT NULL DEFAULT false, + + CONSTRAINT "LiteLLM_EndUserTable_pkey" PRIMARY KEY ("user_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_TagTable" ( + "tag_name" TEXT NOT NULL, + "description" TEXT, + "models" TEXT[], + "model_info" JSONB, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "budget_id" TEXT, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "LiteLLM_TagTable_pkey" PRIMARY KEY ("tag_name") +); + +-- CreateTable +CREATE TABLE "LiteLLM_Config" ( + "param_name" TEXT NOT NULL, + "param_value" JSONB, + + CONSTRAINT "LiteLLM_Config_pkey" PRIMARY KEY ("param_name") +); + +-- CreateTable +CREATE TABLE "LiteLLM_SpendLogs" ( + "request_id" TEXT NOT NULL, + "call_type" TEXT NOT NULL, + "api_key" TEXT NOT NULL DEFAULT '', + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "total_tokens" INTEGER NOT NULL DEFAULT 0, + "prompt_tokens" INTEGER NOT NULL DEFAULT 0, + "completion_tokens" INTEGER NOT NULL DEFAULT 0, + "startTime" TIMESTAMP(3) NOT NULL, + "endTime" TIMESTAMP(3) NOT NULL, + "completionStartTime" TIMESTAMP(3), + "model" TEXT NOT NULL DEFAULT '', + "model_id" TEXT DEFAULT '', + "model_group" TEXT DEFAULT '', + "custom_llm_provider" TEXT DEFAULT '', + "api_base" TEXT DEFAULT '', + "user" TEXT DEFAULT '', + "metadata" JSONB DEFAULT '{}', + "cache_hit" TEXT DEFAULT '', + "cache_key" TEXT DEFAULT '', + "request_tags" JSONB DEFAULT '[]', + "team_id" TEXT, + "end_user" TEXT, + "requester_ip_address" TEXT, + "messages" JSONB DEFAULT '{}', + "response" JSONB DEFAULT '{}', + "session_id" TEXT, + "status" TEXT, + "mcp_namespaced_tool_name" TEXT, + "proxy_server_request" JSONB DEFAULT '{}', + + CONSTRAINT "LiteLLM_SpendLogs_pkey" PRIMARY KEY ("request_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ErrorLogs" ( + "request_id" TEXT NOT NULL, + "startTime" TIMESTAMP(3) NOT NULL, + "endTime" TIMESTAMP(3) NOT NULL, + "api_base" TEXT NOT NULL DEFAULT '', + "model_group" TEXT NOT NULL DEFAULT '', + "litellm_model_name" TEXT NOT NULL DEFAULT '', + "model_id" TEXT NOT NULL DEFAULT '', + "request_kwargs" JSONB NOT NULL DEFAULT '{}', + "exception_type" TEXT NOT NULL DEFAULT '', + "exception_string" TEXT NOT NULL DEFAULT '', + "status_code" TEXT NOT NULL DEFAULT '', + + CONSTRAINT "LiteLLM_ErrorLogs_pkey" PRIMARY KEY ("request_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_UserNotifications" ( + "request_id" TEXT NOT NULL, + "user_id" TEXT NOT NULL, + "models" TEXT[], + "justification" TEXT NOT NULL, + "status" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_UserNotifications_pkey" PRIMARY KEY ("request_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_TeamMembership" ( + "user_id" TEXT NOT NULL, + "team_id" TEXT NOT NULL, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "budget_id" TEXT, + + CONSTRAINT "LiteLLM_TeamMembership_pkey" PRIMARY KEY ("user_id","team_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_OrganizationMembership" ( + "user_id" TEXT NOT NULL, + "organization_id" TEXT NOT NULL, + "user_role" TEXT, + "spend" DOUBLE PRECISION DEFAULT 0.0, + "budget_id" TEXT, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "LiteLLM_OrganizationMembership_pkey" PRIMARY KEY ("user_id","organization_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_InvitationLink" ( + "id" TEXT NOT NULL, + "user_id" TEXT NOT NULL, + "is_accepted" BOOLEAN NOT NULL DEFAULT false, + "accepted_at" TIMESTAMP(3), + "expires_at" TIMESTAMP(3) NOT NULL, + "created_at" TIMESTAMP(3) NOT NULL, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_InvitationLink_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_AuditLog" ( + "id" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "changed_by" TEXT NOT NULL DEFAULT '', + "changed_by_api_key" TEXT NOT NULL DEFAULT '', + "action" TEXT NOT NULL, + "table_name" TEXT NOT NULL, + "object_id" TEXT NOT NULL, + "before_value" JSONB, + "updated_values" JSONB, + + CONSTRAINT "LiteLLM_AuditLog_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_DailyUserSpend" ( + "id" TEXT NOT NULL, + "user_id" TEXT, + "date" TEXT NOT NULL, + "api_key" TEXT NOT NULL, + "model" TEXT, + "model_group" TEXT, + "custom_llm_provider" TEXT, + "mcp_namespaced_tool_name" TEXT, + "prompt_tokens" BIGINT NOT NULL DEFAULT 0, + "completion_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_read_input_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_creation_input_tokens" BIGINT NOT NULL DEFAULT 0, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "api_requests" BIGINT NOT NULL DEFAULT 0, + "successful_requests" BIGINT NOT NULL DEFAULT 0, + "failed_requests" BIGINT NOT NULL DEFAULT 0, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_DailyUserSpend_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_DailyTeamSpend" ( + "id" TEXT NOT NULL, + "team_id" TEXT, + "date" TEXT NOT NULL, + "api_key" TEXT NOT NULL, + "model" TEXT, + "model_group" TEXT, + "custom_llm_provider" TEXT, + "mcp_namespaced_tool_name" TEXT, + "prompt_tokens" BIGINT NOT NULL DEFAULT 0, + "completion_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_read_input_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_creation_input_tokens" BIGINT NOT NULL DEFAULT 0, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "api_requests" BIGINT NOT NULL DEFAULT 0, + "successful_requests" BIGINT NOT NULL DEFAULT 0, + "failed_requests" BIGINT NOT NULL DEFAULT 0, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_DailyTeamSpend_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_DailyTagSpend" ( + "id" TEXT NOT NULL, + "tag" TEXT, + "date" TEXT NOT NULL, + "api_key" TEXT NOT NULL, + "model" TEXT, + "model_group" TEXT, + "custom_llm_provider" TEXT, + "mcp_namespaced_tool_name" TEXT, + "prompt_tokens" BIGINT NOT NULL DEFAULT 0, + "completion_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_read_input_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_creation_input_tokens" BIGINT NOT NULL DEFAULT 0, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "api_requests" BIGINT NOT NULL DEFAULT 0, + "successful_requests" BIGINT NOT NULL DEFAULT 0, + "failed_requests" BIGINT NOT NULL DEFAULT 0, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_DailyTagSpend_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_CronJob" ( + "cronjob_id" TEXT NOT NULL, + "pod_id" TEXT NOT NULL, + "status" "JobStatus" NOT NULL DEFAULT 'INACTIVE', + "last_updated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "ttl" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_CronJob_pkey" PRIMARY KEY ("cronjob_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ManagedFileTable" ( + "id" TEXT NOT NULL, + "unified_file_id" TEXT NOT NULL, + "file_object" JSONB, + "model_mappings" JSONB NOT NULL, + "flat_model_file_ids" TEXT[] DEFAULT ARRAY[]::TEXT[], + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) NOT NULL, + "updated_by" TEXT, + + CONSTRAINT "LiteLLM_ManagedFileTable_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ManagedObjectTable" ( + "id" TEXT NOT NULL, + "unified_object_id" TEXT NOT NULL, + "model_object_id" TEXT NOT NULL, + "file_object" JSONB NOT NULL, + "file_purpose" TEXT NOT NULL, + "status" TEXT, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) NOT NULL, + "updated_by" TEXT, + + CONSTRAINT "LiteLLM_ManagedObjectTable_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ManagedVectorStoresTable" ( + "vector_store_id" TEXT NOT NULL, + "custom_llm_provider" TEXT NOT NULL, + "vector_store_name" TEXT, + "vector_store_description" TEXT, + "vector_store_metadata" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + "litellm_credential_name" TEXT, + "litellm_params" JSONB, + + CONSTRAINT "LiteLLM_ManagedVectorStoresTable_pkey" PRIMARY KEY ("vector_store_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_GuardrailsTable" ( + "guardrail_id" TEXT NOT NULL, + "guardrail_name" TEXT NOT NULL, + "litellm_params" JSONB NOT NULL, + "guardrail_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_GuardrailsTable_pkey" PRIMARY KEY ("guardrail_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_PromptTable" ( + "id" TEXT NOT NULL, + "prompt_id" TEXT NOT NULL, + "litellm_params" JSONB NOT NULL, + "prompt_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_PromptTable_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_HealthCheckTable" ( + "health_check_id" TEXT NOT NULL, + "model_name" TEXT NOT NULL, + "model_id" TEXT, + "status" TEXT NOT NULL, + "healthy_count" INTEGER NOT NULL DEFAULT 0, + "unhealthy_count" INTEGER NOT NULL DEFAULT 0, + "error_message" TEXT, + "response_time_ms" DOUBLE PRECISION, + "details" JSONB, + "checked_by" TEXT, + "checked_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_HealthCheckTable_pkey" PRIMARY KEY ("health_check_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_SearchToolsTable" ( + "search_tool_id" TEXT NOT NULL, + "search_tool_name" TEXT NOT NULL, + "litellm_params" JSONB NOT NULL, + "search_tool_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_SearchToolsTable_pkey" PRIMARY KEY ("search_tool_id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_CredentialsTable_credential_name_key" ON "LiteLLM_CredentialsTable"("credential_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_TeamTable_model_id_key" ON "LiteLLM_TeamTable"("model_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_UserTable_sso_user_id_key" ON "LiteLLM_UserTable"("sso_user_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_SpendLogs_startTime_idx" ON "LiteLLM_SpendLogs"("startTime"); + +-- CreateIndex +CREATE INDEX "LiteLLM_SpendLogs_end_user_idx" ON "LiteLLM_SpendLogs"("end_user"); + +-- CreateIndex +CREATE INDEX "LiteLLM_SpendLogs_session_id_idx" ON "LiteLLM_SpendLogs"("session_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_OrganizationMembership_user_id_organization_id_key" ON "LiteLLM_OrganizationMembership"("user_id", "organization_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_date_idx" ON "LiteLLM_DailyUserSpend"("date"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_user_id_idx" ON "LiteLLM_DailyUserSpend"("user_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_api_key_idx" ON "LiteLLM_DailyUserSpend"("api_key"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_model_idx" ON "LiteLLM_DailyUserSpend"("model"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_mcp_namespaced_tool_name_idx" ON "LiteLLM_DailyUserSpend"("mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_DailyUserSpend_user_id_date_api_key_model_custom_ll_key" ON "LiteLLM_DailyUserSpend"("user_id", "date", "api_key", "model", "custom_llm_provider", "mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_date_idx" ON "LiteLLM_DailyTeamSpend"("date"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_team_id_idx" ON "LiteLLM_DailyTeamSpend"("team_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_api_key_idx" ON "LiteLLM_DailyTeamSpend"("api_key"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_model_idx" ON "LiteLLM_DailyTeamSpend"("model"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_mcp_namespaced_tool_name_idx" ON "LiteLLM_DailyTeamSpend"("mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_DailyTeamSpend_team_id_date_api_key_model_custom_ll_key" ON "LiteLLM_DailyTeamSpend"("team_id", "date", "api_key", "model", "custom_llm_provider", "mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_date_idx" ON "LiteLLM_DailyTagSpend"("date"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_tag_idx" ON "LiteLLM_DailyTagSpend"("tag"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_api_key_idx" ON "LiteLLM_DailyTagSpend"("api_key"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_model_idx" ON "LiteLLM_DailyTagSpend"("model"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_mcp_namespaced_tool_name_idx" ON "LiteLLM_DailyTagSpend"("mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_DailyTagSpend_tag_date_api_key_model_custom_llm_pro_key" ON "LiteLLM_DailyTagSpend"("tag", "date", "api_key", "model", "custom_llm_provider", "mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_ManagedFileTable_unified_file_id_key" ON "LiteLLM_ManagedFileTable"("unified_file_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_ManagedFileTable_unified_file_id_idx" ON "LiteLLM_ManagedFileTable"("unified_file_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_ManagedObjectTable_unified_object_id_key" ON "LiteLLM_ManagedObjectTable"("unified_object_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_ManagedObjectTable_model_object_id_key" ON "LiteLLM_ManagedObjectTable"("model_object_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_ManagedObjectTable_unified_object_id_idx" ON "LiteLLM_ManagedObjectTable"("unified_object_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_ManagedObjectTable_model_object_id_idx" ON "LiteLLM_ManagedObjectTable"("model_object_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_GuardrailsTable_guardrail_name_key" ON "LiteLLM_GuardrailsTable"("guardrail_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_PromptTable_prompt_id_key" ON "LiteLLM_PromptTable"("prompt_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_HealthCheckTable_model_name_idx" ON "LiteLLM_HealthCheckTable"("model_name"); + +-- CreateIndex +CREATE INDEX "LiteLLM_HealthCheckTable_checked_at_idx" ON "LiteLLM_HealthCheckTable"("checked_at"); + +-- CreateIndex +CREATE INDEX "LiteLLM_HealthCheckTable_status_idx" ON "LiteLLM_HealthCheckTable"("status"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_SearchToolsTable_search_tool_name_key" ON "LiteLLM_SearchToolsTable"("search_tool_name"); + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationTable" ADD CONSTRAINT "LiteLLM_OrganizationTable_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationTable" ADD CONSTRAINT "LiteLLM_OrganizationTable_object_permission_id_fkey" FOREIGN KEY ("object_permission_id") REFERENCES "LiteLLM_ObjectPermissionTable"("object_permission_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TeamTable" ADD CONSTRAINT "LiteLLM_TeamTable_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "LiteLLM_OrganizationTable"("organization_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TeamTable" ADD CONSTRAINT "LiteLLM_TeamTable_model_id_fkey" FOREIGN KEY ("model_id") REFERENCES "LiteLLM_ModelTable"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TeamTable" ADD CONSTRAINT "LiteLLM_TeamTable_object_permission_id_fkey" FOREIGN KEY ("object_permission_id") REFERENCES "LiteLLM_ObjectPermissionTable"("object_permission_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_UserTable" ADD CONSTRAINT "LiteLLM_UserTable_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "LiteLLM_OrganizationTable"("organization_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_UserTable" ADD CONSTRAINT "LiteLLM_UserTable_object_permission_id_fkey" FOREIGN KEY ("object_permission_id") REFERENCES "LiteLLM_ObjectPermissionTable"("object_permission_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_VerificationToken" ADD CONSTRAINT "LiteLLM_VerificationToken_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_VerificationToken" ADD CONSTRAINT "LiteLLM_VerificationToken_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "LiteLLM_OrganizationTable"("organization_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_VerificationToken" ADD CONSTRAINT "LiteLLM_VerificationToken_object_permission_id_fkey" FOREIGN KEY ("object_permission_id") REFERENCES "LiteLLM_ObjectPermissionTable"("object_permission_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_EndUserTable" ADD CONSTRAINT "LiteLLM_EndUserTable_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TagTable" ADD CONSTRAINT "LiteLLM_TagTable_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TeamMembership" ADD CONSTRAINT "LiteLLM_TeamMembership_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationMembership" ADD CONSTRAINT "LiteLLM_OrganizationMembership_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "LiteLLM_UserTable"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationMembership" ADD CONSTRAINT "LiteLLM_OrganizationMembership_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "LiteLLM_OrganizationTable"("organization_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationMembership" ADD CONSTRAINT "LiteLLM_OrganizationMembership_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_InvitationLink" ADD CONSTRAINT "LiteLLM_InvitationLink_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "LiteLLM_UserTable"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_InvitationLink" ADD CONSTRAINT "LiteLLM_InvitationLink_created_by_fkey" FOREIGN KEY ("created_by") REFERENCES "LiteLLM_UserTable"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_InvitationLink" ADD CONSTRAINT "LiteLLM_InvitationLink_updated_by_fkey" FOREIGN KEY ("updated_by") REFERENCES "LiteLLM_UserTable"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE; + diff --git a/temp_migrations/20251030013554_initial/raw_migration.sql b/temp_migrations/20251030013554_initial/raw_migration.sql new file mode 100644 index 000000000000..dfc585189d16 --- /dev/null +++ b/temp_migrations/20251030013554_initial/raw_migration.sql @@ -0,0 +1,724 @@ +Installing Prisma CLI +-- CreateEnum +CREATE TYPE "JobStatus" AS ENUM ('ACTIVE', 'INACTIVE'); + +-- CreateTable +CREATE TABLE "LiteLLM_BudgetTable" ( + "budget_id" TEXT NOT NULL, + "max_budget" DOUBLE PRECISION, + "soft_budget" DOUBLE PRECISION, + "max_parallel_requests" INTEGER, + "tpm_limit" BIGINT, + "rpm_limit" BIGINT, + "model_max_budget" JSONB, + "budget_duration" TEXT, + "budget_reset_at" TIMESTAMP(3), + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_BudgetTable_pkey" PRIMARY KEY ("budget_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_CredentialsTable" ( + "credential_id" TEXT NOT NULL, + "credential_name" TEXT NOT NULL, + "credential_values" JSONB NOT NULL, + "credential_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_CredentialsTable_pkey" PRIMARY KEY ("credential_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ProxyModelTable" ( + "model_id" TEXT NOT NULL, + "model_name" TEXT NOT NULL, + "litellm_params" JSONB NOT NULL, + "model_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_ProxyModelTable_pkey" PRIMARY KEY ("model_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_OrganizationTable" ( + "organization_id" TEXT NOT NULL, + "organization_alias" TEXT NOT NULL, + "budget_id" TEXT NOT NULL, + "metadata" JSONB NOT NULL DEFAULT '{}', + "models" TEXT[], + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "model_spend" JSONB NOT NULL DEFAULT '{}', + "object_permission_id" TEXT, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_OrganizationTable_pkey" PRIMARY KEY ("organization_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ModelTable" ( + "id" SERIAL NOT NULL, + "aliases" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_ModelTable_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_TeamTable" ( + "team_id" TEXT NOT NULL, + "team_alias" TEXT, + "organization_id" TEXT, + "object_permission_id" TEXT, + "admins" TEXT[], + "members" TEXT[], + "members_with_roles" JSONB NOT NULL DEFAULT '{}', + "metadata" JSONB NOT NULL DEFAULT '{}', + "max_budget" DOUBLE PRECISION, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "models" TEXT[], + "max_parallel_requests" INTEGER, + "tpm_limit" BIGINT, + "rpm_limit" BIGINT, + "budget_duration" TEXT, + "budget_reset_at" TIMESTAMP(3), + "blocked" BOOLEAN NOT NULL DEFAULT false, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "model_spend" JSONB NOT NULL DEFAULT '{}', + "model_max_budget" JSONB NOT NULL DEFAULT '{}', + "team_member_permissions" TEXT[] DEFAULT ARRAY[]::TEXT[], + "model_id" INTEGER, + + CONSTRAINT "LiteLLM_TeamTable_pkey" PRIMARY KEY ("team_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_UserTable" ( + "user_id" TEXT NOT NULL, + "user_alias" TEXT, + "team_id" TEXT, + "sso_user_id" TEXT, + "organization_id" TEXT, + "object_permission_id" TEXT, + "password" TEXT, + "teams" TEXT[] DEFAULT ARRAY[]::TEXT[], + "user_role" TEXT, + "max_budget" DOUBLE PRECISION, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "user_email" TEXT, + "models" TEXT[], + "metadata" JSONB NOT NULL DEFAULT '{}', + "max_parallel_requests" INTEGER, + "tpm_limit" BIGINT, + "rpm_limit" BIGINT, + "budget_duration" TEXT, + "budget_reset_at" TIMESTAMP(3), + "allowed_cache_controls" TEXT[] DEFAULT ARRAY[]::TEXT[], + "model_spend" JSONB NOT NULL DEFAULT '{}', + "model_max_budget" JSONB NOT NULL DEFAULT '{}', + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "LiteLLM_UserTable_pkey" PRIMARY KEY ("user_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ObjectPermissionTable" ( + "object_permission_id" TEXT NOT NULL, + "mcp_servers" TEXT[] DEFAULT ARRAY[]::TEXT[], + "mcp_access_groups" TEXT[] DEFAULT ARRAY[]::TEXT[], + "mcp_tool_permissions" JSONB, + "vector_stores" TEXT[] DEFAULT ARRAY[]::TEXT[], + + CONSTRAINT "LiteLLM_ObjectPermissionTable_pkey" PRIMARY KEY ("object_permission_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_MCPServerTable" ( + "server_id" TEXT NOT NULL, + "server_name" TEXT, + "alias" TEXT, + "description" TEXT, + "url" TEXT, + "transport" TEXT NOT NULL DEFAULT 'sse', + "auth_type" TEXT, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT, + "mcp_info" JSONB DEFAULT '{}', + "mcp_access_groups" TEXT[], + "allowed_tools" TEXT[] DEFAULT ARRAY[]::TEXT[], + "extra_headers" TEXT[] DEFAULT ARRAY[]::TEXT[], + "status" TEXT DEFAULT 'unknown', + "last_health_check" TIMESTAMP(3), + "health_check_error" TEXT, + "command" TEXT, + "args" TEXT[] DEFAULT ARRAY[]::TEXT[], + "env" JSONB DEFAULT '{}', + + CONSTRAINT "LiteLLM_MCPServerTable_pkey" PRIMARY KEY ("server_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_VerificationToken" ( + "token" TEXT NOT NULL, + "key_name" TEXT, + "key_alias" TEXT, + "soft_budget_cooldown" BOOLEAN NOT NULL DEFAULT false, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "expires" TIMESTAMP(3), + "models" TEXT[], + "aliases" JSONB NOT NULL DEFAULT '{}', + "config" JSONB NOT NULL DEFAULT '{}', + "user_id" TEXT, + "team_id" TEXT, + "permissions" JSONB NOT NULL DEFAULT '{}', + "max_parallel_requests" INTEGER, + "metadata" JSONB NOT NULL DEFAULT '{}', + "blocked" BOOLEAN, + "tpm_limit" BIGINT, + "rpm_limit" BIGINT, + "max_budget" DOUBLE PRECISION, + "budget_duration" TEXT, + "budget_reset_at" TIMESTAMP(3), + "allowed_cache_controls" TEXT[] DEFAULT ARRAY[]::TEXT[], + "allowed_routes" TEXT[] DEFAULT ARRAY[]::TEXT[], + "model_spend" JSONB NOT NULL DEFAULT '{}', + "model_max_budget" JSONB NOT NULL DEFAULT '{}', + "budget_id" TEXT, + "organization_id" TEXT, + "object_permission_id" TEXT, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_by" TEXT, + "rotation_count" INTEGER DEFAULT 0, + "auto_rotate" BOOLEAN DEFAULT false, + "rotation_interval" TEXT, + "last_rotation_at" TIMESTAMP(3), + "key_rotation_at" TIMESTAMP(3), + + CONSTRAINT "LiteLLM_VerificationToken_pkey" PRIMARY KEY ("token") +); + +-- CreateTable +CREATE TABLE "LiteLLM_EndUserTable" ( + "user_id" TEXT NOT NULL, + "alias" TEXT, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "allowed_model_region" TEXT, + "default_model" TEXT, + "budget_id" TEXT, + "blocked" BOOLEAN NOT NULL DEFAULT false, + + CONSTRAINT "LiteLLM_EndUserTable_pkey" PRIMARY KEY ("user_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_TagTable" ( + "tag_name" TEXT NOT NULL, + "description" TEXT, + "models" TEXT[], + "model_info" JSONB, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "budget_id" TEXT, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "LiteLLM_TagTable_pkey" PRIMARY KEY ("tag_name") +); + +-- CreateTable +CREATE TABLE "LiteLLM_Config" ( + "param_name" TEXT NOT NULL, + "param_value" JSONB, + + CONSTRAINT "LiteLLM_Config_pkey" PRIMARY KEY ("param_name") +); + +-- CreateTable +CREATE TABLE "LiteLLM_SpendLogs" ( + "request_id" TEXT NOT NULL, + "call_type" TEXT NOT NULL, + "api_key" TEXT NOT NULL DEFAULT '', + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "total_tokens" INTEGER NOT NULL DEFAULT 0, + "prompt_tokens" INTEGER NOT NULL DEFAULT 0, + "completion_tokens" INTEGER NOT NULL DEFAULT 0, + "startTime" TIMESTAMP(3) NOT NULL, + "endTime" TIMESTAMP(3) NOT NULL, + "completionStartTime" TIMESTAMP(3), + "model" TEXT NOT NULL DEFAULT '', + "model_id" TEXT DEFAULT '', + "model_group" TEXT DEFAULT '', + "custom_llm_provider" TEXT DEFAULT '', + "api_base" TEXT DEFAULT '', + "user" TEXT DEFAULT '', + "metadata" JSONB DEFAULT '{}', + "cache_hit" TEXT DEFAULT '', + "cache_key" TEXT DEFAULT '', + "request_tags" JSONB DEFAULT '[]', + "team_id" TEXT, + "end_user" TEXT, + "requester_ip_address" TEXT, + "messages" JSONB DEFAULT '{}', + "response" JSONB DEFAULT '{}', + "session_id" TEXT, + "status" TEXT, + "mcp_namespaced_tool_name" TEXT, + "proxy_server_request" JSONB DEFAULT '{}', + + CONSTRAINT "LiteLLM_SpendLogs_pkey" PRIMARY KEY ("request_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ErrorLogs" ( + "request_id" TEXT NOT NULL, + "startTime" TIMESTAMP(3) NOT NULL, + "endTime" TIMESTAMP(3) NOT NULL, + "api_base" TEXT NOT NULL DEFAULT '', + "model_group" TEXT NOT NULL DEFAULT '', + "litellm_model_name" TEXT NOT NULL DEFAULT '', + "model_id" TEXT NOT NULL DEFAULT '', + "request_kwargs" JSONB NOT NULL DEFAULT '{}', + "exception_type" TEXT NOT NULL DEFAULT '', + "exception_string" TEXT NOT NULL DEFAULT '', + "status_code" TEXT NOT NULL DEFAULT '', + + CONSTRAINT "LiteLLM_ErrorLogs_pkey" PRIMARY KEY ("request_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_UserNotifications" ( + "request_id" TEXT NOT NULL, + "user_id" TEXT NOT NULL, + "models" TEXT[], + "justification" TEXT NOT NULL, + "status" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_UserNotifications_pkey" PRIMARY KEY ("request_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_TeamMembership" ( + "user_id" TEXT NOT NULL, + "team_id" TEXT NOT NULL, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "budget_id" TEXT, + + CONSTRAINT "LiteLLM_TeamMembership_pkey" PRIMARY KEY ("user_id","team_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_OrganizationMembership" ( + "user_id" TEXT NOT NULL, + "organization_id" TEXT NOT NULL, + "user_role" TEXT, + "spend" DOUBLE PRECISION DEFAULT 0.0, + "budget_id" TEXT, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "LiteLLM_OrganizationMembership_pkey" PRIMARY KEY ("user_id","organization_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_InvitationLink" ( + "id" TEXT NOT NULL, + "user_id" TEXT NOT NULL, + "is_accepted" BOOLEAN NOT NULL DEFAULT false, + "accepted_at" TIMESTAMP(3), + "expires_at" TIMESTAMP(3) NOT NULL, + "created_at" TIMESTAMP(3) NOT NULL, + "created_by" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL, + "updated_by" TEXT NOT NULL, + + CONSTRAINT "LiteLLM_InvitationLink_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_AuditLog" ( + "id" TEXT NOT NULL, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "changed_by" TEXT NOT NULL DEFAULT '', + "changed_by_api_key" TEXT NOT NULL DEFAULT '', + "action" TEXT NOT NULL, + "table_name" TEXT NOT NULL, + "object_id" TEXT NOT NULL, + "before_value" JSONB, + "updated_values" JSONB, + + CONSTRAINT "LiteLLM_AuditLog_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_DailyUserSpend" ( + "id" TEXT NOT NULL, + "user_id" TEXT, + "date" TEXT NOT NULL, + "api_key" TEXT NOT NULL, + "model" TEXT, + "model_group" TEXT, + "custom_llm_provider" TEXT, + "mcp_namespaced_tool_name" TEXT, + "prompt_tokens" BIGINT NOT NULL DEFAULT 0, + "completion_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_read_input_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_creation_input_tokens" BIGINT NOT NULL DEFAULT 0, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "api_requests" BIGINT NOT NULL DEFAULT 0, + "successful_requests" BIGINT NOT NULL DEFAULT 0, + "failed_requests" BIGINT NOT NULL DEFAULT 0, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_DailyUserSpend_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_DailyTeamSpend" ( + "id" TEXT NOT NULL, + "team_id" TEXT, + "date" TEXT NOT NULL, + "api_key" TEXT NOT NULL, + "model" TEXT, + "model_group" TEXT, + "custom_llm_provider" TEXT, + "mcp_namespaced_tool_name" TEXT, + "prompt_tokens" BIGINT NOT NULL DEFAULT 0, + "completion_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_read_input_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_creation_input_tokens" BIGINT NOT NULL DEFAULT 0, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "api_requests" BIGINT NOT NULL DEFAULT 0, + "successful_requests" BIGINT NOT NULL DEFAULT 0, + "failed_requests" BIGINT NOT NULL DEFAULT 0, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_DailyTeamSpend_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_DailyTagSpend" ( + "id" TEXT NOT NULL, + "tag" TEXT, + "date" TEXT NOT NULL, + "api_key" TEXT NOT NULL, + "model" TEXT, + "model_group" TEXT, + "custom_llm_provider" TEXT, + "mcp_namespaced_tool_name" TEXT, + "prompt_tokens" BIGINT NOT NULL DEFAULT 0, + "completion_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_read_input_tokens" BIGINT NOT NULL DEFAULT 0, + "cache_creation_input_tokens" BIGINT NOT NULL DEFAULT 0, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "api_requests" BIGINT NOT NULL DEFAULT 0, + "successful_requests" BIGINT NOT NULL DEFAULT 0, + "failed_requests" BIGINT NOT NULL DEFAULT 0, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_DailyTagSpend_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_CronJob" ( + "cronjob_id" TEXT NOT NULL, + "pod_id" TEXT NOT NULL, + "status" "JobStatus" NOT NULL DEFAULT 'INACTIVE', + "last_updated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "ttl" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_CronJob_pkey" PRIMARY KEY ("cronjob_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ManagedFileTable" ( + "id" TEXT NOT NULL, + "unified_file_id" TEXT NOT NULL, + "file_object" JSONB, + "model_mappings" JSONB NOT NULL, + "flat_model_file_ids" TEXT[] DEFAULT ARRAY[]::TEXT[], + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) NOT NULL, + "updated_by" TEXT, + + CONSTRAINT "LiteLLM_ManagedFileTable_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ManagedObjectTable" ( + "id" TEXT NOT NULL, + "unified_object_id" TEXT NOT NULL, + "model_object_id" TEXT NOT NULL, + "file_object" JSONB NOT NULL, + "file_purpose" TEXT NOT NULL, + "status" TEXT, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by" TEXT, + "updated_at" TIMESTAMP(3) NOT NULL, + "updated_by" TEXT, + + CONSTRAINT "LiteLLM_ManagedObjectTable_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_ManagedVectorStoresTable" ( + "vector_store_id" TEXT NOT NULL, + "custom_llm_provider" TEXT NOT NULL, + "vector_store_name" TEXT, + "vector_store_description" TEXT, + "vector_store_metadata" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + "litellm_credential_name" TEXT, + "litellm_params" JSONB, + + CONSTRAINT "LiteLLM_ManagedVectorStoresTable_pkey" PRIMARY KEY ("vector_store_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_GuardrailsTable" ( + "guardrail_id" TEXT NOT NULL, + "guardrail_name" TEXT NOT NULL, + "litellm_params" JSONB NOT NULL, + "guardrail_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_GuardrailsTable_pkey" PRIMARY KEY ("guardrail_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_PromptTable" ( + "id" TEXT NOT NULL, + "prompt_id" TEXT NOT NULL, + "litellm_params" JSONB NOT NULL, + "prompt_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_PromptTable_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_HealthCheckTable" ( + "health_check_id" TEXT NOT NULL, + "model_name" TEXT NOT NULL, + "model_id" TEXT, + "status" TEXT NOT NULL, + "healthy_count" INTEGER NOT NULL DEFAULT 0, + "unhealthy_count" INTEGER NOT NULL DEFAULT 0, + "error_message" TEXT, + "response_time_ms" DOUBLE PRECISION, + "details" JSONB, + "checked_by" TEXT, + "checked_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_HealthCheckTable_pkey" PRIMARY KEY ("health_check_id") +); + +-- CreateTable +CREATE TABLE "LiteLLM_SearchToolsTable" ( + "search_tool_id" TEXT NOT NULL, + "search_tool_name" TEXT NOT NULL, + "litellm_params" JSONB NOT NULL, + "search_tool_info" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_SearchToolsTable_pkey" PRIMARY KEY ("search_tool_id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_CredentialsTable_credential_name_key" ON "LiteLLM_CredentialsTable"("credential_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_TeamTable_model_id_key" ON "LiteLLM_TeamTable"("model_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_UserTable_sso_user_id_key" ON "LiteLLM_UserTable"("sso_user_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_SpendLogs_startTime_idx" ON "LiteLLM_SpendLogs"("startTime"); + +-- CreateIndex +CREATE INDEX "LiteLLM_SpendLogs_end_user_idx" ON "LiteLLM_SpendLogs"("end_user"); + +-- CreateIndex +CREATE INDEX "LiteLLM_SpendLogs_session_id_idx" ON "LiteLLM_SpendLogs"("session_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_OrganizationMembership_user_id_organization_id_key" ON "LiteLLM_OrganizationMembership"("user_id", "organization_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_date_idx" ON "LiteLLM_DailyUserSpend"("date"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_user_id_idx" ON "LiteLLM_DailyUserSpend"("user_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_api_key_idx" ON "LiteLLM_DailyUserSpend"("api_key"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_model_idx" ON "LiteLLM_DailyUserSpend"("model"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyUserSpend_mcp_namespaced_tool_name_idx" ON "LiteLLM_DailyUserSpend"("mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_DailyUserSpend_user_id_date_api_key_model_custom_ll_key" ON "LiteLLM_DailyUserSpend"("user_id", "date", "api_key", "model", "custom_llm_provider", "mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_date_idx" ON "LiteLLM_DailyTeamSpend"("date"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_team_id_idx" ON "LiteLLM_DailyTeamSpend"("team_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_api_key_idx" ON "LiteLLM_DailyTeamSpend"("api_key"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_model_idx" ON "LiteLLM_DailyTeamSpend"("model"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTeamSpend_mcp_namespaced_tool_name_idx" ON "LiteLLM_DailyTeamSpend"("mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_DailyTeamSpend_team_id_date_api_key_model_custom_ll_key" ON "LiteLLM_DailyTeamSpend"("team_id", "date", "api_key", "model", "custom_llm_provider", "mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_date_idx" ON "LiteLLM_DailyTagSpend"("date"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_tag_idx" ON "LiteLLM_DailyTagSpend"("tag"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_api_key_idx" ON "LiteLLM_DailyTagSpend"("api_key"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_model_idx" ON "LiteLLM_DailyTagSpend"("model"); + +-- CreateIndex +CREATE INDEX "LiteLLM_DailyTagSpend_mcp_namespaced_tool_name_idx" ON "LiteLLM_DailyTagSpend"("mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_DailyTagSpend_tag_date_api_key_model_custom_llm_pro_key" ON "LiteLLM_DailyTagSpend"("tag", "date", "api_key", "model", "custom_llm_provider", "mcp_namespaced_tool_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_ManagedFileTable_unified_file_id_key" ON "LiteLLM_ManagedFileTable"("unified_file_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_ManagedFileTable_unified_file_id_idx" ON "LiteLLM_ManagedFileTable"("unified_file_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_ManagedObjectTable_unified_object_id_key" ON "LiteLLM_ManagedObjectTable"("unified_object_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_ManagedObjectTable_model_object_id_key" ON "LiteLLM_ManagedObjectTable"("model_object_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_ManagedObjectTable_unified_object_id_idx" ON "LiteLLM_ManagedObjectTable"("unified_object_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_ManagedObjectTable_model_object_id_idx" ON "LiteLLM_ManagedObjectTable"("model_object_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_GuardrailsTable_guardrail_name_key" ON "LiteLLM_GuardrailsTable"("guardrail_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_PromptTable_prompt_id_key" ON "LiteLLM_PromptTable"("prompt_id"); + +-- CreateIndex +CREATE INDEX "LiteLLM_HealthCheckTable_model_name_idx" ON "LiteLLM_HealthCheckTable"("model_name"); + +-- CreateIndex +CREATE INDEX "LiteLLM_HealthCheckTable_checked_at_idx" ON "LiteLLM_HealthCheckTable"("checked_at"); + +-- CreateIndex +CREATE INDEX "LiteLLM_HealthCheckTable_status_idx" ON "LiteLLM_HealthCheckTable"("status"); + +-- CreateIndex +CREATE UNIQUE INDEX "LiteLLM_SearchToolsTable_search_tool_name_key" ON "LiteLLM_SearchToolsTable"("search_tool_name"); + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationTable" ADD CONSTRAINT "LiteLLM_OrganizationTable_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationTable" ADD CONSTRAINT "LiteLLM_OrganizationTable_object_permission_id_fkey" FOREIGN KEY ("object_permission_id") REFERENCES "LiteLLM_ObjectPermissionTable"("object_permission_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TeamTable" ADD CONSTRAINT "LiteLLM_TeamTable_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "LiteLLM_OrganizationTable"("organization_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TeamTable" ADD CONSTRAINT "LiteLLM_TeamTable_model_id_fkey" FOREIGN KEY ("model_id") REFERENCES "LiteLLM_ModelTable"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TeamTable" ADD CONSTRAINT "LiteLLM_TeamTable_object_permission_id_fkey" FOREIGN KEY ("object_permission_id") REFERENCES "LiteLLM_ObjectPermissionTable"("object_permission_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_UserTable" ADD CONSTRAINT "LiteLLM_UserTable_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "LiteLLM_OrganizationTable"("organization_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_UserTable" ADD CONSTRAINT "LiteLLM_UserTable_object_permission_id_fkey" FOREIGN KEY ("object_permission_id") REFERENCES "LiteLLM_ObjectPermissionTable"("object_permission_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_VerificationToken" ADD CONSTRAINT "LiteLLM_VerificationToken_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_VerificationToken" ADD CONSTRAINT "LiteLLM_VerificationToken_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "LiteLLM_OrganizationTable"("organization_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_VerificationToken" ADD CONSTRAINT "LiteLLM_VerificationToken_object_permission_id_fkey" FOREIGN KEY ("object_permission_id") REFERENCES "LiteLLM_ObjectPermissionTable"("object_permission_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_EndUserTable" ADD CONSTRAINT "LiteLLM_EndUserTable_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TagTable" ADD CONSTRAINT "LiteLLM_TagTable_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_TeamMembership" ADD CONSTRAINT "LiteLLM_TeamMembership_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationMembership" ADD CONSTRAINT "LiteLLM_OrganizationMembership_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "LiteLLM_UserTable"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationMembership" ADD CONSTRAINT "LiteLLM_OrganizationMembership_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "LiteLLM_OrganizationTable"("organization_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_OrganizationMembership" ADD CONSTRAINT "LiteLLM_OrganizationMembership_budget_id_fkey" FOREIGN KEY ("budget_id") REFERENCES "LiteLLM_BudgetTable"("budget_id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_InvitationLink" ADD CONSTRAINT "LiteLLM_InvitationLink_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "LiteLLM_UserTable"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_InvitationLink" ADD CONSTRAINT "LiteLLM_InvitationLink_created_by_fkey" FOREIGN KEY ("created_by") REFERENCES "LiteLLM_UserTable"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LiteLLM_InvitationLink" ADD CONSTRAINT "LiteLLM_InvitationLink_updated_by_fkey" FOREIGN KEY ("updated_by") REFERENCES "LiteLLM_UserTable"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE; + diff --git a/temp_migrations/migration_lock.toml b/temp_migrations/migration_lock.toml new file mode 100644 index 000000000000..2fe25d87cc30 --- /dev/null +++ b/temp_migrations/migration_lock.toml @@ -0,0 +1 @@ +provider = "postgresql" diff --git a/test_apscheduler_memory_fix.py b/test_apscheduler_memory_fix.py new file mode 100644 index 000000000000..1c3cc0db98cc --- /dev/null +++ b/test_apscheduler_memory_fix.py @@ -0,0 +1,238 @@ +#!/usr/bin/env python3 +""" +Test script to verify APScheduler memory leak fix. +Run this to ensure the scheduler doesn't cause excessive memory allocations. +""" + +import asyncio +import random +import tracemalloc +from datetime import datetime, timezone +from apscheduler.schedulers.asyncio import AsyncIOScheduler +from apscheduler.jobstores.memory import MemoryJobStore +from apscheduler.executors.asyncio import AsyncIOExecutor + +# Test job functions +async def test_job_1(): + print(f"[{datetime.now()}] Test job 1 executed") + +async def test_job_2(): + print(f"[{datetime.now()}] Test job 2 executed") + +async def test_job_3(): + print(f"[{datetime.now()}] Test job 3 executed") + + +async def test_scheduler_memory(): + """Test the scheduler configuration for memory leaks""" + + print("Starting memory leak test for APScheduler...") + print("-" * 50) + + # Start memory tracking + tracemalloc.start() + + # OLD CONFIGURATION (causes memory leak) + print("\n1. Testing OLD configuration (with jitter)...") + old_scheduler = AsyncIOScheduler( + job_defaults={ + "coalesce": True, + "misfire_grace_time": 120, + "max_instances": 1, + } + ) + + # Add jobs with jitter (OLD way that causes memory leak) + old_scheduler.add_job( + test_job_1, + "interval", + seconds=10, + jitter=3, # This causes memory leak! + id="old_job_1", + replace_existing=True, + ) + + old_scheduler.add_job( + test_job_2, + "interval", + seconds=10, + jitter=2, # This causes memory leak! + id="old_job_2", + replace_existing=True, + ) + + # Get memory snapshot after adding old jobs + snapshot1 = tracemalloc.take_snapshot() + + # Start and immediately stop old scheduler + old_scheduler.start() + await asyncio.sleep(0.1) + old_scheduler.shutdown(wait=False) + + print("OLD configuration jobs added and scheduler started/stopped") + + # NEW CONFIGURATION (memory leak fixed) + print("\n2. Testing NEW configuration (without jitter)...") + new_scheduler = AsyncIOScheduler( + job_defaults={ + "coalesce": True, + "misfire_grace_time": 3600, # Increased + "max_instances": 1, + "replace_existing": True, + }, + jobstores={'default': MemoryJobStore()}, + executors={'default': AsyncIOExecutor()}, + timezone=None + ) + + # Add jobs without jitter (NEW way that prevents memory leak) + # Use random offset in interval instead + new_scheduler.add_job( + test_job_1, + "interval", + seconds=30 + random.randint(0, 5), # Random offset instead of jitter + id="new_job_1", + replace_existing=True, + misfire_grace_time=3600, + ) + + new_scheduler.add_job( + test_job_2, + "interval", + seconds=30 + random.randint(0, 5), # Random offset instead of jitter + id="new_job_2", + replace_existing=True, + misfire_grace_time=3600, + ) + + new_scheduler.add_job( + test_job_3, + "interval", + seconds=600 + random.randint(0, 30), # Longer interval + id="new_job_3", + replace_existing=True, + misfire_grace_time=3600, + ) + + # Get memory snapshot after adding new jobs + snapshot2 = tracemalloc.take_snapshot() + + # Start new scheduler + new_scheduler.start(paused=False) + print("NEW configuration jobs added and scheduler started") + + # Compare memory usage + print("\n3. Memory Usage Comparison:") + print("-" * 50) + + # Get top memory allocations + top_stats = snapshot2.compare_to(snapshot1, 'lineno') + + print("Top 10 memory differences:") + for stat in top_stats[:10]: + print(f" {stat}") + + # Run for a short time to observe behavior + print("\n4. Running scheduler for 10 seconds...") + await asyncio.sleep(10) + + # Take final snapshot + snapshot3 = tracemalloc.take_snapshot() + + # Show memory growth during runtime + print("\n5. Memory growth during runtime:") + print("-" * 50) + runtime_stats = snapshot3.compare_to(snapshot2, 'lineno') + + total_memory_change = sum(stat.size_diff for stat in runtime_stats) + print(f"Total memory change: {total_memory_change / 1024 / 1024:.2f} MB") + + if total_memory_change > 10 * 1024 * 1024: # More than 10MB growth + print("⚠️ WARNING: Significant memory growth detected!") + print("Top memory growth areas:") + for stat in runtime_stats[:5]: + if stat.size_diff > 0: + print(f" {stat}") + else: + print("✅ Memory usage is stable!") + + # Shutdown + new_scheduler.shutdown(wait=True) + tracemalloc.stop() + + print("\nTest completed!") + + +async def test_job_rescheduling(): + """Test the impact of rescheduling jobs to 'now'""" + + print("\n" + "=" * 50) + print("Testing Job Rescheduling Impact") + print("=" * 50) + + tracemalloc.start() + + scheduler = AsyncIOScheduler( + job_defaults={ + "coalesce": True, + "misfire_grace_time": 3600, + "max_instances": 1, + } + ) + + # Add some jobs + for i in range(5): + scheduler.add_job( + test_job_1, + "interval", + seconds=30 + i, + id=f"test_job_{i}", + replace_existing=True, + ) + + scheduler.start() + + # Take initial snapshot + snapshot_before = tracemalloc.take_snapshot() + + print("Resetting all jobs to 'now'...") + # This is what the old code was doing - can cause memory issues + for job in scheduler.get_jobs(): + try: + job.modify(next_run_time=datetime.now(timezone.utc)) + except Exception as e: + print(f"Could not reset job {job.id}: {e}") + + # Take snapshot after rescheduling + snapshot_after = tracemalloc.take_snapshot() + + # Compare + stats = snapshot_after.compare_to(snapshot_before, 'lineno') + total_diff = sum(stat.size_diff for stat in stats) + + print(f"Memory change from rescheduling: {total_diff / 1024:.2f} KB") + + if total_diff > 1024 * 1024: # More than 1MB + print("⚠️ WARNING: Rescheduling jobs caused significant memory allocation!") + else: + print("✅ Rescheduling impact is minimal") + + scheduler.shutdown(wait=True) + tracemalloc.stop() + + +if __name__ == "__main__": + print("APScheduler Memory Leak Test") + print("=" * 50) + + # Run tests + asyncio.run(test_scheduler_memory()) + asyncio.run(test_job_rescheduling()) + + print("\n" + "=" * 50) + print("All tests completed!") + print("\nRecommendations:") + print("- Use the NEW configuration without jitter") + print("- Keep job intervals >= 30 seconds") + print("- Avoid rescheduling jobs to 'now' on startup") + print("- Use misfire_grace_time >= 3600 for production") \ No newline at end of file diff --git a/test_redis_session_patch.py b/test_redis_session_patch.py new file mode 100644 index 000000000000..361a2095a0d4 --- /dev/null +++ b/test_redis_session_patch.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 +""" +Test script to verify Redis session patch is working for issue #12364 +Requires Redis to be running on localhost:6379 and a valid Gemini API key +""" + +import asyncio +import sys +import os + +# Add the current directory to the path so we can import litellm +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) + +import litellm +from litellm.caching.caching import Cache +from litellm.responses.main import aresponses + + +async def test_redis_session_patch(): + """Test that conversation context is maintained with Redis patch""" + + # Check if Redis cache is configured + if not hasattr(litellm, 'cache') or litellm.cache is None: + print("❌ Redis cache not configured. Please set up Redis cache in your config.") + return False + + # Test configuration + API_KEY = os.getenv("GEMINI_API_KEY", "your-api-key-here") + if API_KEY == "your-api-key-here": + print("❌ Please set GEMINI_API_KEY environment variable") + return False + + try: + print("Testing Redis session patch for conversation context...") + + # First request - establish context + print("Making first request...") + response1 = await aresponses( + model="gemini-1.5-flash", + input="Hello, my name is John. Please remember my name.", + api_key=API_KEY, + custom_llm_provider="gemini" + ) + + print(f"First response: {response1.output[0].content[0].text}") + + # Second request - test context continuity + print("Making second request with context...") + response2 = await aresponses( + model="gemini-1.5-flash", + input="What is my name?", + previous_response_id=response1.id, + api_key=API_KEY, + custom_llm_provider="gemini" + ) + + print(f"Second response: {response2.output[0].content[0].text}") + + # Check if context was maintained + response_text = response2.output[0].content[0].text.lower() + if "john" in response_text: + print("✅ SUCCESS: Context maintained - AI remembered the name!") + return True + else: + print("❌ FAILED: Context not maintained - AI forgot the name") + return False + + except Exception as e: + print(f"❌ ERROR: {e}") + return False + + +if __name__ == "__main__": + # Set up Redis cache if not already configured + if not hasattr(litellm, 'cache') or litellm.cache is None: + print("Setting up Redis cache...") + litellm.cache = Cache( + type="redis", + host="localhost", + port=6379, + supported_call_types=["completion", "acompletion", "aresponses", "responses"] + ) + + # Run test + success = asyncio.run(test_redis_session_patch()) + + if success: + print("\n✅ Redis session patch is working correctly!") + sys.exit(0) + else: + print("\n❌ Redis session patch test failed!") + sys.exit(1) \ No newline at end of file diff --git a/test_responses_api.py b/test_responses_api.py new file mode 100644 index 000000000000..82eee826425b --- /dev/null +++ b/test_responses_api.py @@ -0,0 +1,229 @@ +#!/usr/bin/env python3 +""" +Comprehensive test for LiteLLM Responses API with multiple providers +Tests session management and context retention +""" + +import requests +import json +import time +import sys + +BASE_URL = "http://localhost:4000" +HEADERS = { + "Authorization": "Bearer sk-test-key-1234", + "Content-Type": "application/json" +} + +# Test configuration for different providers +PROVIDERS = [ + { + "name": "Claude 3.5 Sonnet", + "model": "claude-3-5-sonnet", + "supports_context": True + }, + { + "name": "DeepSeek Chat", + "model": "deepseek-chat", + "supports_context": True + }, + { + "name": "Gemini 2.0 Flash", + "model": "gemini-2.0-flash", + "supports_context": True + } +] + +def test_basic_response(model_name, provider_name): + """Test basic request/response functionality""" + print(f"\n1. Testing basic response for {provider_name}...") + + response = requests.post( + f"{BASE_URL}/v1/responses", + headers=HEADERS, + json={ + "model": model_name, + "input": "Say 'Hello World' and nothing else.", + "max_tokens": 20 + } + ) + + if response.status_code == 200: + result = response.json() + response_text = result['output'][0]['content'][0]['text'] + print(f" ✅ Basic response successful") + print(f" Response: {response_text[:100]}") + return True + else: + print(f" ❌ Failed: {response.status_code}") + print(f" Error: {response.text[:200]}") + return False + +def test_session_management(model_name, provider_name, supports_context=True): + """Test session management with context retention""" + print(f"\n2. Testing session management for {provider_name}...") + + # First message - establish context + response1 = requests.post( + f"{BASE_URL}/v1/responses", + headers=HEADERS, + json={ + "model": model_name, + "input": "My name is Alice and I love Python programming. Remember this.", + "max_tokens": 100 + } + ) + + if response1.status_code != 200: + print(f" ❌ First request failed: {response1.status_code}") + return False + + result1 = response1.json() + response_id = result1["id"] + print(f" ✅ First message sent, Response ID: {response_id[:50]}...") + print(f" Assistant: {result1['output'][0]['content'][0]['text'][:100]}...") + + # Small delay to ensure session is saved + time.sleep(1) + + # Second message - test context retention + response2 = requests.post( + f"{BASE_URL}/v1/responses", + headers=HEADERS, + json={ + "model": model_name, + "input": "What's my name and what programming language do I love?", + "previous_response_id": response_id, + "max_tokens": 100 + } + ) + + if response2.status_code != 200: + print(f" ❌ Second request failed: {response2.status_code}") + return False + + result2 = response2.json() + response_text = result2['output'][0]['content'][0]['text'].lower() + print(f" ✅ Second message sent with context") + print(f" Assistant: {result2['output'][0]['content'][0]['text'][:200]}...") + + # Check if context was maintained + if supports_context: + if "alice" in response_text and "python" in response_text: + print(f" ✅ Context successfully maintained!") + return True + else: + print(f" ⚠️ Context not maintained (expected for some models)") + return False + else: + print(f" ℹ️ Context retention not expected for this provider") + return True + +def test_streaming(model_name, provider_name): + """Test streaming responses""" + print(f"\n3. Testing streaming for {provider_name}...") + + try: + response = requests.post( + f"{BASE_URL}/v1/responses", + headers=HEADERS, + json={ + "model": model_name, + "input": "Count from 1 to 3", + "max_tokens": 30, + "stream": True + }, + stream=True, + timeout=10 + ) + + if response.status_code == 200: + print(f" ✅ Streaming response received") + chunks_received = 0 + for line in response.iter_lines(): + if line: + chunks_received += 1 + if chunks_received > 10: # Limit output + break + print(f" Received {chunks_received} chunks") + return True + else: + print(f" ❌ Streaming failed: {response.status_code}") + return False + except Exception as e: + print(f" ❌ Streaming error: {str(e)[:100]}") + return False + +def main(): + """Run all tests for each provider""" + print("=" * 70) + print("LITELLM RESPONSES API COMPREHENSIVE TEST") + print("=" * 70) + + # Check if proxy is running + try: + health = requests.get(f"{BASE_URL}/health", timeout=2) + if health.status_code != 200: + print("❌ Proxy server is not responding at http://localhost:4000") + print("Please start the proxy with: litellm --config responses_api_config.yaml --port 4000") + sys.exit(1) + except: + print("❌ Cannot connect to proxy server at http://localhost:4000") + print("Please start the proxy with: litellm --config responses_api_config.yaml --port 4000") + sys.exit(1) + + print("✅ Proxy server is running\n") + + results = {} + + for provider in PROVIDERS: + print(f"\n{'='*70}") + print(f"Testing {provider['name']}") + print(f"{'='*70}") + + results[provider['name']] = { + 'basic': False, + 'session': False, + 'streaming': False + } + + # Run tests + results[provider['name']]['basic'] = test_basic_response( + provider['model'], provider['name'] + ) + + if results[provider['name']]['basic']: + results[provider['name']]['session'] = test_session_management( + provider['model'], provider['name'], provider['supports_context'] + ) + results[provider['name']]['streaming'] = test_streaming( + provider['model'], provider['name'] + ) + + # Print summary + print(f"\n{'='*70}") + print("TEST SUMMARY") + print(f"{'='*70}") + + for provider_name, test_results in results.items(): + print(f"\n{provider_name}:") + print(f" Basic Response: {'✅' if test_results['basic'] else '❌'}") + print(f" Session Management: {'✅' if test_results['session'] else '❌'}") + print(f" Streaming: {'✅' if test_results['streaming'] else '❌'}") + + # Overall result + all_passed = all( + test_results['basic'] and test_results['session'] + for test_results in results.values() + ) + + print(f"\n{'='*70}") + if all_passed: + print("✅ ALL CRITICAL TESTS PASSED!") + print("The Responses API is working correctly with session management.") + else: + print("⚠️ Some tests failed. Check the details above.") + print(f"{'='*70}") + +if __name__ == "__main__": + main() \ No newline at end of file