Merge remote-tracking branch 'origin/main' into fix-sap-creds
# Conflicts: # docs/my-website/docs/providers/sap.md
|
|
@ -144,8 +144,8 @@ jobs:
|
|||
pip install "google-generativeai==0.3.2"
|
||||
pip install "google-cloud-aiplatform==1.43.0"
|
||||
pip install pyarrow
|
||||
pip install "boto3==1.36.0"
|
||||
pip install "aioboto3==13.4.0"
|
||||
pip install "boto3==1.40.61"
|
||||
pip install "aioboto3==15.5.0"
|
||||
pip install langchain
|
||||
pip install lunary==0.2.5
|
||||
pip install "azure-identity==1.16.1"
|
||||
|
|
@ -260,8 +260,8 @@ jobs:
|
|||
pip install "google-generativeai==0.3.2"
|
||||
pip install "google-cloud-aiplatform==1.43.0"
|
||||
pip install pyarrow
|
||||
pip install "boto3==1.36.0"
|
||||
pip install "aioboto3==13.4.0"
|
||||
pip install "boto3==1.40.61"
|
||||
pip install "aioboto3==15.5.0"
|
||||
pip install langchain
|
||||
pip install lunary==0.2.5
|
||||
pip install "azure-identity==1.16.1"
|
||||
|
|
@ -367,8 +367,8 @@ jobs:
|
|||
pip install "google-generativeai==0.3.2"
|
||||
pip install "google-cloud-aiplatform==1.43.0"
|
||||
pip install pyarrow
|
||||
pip install "boto3==1.36.0"
|
||||
pip install "aioboto3==13.4.0"
|
||||
pip install "boto3==1.40.61"
|
||||
pip install "aioboto3==15.5.0"
|
||||
pip install langchain
|
||||
pip install lunary==0.2.5
|
||||
pip install "azure-identity==1.16.1"
|
||||
|
|
@ -637,8 +637,8 @@ jobs:
|
|||
pip install "google-generativeai==0.3.2"
|
||||
pip install "google-cloud-aiplatform==1.43.0"
|
||||
pip install pyarrow
|
||||
pip install "boto3==1.36.0"
|
||||
pip install "aioboto3==13.4.0"
|
||||
pip install "boto3==1.40.61"
|
||||
pip install "aioboto3==15.5.0"
|
||||
pip install langchain
|
||||
pip install "langfuse>=2.0.0"
|
||||
pip install "logfire==0.29.0"
|
||||
|
|
@ -759,8 +759,8 @@ jobs:
|
|||
pip install "google-cloud-aiplatform==1.43.0"
|
||||
pip install "google-genai==1.22.0"
|
||||
pip install pyarrow
|
||||
pip install "boto3==1.36.0"
|
||||
pip install "aioboto3==13.4.0"
|
||||
pip install "boto3==1.40.61"
|
||||
pip install "aioboto3==15.5.0"
|
||||
pip install langchain
|
||||
pip install lunary==0.2.5
|
||||
pip install "azure-identity==1.16.1"
|
||||
|
|
@ -865,8 +865,8 @@ jobs:
|
|||
pip install "google-cloud-aiplatform==1.43.0"
|
||||
pip install "google-genai==1.22.0"
|
||||
pip install pyarrow
|
||||
pip install "boto3==1.36.0"
|
||||
pip install "aioboto3==13.4.0"
|
||||
pip install "boto3==1.40.61"
|
||||
pip install "aioboto3==15.5.0"
|
||||
pip install langchain
|
||||
pip install lunary==0.2.5
|
||||
pip install "azure-identity==1.16.1"
|
||||
|
|
@ -972,8 +972,8 @@ jobs:
|
|||
pip install "google-cloud-aiplatform==1.43.0"
|
||||
pip install "google-genai==1.22.0"
|
||||
pip install pyarrow
|
||||
pip install "boto3==1.36.0"
|
||||
pip install "aioboto3==13.4.0"
|
||||
pip install "boto3==1.40.61"
|
||||
pip install "aioboto3==15.5.0"
|
||||
pip install langchain
|
||||
pip install lunary==0.2.5
|
||||
pip install "azure-identity==1.16.1"
|
||||
|
|
@ -1198,7 +1198,7 @@ jobs:
|
|||
pip install "pytest-asyncio==0.21.1"
|
||||
pip install "respx==0.22.0"
|
||||
pip install "pydantic==2.10.2"
|
||||
pip install "boto3==1.36.0"
|
||||
pip install "boto3==1.40.61"
|
||||
# Run pytest and generate JUnit XML report
|
||||
- run:
|
||||
name: Run tests
|
||||
|
|
@ -1879,7 +1879,7 @@ jobs:
|
|||
pip install aiohttp
|
||||
pip install openai
|
||||
pip install click
|
||||
pip install "boto3==1.36.0"
|
||||
pip install "boto3==1.40.61"
|
||||
pip install jinja2
|
||||
pip install "tokenizers==0.20.0"
|
||||
pip install "uvloop==0.21.0"
|
||||
|
|
@ -1959,6 +1959,18 @@ jobs:
|
|||
command: |
|
||||
kind create cluster --name litellm-test
|
||||
|
||||
- run:
|
||||
name: Build Docker image for helm tests
|
||||
command: |
|
||||
IMAGE_TAG=${CIRCLE_SHA1:-ci}
|
||||
docker build -t litellm-ci:${IMAGE_TAG} -f docker/Dockerfile.database .
|
||||
|
||||
- run:
|
||||
name: Load Docker image into Kind
|
||||
command: |
|
||||
IMAGE_TAG=${CIRCLE_SHA1:-ci}
|
||||
kind load docker-image litellm-ci:${IMAGE_TAG} --name litellm-test
|
||||
|
||||
# Run helm lint
|
||||
- run:
|
||||
name: Run helm lint
|
||||
|
|
@ -1969,7 +1981,11 @@ jobs:
|
|||
- run:
|
||||
name: Run helm tests
|
||||
command: |
|
||||
helm install litellm ./deploy/charts/litellm-helm -f ./deploy/charts/litellm-helm/ci/test-values.yaml
|
||||
IMAGE_TAG=${CIRCLE_SHA1:-ci}
|
||||
helm install litellm ./deploy/charts/litellm-helm -f ./deploy/charts/litellm-helm/ci/test-values.yaml \
|
||||
--set image.repository=litellm-ci \
|
||||
--set image.tag=${IMAGE_TAG} \
|
||||
--set image.pullPolicy=Never
|
||||
# Wait for pod to be ready
|
||||
echo "Waiting 30 seconds for pod to be ready..."
|
||||
sleep 30
|
||||
|
|
@ -2020,6 +2036,7 @@ jobs:
|
|||
- run: python ./tests/code_coverage_tests/info_log_check.py
|
||||
- run: python ./tests/code_coverage_tests/test_ban_set_verbose.py
|
||||
- run: python ./tests/code_coverage_tests/code_qa_check_tests.py
|
||||
- run: python ./tests/code_coverage_tests/check_get_model_cost_key_performance.py
|
||||
- run: python ./tests/code_coverage_tests/test_proxy_types_import.py
|
||||
- run: python ./tests/code_coverage_tests/callback_manager_test.py
|
||||
- run: python ./tests/code_coverage_tests/recursive_detector.py
|
||||
|
|
@ -2102,10 +2119,11 @@ jobs:
|
|||
name: Check container logs for expected message
|
||||
command: |
|
||||
echo "=== Printing Full Container Startup Logs ==="
|
||||
docker logs my-app
|
||||
LOG_OUTPUT="$(docker logs my-app 2>&1)"
|
||||
printf '%s\n' "$LOG_OUTPUT"
|
||||
echo "=== End of Full Container Startup Logs ==="
|
||||
|
||||
if docker logs my-app 2>&1 | grep -q "prisma schema out of sync with db. Consider running these sql_commands to sync the two"; then
|
||||
if printf '%s\n' "$LOG_OUTPUT" | grep -q "prisma schema out of sync with db. Consider running these sql_commands to sync the two"; then
|
||||
echo "Expected message found in logs. Test passed."
|
||||
else
|
||||
echo "Expected message not found in logs. Test failed."
|
||||
|
|
@ -2158,8 +2176,8 @@ jobs:
|
|||
pip install "google-generativeai==0.3.2"
|
||||
pip install "google-cloud-aiplatform==1.43.0"
|
||||
pip install pyarrow
|
||||
pip install "boto3==1.36.0"
|
||||
pip install "aioboto3==13.4.0"
|
||||
pip install "boto3==1.40.61"
|
||||
pip install "aioboto3==15.5.0"
|
||||
pip install langchain
|
||||
pip install "langfuse>=2.0.0"
|
||||
pip install "logfire==0.29.0"
|
||||
|
|
@ -2298,8 +2316,8 @@ jobs:
|
|||
pip install "google-generativeai==0.3.2"
|
||||
pip install "google-cloud-aiplatform==1.43.0"
|
||||
pip install pyarrow
|
||||
pip install "boto3==1.36.0"
|
||||
pip install "aioboto3==13.4.0"
|
||||
pip install "boto3==1.40.61"
|
||||
pip install "aioboto3==15.5.0"
|
||||
pip install langchain
|
||||
pip install "langchain_mcp_adapters==0.0.5"
|
||||
pip install "langfuse>=2.0.0"
|
||||
|
|
@ -2444,8 +2462,8 @@ jobs:
|
|||
pip install "google-generativeai==0.3.2"
|
||||
pip install "google-cloud-aiplatform==1.43.0"
|
||||
pip install pyarrow
|
||||
pip install "boto3==1.36.0"
|
||||
pip install "aioboto3==13.4.0"
|
||||
pip install "boto3==1.40.61"
|
||||
pip install "aioboto3==15.5.0"
|
||||
pip install langchain
|
||||
pip install "langfuse>=2.0.0"
|
||||
pip install "logfire==0.29.0"
|
||||
|
|
@ -3100,7 +3118,7 @@ jobs:
|
|||
pip install "pytest==7.3.1"
|
||||
pip install "pytest-mock==3.12.0"
|
||||
pip install "pytest-asyncio==0.21.1"
|
||||
pip install "boto3==1.36.0"
|
||||
pip install "boto3==1.40.61"
|
||||
pip install "mypy==1.18.2"
|
||||
pip install pyarrow
|
||||
pip install numpydoc
|
||||
|
|
@ -3557,12 +3575,34 @@ jobs:
|
|||
name: Install Playwright Browsers
|
||||
command: |
|
||||
npx playwright install
|
||||
- run:
|
||||
name: Install Neon CLI
|
||||
command: |
|
||||
npm i -g neonctl
|
||||
- run:
|
||||
name: Create Neon branch
|
||||
command: |
|
||||
export EXPIRES_AT=$(date -u -d "+3 hours" +"%Y-%m-%dT%H:%M:%SZ")
|
||||
echo "Expires at: $EXPIRES_AT"
|
||||
neon branches create \
|
||||
--project-id $NEON_PROJECT_ID \
|
||||
--name preview/commit-${CIRCLE_SHA1:0:7} \
|
||||
--expires-at $EXPIRES_AT \
|
||||
--parent br-fancy-paper-ad1olsb3 \
|
||||
--api-key $NEON_API_KEY || true
|
||||
- run:
|
||||
name: Run Docker container
|
||||
command: |
|
||||
E2E_UI_TEST_DATABASE_URL=$(neon connection-string \
|
||||
--project-id $NEON_PROJECT_ID \
|
||||
--api-key $NEON_API_KEY \
|
||||
--branch preview/commit-${CIRCLE_SHA1:0:7} \
|
||||
--database-name yuneng-trial-db \
|
||||
--role neondb_owner)
|
||||
echo $E2E_UI_TEST_DATABASE_URL
|
||||
docker run -d \
|
||||
-p 4000:4000 \
|
||||
-e DATABASE_URL=$SMALL_DATABASE_URL \
|
||||
-e DATABASE_URL=$E2E_UI_TEST_DATABASE_URL \
|
||||
-e LITELLM_MASTER_KEY="sk-1234" \
|
||||
-e OPENAI_API_KEY=$OPENAI_API_KEY \
|
||||
-e UI_USERNAME="admin" \
|
||||
|
|
@ -3792,6 +3832,7 @@ workflows:
|
|||
- main
|
||||
- /litellm_.*/
|
||||
- e2e_ui_testing:
|
||||
context: e2e_ui_tests
|
||||
requires:
|
||||
- ui_build
|
||||
- build_docker_database_image
|
||||
|
|
|
|||
25
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
|
@ -7,6 +7,16 @@ body:
|
|||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
|
||||
**💡 Tip:** See our [Troubleshooting Guide](https://docs.litellm.ai/docs/troubleshoot) for what information to include.
|
||||
- type: checkboxes
|
||||
id: duplicate-check
|
||||
attributes:
|
||||
label: Check for existing issues
|
||||
description: Please search to see if an issue already exists for the bug you encountered.
|
||||
options:
|
||||
- label: I have searched the existing issues and checked that my issue is not a duplicate.
|
||||
required: true
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
|
|
@ -16,6 +26,21 @@ body:
|
|||
value: "A bug happened!"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: steps-to-reproduce
|
||||
attributes:
|
||||
label: Steps to Reproduce
|
||||
description: Please provide detailed steps to reproduce this bug(A curl/python code to reproduce the bug)
|
||||
placeholder: |
|
||||
1. config.yaml file/ .env file/ etc.
|
||||
2. Run the following code...
|
||||
3. Observe the error...
|
||||
value: |
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
|
|
|
|||
8
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
|
|
@ -7,6 +7,14 @@ body:
|
|||
attributes:
|
||||
value: |
|
||||
Thanks for making LiteLLM better!
|
||||
- type: checkboxes
|
||||
id: duplicate-check
|
||||
attributes:
|
||||
label: Check for existing issues
|
||||
description: Please search to see if an issue already exists for the feature you are requesting.
|
||||
options:
|
||||
- label: I have searched the existing issues and checked that my issue is not a duplicate.
|
||||
required: true
|
||||
- type: textarea
|
||||
id: the-feature
|
||||
attributes:
|
||||
|
|
|
|||
29
.github/workflows/check_duplicate_issues.yml
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
name: Check Duplicate Issues
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
|
||||
jobs:
|
||||
check-duplicate:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: Check for potential duplicates
|
||||
uses: wow-actions/potential-duplicates@v1
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
label: potential-duplicate
|
||||
threshold: 0.6
|
||||
reaction: eyes
|
||||
comment: |
|
||||
**⚠️ Potential duplicate detected**
|
||||
|
||||
This issue appears similar to existing issue(s):
|
||||
{{#issues}}
|
||||
- [#{{number}}]({{html_url}}) - {{title}} ({{accuracy}}% similar)
|
||||
{{/issues}}
|
||||
|
||||
Please review the linked issue(s) to see if they address your concern. If this is not a duplicate, please provide additional context to help us understand the difference.
|
||||
29
.github/workflows/ghcr_deploy.yml
vendored
|
|
@ -5,6 +5,7 @@ on:
|
|||
inputs:
|
||||
tag:
|
||||
description: "The tag version you want to build"
|
||||
required: true
|
||||
release_type:
|
||||
description: "The release type you want to build. Can be 'latest', 'stable', 'dev', 'rc'"
|
||||
type: string
|
||||
|
|
@ -336,9 +337,9 @@ jobs:
|
|||
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
|
||||
echo "current-version=1.0.0" | tee -a $GITHUB_OUTPUT
|
||||
else
|
||||
# Extract version and strip any prerelease suffix (e.g., 0.1.827-latest -> 0.1.827)
|
||||
# Extract version and strip any prerelease suffix (e.g., 1.0.5-latest -> 1.0.5)
|
||||
VERSION=$(printf '%s' "${CHART_LIST}" | grep '^version:' | awk 'BEGIN{FS=":"}{print $2}' | tr -d " " | cut -d'-' -f1)
|
||||
echo "current-version=${VERSION}" | tee -a $GITHUB_OUTPUT
|
||||
fi
|
||||
|
|
@ -350,28 +351,42 @@ jobs:
|
|||
id: bump_version
|
||||
uses: christian-draeger/increment-semantic-version@1.1.0
|
||||
with:
|
||||
current-version: ${{ steps.current_version.outputs.current-version || '0.1.0' }}
|
||||
current-version: ${{ steps.current_version.outputs.current-version || '1.0.0' }}
|
||||
version-fragment: 'bug'
|
||||
|
||||
# Add suffix for non-stable releases (semantic versioning)
|
||||
- name: Calculate chart version with prerelease suffix
|
||||
- name: Calculate chart and app versions
|
||||
id: chart_version
|
||||
shell: bash
|
||||
run: |
|
||||
BASE_VERSION="${{ steps.bump_version.outputs.next-version || '0.1.0' }}"
|
||||
BASE_VERSION="${{ steps.bump_version.outputs.next-version || '1.0.0' }}"
|
||||
RELEASE_TYPE="${{ github.event.inputs.release_type }}"
|
||||
INPUT_TAG="${{ github.event.inputs.tag }}"
|
||||
|
||||
# Chart version (independent Helm chart versioning with release type suffix)
|
||||
if [ "$RELEASE_TYPE" = "stable" ]; then
|
||||
echo "version=${BASE_VERSION}" | tee -a $GITHUB_OUTPUT
|
||||
else
|
||||
echo "version=${BASE_VERSION}-${RELEASE_TYPE}" | tee -a $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
# App version (must match Docker tags)
|
||||
# stable/rc releases: Docker creates main-{tag}, so use the tag
|
||||
# latest/dev releases: Docker only creates main-{release_type}, so use release_type
|
||||
if [ "$RELEASE_TYPE" = "stable" ] || [ "$RELEASE_TYPE" = "rc" ]; then
|
||||
APP_VERSION="${INPUT_TAG}"
|
||||
else
|
||||
APP_VERSION="${RELEASE_TYPE}"
|
||||
fi
|
||||
|
||||
echo "app_version=${APP_VERSION}" | tee -a $GITHUB_OUTPUT
|
||||
|
||||
- uses: ./.github/actions/helm-oci-chart-releaser
|
||||
with:
|
||||
name: ${{ env.CHART_NAME }}
|
||||
repository: ${{ env.REPO_OWNER }}
|
||||
tag: ${{ github.event.inputs.chartVersion || steps.chart_version.outputs.version || '0.1.0' }}
|
||||
app_version: ${{ steps.current_app_tag.outputs.latest_tag }}
|
||||
tag: ${{ github.event.inputs.chartVersion || steps.chart_version.outputs.version || '1.0.0' }}
|
||||
app_version: ${{ steps.chart_version.outputs.app_version }}
|
||||
path: deploy/charts/${{ env.CHART_NAME }}
|
||||
registry: ${{ env.REGISTRY }}
|
||||
registry_username: ${{ github.actor }}
|
||||
|
|
|
|||
174
.github/workflows/label-component.yml
vendored
|
|
@ -11,134 +11,72 @@ jobs:
|
|||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
- name: Add SDK label
|
||||
if: contains(github.event.issue.body, 'What part of LiteLLM is this about?\n\nSDK (litellm Python package)')
|
||||
- name: Add component labels
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const labelName = 'sdk';
|
||||
try {
|
||||
await github.rest.issues.getLabel({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: labelName
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.status === 404) {
|
||||
await github.rest.issues.createLabel({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: labelName,
|
||||
color: '0E7C86',
|
||||
description: 'Issues related to the litellm Python SDK'
|
||||
});
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
labels: [labelName]
|
||||
});
|
||||
const body = context.payload.issue.body;
|
||||
if (!body) return;
|
||||
|
||||
- name: Add Proxy label
|
||||
if: contains(github.event.issue.body, 'What part of LiteLLM is this about?\n\nProxy')
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const labelName = 'proxy';
|
||||
try {
|
||||
await github.rest.issues.getLabel({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: labelName
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.status === 404) {
|
||||
await github.rest.issues.createLabel({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: labelName,
|
||||
color: '5319E7',
|
||||
description: 'Issues related to the LiteLLM Proxy'
|
||||
});
|
||||
} else {
|
||||
throw error;
|
||||
// Define component mappings with regex patterns that handle flexible whitespace
|
||||
const components = [
|
||||
{
|
||||
pattern: /What part of LiteLLM is this about\?\s*SDK \(litellm Python package\)/,
|
||||
label: 'sdk',
|
||||
color: '0E7C86',
|
||||
description: 'Issues related to the litellm Python SDK'
|
||||
},
|
||||
{
|
||||
pattern: /What part of LiteLLM is this about\?\s*Proxy/,
|
||||
label: 'proxy',
|
||||
color: '5319E7',
|
||||
description: 'Issues related to the LiteLLM Proxy'
|
||||
},
|
||||
{
|
||||
pattern: /What part of LiteLLM is this about\?\s*UI Dashboard/,
|
||||
label: 'ui-dashboard',
|
||||
color: 'D876E3',
|
||||
description: 'Issues related to the LiteLLM UI Dashboard'
|
||||
},
|
||||
{
|
||||
pattern: /What part of LiteLLM is this about\?\s*Docs/,
|
||||
label: 'docs',
|
||||
color: 'FBCA04',
|
||||
description: 'Issues related to LiteLLM documentation'
|
||||
}
|
||||
}
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
labels: [labelName]
|
||||
});
|
||||
];
|
||||
|
||||
- name: Add UI Dashboard label
|
||||
if: contains(github.event.issue.body, 'What part of LiteLLM is this about?\n\nUI Dashboard')
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const labelName = 'ui-dashboard';
|
||||
try {
|
||||
await github.rest.issues.getLabel({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: labelName
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.status === 404) {
|
||||
await github.rest.issues.createLabel({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: labelName,
|
||||
color: 'D876E3',
|
||||
description: 'Issues related to the LiteLLM UI Dashboard'
|
||||
});
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
labels: [labelName]
|
||||
});
|
||||
// Find matching component
|
||||
for (const component of components) {
|
||||
if (component.pattern.test(body)) {
|
||||
// Ensure label exists
|
||||
try {
|
||||
await github.rest.issues.getLabel({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: component.label
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.status === 404) {
|
||||
await github.rest.issues.createLabel({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: component.label,
|
||||
color: component.color,
|
||||
description: component.description
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- name: Add Docs label
|
||||
if: contains(github.event.issue.body, 'What part of LiteLLM is this about?\n\nDocs')
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const labelName = 'docs';
|
||||
try {
|
||||
await github.rest.issues.getLabel({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: labelName
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.status === 404) {
|
||||
await github.rest.issues.createLabel({
|
||||
// Add label to issue
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: labelName,
|
||||
color: 'FBCA04',
|
||||
description: 'Issues related to LiteLLM documentation'
|
||||
issue_number: context.issue.number,
|
||||
labels: [component.label]
|
||||
});
|
||||
} else {
|
||||
throw error;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
labels: [labelName]
|
||||
});
|
||||
|
|
|
|||
1
.github/workflows/publish-migrations.yml
vendored
|
|
@ -13,6 +13,7 @@ on:
|
|||
|
||||
jobs:
|
||||
publish-migrations:
|
||||
if: github.repository == 'BerriAI/litellm'
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
postgres:
|
||||
|
|
|
|||
1
.github/workflows/test-litellm.yml
vendored
|
|
@ -35,6 +35,7 @@ jobs:
|
|||
poetry run pip install "google-cloud-aiplatform>=1.38"
|
||||
poetry run pip install "fastapi-offline==1.7.3"
|
||||
poetry run pip install "python-multipart==0.0.18"
|
||||
poetry run pip install "openapi-core"
|
||||
- name: Setup litellm-enterprise as local package
|
||||
run: |
|
||||
cd enterprise
|
||||
|
|
|
|||
1
.gitignore
vendored
|
|
@ -59,6 +59,7 @@ litellm/proxy/_super_secret_config.yaml
|
|||
litellm/proxy/myenv/bin/activate
|
||||
litellm/proxy/myenv/bin/Activate.ps1
|
||||
myenv/*
|
||||
litellm/proxy/_experimental/out/_next/
|
||||
litellm/proxy/_experimental/out/404/index.html
|
||||
litellm/proxy/_experimental/out/model_hub/index.html
|
||||
litellm/proxy/_experimental/out/onboarding/index.html
|
||||
|
|
|
|||
277
ARCHITECTURE.md
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
# LiteLLM Architecture - LiteLLM SDK + AI Gateway
|
||||
|
||||
This document helps contributors understand where to make changes in LiteLLM.
|
||||
|
||||
---
|
||||
|
||||
## How It Works
|
||||
|
||||
The LiteLLM AI Gateway (Proxy) uses the LiteLLM SDK internally for all LLM calls:
|
||||
|
||||
```
|
||||
OpenAI SDK (client) ──▶ LiteLLM AI Gateway (proxy/) ──▶ LiteLLM SDK (litellm/) ──▶ LLM API
|
||||
Anthropic SDK (client) ──▶ LiteLLMAI Gateway (proxy/) ──▶ LiteLLM SDK (litellm/) ──▶ LLM API
|
||||
Any HTTP client ──▶ LiteLLMAI Gateway (proxy/) ──▶ LiteLLM SDK (litellm/) ──▶ LLM API
|
||||
```
|
||||
|
||||
The **AI Gateway** adds authentication, rate limiting, budgets, and routing on top of the SDK.
|
||||
The **SDK** handles the actual LLM provider calls, request/response transformations, and streaming.
|
||||
|
||||
---
|
||||
|
||||
## 1. AI Gateway (Proxy) Request Flow
|
||||
|
||||
The AI Gateway (`litellm/proxy/`) wraps the SDK with authentication, rate limiting, and management features.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client
|
||||
participant ProxyServer as proxy/proxy_server.py
|
||||
participant Auth as proxy/auth/user_api_key_auth.py
|
||||
participant Hooks as proxy/hooks/
|
||||
participant Router as router.py
|
||||
participant Main as main.py
|
||||
participant Handler as llms/custom_httpx/llm_http_handler.py
|
||||
participant Transform as llms/{provider}/chat/transformation.py
|
||||
participant Provider as LLM Provider API
|
||||
|
||||
Client->>ProxyServer: POST /v1/chat/completions
|
||||
ProxyServer->>Auth: user_api_key_auth()
|
||||
ProxyServer->>Hooks: max_budget_limiter, parallel_request_limiter
|
||||
ProxyServer->>Router: route_request()
|
||||
Router->>Main: litellm.acompletion()
|
||||
Main->>Handler: BaseLLMHTTPHandler.completion()
|
||||
Handler->>Transform: ProviderConfig.transform_request()
|
||||
Handler->>Provider: HTTP Request
|
||||
Provider-->>Handler: Response
|
||||
Handler->>Transform: ProviderConfig.transform_response()
|
||||
Handler-->>Hooks: async_log_success_event()
|
||||
Handler-->>Client: ModelResponse
|
||||
```
|
||||
|
||||
### Proxy Components
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph "Incoming Request"
|
||||
Client["POST /v1/chat/completions"]
|
||||
end
|
||||
|
||||
subgraph "proxy/proxy_server.py"
|
||||
Endpoint["chat_completion()"]
|
||||
end
|
||||
|
||||
subgraph "proxy/auth/"
|
||||
Auth["user_api_key_auth()"]
|
||||
end
|
||||
|
||||
subgraph "proxy/"
|
||||
PreCall["litellm_pre_call_utils.py"]
|
||||
RouteRequest["route_llm_request.py"]
|
||||
end
|
||||
|
||||
subgraph "litellm/"
|
||||
Router["router.py"]
|
||||
Main["main.py"]
|
||||
end
|
||||
|
||||
Client --> Endpoint
|
||||
Endpoint --> Auth
|
||||
Auth --> PreCall
|
||||
PreCall --> RouteRequest
|
||||
RouteRequest --> Router
|
||||
Router --> Main
|
||||
Main --> Client
|
||||
```
|
||||
|
||||
**Key proxy files:**
|
||||
- `proxy/proxy_server.py` - Main API endpoints
|
||||
- `proxy/auth/` - Authentication (API keys, JWT, OAuth2)
|
||||
- `proxy/hooks/` - Proxy-level callbacks
|
||||
- `router.py` - Load balancing, fallbacks
|
||||
- `router_strategy/` - Routing algorithms (`lowest_latency.py`, `simple_shuffle.py`, etc.)
|
||||
|
||||
**LLM-specific proxy endpoints:**
|
||||
|
||||
| Endpoint | Directory | Purpose |
|
||||
|----------|-----------|---------|
|
||||
| `/v1/messages` | `proxy/anthropic_endpoints/` | Anthropic Messages API |
|
||||
| `/vertex-ai/*` | `proxy/vertex_ai_endpoints/` | Vertex AI passthrough |
|
||||
| `/gemini/*` | `proxy/google_endpoints/` | Google AI Studio passthrough |
|
||||
| `/v1/images/*` | `proxy/image_endpoints/` | Image generation |
|
||||
| `/v1/batches` | `proxy/batches_endpoints/` | Batch processing |
|
||||
| `/v1/files` | `proxy/openai_files_endpoints/` | File uploads |
|
||||
| `/v1/fine_tuning` | `proxy/fine_tuning_endpoints/` | Fine-tuning jobs |
|
||||
| `/v1/rerank` | `proxy/rerank_endpoints/` | Reranking |
|
||||
| `/v1/responses` | `proxy/response_api_endpoints/` | OpenAI Responses API |
|
||||
| `/v1/vector_stores` | `proxy/vector_store_endpoints/` | Vector stores |
|
||||
| `/*` (passthrough) | `proxy/pass_through_endpoints/` | Direct provider passthrough |
|
||||
|
||||
**Proxy Hooks** (`proxy/hooks/__init__.py`):
|
||||
|
||||
| Hook | File | Purpose |
|
||||
|------|------|---------|
|
||||
| `max_budget_limiter` | `proxy/hooks/max_budget_limiter.py` | Enforce budget limits |
|
||||
| `parallel_request_limiter` | `proxy/hooks/parallel_request_limiter_v3.py` | Rate limiting per key/user |
|
||||
| `cache_control_check` | `proxy/hooks/cache_control_check.py` | Cache validation |
|
||||
| `responses_id_security` | `proxy/hooks/responses_id_security.py` | Response ID validation |
|
||||
| `litellm_skills` | `proxy/hooks/skills_injection.py` | Skills injection |
|
||||
|
||||
To add a new proxy hook, implement `CustomLogger` and register in `PROXY_HOOKS`.
|
||||
|
||||
---
|
||||
|
||||
## 2. SDK Request Flow
|
||||
|
||||
The SDK (`litellm/`) provides the core LLM calling functionality used by both direct SDK users and the AI Gateway.
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph "SDK Entry Points"
|
||||
Completion["litellm.completion()"]
|
||||
Messages["litellm.messages()"]
|
||||
end
|
||||
|
||||
subgraph "main.py"
|
||||
Main["completion()<br/>acompletion()"]
|
||||
end
|
||||
|
||||
subgraph "utils.py"
|
||||
GetProvider["get_llm_provider()"]
|
||||
end
|
||||
|
||||
subgraph "llms/custom_httpx/"
|
||||
Handler["llm_http_handler.py<br/>BaseLLMHTTPHandler"]
|
||||
HTTP["http_handler.py<br/>HTTPHandler / AsyncHTTPHandler"]
|
||||
end
|
||||
|
||||
subgraph "llms/{provider}/chat/"
|
||||
TransformReq["transform_request()"]
|
||||
TransformResp["transform_response()"]
|
||||
end
|
||||
|
||||
subgraph "litellm_core_utils/"
|
||||
Streaming["streaming_handler.py"]
|
||||
end
|
||||
|
||||
subgraph "integrations/ (async, off main thread)"
|
||||
Callbacks["custom_logger.py<br/>Langfuse, Datadog, etc."]
|
||||
end
|
||||
|
||||
Completion --> Main
|
||||
Messages --> Main
|
||||
Main --> GetProvider
|
||||
GetProvider --> Handler
|
||||
Handler --> TransformReq
|
||||
TransformReq --> HTTP
|
||||
HTTP --> Provider["LLM Provider API"]
|
||||
Provider --> HTTP
|
||||
HTTP --> TransformResp
|
||||
TransformResp --> Streaming
|
||||
Streaming --> Response["ModelResponse"]
|
||||
Response -.->|async| Callbacks
|
||||
```
|
||||
|
||||
**Key SDK files:**
|
||||
- `main.py` - Entry points: `completion()`, `acompletion()`, `embedding()`
|
||||
- `utils.py` - `get_llm_provider()` resolves model → provider
|
||||
- `llms/custom_httpx/llm_http_handler.py` - Central HTTP orchestrator
|
||||
- `llms/custom_httpx/http_handler.py` - Low-level HTTP client
|
||||
- `llms/{provider}/chat/transformation.py` - Provider-specific transformations
|
||||
- `litellm_core_utils/streaming_handler.py` - Streaming response handling
|
||||
- `integrations/` - Async callbacks (Langfuse, Datadog, etc.)
|
||||
|
||||
---
|
||||
|
||||
## 3. Translation Layer
|
||||
|
||||
When a request comes in, it goes through a **translation layer** that converts between API formats.
|
||||
Each translation is isolated in its own file, making it easy to test and modify independently.
|
||||
|
||||
### Where to find translations
|
||||
|
||||
| Incoming API | Provider | Translation File |
|
||||
|--------------|----------|------------------|
|
||||
| `/v1/chat/completions` | Anthropic | `llms/anthropic/chat/transformation.py` |
|
||||
| `/v1/chat/completions` | Bedrock Converse | `llms/bedrock/chat/converse_transformation.py` |
|
||||
| `/v1/chat/completions` | Bedrock Invoke | `llms/bedrock/chat/invoke_transformations/anthropic_claude3_transformation.py` |
|
||||
| `/v1/chat/completions` | Gemini | `llms/gemini/chat/transformation.py` |
|
||||
| `/v1/chat/completions` | Vertex AI | `llms/vertex_ai/gemini/transformation.py` |
|
||||
| `/v1/chat/completions` | OpenAI | `llms/openai/chat/gpt_transformation.py` |
|
||||
| `/v1/messages` (passthrough) | Anthropic | `llms/anthropic/experimental_pass_through/messages/transformation.py` |
|
||||
| `/v1/messages` (passthrough) | Bedrock | `llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py` |
|
||||
| `/v1/messages` (passthrough) | Vertex AI | `llms/vertex_ai/vertex_ai_partner_models/anthropic/experimental_pass_through/transformation.py` |
|
||||
| Passthrough endpoints | All | `proxy/pass_through_endpoints/llm_provider_handlers/` |
|
||||
|
||||
### Example: Debugging prompt caching
|
||||
|
||||
If `/v1/messages` → Bedrock Converse prompt caching isn't working but Bedrock Invoke works:
|
||||
|
||||
1. **Bedrock Converse translation**: `llms/bedrock/chat/converse_transformation.py`
|
||||
2. **Bedrock Invoke translation**: `llms/bedrock/chat/invoke_transformations/anthropic_claude3_transformation.py`
|
||||
3. Compare how each handles `cache_control` in `transform_request()`
|
||||
|
||||
### How translations work
|
||||
|
||||
Each provider has a `Config` class that inherits from `BaseConfig` (`llms/base_llm/chat/transformation.py`):
|
||||
|
||||
```python
|
||||
class ProviderConfig(BaseConfig):
|
||||
def transform_request(self, model, messages, optional_params, litellm_params, headers):
|
||||
# Convert OpenAI format → Provider format
|
||||
return {"messages": transformed_messages, ...}
|
||||
|
||||
def transform_response(self, model, raw_response, model_response, logging_obj, ...):
|
||||
# Convert Provider format → OpenAI format
|
||||
return ModelResponse(choices=[...], usage=Usage(...))
|
||||
```
|
||||
|
||||
The `BaseLLMHTTPHandler` (`llms/custom_httpx/llm_http_handler.py`) calls these methods - you never need to modify the handler itself.
|
||||
|
||||
---
|
||||
|
||||
## 4. Adding/Modifying Providers
|
||||
|
||||
### To add a new provider:
|
||||
|
||||
1. Create `llms/{provider}/chat/transformation.py`
|
||||
2. Implement `Config` class with `transform_request()` and `transform_response()`
|
||||
3. Add tests in `tests/llm_translation/test_{provider}.py`
|
||||
|
||||
### To add a feature (e.g., prompt caching):
|
||||
|
||||
1. Find the translation file from the table above
|
||||
2. Modify `transform_request()` to handle the new parameter
|
||||
3. Add unit tests that verify the transformation
|
||||
|
||||
### Testing checklist
|
||||
|
||||
When adding a feature, verify it works across all paths:
|
||||
|
||||
| Test | File Pattern |
|
||||
|------|--------------|
|
||||
| OpenAI passthrough | `tests/llm_translation/test_openai*.py` |
|
||||
| Anthropic direct | `tests/llm_translation/test_anthropic*.py` |
|
||||
| Bedrock Invoke | `tests/llm_translation/test_bedrock*.py` |
|
||||
| Bedrock Converse | `tests/llm_translation/test_bedrock*converse*.py` |
|
||||
| Vertex AI | `tests/llm_translation/test_vertex*.py` |
|
||||
| Gemini | `tests/llm_translation/test_gemini*.py` |
|
||||
|
||||
### Unit testing translations
|
||||
|
||||
Translations are designed to be unit testable without making API calls:
|
||||
|
||||
```python
|
||||
from litellm.llms.bedrock.chat.converse_transformation import BedrockConverseConfig
|
||||
|
||||
def test_prompt_caching_transform():
|
||||
config = BedrockConverseConfig()
|
||||
result = config.transform_request(
|
||||
model="anthropic.claude-3-opus",
|
||||
messages=[{"role": "user", "content": "test", "cache_control": {"type": "ephemeral"}}],
|
||||
optional_params={},
|
||||
litellm_params={},
|
||||
headers={}
|
||||
)
|
||||
assert "cachePoint" in str(result) # Verify cache_control was translated
|
||||
```
|
||||
3
Makefile
|
|
@ -45,6 +45,7 @@ install-proxy-dev-ci:
|
|||
install-test-deps: install-proxy-dev
|
||||
poetry run pip install "pytest-retry==1.6.3"
|
||||
poetry run pip install pytest-xdist
|
||||
poetry run pip install openapi-core
|
||||
cd enterprise && poetry run pip install -e . && cd ..
|
||||
|
||||
install-helm-unittest:
|
||||
|
|
@ -100,4 +101,4 @@ test-llm-translation-single: install-test-deps
|
|||
@mkdir -p test-results
|
||||
poetry run pytest tests/llm_translation/$(FILE) \
|
||||
--junitxml=test-results/junit.xml \
|
||||
-v --tb=short --maxfail=100 --timeout=300
|
||||
-v --tb=short --maxfail=100 --timeout=300
|
||||
|
|
|
|||
|
|
@ -262,6 +262,7 @@ Support for more providers. Missing a provider or LLM Platform, raise a [feature
|
|||
|
||||
| Provider | `/chat/completions` | `/messages` | `/responses` | `/embeddings` | `/image/generations` | `/audio/transcriptions` | `/audio/speech` | `/moderations` | `/batches` | `/rerank` |
|
||||
|-------------------------------------------------------------------------------------|---------------------|-------------|--------------|---------------|----------------------|-------------------------|-----------------|----------------|-----------|-----------|
|
||||
| [Abliteration (`abliteration`)](https://docs.litellm.ai/docs/providers/abliteration) | ✅ | | | | | | | | | |
|
||||
| [AI/ML API (`aiml`)](https://docs.litellm.ai/docs/providers/aiml) | ✅ | ✅ | ✅ | ✅ | ✅ | | | | | |
|
||||
| [AI21 (`ai21`)](https://docs.litellm.ai/docs/providers/ai21) | ✅ | ✅ | ✅ | | | | | | | |
|
||||
| [AI21 Chat (`ai21_chat`)](https://docs.litellm.ai/docs/providers/ai21) | ✅ | ✅ | ✅ | | | | | | | |
|
||||
|
|
@ -455,4 +456,3 @@ All these checks must pass before your PR can be merged.
|
|||
<img src="https://contrib.rocks/image?repo=BerriAI/litellm" />
|
||||
</a>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
{"custom_id": "request-1", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gpt-3.5-turbo", "messages": [{"role": "user", "content": "Hello, how are you?"}]}}
|
||||
{"custom_id": "request-2", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gpt-3.5-turbo", "messages": [{"role": "user", "content": "What is the weather today?"}]}}
|
||||
{"custom_id": "request-3", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gpt-3.5-turbo", "messages": [{"role": "user", "content": "Tell me a short joke"}]}}
|
||||
|
||||
3
ci_cd/.grype.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
ignore:
|
||||
- vulnerability: CVE-2026-22184
|
||||
reason: no fixed zlib package is available yet in the Wolfi repositories, so this is ignored temporarily until an upstream release exists
|
||||
|
|
@ -101,12 +101,12 @@ run_grype_scans() {
|
|||
# Build and scan Dockerfile.database
|
||||
echo "Building and scanning Dockerfile.database..."
|
||||
docker build --no-cache -t litellm-database:latest -f ./docker/Dockerfile.database .
|
||||
grype litellm-database:latest --fail-on critical
|
||||
grype litellm-database:latest --config ci_cd/.grype.yaml --fail-on critical
|
||||
|
||||
# Build and scan main Dockerfile
|
||||
echo "Building and scanning main Dockerfile..."
|
||||
docker build --no-cache -t litellm:latest .
|
||||
grype litellm:latest --fail-on critical
|
||||
grype litellm:latest --config ci_cd/.grype.yaml --fail-on critical
|
||||
|
||||
# Restore original .dockerignore
|
||||
echo "Restoring original .dockerignore..."
|
||||
|
|
@ -129,6 +129,14 @@ run_grype_scans() {
|
|||
"CVE-2025-13836" # Python 3.13 HTTP response reading OOM/DoS - no fix available in base image
|
||||
"CVE-2025-12084" # Python 3.13 xml.dom.minidom quadratic algorithm - no fix available in base image
|
||||
"CVE-2025-60876" # BusyBox wget HTTP request splitting - no fix available in Chainguard Wolfi base image
|
||||
"CVE-2026-0861" # Wolfi glibc still flagged even on 2.42-r5; upstream patched build unavailable yet
|
||||
"CVE-2010-4756" # glibc glob DoS - awaiting patched Wolfi glibc build
|
||||
"CVE-2019-1010022" # glibc stack guard bypass - awaiting patched Wolfi glibc build
|
||||
"CVE-2019-1010023" # glibc ldd remap issue - awaiting patched Wolfi glibc build
|
||||
"CVE-2019-1010024" # glibc ASLR mitigation bypass - awaiting patched Wolfi glibc build
|
||||
"CVE-2019-1010025" # glibc pthread heap address leak - awaiting patched Wolfi glibc build
|
||||
"CVE-2026-22184" # zlib untgz buffer overflow - untgz unused + no fixed Wolfi build yet
|
||||
"GHSA-58pv-8j8x-9vj2" # jaraco.context path traversal - setuptools vendored only (v5.3.0), not used in application code (using v6.1.0+)
|
||||
)
|
||||
|
||||
# Build JSON array of allowlisted CVE IDs for jq
|
||||
|
|
|
|||
195
cookbook/ai_coding_tool_guides/claude_code_quickstart/guide.md
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
# Claude Code with LiteLLM Quickstart
|
||||
|
||||
This guide shows how to call Claude models (and any LiteLLM-supported model) through LiteLLM proxy from Claude Code.
|
||||
|
||||
> **Note:** This integration is based on [Anthropic's official LiteLLM configuration documentation](https://docs.anthropic.com/en/docs/claude-code/llm-gateway#litellm-configuration). It allows you to use any LiteLLM supported model through Claude Code with centralized authentication, usage tracking, and cost controls.
|
||||
|
||||
## Video Walkthrough
|
||||
|
||||
Watch the full tutorial: https://www.loom.com/embed/3c17d683cdb74d36a3698763cc558f56
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) installed
|
||||
- API keys for your chosen providers
|
||||
|
||||
## Installation
|
||||
|
||||
First, install LiteLLM with proxy support:
|
||||
|
||||
```bash
|
||||
pip install 'litellm[proxy]'
|
||||
```
|
||||
|
||||
## Step 1: Setup config.yaml
|
||||
|
||||
Create a secure configuration using environment variables:
|
||||
|
||||
```yaml
|
||||
model_list:
|
||||
# Claude models
|
||||
- model_name: claude-3-5-sonnet-20241022
|
||||
litellm_params:
|
||||
model: anthropic/claude-3-5-sonnet-20241022
|
||||
api_key: os.environ/ANTHROPIC_API_KEY
|
||||
|
||||
- model_name: claude-3-5-haiku-20241022
|
||||
litellm_params:
|
||||
model: anthropic/claude-3-5-haiku-20241022
|
||||
api_key: os.environ/ANTHROPIC_API_KEY
|
||||
|
||||
|
||||
litellm_settings:
|
||||
master_key: os.environ/LITELLM_MASTER_KEY
|
||||
```
|
||||
|
||||
Set your environment variables:
|
||||
|
||||
```bash
|
||||
export ANTHROPIC_API_KEY="your-anthropic-api-key"
|
||||
export LITELLM_MASTER_KEY="sk-1234567890" # Generate a secure key
|
||||
```
|
||||
|
||||
## Step 2: Start Proxy
|
||||
|
||||
```bash
|
||||
litellm --config /path/to/config.yaml
|
||||
|
||||
# RUNNING on http://0.0.0.0:4000
|
||||
```
|
||||
|
||||
## Step 3: Verify Setup
|
||||
|
||||
Test that your proxy is working correctly:
|
||||
|
||||
```bash
|
||||
curl -X POST http://0.0.0.0:4000/v1/messages \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "claude-3-5-sonnet-20241022",
|
||||
"max_tokens": 1000,
|
||||
"messages": [{"role": "user", "content": "What is the capital of France?"}]
|
||||
}'
|
||||
```
|
||||
|
||||
## Step 4: Configure Claude Code
|
||||
|
||||
### Method 1: Unified Endpoint (Recommended)
|
||||
|
||||
Configure Claude Code to use LiteLLM's unified endpoint. Either a virtual key or master key can be used here:
|
||||
|
||||
```bash
|
||||
export ANTHROPIC_BASE_URL="http://0.0.0.0:4000"
|
||||
export ANTHROPIC_AUTH_TOKEN="$LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
> **Tip:** LITELLM_MASTER_KEY gives Claude access to all proxy models, whereas a virtual key would be limited to the models set in the UI.
|
||||
|
||||
### Method 2: Provider-specific Pass-through Endpoint
|
||||
|
||||
Alternatively, use the Anthropic pass-through endpoint:
|
||||
|
||||
```bash
|
||||
export ANTHROPIC_BASE_URL="http://0.0.0.0:4000/anthropic"
|
||||
export ANTHROPIC_AUTH_TOKEN="$LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
## Step 5: Use Claude Code
|
||||
|
||||
Start Claude Code and it will automatically use your configured models:
|
||||
|
||||
```bash
|
||||
# Claude Code will use the models configured in your LiteLLM proxy
|
||||
claude
|
||||
|
||||
# Or specify a model if you have multiple configured
|
||||
claude --model claude-3-5-sonnet-20241022
|
||||
claude --model claude-3-5-haiku-20241022
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Common issues and solutions:
|
||||
|
||||
**Claude Code not connecting:**
|
||||
- Verify your proxy is running: `curl http://0.0.0.0:4000/health`
|
||||
- Check that `ANTHROPIC_BASE_URL` is set correctly
|
||||
- Ensure your `ANTHROPIC_AUTH_TOKEN` matches your LiteLLM master key
|
||||
|
||||
**Authentication errors:**
|
||||
- Verify your environment variables are set: `echo $LITELLM_MASTER_KEY`
|
||||
- Check that your API keys are valid and have sufficient credits
|
||||
- Ensure the `ANTHROPIC_AUTH_TOKEN` matches your LiteLLM master key
|
||||
|
||||
**Model not found:**
|
||||
- Ensure the model name in Claude Code matches exactly with your `config.yaml`
|
||||
- Check LiteLLM logs for detailed error messages
|
||||
|
||||
## Using Multiple Models and Providers
|
||||
|
||||
Expand your configuration to support multiple providers and models:
|
||||
|
||||
```yaml
|
||||
model_list:
|
||||
# OpenAI models
|
||||
- model_name: codex-mini
|
||||
litellm_params:
|
||||
model: openai/codex-mini
|
||||
api_key: os.environ/OPENAI_API_KEY
|
||||
api_base: https://api.openai.com/v1
|
||||
|
||||
- model_name: o3-pro
|
||||
litellm_params:
|
||||
model: openai/o3-pro
|
||||
api_key: os.environ/OPENAI_API_KEY
|
||||
api_base: https://api.openai.com/v1
|
||||
|
||||
- model_name: gpt-4o
|
||||
litellm_params:
|
||||
model: openai/gpt-4o
|
||||
api_key: os.environ/OPENAI_API_KEY
|
||||
api_base: https://api.openai.com/v1
|
||||
|
||||
# Anthropic models
|
||||
- model_name: claude-3-5-sonnet-20241022
|
||||
litellm_params:
|
||||
model: anthropic/claude-3-5-sonnet-20241022
|
||||
api_key: os.environ/ANTHROPIC_API_KEY
|
||||
|
||||
- model_name: claude-3-5-haiku-20241022
|
||||
litellm_params:
|
||||
model: anthropic/claude-3-5-haiku-20241022
|
||||
api_key: os.environ/ANTHROPIC_API_KEY
|
||||
|
||||
# AWS Bedrock
|
||||
- model_name: claude-bedrock
|
||||
litellm_params:
|
||||
model: bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0
|
||||
aws_access_key_id: os.environ/AWS_ACCESS_KEY_ID
|
||||
aws_secret_access_key: os.environ/AWS_SECRET_ACCESS_KEY
|
||||
aws_region_name: us-east-1
|
||||
|
||||
litellm_settings:
|
||||
master_key: os.environ/LITELLM_MASTER_KEY
|
||||
```
|
||||
|
||||
Switch between models seamlessly:
|
||||
|
||||
```bash
|
||||
# Use Claude for complex reasoning
|
||||
claude --model claude-3-5-sonnet-20241022
|
||||
|
||||
# Use Haiku for fast responses
|
||||
claude --model claude-3-5-haiku-20241022
|
||||
|
||||
# Use Bedrock deployment
|
||||
claude --model claude-bedrock
|
||||
```
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [LiteLLM Documentation](https://docs.litellm.ai/)
|
||||
- [Claude Code Documentation](https://docs.anthropic.com/en/docs/claude-code/overview)
|
||||
- [Anthropic's LiteLLM Configuration Guide](https://docs.anthropic.com/en/docs/claude-code/llm-gateway#litellm-configuration)
|
||||
|
||||
98
cookbook/ai_coding_tool_guides/index.json
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
[{
|
||||
"title": "Claude Code Quickstart",
|
||||
"description": "This is a quickstart guide to using Claude Code with LiteLLM.",
|
||||
"url": "https://docs.litellm.ai/docs/tutorials/claude_responses_api",
|
||||
"date": "2026-01-15",
|
||||
"version": "1.0.0",
|
||||
"tags": [
|
||||
"Claude Code",
|
||||
"LiteLLM"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Claude Code with MCPs",
|
||||
"description": "This is a guide to using Claude Code with MCPs via LiteLLM Proxy.",
|
||||
"url": "https://docs.litellm.ai/docs/tutorials/claude_mcp",
|
||||
"date": "2026-01-15",
|
||||
"version": "1.0.0",
|
||||
"tags": [
|
||||
"Claude Code",
|
||||
"LiteLLM",
|
||||
"MCP"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Claude Code with Non-Anthropic Models",
|
||||
"description": "This is a guide to using Claude Code with non-Anthropic models via LiteLLM Proxy.",
|
||||
"url": "https://docs.litellm.ai/docs/tutorials/claude_non_anthropic_models",
|
||||
"date": "2026-01-16",
|
||||
"version": "1.0.0",
|
||||
"tags": [
|
||||
"Claude Code",
|
||||
"LiteLLM",
|
||||
"OpenAI",
|
||||
"Gemini"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Cursor Quickstart",
|
||||
"description": "This is a quickstart guide to using Cursor with LiteLLM.",
|
||||
"url": "https://docs.litellm.ai/docs/tutorials/cursor_integration",
|
||||
"date": "2026-01-16",
|
||||
"version": "1.0.0",
|
||||
"tags": [
|
||||
"Cursor",
|
||||
"LiteLLM",
|
||||
"Quickstart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Github Copilot Quickstart",
|
||||
"description": "This is a quickstart guide to using Github Copilot with LiteLLM.",
|
||||
"url": "https://docs.litellm.ai/docs/tutorials/github_copilot_integration",
|
||||
"date": "2026-01-16",
|
||||
"version": "1.0.0",
|
||||
"tags": [
|
||||
"Github Copilot",
|
||||
"LiteLLM",
|
||||
"Quickstart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "LiteLLM Gemini CLI Quickstart",
|
||||
"description": "This is a quickstart guide to using LiteLLM Gemini CLI.",
|
||||
"url": "https://docs.litellm.ai/docs/tutorials/litellm_gemini_cli",
|
||||
"date": "2026-01-16",
|
||||
"version": "1.0.0",
|
||||
"tags": [
|
||||
"Gemini CLI",
|
||||
"Gemini",
|
||||
"LiteLLM",
|
||||
"Quickstart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "OpenAI Codex CLI Quickstart",
|
||||
"description": "This is a quickstart guide to using OpenAI Codex CLI.",
|
||||
"url": "https://docs.litellm.ai/docs/tutorials/openai_codex",
|
||||
"date": "2026-01-16",
|
||||
"version": "1.0.0",
|
||||
"tags": [
|
||||
"OpenAI Codex CLI",
|
||||
"OpenAI",
|
||||
"LiteLLM",
|
||||
"Quickstart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "OpenWebUI Quickstart",
|
||||
"description": "This is a quickstart guide to using OpenWebUI with LiteLLM.",
|
||||
"url": "https://docs.litellm.ai/docs/tutorials/openweb_ui",
|
||||
"date": "2026-01-16",
|
||||
"version": "1.0.0",
|
||||
"tags": [
|
||||
"OpenWebUI",
|
||||
"LiteLLM",
|
||||
"Quickstart"
|
||||
]
|
||||
}]
|
||||
|
|
@ -18,13 +18,13 @@ type: application
|
|||
# This is the chart version. This version number should be incremented each time you make changes
|
||||
# to the chart and its templates, including the app version.
|
||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||
version: 0.4.10
|
||||
version: 1.0.0
|
||||
|
||||
# This is the version number of the application being deployed. This version number should be
|
||||
# incremented each time you make changes to the application. Versions are not expected to
|
||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||
# It is recommended to use it with quotes.
|
||||
appVersion: v1.50.2
|
||||
appVersion: v1.80.12
|
||||
|
||||
dependencies:
|
||||
- name: "postgresql"
|
||||
|
|
|
|||
|
|
@ -170,7 +170,8 @@ spec:
|
|||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: litellm-config
|
||||
mountPath: /etc/litellm/
|
||||
mountPath: /etc/litellm/config.yaml
|
||||
subPath: config.yaml
|
||||
{{ if .Values.securityContext.readOnlyRootFilesystem }}
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
|
|
|
|||
|
|
@ -136,7 +136,8 @@ tests:
|
|||
path: spec.template.spec.containers[0].volumeMounts
|
||||
content:
|
||||
name: litellm-config
|
||||
mountPath: /etc/litellm/
|
||||
mountPath: /etc/litellm/config.yaml
|
||||
subPath: config.yaml
|
||||
- it: should work with lifecycle hooks
|
||||
template: deployment.yaml
|
||||
set:
|
||||
|
|
|
|||
|
|
@ -110,6 +110,8 @@ COPY --from=builder /app/requirements.txt /app/requirements.txt
|
|||
COPY --from=builder /app/docker/entrypoint.sh /app/docker/prod_entrypoint.sh /app/docker/
|
||||
COPY --from=builder /app/docker/supervisord.conf /etc/supervisord.conf
|
||||
COPY --from=builder /app/schema.prisma /app/
|
||||
# Copy prisma_migration.py for Helm migrations job compatibility
|
||||
COPY --from=builder /app/litellm/proxy/prisma_migration.py /app/litellm/proxy/prisma_migration.py
|
||||
COPY --from=builder /wheels/ /wheels/
|
||||
COPY --from=builder /var/lib/litellm/ui /var/lib/litellm/ui
|
||||
COPY --from=builder /var/lib/litellm/assets /var/lib/litellm/assets
|
||||
|
|
|
|||
|
|
@ -142,7 +142,47 @@ def completion(
|
|||
- `tool_call_id`: *str (optional)* - Tool call that this message is responding to.
|
||||
|
||||
|
||||
[**See All Message Values**](https://github.com/BerriAI/litellm/blob/8600ec77042dacad324d3879a2bd918fc6a719fa/litellm/types/llms/openai.py#L392)
|
||||
[**See All Message Values**](https://github.com/BerriAI/litellm/blob/main/litellm/types/llms/openai.py#L664)
|
||||
|
||||
#### Content Types
|
||||
|
||||
`content` can be a string (text only) or a list of content blocks (multimodal):
|
||||
|
||||
| Type | Description | Docs |
|
||||
|------|-------------|------|
|
||||
| `text` | Text content | [Type Definition](https://github.com/BerriAI/litellm/blob/main/litellm/types/llms/openai.py#L598) |
|
||||
| `image_url` | Images | [Vision](./vision.md) |
|
||||
| `input_audio` | Audio input | [Audio](./audio.md) |
|
||||
| `video_url` | Video input | [Type Definition](https://github.com/BerriAI/litellm/blob/main/litellm/types/llms/openai.py#L625) |
|
||||
| `file` | Files | [Document Understanding](./document_understanding.md) |
|
||||
| `document` | Documents/PDFs | [Document Understanding](./document_understanding.md) |
|
||||
|
||||
**Examples:**
|
||||
```python
|
||||
# Text
|
||||
messages=[{"role": "user", "content": [{"type": "text", "text": "Hello!"}]}]
|
||||
|
||||
# Image
|
||||
messages=[{"role": "user", "content": [{"type": "image_url", "image_url": {"url": "https://example.com/image.jpg"}}]}]
|
||||
|
||||
# Audio
|
||||
messages=[{"role": "user", "content": [{"type": "input_audio", "input_audio": {"data": "<base64>", "format": "wav"}}]}]
|
||||
|
||||
# Video
|
||||
messages=[{"role": "user", "content": [{"type": "video_url", "video_url": {"url": "https://example.com/video.mp4"}}]}]
|
||||
|
||||
# File
|
||||
messages=[{"role": "user", "content": [{"type": "file", "file": {"file_id": "https://example.com/doc.pdf"}}]}]
|
||||
|
||||
# Document
|
||||
messages=[{"role": "user", "content": [{"type": "document", "source": {"type": "text", "media_type": "application/pdf", "data": "<base64>"}}]}]
|
||||
|
||||
# Combining multiple types (multimodal)
|
||||
messages=[{"role": "user", "content": [
|
||||
{"type": "text", "text": "Generate a product description based on this image"},
|
||||
{"type": "image_url", "image_url": {"url": "https://example.com/image.jpg"}}
|
||||
]}]
|
||||
```
|
||||
|
||||
## Optional Fields
|
||||
|
||||
|
|
|
|||
468
docs/my-website/docs/completion/message_sanitization.md
Normal file
|
|
@ -0,0 +1,468 @@
|
|||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Message Sanitization for Tool Calling for anthropic models
|
||||
|
||||
**Automatically fix common message formatting issues when using tool calling with `modify_params=True`**
|
||||
|
||||
LiteLLM can automatically sanitize messages to handle common issues that occur during tool calling workflows, especially when using OpenAI-compatible clients with providers that have strict message format requirements (like Anthropic Claude).
|
||||
|
||||
## Overview
|
||||
|
||||
When `litellm.modify_params = True` is enabled, LiteLLM automatically sanitizes messages to fix three common issues:
|
||||
|
||||
1. **Orphaned Tool Calls** - Assistant messages with tool_calls but missing tool results
|
||||
2. **Orphaned Tool Results** - Tool messages that reference non-existent tool_call_ids
|
||||
3. **Empty Message Content** - Messages with empty or whitespace-only text content
|
||||
|
||||
This ensures your tool calling workflows work seamlessly across different LLM providers without manual message validation.
|
||||
|
||||
## Why Message Sanitization?
|
||||
|
||||
Different LLM providers have varying requirements for message formats, especially during tool calling:
|
||||
|
||||
- **Anthropic Claude** requires every tool_call to have a corresponding tool result
|
||||
- Some providers reject messages with empty content
|
||||
- OpenAI-compatible clients may not always maintain perfect message consistency
|
||||
|
||||
Without sanitization, these issues cause API errors that interrupt your workflows. With `modify_params=True`, LiteLLM handles these edge cases automatically.
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="sdk" label="SDK">
|
||||
|
||||
```python
|
||||
import litellm
|
||||
|
||||
# Enable automatic message sanitization
|
||||
litellm.modify_params = True
|
||||
|
||||
# This will work even if messages have formatting issues
|
||||
response = litellm.completion(
|
||||
model="anthropic/claude-3-5-sonnet-20241022",
|
||||
messages=[
|
||||
{"role": "user", "content": "What's the weather in Boston?"},
|
||||
{
|
||||
"role": "assistant",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call_123",
|
||||
"type": "function",
|
||||
"function": {"name": "get_weather", "arguments": '{"city": "Boston"}'}
|
||||
}
|
||||
]
|
||||
# Missing tool result - LiteLLM will add a dummy result automatically
|
||||
},
|
||||
{"role": "user", "content": "Thanks!"}
|
||||
],
|
||||
tools=[{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "get_weather",
|
||||
"description": "Get weather for a city",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {"city": {"type": "string"}},
|
||||
"required": ["city"]
|
||||
}
|
||||
}
|
||||
}]
|
||||
)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="proxy" label="PROXY">
|
||||
|
||||
```yaml
|
||||
litellm_settings:
|
||||
modify_params: true # Enable automatic message sanitization
|
||||
|
||||
model_list:
|
||||
- model_name: claude-3-5-sonnet
|
||||
litellm_params:
|
||||
model: anthropic/claude-3-5-sonnet-20241022
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Sanitization Cases
|
||||
|
||||
### Case A: Orphaned Tool Calls (Missing Tool Results)
|
||||
|
||||
**Problem:** An assistant message contains `tool_calls`, but no corresponding tool result messages follow.
|
||||
|
||||
**Solution:** LiteLLM automatically adds dummy tool result messages for any missing tool results.
|
||||
|
||||
**Example:**
|
||||
|
||||
```python
|
||||
import litellm
|
||||
litellm.modify_params = True
|
||||
|
||||
# Messages with orphaned tool calls
|
||||
messages = [
|
||||
{"role": "user", "content": "Search for Python tutorials"},
|
||||
{
|
||||
"role": "assistant",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call_abc123",
|
||||
"type": "function",
|
||||
"function": {"name": "web_search", "arguments": '{"query": "Python tutorials"}'}
|
||||
}
|
||||
]
|
||||
},
|
||||
# Missing tool result here!
|
||||
{"role": "user", "content": "What about JavaScript?"}
|
||||
]
|
||||
|
||||
# LiteLLM automatically adds:
|
||||
# {
|
||||
# "role": "tool",
|
||||
# "tool_call_id": "call_abc123",
|
||||
# "content": "[System: Tool execution skipped/interrupted by user. No result provided for tool 'web_search'.]"
|
||||
# }
|
||||
|
||||
response = litellm.completion(
|
||||
model="anthropic/claude-3-5-sonnet-20241022",
|
||||
messages=messages,
|
||||
tools=[...]
|
||||
)
|
||||
```
|
||||
|
||||
**When this happens:**
|
||||
- User interrupts tool execution
|
||||
- Client loses tool results due to network issues
|
||||
- Conversation flow changes before tool completes
|
||||
- Multi-turn conversations where tools are optional
|
||||
|
||||
### Case B: Orphaned Tool Results (Invalid tool_call_id)
|
||||
|
||||
**Problem:** A tool message references a `tool_call_id` that doesn't exist in any previous assistant message.
|
||||
|
||||
**Solution:** LiteLLM automatically removes these orphaned tool result messages.
|
||||
|
||||
**Example:**
|
||||
|
||||
```python
|
||||
import litellm
|
||||
litellm.modify_params = True
|
||||
|
||||
# Messages with orphaned tool result
|
||||
messages = [
|
||||
{"role": "user", "content": "Hello"},
|
||||
{"role": "assistant", "content": "Hi! How can I help?"},
|
||||
{
|
||||
"role": "tool",
|
||||
"tool_call_id": "call_nonexistent", # This tool_call_id doesn't exist!
|
||||
"content": "Some result"
|
||||
}
|
||||
]
|
||||
|
||||
# LiteLLM automatically removes the orphaned tool message
|
||||
|
||||
response = litellm.completion(
|
||||
model="anthropic/claude-3-5-sonnet-20241022",
|
||||
messages=messages
|
||||
)
|
||||
```
|
||||
|
||||
**When this happens:**
|
||||
- Message history is manually edited
|
||||
- Tool results are duplicated or mismatched
|
||||
- Conversation state is restored incorrectly
|
||||
- Messages are merged from different conversations
|
||||
|
||||
### Case C: Empty Message Content
|
||||
|
||||
**Problem:** User or assistant messages have empty or whitespace-only content.
|
||||
|
||||
**Solution:** LiteLLM replaces empty content with a system placeholder message.
|
||||
|
||||
**Example:**
|
||||
|
||||
```python
|
||||
import litellm
|
||||
litellm.modify_params = True
|
||||
|
||||
# Messages with empty content
|
||||
messages = [
|
||||
{"role": "user", "content": ""}, # Empty content
|
||||
{"role": "assistant", "content": " "}, # Whitespace only
|
||||
]
|
||||
|
||||
# LiteLLM automatically replaces with:
|
||||
# {"role": "user", "content": "[System: Empty message content sanitised to satisfy protocol]"}
|
||||
# {"role": "assistant", "content": "[System: Empty message content sanitised to satisfy protocol]"}
|
||||
|
||||
response = litellm.completion(
|
||||
model="anthropic/claude-3-5-sonnet-20241022",
|
||||
messages=messages
|
||||
)
|
||||
```
|
||||
|
||||
**When this happens:**
|
||||
- UI sends empty messages
|
||||
- Content is stripped during preprocessing
|
||||
- Placeholder messages in conversation history
|
||||
- Edge cases in message construction
|
||||
|
||||
## Configuration
|
||||
|
||||
### Enable Globally
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="sdk" label="SDK">
|
||||
|
||||
```python
|
||||
import litellm
|
||||
|
||||
# Enable for all completion calls
|
||||
litellm.modify_params = True
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="proxy" label="PROXY">
|
||||
|
||||
```yaml
|
||||
litellm_settings:
|
||||
modify_params: true
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="env" label="Environment Variable">
|
||||
|
||||
```bash
|
||||
export LITELLM_MODIFY_PARAMS=True
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Enable Per-Request
|
||||
|
||||
```python
|
||||
import litellm
|
||||
|
||||
# Enable only for specific requests
|
||||
response = litellm.completion(
|
||||
model="anthropic/claude-3-5-sonnet-20241022",
|
||||
messages=messages,
|
||||
modify_params=True # Override global setting
|
||||
)
|
||||
```
|
||||
|
||||
## Supported Providers
|
||||
|
||||
Message sanitization works with all LLM providers that support tool calling:
|
||||
|
||||
- ✅ Anthropic (Claude)
|
||||
- ✅ OpenAI (GPT-4, GPT-3.5)
|
||||
- ✅ AWS Bedrock (Claude, Titan)
|
||||
- ✅ Google Vertex AI (Claude, Gemini)
|
||||
- ✅ Azure OpenAI
|
||||
- ✅ And all other providers with tool calling support
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### How It Works
|
||||
|
||||
The message sanitization process runs **before** messages are converted to provider-specific formats:
|
||||
|
||||
1. **Input:** OpenAI-format messages with potential issues
|
||||
2. **Sanitization:** Three helper functions process the messages:
|
||||
- `_sanitize_empty_text_content()` - Fixes empty content
|
||||
- `_add_missing_tool_results()` - Adds dummy tool results
|
||||
- `_is_orphaned_tool_result()` - Identifies orphaned results
|
||||
3. **Output:** Clean, provider-compatible messages
|
||||
|
||||
### Code Reference
|
||||
|
||||
The sanitization logic is implemented in:
|
||||
- `litellm/litellm_core_utils/prompt_templates/factory.py`
|
||||
- Function: `sanitize_messages_for_tool_calling()`
|
||||
|
||||
### Logging
|
||||
|
||||
When sanitization occurs, LiteLLM logs debug messages:
|
||||
|
||||
```python
|
||||
import litellm
|
||||
litellm.set_verbose = True # Enable debug logging
|
||||
|
||||
# You'll see logs like:
|
||||
# "_add_missing_tool_results: Found 1 orphaned tool calls. Adding dummy tool results."
|
||||
# "_is_orphaned_tool_result: Found orphaned tool result with tool_call_id=call_123"
|
||||
# "_sanitize_empty_text_content: Replaced empty text content in user message"
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Enable for Production Workflows
|
||||
|
||||
```python
|
||||
# Recommended for production
|
||||
litellm.modify_params = True
|
||||
|
||||
# Ensures robust handling of edge cases
|
||||
response = litellm.completion(
|
||||
model="anthropic/claude-3-5-sonnet-20241022",
|
||||
messages=messages,
|
||||
tools=tools
|
||||
)
|
||||
```
|
||||
|
||||
### 2. Preserve Tool Results When Possible
|
||||
|
||||
While sanitization handles missing tool results, it's better to provide actual results:
|
||||
|
||||
```python
|
||||
# Good: Provide actual tool results
|
||||
messages = [
|
||||
{"role": "user", "content": "Search for Python"},
|
||||
{"role": "assistant", "tool_calls": [...]},
|
||||
{"role": "tool", "tool_call_id": "call_123", "content": "Actual search results"}
|
||||
]
|
||||
|
||||
# Fallback: Sanitization adds dummy result if missing
|
||||
messages = [
|
||||
{"role": "user", "content": "Search for Python"},
|
||||
{"role": "assistant", "tool_calls": [...]},
|
||||
# Missing tool result - sanitization adds dummy
|
||||
]
|
||||
```
|
||||
|
||||
### 3. Monitor Sanitization Events
|
||||
|
||||
Use logging to track when sanitization occurs:
|
||||
|
||||
```python
|
||||
import litellm
|
||||
import logging
|
||||
|
||||
# Enable debug logging
|
||||
litellm.set_verbose = True
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
# Track sanitization events in your application
|
||||
response = litellm.completion(
|
||||
model="anthropic/claude-3-5-sonnet-20241022",
|
||||
messages=messages
|
||||
)
|
||||
```
|
||||
|
||||
### 4. Test Edge Cases
|
||||
|
||||
Ensure your application handles sanitized messages correctly:
|
||||
|
||||
```python
|
||||
import litellm
|
||||
litellm.modify_params = True
|
||||
|
||||
# Test orphaned tool calls
|
||||
test_messages = [
|
||||
{"role": "user", "content": "Test"},
|
||||
{"role": "assistant", "tool_calls": [{"id": "call_1", "type": "function", "function": {"name": "test", "arguments": "{}"}}]},
|
||||
{"role": "user", "content": "Continue"} # No tool result
|
||||
]
|
||||
|
||||
response = litellm.completion(
|
||||
model="anthropic/claude-3-5-sonnet-20241022",
|
||||
messages=test_messages,
|
||||
tools=[...]
|
||||
)
|
||||
|
||||
# Verify the response handles the dummy tool result appropriately
|
||||
```
|
||||
|
||||
## Related Features
|
||||
|
||||
- **[Drop Params](./drop_params.md)** - Drop unsupported parameters for specific providers
|
||||
- **[Message Trimming](./message_trimming.md)** - Trim messages to fit token limits
|
||||
- **[Function Calling](./function_call.md)** - Complete guide to tool/function calling
|
||||
- **[Reasoning Content](../reasoning_content.md)** - Extended thinking with tool calling
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Sanitization Not Working
|
||||
|
||||
**Issue:** Messages still cause errors despite `modify_params=True`
|
||||
|
||||
**Solution:**
|
||||
1. Verify `modify_params` is enabled:
|
||||
```python
|
||||
import litellm
|
||||
print(litellm.modify_params) # Should be True
|
||||
```
|
||||
|
||||
2. Check if the issue is provider-specific:
|
||||
```python
|
||||
litellm.set_verbose = True # Enable debug logging
|
||||
```
|
||||
|
||||
3. Ensure you're using a recent version of LiteLLM:
|
||||
```bash
|
||||
pip install --upgrade litellm
|
||||
```
|
||||
|
||||
### Unexpected Dummy Tool Results
|
||||
|
||||
**Issue:** Dummy tool results appear when you expect actual results
|
||||
|
||||
**Cause:** Tool result messages are missing or have incorrect `tool_call_id`
|
||||
|
||||
**Solution:**
|
||||
1. Verify tool result messages have correct `tool_call_id`:
|
||||
```python
|
||||
# Correct
|
||||
{"role": "tool", "tool_call_id": "call_123", "content": "result"}
|
||||
|
||||
# Incorrect - will be treated as orphaned
|
||||
{"role": "tool", "tool_call_id": "wrong_id", "content": "result"}
|
||||
```
|
||||
|
||||
2. Ensure tool results immediately follow assistant messages with tool_calls
|
||||
|
||||
### Performance Impact
|
||||
|
||||
**Issue:** Concerned about performance overhead
|
||||
|
||||
**Details:** Message sanitization has minimal performance impact:
|
||||
- Runs in O(n) time where n = number of messages
|
||||
- Only processes messages when `modify_params=True`
|
||||
- Typically adds < 1ms to request processing time
|
||||
|
||||
## FAQ
|
||||
|
||||
**Q: Does sanitization modify my original messages?**
|
||||
|
||||
A: No, sanitization creates a new list of messages. Your original messages remain unchanged.
|
||||
|
||||
**Q: Can I disable specific sanitization cases?**
|
||||
|
||||
A: Currently, all three cases are handled together when `modify_params=True`. To disable sanitization entirely, set `modify_params=False`.
|
||||
|
||||
**Q: What happens to the dummy tool results?**
|
||||
|
||||
A: Dummy tool results are sent to the LLM provider along with other messages. The model sees them as regular tool results with informative error messages.
|
||||
|
||||
**Q: Does this work with streaming?**
|
||||
|
||||
A: Yes, message sanitization works with both streaming and non-streaming requests.
|
||||
|
||||
**Q: Is this related to `drop_params`?**
|
||||
|
||||
A: No, they're separate features:
|
||||
- `modify_params` - Modifies/fixes message content and structure
|
||||
- `drop_params` - Removes unsupported API parameters
|
||||
|
||||
Both can be enabled simultaneously.
|
||||
|
||||
## See Also
|
||||
|
||||
- [Reasoning Content with Tool Calling](../reasoning_content.md)
|
||||
- [Function Calling Guide](./function_call.md)
|
||||
- [Bedrock Provider Documentation](../providers/bedrock.md)
|
||||
- [Anthropic Provider Documentation](../providers/anthropic.md)
|
||||
|
|
@ -10,7 +10,7 @@ This policy outlines the requirements and controls/procedures LiteLLM Cloud has
|
|||
For Customers
|
||||
1. Active Accounts
|
||||
|
||||
- Customer data is retained for as long as the customer’s account is in active status. This includes data such as prompts, generated content, logs, and usage metrics.
|
||||
- Customer data is retained for as long as the customer’s account is in active status. This includes data such as prompts, generated content, logs, and usage metrics. By default, we do not store the message / response content of your API requests or responses. Cloud users need to explicitly opt in to store the message / response content of your API requests or responses.
|
||||
|
||||
2. Voluntary Account Closure
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import TabItem from '@theme/TabItem';
|
|||
| Fallbacks | ✅ | Works between supported models |
|
||||
| Loadbalancing | ✅ | Works between supported models |
|
||||
| Guardrails | ✅ | Applies to input prompts (non-streaming only) |
|
||||
| Supported Providers | OpenAI, Azure, Google AI Studio, Vertex AI, AWS Bedrock, Recraft, Xinference, Nscale | |
|
||||
| Supported Providers | OpenAI, Azure, Google AI Studio, Vertex AI, AWS Bedrock, Recraft, OpenRouter, Xinference, Nscale | |
|
||||
|
||||
## Quick Start
|
||||
|
||||
|
|
@ -238,6 +238,27 @@ print(response)
|
|||
|
||||
See Recraft usage with LiteLLM [here](./providers/recraft.md#image-generation)
|
||||
|
||||
## OpenRouter Image Generation Models
|
||||
|
||||
Use this for image generation models available through OpenRouter (e.g., Google Gemini image generation models)
|
||||
|
||||
#### Usage
|
||||
|
||||
```python showLineNumbers
|
||||
from litellm import image_generation
|
||||
import os
|
||||
|
||||
os.environ['OPENROUTER_API_KEY'] = "your-api-key"
|
||||
|
||||
response = image_generation(
|
||||
model="openrouter/google/gemini-2.5-flash-image",
|
||||
prompt="A beautiful sunset over a calm ocean",
|
||||
size="1024x1024",
|
||||
quality="high",
|
||||
)
|
||||
print(response)
|
||||
```
|
||||
|
||||
## OpenAI Compatible Image Generation Models
|
||||
Use this for calling `/image_generation` endpoints on OpenAI Compatible Servers, example https://github.com/xorbitsai/inference
|
||||
|
||||
|
|
@ -301,5 +322,6 @@ print(f"response: {response}")
|
|||
| Vertex AI | [Vertex AI Image Generation →](./providers/vertex_image) |
|
||||
| AWS Bedrock | [Bedrock Image Generation →](./providers/bedrock) |
|
||||
| Recraft | [Recraft Image Generation →](./providers/recraft#image-generation) |
|
||||
| OpenRouter | [OpenRouter Image Generation →](./providers/openrouter#image-generation) |
|
||||
| Xinference | [Xinference Image Generation →](./providers/xinference#image-generation) |
|
||||
| Nscale | [Nscale Image Generation →](./providers/nscale#image-generation) |
|
||||
|
|
@ -60,6 +60,8 @@ model_list:
|
|||
|
||||
If `supported_db_objects` is not set, all object types are loaded from the database (default behavior).
|
||||
|
||||
For diagnosing connectivity problems after setup, see the [MCP Troubleshooting Guide](./mcp_troubleshoot.md).
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="ui" label="LiteLLM UI">
|
||||
|
||||
|
|
@ -326,6 +328,7 @@ litellm_settings:
|
|||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
## Converting OpenAPI Specs to MCP Servers
|
||||
|
||||
LiteLLM can automatically convert OpenAPI specifications into MCP servers, allowing you to expose any REST API as MCP tools. This is useful when you have existing APIs with OpenAPI/Swagger documentation and want to make them available as MCP tools.
|
||||
|
|
@ -502,7 +505,7 @@ Your OpenAPI specification should follow standard OpenAPI/Swagger conventions:
|
|||
|
||||
LiteLLM v 1.77.6 added support for OAuth 2.0 Client Credentials for MCP servers.
|
||||
|
||||
This configuration is currently available on the config.yaml, with UI support coming soon.
|
||||
You can configure this either in `config.yaml` or directly from the LiteLLM UI (MCP Servers → Authentication → OAuth).
|
||||
|
||||
```yaml
|
||||
mcp_servers:
|
||||
|
|
@ -1473,3 +1476,17 @@ async with stdio_client(server_params) as (read, write):
|
|||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## FAQ
|
||||
|
||||
**Q: How do I use OAuth2 client_credentials (machine-to-machine) with MCP servers behind LiteLLM?**
|
||||
|
||||
At the moment LiteLLM only forwards whatever `Authorization` header/value you configure for the MCP server; it does not issue OAuth2 tokens by itself. If your MCP requires the Client Credentials grant, obtain the access token directly from the authorization server and set that bearer token as the MCP server’s Authorization header value. LiteLLM does not yet fetch or refresh those machine-to-machine tokens on your behalf, but we plan to add first-class client_credentials support in a future release so the proxy can manage those tokens automatically.
|
||||
|
||||
**Q: When I fetch an OAuth token from the LiteLLM UI, where is it stored?**
|
||||
|
||||
The UI keeps only transient state in `sessionStorage` so the OAuth redirect flow can finish; the token is not persisted in the server or database.
|
||||
|
||||
**Q: I'm seeing MCP connection errors—what should I check?**
|
||||
|
||||
Walk through the [MCP Troubleshooting Guide](./mcp_troubleshoot.md) for step-by-step isolation (Client → LiteLLM vs. LiteLLM → MCP), log examples, and verification methods like MCP Inspector and `curl`.
|
||||
|
|
|
|||
|
|
@ -649,3 +649,16 @@ general_settings:
|
|||
```
|
||||
|
||||
This is useful when you want discoverability for MCP offerings without granting additional execution privileges.
|
||||
|
||||
|
||||
## Publish MCP Registry
|
||||
|
||||
If you want other systems—for example external agent frameworks such as MCP-capable IDEs running outside your network—to automatically discover the MCP servers hosted on LiteLLM, you can expose a Model Context Protocol Registry endpoint. This registry lists the built-in LiteLLM MCP server and every server you have configured, using the [official MCP Registry spec](https://github.com/modelcontextprotocol/registry).
|
||||
|
||||
1. Set `enable_mcp_registry: true` under `general_settings` in your proxy config (or DB settings) and restart the proxy.
|
||||
2. LiteLLM will serve the registry at `GET /v1/mcp/registry.json`.
|
||||
3. Each entry points to either `/mcp` (built-in server) or `/{mcp_server_name}/mcp` for your custom servers, so clients can connect directly using the advertised Streamable HTTP URL.
|
||||
|
||||
:::note Permissions still apply
|
||||
The registry only advertises server URLs. Actual access control is still enforced by LiteLLM when the client connects to `/mcp` or `/{server}/mcp`, so publishing the registry does not bypass per-key permissions.
|
||||
:::
|
||||
|
|
|
|||
99
docs/my-website/docs/mcp_troubleshoot.md
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
import Image from '@theme/IdealImage';
|
||||
|
||||
# MCP Troubleshooting Guide
|
||||
|
||||
When LiteLLM acts as an MCP proxy, traffic normally flows `Client → LiteLLM Proxy → MCP Server`, while OAuth-enabled setups add an authorization server for metadata discovery.
|
||||
|
||||
For provisioning steps, transport options, and configuration fields, refer to [mcp.md](./mcp.md).
|
||||
|
||||
## Locate the Error Source
|
||||
|
||||
Pin down where the failure occurs before adjusting settings so you do not mix symptoms from separate hops.
|
||||
|
||||
### LiteLLM UI / Playground Errors (LiteLLM → MCP)
|
||||
Failures shown on the MCP creation form or within the MCP Tool Testing Playground mean the LiteLLM proxy cannot reach the MCP server. Typical causes are misconfiguration (transport, headers, credentials), MCP/server outages, network/firewall blocks, or inaccessible OAuth metadata.
|
||||
|
||||
<Image
|
||||
img={require('../img/mcp_tool_testing_playground.png')}
|
||||
style={{width: '80%', display: 'block', margin: '0'}}
|
||||
/>
|
||||
|
||||
<br/>
|
||||
|
||||
**Actions**
|
||||
- Capture LiteLLM proxy logs alongside MCP-server logs (see [Error Log Example](./mcp_troubleshoot#error-log-example-failed-mcp-call)) to inspect the request/response pair and stack traces.
|
||||
- From the LiteLLM server, run Method 2 ([`curl` smoke test](./mcp_troubleshoot#curl-smoke-test)) against the MCP endpoint to confirm basic connectivity.
|
||||
|
||||
### Client Traffic Issues (Client → LiteLLM)
|
||||
If only real client requests fail, determine whether LiteLLM ever reaches the MCP hop.
|
||||
|
||||
#### MCP Protocol Sessions
|
||||
Clients such as IDEs or agent runtimes speak the MCP protocol directly with LiteLLM.
|
||||
|
||||
**Actions**
|
||||
- Inspect LiteLLM access logs (see [Access Log Example](./mcp_troubleshoot#access-log-example-successful-mcp-call)) to verify the client request reached the proxy and which MCP server it targeted.
|
||||
- Review LiteLLM error logs (see [Error Log Example](./mcp_troubleshoot#error-log-example-failed-mcp-call)) for TLS, authentication, or routing errors that block the request before the MCP call starts.
|
||||
- Use the [MCP Inspector](./mcp_troubleshoot#mcp-inspector) to confirm the MCP server is reachable outside of the failing client.
|
||||
|
||||
#### Responses/Completions with Embedded MCP Calls
|
||||
During `/responses` or `/chat/completions`, LiteLLM may trigger MCP tool calls mid-request. An error could occur before the MCP call begins or after the MCP responds.
|
||||
|
||||
**Actions**
|
||||
- Check LiteLLM request logs (see [Access Log Example](./mcp_troubleshoot#access-log-example-successful-mcp-call)) to see whether an MCP attempt was recorded; if not, the problem lies in `Client → LiteLLM`.
|
||||
- Validate MCP connectivity with the [MCP Inspector](./mcp_troubleshoot#mcp-inspector) to ensure the server responds.
|
||||
- Reproduce the same MCP call via the LiteLLM Playground to confirm LiteLLM can complete the MCP hop independently.
|
||||
|
||||
<Image
|
||||
img={require('../img/mcp_playground.png')}
|
||||
style={{width: '80%', display: 'block', margin: '0'}}
|
||||
/>
|
||||
|
||||
### OAuth Metadata Discovery
|
||||
LiteLLM performs metadata discovery per the MCP spec ([section 2.3](https://modelcontextprotocol.info/specification/draft/basic/authorization/#23-server-metadata-discovery)). When OAuth is enabled, confirm the authorization server exposes the metadata URL and that LiteLLM can fetch it.
|
||||
|
||||
**Actions**
|
||||
- Use `curl <metadata_url>` (or similar) from the LiteLLM host to ensure the discovery document is reachable and contains the expected authorization/token endpoints.
|
||||
- Record the exact metadata URL, requested scopes, and any static client credentials so support can replay the discovery step if needed.
|
||||
|
||||
## Verify Connectivity
|
||||
|
||||
Run lightweight validations before impacting production traffic.
|
||||
|
||||
### MCP Inspector
|
||||
Use the MCP Inspector when you need to test both `Client → LiteLLM` and `Client → MCP` communications in one place; it makes isolating the failing hop straightforward.
|
||||
|
||||
1. Execute `npx @modelcontextprotocol/inspector` on your workstation.
|
||||
2. Configure and connect:
|
||||
- **Transport Type:** choose the transport the client uses (Streamable HTTP for LiteLLM).
|
||||
- **URL:** the endpoint under test (LiteLLM MCP URL for `Client → LiteLLM`, or the MCP server URL for `Client → MCP`).
|
||||
- **Custom Headers:** e.g., `Authorization: Bearer <LiteLLM API Key>`.
|
||||
3. Open the **Tools** tab and click **List Tools** to verify the MCP alias responds.
|
||||
|
||||
### `curl` Smoke Test
|
||||
`curl` is ideal on servers where installing the Inspector is impractical. It replicates the MCP tool call LiteLLM would make—swap in the domain of the system under test (LiteLLM or the MCP server).
|
||||
|
||||
```bash
|
||||
curl -X POST https://your-target-domain.example.com/mcp \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json, text/event-stream" \
|
||||
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
|
||||
```
|
||||
|
||||
Add `-H "Authorization: Bearer <LiteLLM API Key>"` when the target is a LiteLLM endpoint that requires authentication. Adjust the headers, or payload to target other MCP methods. Matching failures between `curl` and LiteLLM confirm that the MCP server or network/OAuth layer is the culprit.
|
||||
|
||||
## Review Logs
|
||||
|
||||
Well-scoped logs make it clear whether LiteLLM reached the MCP server and what happened next.
|
||||
|
||||
### Access Log Example (successful MCP call)
|
||||
```text
|
||||
INFO: 127.0.0.1:57230 - "POST /everything/mcp HTTP/1.1" 200 OK
|
||||
```
|
||||
|
||||
### Error Log Example (failed MCP call)
|
||||
```text
|
||||
07:22:00 - LiteLLM:ERROR: client.py:224 - MCP client list_tools failed - Error Type: ExceptionGroup, Error: unhandled errors in a TaskGroup (1 sub-exception), Server: http://localhost:3001/mcp, Transport: MCPTransport.http
|
||||
httpcore.ConnectError: All connection attempts failed
|
||||
ERROR:LiteLLM:MCP client list_tools failed - Error Type: ExceptionGroup, Error: unhandled errors in a TaskGroup (1 sub-exception)...
|
||||
httpx.ConnectError: All connection attempts failed
|
||||
```
|
||||
93
docs/my-website/docs/observability/focus.md
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Focus Export (Experimental)
|
||||
|
||||
:::caution Experimental feature
|
||||
Focus Format export is under active development and currently considered experimental.
|
||||
Interfaces, schema mappings, and configuration options may change as we iterate based on user feedback.
|
||||
Please treat this integration as a preview and report any issues or suggestions to help us stabilize and improve the workflow.
|
||||
:::
|
||||
|
||||
LiteLLM can emit usage data in the [FinOps FOCUS format](https://focus.finops.org/focus-specification/v1-2/) and push artifacts (for example Parquet files) to destinations such as Amazon S3. This enables downstream cost-analysis tooling to ingest a standardised dataset directly from LiteLLM.
|
||||
|
||||
LiteLLM currently conforms to the FinOps FOCUS v1.2 specification when emitting this dataset.
|
||||
|
||||
## Overview
|
||||
|
||||
| Property | Details |
|
||||
|----------|---------|
|
||||
| Destination | Export LiteLLM usage data in FOCUS format to managed storage (currently S3) |
|
||||
| Callback name | `focus` |
|
||||
| Supported operations | Automatic scheduled export |
|
||||
| Data format | FOCUS Normalised Dataset (Parquet) |
|
||||
|
||||
## Environment Variables
|
||||
|
||||
### Common settings
|
||||
|
||||
| Variable | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `FOCUS_PROVIDER` | No | Destination provider (defaults to `s3`). |
|
||||
| `FOCUS_FORMAT` | No | Output format (currently only `parquet`). |
|
||||
| `FOCUS_FREQUENCY` | No | Export cadence. Prefer `hourly` or `daily` for production; `interval` is intended for short test loops. Defaults to `hourly`. |
|
||||
| `FOCUS_CRON_OFFSET` | No | Minute offset used for hourly/daily cron triggers. Defaults to `5`. |
|
||||
| `FOCUS_INTERVAL_SECONDS` | No | Interval (seconds) when `FOCUS_FREQUENCY="interval"`. |
|
||||
| `FOCUS_PREFIX` | No | Object key prefix/folder. Defaults to `focus_exports`. |
|
||||
|
||||
### S3 destination
|
||||
|
||||
| Variable | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `FOCUS_S3_BUCKET_NAME` | Yes | Destination bucket for exported files. |
|
||||
| `FOCUS_S3_REGION_NAME` | No | AWS region for the bucket. |
|
||||
| `FOCUS_S3_ENDPOINT_URL` | No | Custom endpoint (useful for S3-compatible storage). |
|
||||
| `FOCUS_S3_ACCESS_KEY` | Yes | AWS access key for uploads. |
|
||||
| `FOCUS_S3_SECRET_KEY` | Yes | AWS secret key for uploads. |
|
||||
| `FOCUS_S3_SESSION_TOKEN` | No | AWS session token if using temporary credentials. |
|
||||
|
||||
## Setup via Config
|
||||
|
||||
### Configure environment variables
|
||||
|
||||
```bash
|
||||
export FOCUS_PROVIDER="s3"
|
||||
export FOCUS_PREFIX="focus_exports"
|
||||
|
||||
# S3 example
|
||||
export FOCUS_S3_BUCKET_NAME="my-litellm-focus-bucket"
|
||||
export FOCUS_S3_REGION_NAME="us-east-1"
|
||||
export FOCUS_S3_ACCESS_KEY="AKIA..."
|
||||
export FOCUS_S3_SECRET_KEY="..."
|
||||
```
|
||||
|
||||
### Update LiteLLM config
|
||||
|
||||
```yaml
|
||||
model_list:
|
||||
- model_name: gpt-4o
|
||||
litellm_params:
|
||||
model: openai/gpt-4o
|
||||
api_key: sk-your-key
|
||||
|
||||
litellm_settings:
|
||||
callbacks: ["focus"]
|
||||
```
|
||||
|
||||
### Start the proxy
|
||||
|
||||
```bash
|
||||
litellm --config /path/to/config.yaml
|
||||
```
|
||||
|
||||
During boot LiteLLM registers the Focus logger and a background job that runs according to the configured frequency.
|
||||
|
||||
## Planned Enhancements
|
||||
- Add "Setup on UI" flow alongside the current configuration-based setup.
|
||||
- Add GCS / Azure Blob to the Destination options.
|
||||
- Support CSV output alongside Parquet.
|
||||
|
||||
## Related Links
|
||||
|
||||
- [Focus](https://focus.finops.org/)
|
||||
|
||||
|
|
@ -40,6 +40,10 @@ import os
|
|||
# from https://logfire.pydantic.dev/
|
||||
os.environ["LOGFIRE_TOKEN"] = ""
|
||||
|
||||
# Optionally customize the base url
|
||||
# from https://logfire.pydantic.dev/
|
||||
os.environ["LOGFIRE_BASE_URL"] = ""
|
||||
|
||||
# LLM API Keys
|
||||
os.environ['OPENAI_API_KEY']=""
|
||||
|
||||
|
|
|
|||
122
docs/my-website/docs/observability/qualifire_integration.md
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
import Image from '@theme/IdealImage';
|
||||
|
||||
# Qualifire - LLM Evaluation, Guardrails & Observability
|
||||
|
||||
[Qualifire](https://qualifire.ai/) provides real-time Agentic evaluations, guardrails and observability for production AI applications.
|
||||
|
||||
**Key Features:**
|
||||
|
||||
- **Evaluation** - Systematically assess AI behavior to detect hallucinations, jailbreaks, policy breaches, and other vulnerabilities
|
||||
- **Guardrails** - Real-time interventions to prevent risks like brand damage, data leaks, and compliance breaches
|
||||
- **Observability** - Complete tracing and logging for RAG pipelines, chatbots, and AI agents
|
||||
- **Prompt Management** - Centralized prompt management with versioning and no-code studio
|
||||
|
||||
:::tip
|
||||
|
||||
Looking for Qualifire Guardrails? Check out the [Qualifire Guardrails Integration](../proxy/guardrails/qualifire.md) for real-time content moderation, prompt injection detection, PII checks, and more.
|
||||
|
||||
:::
|
||||
|
||||
## Pre-Requisites
|
||||
|
||||
1. Create an account on [Qualifire](https://app.qualifire.ai/)
|
||||
2. Get your API key and webhook URL from the Qualifire dashboard
|
||||
|
||||
```bash
|
||||
pip install litellm
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
Use just 2 lines of code to instantly log your responses **across all providers** with Qualifire.
|
||||
|
||||
```python
|
||||
litellm.callbacks = ["qualifire_eval"]
|
||||
```
|
||||
|
||||
```python
|
||||
import litellm
|
||||
import os
|
||||
|
||||
# Set Qualifire credentials
|
||||
os.environ["QUALIFIRE_API_KEY"] = "your-qualifire-api-key"
|
||||
os.environ["QUALIFIRE_WEBHOOK_URL"] = "https://your-qualifire-webhook-url"
|
||||
|
||||
# LLM API Keys
|
||||
os.environ['OPENAI_API_KEY'] = "your-openai-api-key"
|
||||
|
||||
# Set qualifire_eval as a callback & LiteLLM will send the data to Qualifire
|
||||
litellm.callbacks = ["qualifire_eval"]
|
||||
|
||||
# OpenAI call
|
||||
response = litellm.completion(
|
||||
model="gpt-5",
|
||||
messages=[
|
||||
{"role": "user", "content": "Hi 👋 - i'm openai"}
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
## Using with LiteLLM Proxy
|
||||
|
||||
1. Setup config.yaml
|
||||
|
||||
```yaml
|
||||
model_list:
|
||||
- model_name: gpt-4o
|
||||
litellm_params:
|
||||
model: openai/gpt-4o
|
||||
api_key: os.environ/OPENAI_API_KEY
|
||||
|
||||
litellm_settings:
|
||||
callbacks: ["qualifire_eval"]
|
||||
|
||||
general_settings:
|
||||
master_key: "sk-1234"
|
||||
|
||||
environment_variables:
|
||||
QUALIFIRE_API_KEY: "your-qualifire-api-key"
|
||||
QUALIFIRE_WEBHOOK_URL: "https://app.qualifire.ai/api/v1/webhooks/evaluations"
|
||||
```
|
||||
|
||||
2. Start the proxy
|
||||
|
||||
```bash
|
||||
litellm --config config.yaml
|
||||
```
|
||||
|
||||
3. Test it!
|
||||
|
||||
```bash
|
||||
curl -X POST 'http://0.0.0.0:4000/chat/completions' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'Authorization: Bearer sk-1234' \
|
||||
-d '{ "model": "gpt-4o", "messages": [{"role": "user", "content": "Hi 👋 - i'm openai"}]}'
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
| ----------------------- | ------------------------------------------------------ |
|
||||
| `QUALIFIRE_API_KEY` | Your Qualifire API key for authentication |
|
||||
| `QUALIFIRE_WEBHOOK_URL` | The Qualifire webhook endpoint URL from your dashboard |
|
||||
|
||||
## What Gets Logged?
|
||||
|
||||
The [LiteLLM Standard Logging Payload](https://docs.litellm.ai/docs/proxy/logging_spec) is sent to your Qualifire endpoint on each successful LLM API call.
|
||||
|
||||
This includes:
|
||||
|
||||
- Request messages and parameters
|
||||
- Response content and metadata
|
||||
- Token usage statistics
|
||||
- Latency metrics
|
||||
- Model information
|
||||
- Cost data
|
||||
|
||||
Once data is in Qualifire, you can:
|
||||
|
||||
- Run evaluations to detect hallucinations, toxicity, and policy violations
|
||||
- Set up guardrails to block or modify responses in real-time
|
||||
- View traces across your entire AI pipeline
|
||||
- Track performance and quality metrics over time
|
||||
109
docs/my-website/docs/providers/abliteration.md
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
# Abliteration
|
||||
|
||||
## Overview
|
||||
|
||||
| Property | Details |
|
||||
|-------|-------|
|
||||
| Description | Abliteration provides an OpenAI-compatible `/chat/completions` endpoint. |
|
||||
| Provider Route on LiteLLM | `abliteration/` |
|
||||
| Link to Provider Doc | [Abliteration](https://abliteration.ai) |
|
||||
| Base URL | `https://api.abliteration.ai/v1` |
|
||||
| Supported Operations | [`/chat/completions`](#sample-usage) |
|
||||
|
||||
<br />
|
||||
|
||||
## Required Variables
|
||||
|
||||
```python showLineNumbers title="Environment Variables"
|
||||
os.environ["ABLITERATION_API_KEY"] = "" # your Abliteration API key
|
||||
```
|
||||
|
||||
## Sample Usage
|
||||
|
||||
```python showLineNumbers title="Abliteration Completion"
|
||||
import os
|
||||
from litellm import completion
|
||||
|
||||
os.environ["ABLITERATION_API_KEY"] = ""
|
||||
|
||||
response = completion(
|
||||
model="abliteration/abliterated-model",
|
||||
messages=[{"role": "user", "content": "Hello from LiteLLM"}],
|
||||
)
|
||||
|
||||
print(response)
|
||||
```
|
||||
|
||||
## Sample Usage - Streaming
|
||||
|
||||
```python showLineNumbers title="Abliteration Streaming Completion"
|
||||
import os
|
||||
from litellm import completion
|
||||
|
||||
os.environ["ABLITERATION_API_KEY"] = ""
|
||||
|
||||
response = completion(
|
||||
model="abliteration/abliterated-model",
|
||||
messages=[{"role": "user", "content": "Stream a short reply"}],
|
||||
stream=True,
|
||||
)
|
||||
|
||||
for chunk in response:
|
||||
print(chunk)
|
||||
```
|
||||
|
||||
## Usage with LiteLLM Proxy Server
|
||||
|
||||
1. Add the model to your proxy config:
|
||||
|
||||
```yaml showLineNumbers title="config.yaml"
|
||||
model_list:
|
||||
- model_name: abliteration-chat
|
||||
litellm_params:
|
||||
model: abliteration/abliterated-model
|
||||
api_key: os.environ/ABLITERATION_API_KEY
|
||||
```
|
||||
|
||||
2. Start the proxy:
|
||||
|
||||
```bash
|
||||
litellm --config /path/to/config.yaml
|
||||
```
|
||||
|
||||
## Direct API Usage (Bearer Token)
|
||||
|
||||
Use the environment variable as a Bearer token against the OpenAI-compatible endpoint:
|
||||
`https://api.abliteration.ai/v1/chat/completions`.
|
||||
|
||||
```bash showLineNumbers title="cURL"
|
||||
export ABLITERATION_API_KEY=""
|
||||
curl https://api.abliteration.ai/v1/chat/completions \
|
||||
-H "Authorization: Bearer ${ABLITERATION_API_KEY}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "abliterated-model",
|
||||
"messages": [{"role": "user", "content": "Hello from Abliteration"}]
|
||||
}'
|
||||
```
|
||||
|
||||
```python showLineNumbers title="Python (requests)"
|
||||
import os
|
||||
import requests
|
||||
|
||||
api_key = os.environ["ABLITERATION_API_KEY"]
|
||||
|
||||
response = requests.post(
|
||||
"https://api.abliteration.ai/v1/chat/completions",
|
||||
headers={
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
json={
|
||||
"model": "abliterated-model",
|
||||
"messages": [{"role": "user", "content": "Hello from Abliteration"}],
|
||||
},
|
||||
timeout=60,
|
||||
)
|
||||
|
||||
print(response.json())
|
||||
```
|
||||
|
|
@ -1692,9 +1692,9 @@ Assistant:
|
|||
```
|
||||
|
||||
|
||||
## Usage - PDF
|
||||
## Usage - PDF
|
||||
|
||||
Pass base64 encoded PDF files to Anthropic models using the `image_url` field.
|
||||
Pass base64 encoded PDF files to Anthropic models using the `file` content type with a `file_data` field.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="sdk" label="SDK">
|
||||
|
|
|
|||
232
docs/my-website/docs/providers/azure_ai/azure_model_router.md
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
# Azure Model Router
|
||||
|
||||
Azure Model Router is a feature in Azure AI Foundry that automatically routes your requests to the best available model based on your requirements. This allows you to use a single endpoint that intelligently selects the optimal model for each request.
|
||||
|
||||
## Key Features
|
||||
|
||||
- **Automatic Model Selection**: Azure Model Router dynamically selects the best model for your request
|
||||
- **Cost Tracking**: LiteLLM automatically tracks costs based on the actual model used (e.g., `gpt-4.1-nano`), not the router endpoint
|
||||
- **Streaming Support**: Full support for streaming responses with accurate cost calculation
|
||||
|
||||
## LiteLLM Python SDK
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```python
|
||||
import litellm
|
||||
import os
|
||||
|
||||
response = litellm.completion(
|
||||
model="azure_ai/azure-model-router",
|
||||
messages=[{"role": "user", "content": "Hello!"}],
|
||||
api_base="https://your-endpoint.cognitiveservices.azure.com/openai/v1/",
|
||||
api_key=os.getenv("AZURE_MODEL_ROUTER_API_KEY"),
|
||||
)
|
||||
|
||||
print(response)
|
||||
```
|
||||
|
||||
### Streaming with Usage Tracking
|
||||
|
||||
```python
|
||||
import litellm
|
||||
import os
|
||||
|
||||
response = await litellm.acompletion(
|
||||
model="azure_ai/azure-model-router",
|
||||
messages=[{"role": "user", "content": "hi"}],
|
||||
api_base="https://your-endpoint.cognitiveservices.azure.com/openai/v1/",
|
||||
api_key=os.getenv("AZURE_MODEL_ROUTER_API_KEY"),
|
||||
stream=True,
|
||||
stream_options={"include_usage": True},
|
||||
)
|
||||
|
||||
async for chunk in response:
|
||||
print(chunk)
|
||||
```
|
||||
|
||||
## LiteLLM Proxy (AI Gateway)
|
||||
|
||||
### config.yaml
|
||||
|
||||
```yaml
|
||||
model_list:
|
||||
- model_name: azure-model-router
|
||||
litellm_params:
|
||||
model: azure_ai/azure-model-router
|
||||
api_base: https://your-endpoint.cognitiveservices.azure.com/openai/v1/
|
||||
api_key: os.environ/AZURE_MODEL_ROUTER_API_KEY
|
||||
```
|
||||
|
||||
### Start Proxy
|
||||
|
||||
```bash
|
||||
litellm --config config.yaml
|
||||
```
|
||||
|
||||
### Test Request
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:4000/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-d '{
|
||||
"model": "azure-model-router",
|
||||
"messages": [{"role": "user", "content": "Hello!"}]
|
||||
}'
|
||||
```
|
||||
|
||||
## Add Azure Model Router via LiteLLM UI
|
||||
|
||||
This walkthrough shows how to add an Azure Model Router endpoint to LiteLLM using the Admin Dashboard.
|
||||
|
||||
### Select Provider
|
||||
|
||||
Navigate to the Models page and select "Azure AI Foundry (Studio)" as the provider.
|
||||
|
||||
#### Navigate to Models Page
|
||||
|
||||

|
||||
|
||||
#### Click Provider Dropdown
|
||||
|
||||

|
||||
|
||||
#### Choose Azure AI Foundry
|
||||
|
||||

|
||||
|
||||
### Configure Model Name
|
||||
|
||||
Set up the model name by entering `azure_ai/` followed by your model router deployment name from Azure.
|
||||
|
||||
#### Click Model Name Field
|
||||
|
||||

|
||||
|
||||
#### Select Custom Model Name
|
||||
|
||||

|
||||
|
||||
#### Enter LiteLLM Model Name
|
||||
|
||||

|
||||
|
||||
#### Click Custom Model Name Field
|
||||
|
||||

|
||||
|
||||
#### Type Model Prefix
|
||||
|
||||
Type `azure_ai/` as the prefix.
|
||||
|
||||

|
||||
|
||||
#### Copy Model Name from Azure Portal
|
||||
|
||||
Switch to Azure AI Foundry and copy your model router deployment name.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
#### Paste Model Name
|
||||
|
||||
Paste to get `azure_ai/azure-model-router`.
|
||||
|
||||

|
||||
|
||||
### Configure API Base and Key
|
||||
|
||||
Copy the endpoint URL and API key from Azure portal.
|
||||
|
||||
#### Copy API Base URL from Azure
|
||||
|
||||

|
||||
|
||||
#### Enter API Base in LiteLLM
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
#### Copy API Key from Azure
|
||||
|
||||

|
||||
|
||||
#### Enter API Key in LiteLLM
|
||||
|
||||

|
||||
|
||||
### Test and Add Model
|
||||
|
||||
Verify your configuration works and save the model.
|
||||
|
||||
#### Test Connection
|
||||
|
||||

|
||||
|
||||
#### Close Test Dialog
|
||||
|
||||

|
||||
|
||||
#### Add Model
|
||||
|
||||

|
||||
|
||||
### Verify in Playground
|
||||
|
||||
Test your model and verify cost tracking is working.
|
||||
|
||||
#### Open Playground
|
||||
|
||||

|
||||
|
||||
#### Select Model
|
||||
|
||||

|
||||
|
||||
#### Send Test Message
|
||||
|
||||

|
||||
|
||||
#### View Logs
|
||||
|
||||

|
||||
|
||||
#### Verify Cost Tracking
|
||||
|
||||
Cost is tracked based on the actual model used (e.g., `gpt-4.1-nano`).
|
||||
|
||||

|
||||
|
||||
## Cost Tracking
|
||||
|
||||
LiteLLM automatically handles cost tracking for Azure Model Router by:
|
||||
|
||||
1. **Detecting the actual model**: When Azure Model Router routes your request to a specific model (e.g., `gpt-4.1-nano-2025-04-14`), LiteLLM extracts this from the response
|
||||
2. **Calculating accurate costs**: Costs are calculated based on the actual model used, not the router endpoint name
|
||||
3. **Streaming support**: Cost tracking works correctly for both streaming and non-streaming requests
|
||||
|
||||
### Example Response with Cost
|
||||
|
||||
```python
|
||||
import litellm
|
||||
|
||||
response = litellm.completion(
|
||||
model="azure_ai/azure-model-router",
|
||||
messages=[{"role": "user", "content": "Hello!"}],
|
||||
api_base="https://your-endpoint.cognitiveservices.azure.com/openai/v1/",
|
||||
api_key="your-api-key",
|
||||
)
|
||||
|
||||
# The response will show the actual model used
|
||||
print(f"Model used: {response.model}") # e.g., "gpt-4.1-nano-2025-04-14"
|
||||
|
||||
# Get cost
|
||||
from litellm import completion_cost
|
||||
cost = completion_cost(completion_response=response)
|
||||
print(f"Cost: ${cost}")
|
||||
```
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 254 KiB |
|
After Width: | Height: | Size: 240 KiB |
|
After Width: | Height: | Size: 239 KiB |
|
After Width: | Height: | Size: 247 KiB |
|
After Width: | Height: | Size: 272 KiB |
|
After Width: | Height: | Size: 307 KiB |
|
After Width: | Height: | Size: 248 KiB |
|
After Width: | Height: | Size: 315 KiB |
|
After Width: | Height: | Size: 492 KiB |
|
After Width: | Height: | Size: 562 KiB |
|
After Width: | Height: | Size: 265 KiB |
|
After Width: | Height: | Size: 471 KiB |
|
After Width: | Height: | Size: 225 KiB |
|
After Width: | Height: | Size: 219 KiB |
|
After Width: | Height: | Size: 485 KiB |
|
After Width: | Height: | Size: 227 KiB |
|
After Width: | Height: | Size: 236 KiB |
|
After Width: | Height: | Size: 214 KiB |
|
After Width: | Height: | Size: 232 KiB |
|
After Width: | Height: | Size: 256 KiB |
|
After Width: | Height: | Size: 250 KiB |
|
After Width: | Height: | Size: 206 KiB |
|
After Width: | Height: | Size: 311 KiB |
|
After Width: | Height: | Size: 419 KiB |
|
|
@ -7,7 +7,7 @@ ALL Bedrock models (Anthropic, Meta, Deepseek, Mistral, Amazon, etc.) are Suppor
|
|||
| Property | Details |
|
||||
|-------|-------|
|
||||
| Description | Amazon Bedrock is a fully managed service that offers a choice of high-performing foundation models (FMs). |
|
||||
| Provider Route on LiteLLM | `bedrock/`, [`bedrock/converse/`](#set-converse--invoke-route), [`bedrock/invoke/`](#set-invoke-route), [`bedrock/converse_like/`](#calling-via-internal-proxy), [`bedrock/llama/`](#deepseek-not-r1), [`bedrock/deepseek_r1/`](#deepseek-r1), [`bedrock/qwen3/`](#qwen3-imported-models), [`bedrock/qwen2/`](./bedrock_imported.md#qwen2-imported-models), [`bedrock/openai/`](./bedrock_imported.md#openai-compatible-imported-models-qwen-25-vl-etc) |
|
||||
| Provider Route on LiteLLM | `bedrock/`, [`bedrock/converse/`](#set-converse--invoke-route), [`bedrock/invoke/`](#set-invoke-route), [`bedrock/converse_like/`](#calling-via-internal-proxy), [`bedrock/llama/`](#deepseek-not-r1), [`bedrock/deepseek_r1/`](#deepseek-r1), [`bedrock/qwen3/`](#qwen3-imported-models), [`bedrock/qwen2/`](./bedrock_imported.md#qwen2-imported-models), [`bedrock/openai/`](./bedrock_imported.md#openai-compatible-imported-models-qwen-25-vl-etc), [`bedrock/moonshot`](./bedrock_imported.md#moonshot-kimi-k2-thinking) |
|
||||
| Provider Doc | [Amazon Bedrock ↗](https://docs.aws.amazon.com/bedrock/latest/userguide/what-is-bedrock.html) |
|
||||
| Supported OpenAI Endpoints | `/chat/completions`, `/completions`, `/embeddings`, `/images/generations` |
|
||||
| Rerank Endpoint | `/rerank` |
|
||||
|
|
@ -967,6 +967,30 @@ Control the processing tier for your Bedrock requests using `serviceTier`. Valid
|
|||
|
||||
[Bedrock ServiceTier API Reference](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ServiceTier.html)
|
||||
|
||||
### OpenAI-compatible `service_tier` parameter
|
||||
|
||||
LiteLLM also supports the OpenAI-style `service_tier` parameter, which is automatically translated to Bedrock's native `serviceTier` format:
|
||||
|
||||
| OpenAI `service_tier` | Bedrock `serviceTier` |
|
||||
|-----------------------|----------------------|
|
||||
| `"priority"` | `{"type": "priority"}` |
|
||||
| `"default"` | `{"type": "default"}` |
|
||||
| `"flex"` | `{"type": "flex"}` |
|
||||
| `"auto"` | `{"type": "default"}` |
|
||||
|
||||
```python
|
||||
from litellm import completion
|
||||
|
||||
# Using OpenAI-style service_tier parameter
|
||||
response = completion(
|
||||
model="bedrock/converse/anthropic.claude-3-sonnet-20240229-v1:0",
|
||||
messages=[{"role": "user", "content": "Hello!"}],
|
||||
service_tier="priority" # Automatically translated to serviceTier={"type": "priority"}
|
||||
)
|
||||
```
|
||||
|
||||
### Native Bedrock `serviceTier` parameter
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="sdk" label="SDK">
|
||||
|
||||
|
|
@ -1941,6 +1965,7 @@ Here's an example of using a bedrock model with LiteLLM. For a complete list, re
|
|||
| Mixtral 8x7B Instruct | `completion(model='bedrock/mistral.mixtral-8x7b-instruct-v0:1', messages=messages)` | `os.environ['AWS_ACCESS_KEY_ID']`, `os.environ['AWS_SECRET_ACCESS_KEY']`, `os.environ['AWS_REGION_NAME']` |
|
||||
| TwelveLabs Pegasus 1.2 (US) | `completion(model='bedrock/us.twelvelabs.pegasus-1-2-v1:0', messages=messages, mediaSource={...})` | `os.environ['AWS_ACCESS_KEY_ID']`, `os.environ['AWS_SECRET_ACCESS_KEY']`, `os.environ['AWS_REGION_NAME']` |
|
||||
| TwelveLabs Pegasus 1.2 (EU) | `completion(model='bedrock/eu.twelvelabs.pegasus-1-2-v1:0', messages=messages, mediaSource={...})` | `os.environ['AWS_ACCESS_KEY_ID']`, `os.environ['AWS_SECRET_ACCESS_KEY']`, `os.environ['AWS_REGION_NAME']` |
|
||||
| Moonshot Kimi K2 Thinking | `completion(model='bedrock/moonshot.kimi-k2-thinking', messages=messages)` or `completion(model='bedrock/invoke/moonshot.kimi-k2-thinking', messages=messages)` | `os.environ['AWS_ACCESS_KEY_ID']`, `os.environ['AWS_SECRET_ACCESS_KEY']`, `os.environ['AWS_REGION_NAME']` |
|
||||
|
||||
|
||||
## Bedrock Embedding
|
||||
|
|
|
|||
|
|
@ -431,4 +431,180 @@ curl --location 'http://0.0.0.0:4000/chat/completions' \
|
|||
"max_tokens": 300,
|
||||
"temperature": 0.5
|
||||
}'
|
||||
```
|
||||
```
|
||||
|
||||
### Moonshot Kimi K2 Thinking
|
||||
|
||||
Moonshot AI's Kimi K2 Thinking model is now available on Amazon Bedrock. This model features advanced reasoning capabilities with automatic reasoning content extraction.
|
||||
|
||||
| Property | Details |
|
||||
|----------|---------|
|
||||
| Provider Route | `bedrock/moonshot.kimi-k2-thinking`, `bedrock/invoke/moonshot.kimi-k2-thinking` |
|
||||
| Provider Documentation | [AWS Bedrock Moonshot Announcement ↗](https://aws.amazon.com/about-aws/whats-new/2025/12/amazon-bedrock-fully-managed-open-weight-models/) |
|
||||
| Supported Parameters | `temperature`, `max_tokens`, `top_p`, `stream`, `tools`, `tool_choice` |
|
||||
| Special Features | Reasoning content extraction, Tool calling |
|
||||
|
||||
#### Supported Features
|
||||
|
||||
- **Reasoning Content Extraction**: Automatically extracts `<reasoning>` tags and returns them as `reasoning_content` (similar to OpenAI's o1 models)
|
||||
- **Tool Calling**: Full support for function/tool calling with tool responses
|
||||
- **Streaming**: Both streaming and non-streaming responses
|
||||
- **System Messages**: System message support
|
||||
|
||||
#### Basic Usage
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="sdk" label="SDK">
|
||||
|
||||
```python title="Moonshot Kimi K2 SDK Usage" showLineNumbers
|
||||
from litellm import completion
|
||||
import os
|
||||
|
||||
os.environ["AWS_ACCESS_KEY_ID"] = "your-aws-access-key"
|
||||
os.environ["AWS_SECRET_ACCESS_KEY"] = "your-aws-secret-key"
|
||||
os.environ["AWS_REGION_NAME"] = "us-west-2" # or your preferred region
|
||||
|
||||
# Basic completion
|
||||
response = completion(
|
||||
model="bedrock/moonshot.kimi-k2-thinking", # or bedrock/invoke/moonshot.kimi-k2-thinking
|
||||
messages=[
|
||||
{"role": "user", "content": "What is 2+2? Think step by step."}
|
||||
],
|
||||
temperature=0.7,
|
||||
max_tokens=200
|
||||
)
|
||||
|
||||
print(response.choices[0].message.content)
|
||||
|
||||
# Access reasoning content if present
|
||||
if response.choices[0].message.reasoning_content:
|
||||
print("Reasoning:", response.choices[0].message.reasoning_content)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="proxy" label="Proxy">
|
||||
|
||||
**1. Add to config**
|
||||
|
||||
```yaml title="config.yaml" showLineNumbers
|
||||
model_list:
|
||||
- model_name: kimi-k2
|
||||
litellm_params:
|
||||
model: bedrock/moonshot.kimi-k2-thinking
|
||||
aws_access_key_id: os.environ/AWS_ACCESS_KEY_ID
|
||||
aws_secret_access_key: os.environ/AWS_SECRET_ACCESS_KEY
|
||||
aws_region_name: us-west-2
|
||||
```
|
||||
|
||||
**2. Start proxy**
|
||||
|
||||
```bash title="Start LiteLLM Proxy" showLineNumbers
|
||||
litellm --config /path/to/config.yaml
|
||||
|
||||
# RUNNING at http://0.0.0.0:4000
|
||||
```
|
||||
|
||||
**3. Test it!**
|
||||
|
||||
```bash title="Test Kimi K2 via Proxy" showLineNumbers
|
||||
curl --location 'http://0.0.0.0:4000/chat/completions' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"model": "kimi-k2",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "What is 2+2? Think step by step."
|
||||
}
|
||||
],
|
||||
"temperature": 0.7,
|
||||
"max_tokens": 200
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### Tool Calling Example
|
||||
|
||||
```python title="Kimi K2 with Tool Calling" showLineNumbers
|
||||
from litellm import completion
|
||||
import os
|
||||
|
||||
os.environ["AWS_ACCESS_KEY_ID"] = "your-aws-access-key"
|
||||
os.environ["AWS_SECRET_ACCESS_KEY"] = "your-aws-secret-key"
|
||||
os.environ["AWS_REGION_NAME"] = "us-west-2"
|
||||
|
||||
# Tool calling example
|
||||
response = completion(
|
||||
model="bedrock/moonshot.kimi-k2-thinking",
|
||||
messages=[
|
||||
{"role": "user", "content": "What's the weather in Tokyo?"}
|
||||
],
|
||||
tools=[
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "get_weather",
|
||||
"description": "Get the current weather in a location",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"location": {
|
||||
"type": "string",
|
||||
"description": "The city name"
|
||||
}
|
||||
},
|
||||
"required": ["location"]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
if response.choices[0].message.tool_calls:
|
||||
tool_call = response.choices[0].message.tool_calls[0]
|
||||
print(f"Tool called: {tool_call.function.name}")
|
||||
print(f"Arguments: {tool_call.function.arguments}")
|
||||
```
|
||||
|
||||
#### Streaming Example
|
||||
|
||||
```python title="Kimi K2 Streaming" showLineNumbers
|
||||
from litellm import completion
|
||||
import os
|
||||
|
||||
os.environ["AWS_ACCESS_KEY_ID"] = "your-aws-access-key"
|
||||
os.environ["AWS_SECRET_ACCESS_KEY"] = "your-aws-secret-key"
|
||||
os.environ["AWS_REGION_NAME"] = "us-west-2"
|
||||
|
||||
response = completion(
|
||||
model="bedrock/moonshot.kimi-k2-thinking",
|
||||
messages=[
|
||||
{"role": "user", "content": "Explain quantum computing in simple terms."}
|
||||
],
|
||||
stream=True,
|
||||
temperature=0.7
|
||||
)
|
||||
|
||||
for chunk in response:
|
||||
if chunk.choices[0].delta.content:
|
||||
print(chunk.choices[0].delta.content, end="")
|
||||
|
||||
# Check for reasoning content in streaming
|
||||
if hasattr(chunk.choices[0].delta, 'reasoning_content') and chunk.choices[0].delta.reasoning_content:
|
||||
print(f"\n[Reasoning: {chunk.choices[0].delta.reasoning_content}]")
|
||||
```
|
||||
|
||||
#### Supported Parameters
|
||||
|
||||
| Parameter | Type | Description | Supported |
|
||||
|-----------|------|-------------|-----------|
|
||||
| `temperature` | float (0-1) | Controls randomness in output | ✅ |
|
||||
| `max_tokens` | integer | Maximum tokens to generate | ✅ |
|
||||
| `top_p` | float | Nucleus sampling parameter | ✅ |
|
||||
| `stream` | boolean | Enable streaming responses | ✅ |
|
||||
| `tools` | array | Tool/function definitions | ✅ |
|
||||
| `tool_choice` | string/object | Tool choice specification | ✅ |
|
||||
| `stop` | array | Stop sequences | ❌ (Not supported on Bedrock) |
|
||||
369
docs/my-website/docs/providers/manus.md
Normal file
|
|
@ -0,0 +1,369 @@
|
|||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Manus
|
||||
|
||||
Use Manus AI agents through LiteLLM's OpenAI-compatible Responses API.
|
||||
|
||||
| Property | Details |
|
||||
|----------|---------|
|
||||
| Description | Manus is an AI agent platform for complex reasoning tasks, document analysis, and multi-step workflows with asynchronous task execution. |
|
||||
| Provider Route on LiteLLM | `manus/{agent_profile}` |
|
||||
| Supported Operations | `/responses` (Responses API), `/files` (Files API) |
|
||||
| Provider Doc | [Manus API ↗](https://open.manus.im/docs/openai-compatibility) |
|
||||
|
||||
## Model Format
|
||||
|
||||
```shell
|
||||
manus/{agent_profile}
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
- `manus/manus-1.6` - General purpose agent
|
||||
- `manus/manus-1.6-lite` - Lightweight agent for simple tasks
|
||||
- `manus/manus-1.6-max` - Advanced agent for complex analysis
|
||||
|
||||
## LiteLLM Python SDK
|
||||
|
||||
```python showLineNumbers title="Basic Usage"
|
||||
import litellm
|
||||
import os
|
||||
import time
|
||||
|
||||
# Set API key
|
||||
os.environ["MANUS_API_KEY"] = "your-manus-api-key"
|
||||
|
||||
# Create task
|
||||
response = litellm.responses(
|
||||
model="manus/manus-1.6",
|
||||
input="What's the capital of France?",
|
||||
)
|
||||
|
||||
print(f"Task ID: {response.id}")
|
||||
print(f"Status: {response.status}") # "running"
|
||||
|
||||
# Poll until complete
|
||||
task_id = response.id
|
||||
while response.status == "running":
|
||||
time.sleep(5)
|
||||
response = litellm.get_response(
|
||||
response_id=task_id,
|
||||
custom_llm_provider="manus",
|
||||
)
|
||||
print(f"Status: {response.status}")
|
||||
|
||||
# Get results
|
||||
if response.status == "completed":
|
||||
for message in response.output:
|
||||
if message.role == "assistant":
|
||||
print(message.content[0].text)
|
||||
```
|
||||
|
||||
## LiteLLM AI Gateway
|
||||
|
||||
### Setup
|
||||
|
||||
```yaml showLineNumbers title="config.yaml"
|
||||
model_list:
|
||||
- model_name: manus-agent
|
||||
litellm_params:
|
||||
model: manus/manus-1.6
|
||||
api_key: os.environ/MANUS_API_KEY
|
||||
```
|
||||
|
||||
```bash title="Start Proxy"
|
||||
litellm --config config.yaml
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash showLineNumbers title="Create Task"
|
||||
# Create task
|
||||
curl -X POST http://localhost:4000/responses \
|
||||
-H "Authorization: Bearer your-proxy-key" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "manus-agent",
|
||||
"input": "What is the capital of France?"
|
||||
}'
|
||||
|
||||
# Response
|
||||
{
|
||||
"id": "task_abc123",
|
||||
"status": "running",
|
||||
"metadata": {
|
||||
"task_url": "https://manus.im/app/task_abc123"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```bash showLineNumbers title="Poll for Completion"
|
||||
# Check status (repeat until status is "completed")
|
||||
curl http://localhost:4000/responses/task_abc123 \
|
||||
-H "Authorization: Bearer your-proxy-key"
|
||||
|
||||
# When completed
|
||||
{
|
||||
"id": "task_abc123",
|
||||
"status": "completed",
|
||||
"output": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": [{"text": "What is the capital of France?"}]
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": [{"text": "The capital of France is Paris."}]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="openai" label="OpenAI SDK">
|
||||
|
||||
```python showLineNumbers title="Create Task and Poll"
|
||||
import openai
|
||||
import time
|
||||
|
||||
client = openai.OpenAI(
|
||||
base_url="http://localhost:4000",
|
||||
api_key="your-proxy-key"
|
||||
)
|
||||
|
||||
# Create task
|
||||
response = client.responses.create(
|
||||
model="manus-agent",
|
||||
input="What is the capital of France?"
|
||||
)
|
||||
|
||||
print(f"Task ID: {response.id}")
|
||||
print(f"Status: {response.status}") # "running"
|
||||
|
||||
# Poll until complete
|
||||
task_id = response.id
|
||||
while response.status == "running":
|
||||
time.sleep(5)
|
||||
response = client.responses.retrieve(response_id=task_id)
|
||||
print(f"Status: {response.status}")
|
||||
|
||||
# Get results
|
||||
if response.status == "completed":
|
||||
for message in response.output:
|
||||
if message.role == "assistant":
|
||||
print(message.content[0].text)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## How It Works
|
||||
|
||||
Manus operates as an **asynchronous agent API**:
|
||||
|
||||
1. **Create Task**: When you call `litellm.responses()`, Manus creates a task and returns immediately with `status: "running"`
|
||||
2. **Task Executes**: The agent works on your request in the background
|
||||
3. **Poll for Completion**: You must repeatedly call `litellm.get_response()` or `client.responses.retrieve()` until the status changes to `"completed"`
|
||||
4. **Get Results**: Once completed, the `output` field contains the full conversation
|
||||
|
||||
**Task Statuses:**
|
||||
- `running` - Agent is actively working
|
||||
- `pending` - Agent is waiting for input
|
||||
- `completed` - Task finished successfully
|
||||
- `error` - Task failed
|
||||
|
||||
:::tip Production Usage
|
||||
For production applications, use [webhooks](https://open.manus.im/docs/webhooks) instead of polling to get notified when tasks complete.
|
||||
:::
|
||||
|
||||
## Supported Parameters
|
||||
|
||||
| Parameter | Supported | Notes |
|
||||
|-----------|-----------|-------|
|
||||
| `input` | ✅ | Text, images, or structured content |
|
||||
| `stream` | ✅ | Fake streaming (task runs async) |
|
||||
| `max_output_tokens` | ✅ | Limits response length |
|
||||
| `previous_response_id` | ✅ | For multi-turn conversations |
|
||||
|
||||
## Files API
|
||||
|
||||
Manus supports file uploads for document analysis and processing. Files can be uploaded and then referenced in Responses API calls.
|
||||
|
||||
### LiteLLM Python SDK
|
||||
|
||||
```python showLineNumbers title="Upload, Use, Retrieve, and Delete Files"
|
||||
import litellm
|
||||
import os
|
||||
|
||||
# Set API key
|
||||
os.environ["MANUS_API_KEY"] = "your-manus-api-key"
|
||||
|
||||
# Upload file
|
||||
file_content = b"This is a document for analysis."
|
||||
created_file = await litellm.acreate_file(
|
||||
file=("document.txt", file_content),
|
||||
purpose="assistants",
|
||||
custom_llm_provider="manus",
|
||||
)
|
||||
print(f"Uploaded file: {created_file.id}")
|
||||
|
||||
# Use file with Responses API
|
||||
response = await litellm.aresponses(
|
||||
model="manus/manus-1.6",
|
||||
input=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "input_text", "text": "Summarize this document."},
|
||||
{"type": "input_file", "file_id": created_file.id},
|
||||
],
|
||||
},
|
||||
],
|
||||
extra_body={"task_mode": "agent", "agent_profile": "manus-1.6-agent"},
|
||||
)
|
||||
print(f"Response: {response.id}")
|
||||
|
||||
# Retrieve file
|
||||
retrieved_file = await litellm.afile_retrieve(
|
||||
file_id=created_file.id,
|
||||
custom_llm_provider="manus",
|
||||
)
|
||||
print(f"File details: {retrieved_file.filename}, {retrieved_file.bytes} bytes")
|
||||
|
||||
# Delete file
|
||||
deleted_file = await litellm.afile_delete(
|
||||
file_id=created_file.id,
|
||||
custom_llm_provider="manus",
|
||||
)
|
||||
print(f"Deleted: {deleted_file.deleted}")
|
||||
```
|
||||
|
||||
### LiteLLM AI Gateway
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash showLineNumbers title="Upload File"
|
||||
# Upload file
|
||||
curl -X POST http://localhost:4000/v1/files \
|
||||
-H "Authorization: Bearer your-proxy-key" \
|
||||
-F "file=@document.txt" \
|
||||
-F "purpose=assistants" \
|
||||
-F "custom_llm_provider=manus"
|
||||
|
||||
# Response
|
||||
{
|
||||
"id": "file_abc123",
|
||||
"object": "file",
|
||||
"bytes": 1024,
|
||||
"created_at": 1234567890,
|
||||
"filename": "document.txt",
|
||||
"purpose": "assistants",
|
||||
"status": "uploaded"
|
||||
}
|
||||
```
|
||||
|
||||
```bash showLineNumbers title="Use File with Responses API"
|
||||
# Create response with file
|
||||
curl -X POST http://localhost:4000/responses \
|
||||
-H "Authorization: Bearer your-proxy-key" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "manus-agent",
|
||||
"input": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "input_text", "text": "Summarize this document."},
|
||||
{"type": "input_file", "file_id": "file_abc123"}
|
||||
]
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
```bash showLineNumbers title="Retrieve File"
|
||||
# Get file details
|
||||
curl http://localhost:4000/v1/files/file_abc123 \
|
||||
-H "Authorization: Bearer your-proxy-key"
|
||||
|
||||
# Response
|
||||
{
|
||||
"id": "file_abc123",
|
||||
"object": "file",
|
||||
"bytes": 1024,
|
||||
"created_at": 1234567890,
|
||||
"filename": "document.txt",
|
||||
"purpose": "assistants",
|
||||
"status": "uploaded"
|
||||
}
|
||||
```
|
||||
|
||||
```bash showLineNumbers title="Delete File"
|
||||
# Delete file
|
||||
curl -X DELETE http://localhost:4000/v1/files/file_abc123 \
|
||||
-H "Authorization: Bearer your-proxy-key"
|
||||
|
||||
# Response
|
||||
{
|
||||
"id": "file_abc123",
|
||||
"object": "file",
|
||||
"deleted": true
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="openai" label="OpenAI SDK">
|
||||
|
||||
```python showLineNumbers title="Upload, Use, Retrieve, and Delete Files"
|
||||
import openai
|
||||
|
||||
client = openai.OpenAI(
|
||||
base_url="http://localhost:4000",
|
||||
api_key="your-proxy-key"
|
||||
)
|
||||
|
||||
# Upload file
|
||||
with open("document.txt", "rb") as f:
|
||||
created_file = client.files.create(
|
||||
file=f,
|
||||
purpose="assistants",
|
||||
extra_body={"custom_llm_provider": "manus"}
|
||||
)
|
||||
print(f"Uploaded file: {created_file.id}")
|
||||
|
||||
# Use file with Responses API
|
||||
response = client.responses.create(
|
||||
model="manus-agent",
|
||||
input=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "input_text", "text": "Summarize this document."},
|
||||
{"type": "input_file", "file_id": created_file.id}
|
||||
]
|
||||
}
|
||||
]
|
||||
)
|
||||
print(f"Response: {response.id}")
|
||||
|
||||
# Retrieve file
|
||||
retrieved_file = client.files.retrieve(created_file.id)
|
||||
print(f"File: {retrieved_file.filename}, {retrieved_file.bytes} bytes")
|
||||
|
||||
# Delete file
|
||||
deleted_file = client.files.delete(created_file.id)
|
||||
print(f"Deleted: {deleted_file.deleted}")
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [LiteLLM Responses API](/docs/response_api)
|
||||
- [LiteLLM Files API](/docs/proxy/litellm_managed_files)
|
||||
- [Manus OpenAI Compatibility](https://open.manus.im/docs/openai-compatibility)
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
# OpenRouter
|
||||
LiteLLM supports all the text / chat / vision models from [OpenRouter](https://openrouter.ai/docs)
|
||||
LiteLLM supports all the text / chat / vision / embedding models from [OpenRouter](https://openrouter.ai/docs)
|
||||
|
||||
<a target="_blank" href="https://colab.research.google.com/github/BerriAI/litellm/blob/main/cookbook/LiteLLM_OpenRouter.ipynb">
|
||||
<img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/>
|
||||
|
|
@ -78,3 +78,135 @@ response = completion(
|
|||
route= ""
|
||||
)
|
||||
```
|
||||
|
||||
## Embedding
|
||||
|
||||
```python
|
||||
from litellm import embedding
|
||||
import os
|
||||
|
||||
os.environ["OPENROUTER_API_KEY"] = "your-api-key"
|
||||
|
||||
response = embedding(
|
||||
model="openrouter/openai/text-embedding-3-small",
|
||||
input=["good morning from litellm", "this is another item"],
|
||||
)
|
||||
print(response)
|
||||
```
|
||||
|
||||
## Image Generation
|
||||
|
||||
OpenRouter supports image generation through select models like Google Gemini image generation models. LiteLLM transforms standard image generation requests to OpenRouter's chat completion format.
|
||||
|
||||
### Supported Parameters
|
||||
|
||||
- `size`: Maps to OpenRouter's `aspect_ratio` format
|
||||
- `1024x1024` → `1:1` (square)
|
||||
- `1536x1024` → `3:2` (landscape)
|
||||
- `1024x1536` → `2:3` (portrait)
|
||||
- `1792x1024` → `16:9` (wide landscape)
|
||||
- `1024x1792` → `9:16` (tall portrait)
|
||||
|
||||
- `quality`: Maps to OpenRouter's `image_size` format (Gemini models)
|
||||
- `low` or `standard` → `1K`
|
||||
- `medium` → `2K`
|
||||
- `high` or `hd` → `4K`
|
||||
|
||||
- `n`: Number of images to generate
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
from litellm import image_generation
|
||||
import os
|
||||
|
||||
os.environ["OPENROUTER_API_KEY"] = "your-api-key"
|
||||
|
||||
# Basic image generation
|
||||
response = image_generation(
|
||||
model="openrouter/google/gemini-2.5-flash-image",
|
||||
prompt="A beautiful sunset over a calm ocean",
|
||||
)
|
||||
print(response)
|
||||
```
|
||||
|
||||
### Advanced Usage with Parameters
|
||||
|
||||
```python
|
||||
from litellm import image_generation
|
||||
import os
|
||||
|
||||
os.environ["OPENROUTER_API_KEY"] = "your-api-key"
|
||||
|
||||
# Generate high-quality landscape image
|
||||
response = image_generation(
|
||||
model="openrouter/google/gemini-2.5-flash-image",
|
||||
prompt="A serene mountain landscape with a lake",
|
||||
size="1536x1024", # Landscape format
|
||||
quality="high", # High quality (4K)
|
||||
)
|
||||
|
||||
# Access the generated image
|
||||
image_data = response.data[0]
|
||||
if image_data.b64_json:
|
||||
# Base64 encoded image
|
||||
print(f"Generated base64 image: {image_data.b64_json[:50]}...")
|
||||
elif image_data.url:
|
||||
# Image URL
|
||||
print(f"Generated image URL: {image_data.url}")
|
||||
```
|
||||
|
||||
### Using OpenRouter-Specific Parameters
|
||||
|
||||
You can also pass OpenRouter-specific parameters directly using `image_config`:
|
||||
|
||||
```python
|
||||
from litellm import image_generation
|
||||
import os
|
||||
|
||||
os.environ["OPENROUTER_API_KEY"] = "your-api-key"
|
||||
|
||||
response = image_generation(
|
||||
model="openrouter/google/gemini-2.5-flash-image",
|
||||
prompt="A futuristic cityscape at night",
|
||||
image_config={
|
||||
"aspect_ratio": "16:9", # OpenRouter native format
|
||||
"image_size": "4K" # OpenRouter native format
|
||||
}
|
||||
)
|
||||
print(response)
|
||||
```
|
||||
|
||||
### Response Format
|
||||
|
||||
The response follows the standard LiteLLM ImageResponse format:
|
||||
|
||||
```python
|
||||
{
|
||||
"created": 1703658209,
|
||||
"data": [{
|
||||
"b64_json": "iVBORw0KGgoAAAANSUhEUgAA...", # Base64 encoded image
|
||||
"url": None,
|
||||
"revised_prompt": None
|
||||
}],
|
||||
"usage": {
|
||||
"input_tokens": 10,
|
||||
"output_tokens": 1290,
|
||||
"total_tokens": 1300
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Cost Tracking
|
||||
|
||||
OpenRouter provides cost information in the response, which LiteLLM automatically tracks:
|
||||
|
||||
```python
|
||||
response = image_generation(
|
||||
model="openrouter/google/gemini-2.5-flash-image",
|
||||
prompt="A cute baby sea otter",
|
||||
)
|
||||
|
||||
# Cost is available in the response metadata
|
||||
print(f"Request cost: ${response._hidden_params['additional_headers']['llm_provider-x-litellm-response-cost']}")
|
||||
```
|
||||
|
|
|
|||
|
|
@ -12,102 +12,340 @@ LiteLLM supports SAP Generative AI Hub's Orchestration Service.
|
|||
| Supported Endpoints | `/chat/completions`, `/embeddings` |
|
||||
| API Reference | [SAP AI Core Documentation](https://help.sap.com/docs/sap-ai-core) |
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, ensure you have:
|
||||
|
||||
1. **SAP BTP Account** with access to SAP AI Core
|
||||
2. **AI Core Service Instance** provisioned in your subaccount
|
||||
3. **Service Key** created for your AI Core instance (this contains your credentials)
|
||||
4. **Resource Group** with deployed AI models (check with your SAP administrator)
|
||||
|
||||
:::tip Where to Find Your Credentials
|
||||
Your credentials come from the **Service Key** you create in SAP BTP Cockpit:
|
||||
|
||||
1. Navigate to your **Subaccount** → **Instances and Subscriptions**
|
||||
2. Find your **AI Core** instance and click on it
|
||||
3. Go to **Service Keys** and create one (or use existing)
|
||||
4. The JSON contains all values needed below
|
||||
|
||||
The service key JSON looks like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"clientid": "sb-abc123...",
|
||||
"clientsecret": "xyz789...",
|
||||
"url": "https://myinstance.authentication.eu10.hana.ondemand.com",
|
||||
"serviceurls": {
|
||||
"AI_API_URL": "https://api.ai.prod.eu-central-1.aws.ml.hana.ondemand.com"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
:::info Resource Group
|
||||
The resource group is typically configured separately in your AI Core deployment, not in the service key itself. You can set it via the `AICORE_RESOURCE_GROUP` environment variable (defaults to "default").
|
||||
:::
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Step 1: Install LiteLLM
|
||||
|
||||
```bash
|
||||
pip install litellm
|
||||
```
|
||||
|
||||
### Step 2: Set Your Credentials
|
||||
|
||||
Choose **one** of these authentication methods:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="service-key" label="Service Key JSON (Recommended)">
|
||||
|
||||
The simplest approach - paste your entire service key as a single environment variable. The service key must be wrapped in a `credentials` object:
|
||||
|
||||
```bash
|
||||
export AICORE_SERVICE_KEY='{
|
||||
"credentials": {
|
||||
"clientid": "your-client-id",
|
||||
"clientsecret": "your-client-secret",
|
||||
"url": "https://<your-instance>.authentication.sap.hana.ondemand.com",
|
||||
"serviceurls": {
|
||||
"AI_API_URL": "https://api.ai.<your-region>.aws.ml.hana.ondemand.com"
|
||||
}
|
||||
}
|
||||
}'
|
||||
export AICORE_RESOURCE_GROUP="default"
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="individual" label="Individual Variables">
|
||||
|
||||
Alternatively, instead of using the service key above, you could set each credential separately:
|
||||
|
||||
```bash
|
||||
export AICORE_AUTH_URL="https://<your-instance>.authentication.sap.hana.ondemand.com/oauth/token"
|
||||
export AICORE_CLIENT_ID="your-client-id"
|
||||
export AICORE_CLIENT_SECRET="your-client-secret"
|
||||
export AICORE_RESOURCE_GROUP="default"
|
||||
export AICORE_BASE_URL="https://api.ai.<your-region>.aws.ml.hana.ondemand.com/v2"
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Step 3: Make Your First Request
|
||||
|
||||
```python title="test_sap.py"
|
||||
from litellm import completion
|
||||
|
||||
response = completion(
|
||||
model="sap/gpt-4o",
|
||||
messages=[{"role": "user", "content": "Hello from LiteLLM!"}]
|
||||
)
|
||||
print(response.choices[0].message.content)
|
||||
```
|
||||
|
||||
Run it:
|
||||
|
||||
```bash
|
||||
python test_sap.py
|
||||
```
|
||||
|
||||
**Expected output:**
|
||||
|
||||
```text
|
||||
Hello! How can I assist you today?
|
||||
```
|
||||
|
||||
### Step 4: Verify Your Setup (Optional)
|
||||
|
||||
Test that everything is working with this diagnostic script:
|
||||
|
||||
```python title="verify_sap_setup.py"
|
||||
import os
|
||||
import litellm
|
||||
|
||||
# Enable debug logging to see what's happening
|
||||
import os
|
||||
os.environ["LITELLM_LOG"] = "DEBUG"
|
||||
|
||||
# Either use AICORE_SERVICE_KEY (contains all credentials including resourcegroup)
|
||||
# OR use individual variables (all required together)
|
||||
individual_vars = ["AICORE_AUTH_URL", "AICORE_CLIENT_ID", "AICORE_CLIENT_SECRET", "AICORE_BASE_URL", "AICORE_RESOURCE_GROUP"]
|
||||
|
||||
print("=== SAP Gen AI Hub Setup Verification ===\n")
|
||||
|
||||
# Check for service key method
|
||||
if os.environ.get("AICORE_SERVICE_KEY"):
|
||||
print("✓ Using AICORE_SERVICE_KEY authentication (includes resource group)")
|
||||
else:
|
||||
# Check individual variables
|
||||
missing = [v for v in individual_vars if not os.environ.get(v)]
|
||||
if missing:
|
||||
print(f"✗ Missing environment variables: {missing}")
|
||||
else:
|
||||
print("✓ Using individual variable authentication")
|
||||
print(f"✓ Resource group: {os.environ.get('AICORE_RESOURCE_GROUP')}")
|
||||
|
||||
# Test API connection
|
||||
print("\n=== Testing API Connection ===\n")
|
||||
try:
|
||||
response = litellm.completion(
|
||||
model="sap/gpt-4o",
|
||||
messages=[{"role": "user", "content": "Say 'Connection successful!' and nothing else."}],
|
||||
max_tokens=20
|
||||
)
|
||||
print(f"✓ API Response: {response.choices[0].message.content}")
|
||||
print("\n🎉 Setup complete! You're ready to use SAP Gen AI Hub with LiteLLM.")
|
||||
except Exception as e:
|
||||
print(f"✗ API Error: {e}")
|
||||
print("\nTroubleshooting tips:")
|
||||
print(" 1. Verify your service key credentials are correct")
|
||||
print(" 2. Check that 'gpt-4o' is deployed in your resource group")
|
||||
print(" 3. Ensure your SAP AI Core instance is running")
|
||||
```
|
||||
|
||||
Run the verification:
|
||||
|
||||
```bash
|
||||
python verify_sap_setup.py
|
||||
```
|
||||
|
||||
**Expected output on success:**
|
||||
|
||||
```text
|
||||
=== SAP Gen AI Hub Setup Verification ===
|
||||
|
||||
✓ Using AICORE_SERVICE_KEY authentication
|
||||
✓ Resource group: default
|
||||
|
||||
=== Testing API Connection ===
|
||||
|
||||
✓ API Response: Connection successful!
|
||||
|
||||
🎉 Setup complete! You're ready to use SAP Gen AI Hub with LiteLLM.
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
SAP Generative AI Hub uses service key authentication. You can provide credentials via:
|
||||
SAP Generative AI Hub uses OAuth2 service keys for authentication. See [Quick Start](#quick-start) for setup instructions.
|
||||
|
||||
1. **Environment variable** - Set `AICORE_SERVICE_KEY` with your service key JSON
|
||||
2. **Direct parameter** - Pass `api_key` with the service key JSON string
|
||||
### Environment Variables Reference
|
||||
|
||||
```python showLineNumbers title="Environment Variable"
|
||||
import os
|
||||
os.environ["AICORE_SERVICE_KEY"] = '{"clientid": "...", "clientsecret": "...", ...}'
|
||||
| Variable | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `AICORE_SERVICE_KEY` | Yes* | Complete service key JSON (recommended method) |
|
||||
| `AICORE_RESOURCE_GROUP` | Yes | Your AI Core resource group name |
|
||||
| `AICORE_AUTH_URL` | Yes* | OAuth token URL (alternative to service key) |
|
||||
| `AICORE_CLIENT_ID` | Yes* | OAuth client ID (alternative to service key) |
|
||||
| `AICORE_CLIENT_SECRET` | Yes* | OAuth client secret (alternative to service key) |
|
||||
| `AICORE_BASE_URL` | Yes* | AI Core API base URL (alternative to service key) |
|
||||
|
||||
*Choose either `AICORE_SERVICE_KEY` OR the individual variables (`AICORE_AUTH_URL`, `AICORE_CLIENT_ID`, `AICORE_CLIENT_SECRET`, `AICORE_BASE_URL`).
|
||||
|
||||
## Model Naming Conventions
|
||||
|
||||
Understanding model naming is crucial for using SAP Gen AI Hub correctly. The naming pattern differs depending on whether you're using the SDK directly or through the proxy.
|
||||
|
||||
### Direct SDK Usage
|
||||
|
||||
When calling LiteLLM's SDK directly, you **must** include the `sap/` prefix in the model name:
|
||||
|
||||
```python
|
||||
# Correct - includes sap/ prefix
|
||||
model="sap/gpt-4o"
|
||||
model="sap/anthropic--claude-4.5-sonnet"
|
||||
model="sap/gemini-2.5-pro"
|
||||
|
||||
# Incorrect - missing prefix
|
||||
model="gpt-4o" # ❌ Won't work
|
||||
```
|
||||
3. **Environment variables** - Set the following list of credentials in .env file
|
||||
<pre>
|
||||
AICORE_AUTH_URL = "https://* * * .authentication.sap.hana.ondemand.com/oauth/token",
|
||||
AICORE_CLIENT_ID = " *** ",
|
||||
AICORE_CLIENT_SECRET = " *** ",
|
||||
AICORE_RESOURCE_GROUP = " *** ",
|
||||
AICORE_BASE_URL = "https://api.ai.***.cfapps.sap.hana.ondemand.com/v2"
|
||||
</pre>
|
||||
|
||||
Other credential configuration options are also available. For more information, see the [SAP AI Core Documentation](https://help.sap.com/doc/generative-ai-hub-sdk/CLOUD/en-US/_reference/README_sphynx.html#configuration).
|
||||
## Usage - LiteLLM Python SDK
|
||||
### Proxy Usage
|
||||
|
||||
```python showLineNumbers title="SAP Chat Completion"
|
||||
from litellm import completion
|
||||
import os
|
||||
When using the LiteLLM Proxy, you use the **friendly `model_name`** defined in your configuration. The proxy automatically handles the `sap/` prefix routing.
|
||||
|
||||
os.environ["AICORE_SERVICE_KEY"] = '{"clientid": "...", "clientsecret": "...", ...}'
|
||||
```yaml
|
||||
# In config.yaml, define the mapping
|
||||
model_list:
|
||||
- model_name: gpt-4o # ← Use this name in client requests
|
||||
litellm_params:
|
||||
model: sap/gpt-4o # ← Proxy handles the sap/ prefix
|
||||
```
|
||||
|
||||
response = completion(
|
||||
model="sap/gpt-4",
|
||||
messages=[{"role": "user", "content": "Hello from LiteLLM"}]
|
||||
```python
|
||||
# Client request - no sap/ prefix needed
|
||||
client.chat.completions.create(
|
||||
model="gpt-4o", # ✓ Correct for proxy usage
|
||||
messages=[...]
|
||||
)
|
||||
print(response)
|
||||
```
|
||||
|
||||
```python showLineNumbers title="SAP Chat Completion - Streaming"
|
||||
### Anthropic Models Special Syntax
|
||||
|
||||
Anthropic models use a double-dash (`--`) prefix convention:
|
||||
|
||||
| Provider | Model Example | LiteLLM Format |
|
||||
|----------|---------------|----------------|
|
||||
| OpenAI | GPT-4o | `sap/gpt-4o` |
|
||||
| Anthropic | Claude 4.5 Sonnet | `sap/anthropic--claude-4.5-sonnet` |
|
||||
| Google | Gemini 2.5 Pro | `sap/gemini-2.5-pro` |
|
||||
| Mistral | Mistral Large | `sap/mistral-large` |
|
||||
|
||||
### Quick Reference Table
|
||||
|
||||
| Usage Type | Model Format | Example |
|
||||
|------------|--------------|---------|
|
||||
| Direct SDK | `sap/<model-name>` | `sap/gpt-4o` |
|
||||
| Direct SDK (Anthropic) | `sap/anthropic--<model>` | `sap/anthropic--claude-4.5-sonnet` |
|
||||
| Proxy Client | `<friendly-name>` | `gpt-4o` or `claude-sonnet` |
|
||||
|
||||
## Using the Python SDK
|
||||
|
||||
The LiteLLM Python SDK automatically detects your authentication method. Simply set your environment variables and make requests.
|
||||
|
||||
```python showLineNumbers title="Basic Completion"
|
||||
from litellm import completion
|
||||
import os
|
||||
|
||||
os.environ["AICORE_SERVICE_KEY"] = '{"clientid": "...", "clientsecret": "...", ...}'
|
||||
|
||||
# Assumes AICORE_AUTH_URL, AICORE_CLIENT_ID, etc. are set
|
||||
response = completion(
|
||||
model="sap/gpt-4",
|
||||
messages=[{"role": "user", "content": "Hello from LiteLLM"}],
|
||||
stream=True
|
||||
model="sap/anthropic--claude-4.5-sonnet",
|
||||
messages=[{"role": "user", "content": "Explain quantum computing"}]
|
||||
)
|
||||
|
||||
for chunk in response:
|
||||
print(chunk.choices[0].delta.content or "", end="")
|
||||
print(response.choices[0].message.content)
|
||||
```
|
||||
|
||||
```python showLineNumbers title="SAP Embedding"
|
||||
from litellm import embedding
|
||||
import os
|
||||
Both authentication methods (individual variables or service key JSON) work automatically - no code changes required.
|
||||
|
||||
os.environ["AICORE_SERVICE_KEY"] = '{"clientid": "...", "clientsecret": "...", ...}'
|
||||
## Using the Proxy Server
|
||||
|
||||
result = embedding(
|
||||
model="sap/text-embedding-3-small",
|
||||
input="Answer to the ultimate question of life, the universe, and everything is 42")
|
||||
print(result.data[0])
|
||||
```
|
||||
The LiteLLM Proxy provides a unified OpenAI-compatible API for your SAP models.
|
||||
|
||||
## Usage - LiteLLM Proxy
|
||||
### Configuration
|
||||
|
||||
Add to your LiteLLM Proxy config:
|
||||
Create a `config.yaml` file in your project directory with your model mappings and credentials:
|
||||
|
||||
```yaml showLineNumbers title="config.yaml"
|
||||
model_list:
|
||||
- model_name: "sap/*"
|
||||
# OpenAI models
|
||||
- model_name: gpt-5
|
||||
litellm_params:
|
||||
model: "sap/*"
|
||||
model: sap/gpt-5
|
||||
|
||||
general_settings:
|
||||
master_key: your-proxy-api-key
|
||||
# Anthropic models (note the double-dash)
|
||||
- model_name: claude-sonnet
|
||||
litellm_params:
|
||||
model: sap/anthropic--claude-4.5-sonnet
|
||||
|
||||
- model_name: claude-opus
|
||||
litellm_params:
|
||||
model: sap/anthropic--claude-4.5-opus
|
||||
|
||||
# Embeddings
|
||||
- model_name: text-embedding-3-small
|
||||
litellm_params:
|
||||
model: sap/text-embedding-3-small
|
||||
|
||||
litellm_settings:
|
||||
drop_params: true
|
||||
set_verbose: false
|
||||
request_timeout: 600
|
||||
num_retries: 2
|
||||
forward_client_headers_to_llm_api: ["anthropic-version"]
|
||||
|
||||
general_settings:
|
||||
master_key: "sk-1234" # Enter here your desired master key starting with 'sk-'.
|
||||
|
||||
# UI Admin is not required but helpful including the management of keys for your team(s). If you are using a database, these parameters are required:
|
||||
database_url: "Enter you database URL."
|
||||
UI_USERNAME: "Your desired UI admin account name"
|
||||
UI_PASSWORD: "Your desired and strong pwd"
|
||||
|
||||
# Authentication
|
||||
environment_variables:
|
||||
AICORE_SERVICE_KEY: '{"clientid": "...", "clientsecret": "...", ...}'
|
||||
AICORE_SERVICE_KEY: '{"credentials": {"clientid": "...", "clientsecret": "...", "url": "...", "serviceurls": {"AI_API_URL": "..."}}}'
|
||||
AICORE_RESOURCE_GROUP: "default"
|
||||
```
|
||||
|
||||
Start the proxy:
|
||||
### Starting the Proxy
|
||||
|
||||
```bash showLineNumbers title="Start Proxy"
|
||||
litellm --config config.yaml
|
||||
```
|
||||
|
||||
The proxy will start on `http://localhost:4000` by default.
|
||||
|
||||
### Making Requests
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash showLineNumbers title="Test Request"
|
||||
curl http://localhost:4000/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer your-proxy-api-key" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-d '{
|
||||
"model": "sap/gpt-4",
|
||||
"model": "gpt-4o",
|
||||
"messages": [{"role": "user", "content": "Hello"}]
|
||||
}'
|
||||
```
|
||||
|
|
@ -120,11 +358,11 @@ from openai import OpenAI
|
|||
|
||||
client = OpenAI(
|
||||
base_url="http://localhost:4000",
|
||||
api_key="your-proxy-api-key"
|
||||
api_key="sk-1234"
|
||||
)
|
||||
|
||||
response = client.chat.completions.create(
|
||||
model="sap/gpt-4",
|
||||
model="gpt-4o",
|
||||
messages=[{"role": "user", "content": "Hello"}]
|
||||
)
|
||||
print(response.choices[0].message.content)
|
||||
|
|
@ -136,12 +374,14 @@ print(response.choices[0].message.content)
|
|||
```python showLineNumbers title="LiteLLM SDK"
|
||||
import os
|
||||
import litellm
|
||||
os.environ["LITELLM_PROXY_API_KEY"] = "your-proxy-api-key"
|
||||
litellm.use_litellm_proxy = True # it is important to set this parameter
|
||||
|
||||
os.environ["LITELLM_PROXY_API_KEY"] = "sk-1234"
|
||||
litellm.use_litellm_proxy = True
|
||||
|
||||
response = litellm.completion(
|
||||
model="sap/gpt-4o",
|
||||
messages=[{ "content": "Hello, how are you?","role": "user"}],
|
||||
api_base="http://your-proxy-api-base"
|
||||
model="claude-sonnet",
|
||||
messages=[{"content": "Hello, how are you?", "role": "user"}],
|
||||
api_base="http://localhost:4000"
|
||||
)
|
||||
|
||||
print(response)
|
||||
|
|
@ -150,15 +390,170 @@ print(response)
|
|||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Supported Parameters
|
||||
## Features
|
||||
|
||||
| Parameter | Description |
|
||||
|-----------|-------------|
|
||||
| `temperature` | Controls randomness |
|
||||
| `max_tokens` | Maximum tokens in response |
|
||||
| `top_p` | Nucleus sampling |
|
||||
| `tools` | Function calling tools |
|
||||
| `tool_choice` | Tool selection behavior |
|
||||
| `response_format` | Output format (json_object, json_schema) |
|
||||
| `stream` | Enable streaming |
|
||||
### Streaming Responses
|
||||
|
||||
Stream responses in real-time for better user experience:
|
||||
|
||||
```python showLineNumbers title="Streaming Chat Completion"
|
||||
from litellm import completion
|
||||
|
||||
response = completion(
|
||||
model="sap/gpt-4o",
|
||||
messages=[{"role": "user", "content": "Count from 1 to 10"}],
|
||||
stream=True
|
||||
)
|
||||
|
||||
for chunk in response:
|
||||
if chunk.choices[0].delta.content:
|
||||
print(chunk.choices[0].delta.content, end="", flush=True)
|
||||
```
|
||||
|
||||
### Structured Output
|
||||
|
||||
#### JSON Schema (Recommended)
|
||||
|
||||
Use JSON Schema for structured output with strict validation:
|
||||
|
||||
```python showLineNumbers title="JSON Schema Response"
|
||||
from litellm import completion
|
||||
|
||||
response = completion(
|
||||
model="sap/gpt-4o",
|
||||
messages=[{
|
||||
"role": "user",
|
||||
"content": "Generate info about Tokyo"
|
||||
}],
|
||||
response_format={
|
||||
"type": "json_schema",
|
||||
"json_schema": {
|
||||
"name": "city_info",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"population": {"type": "number"},
|
||||
"country": {"type": "string"}
|
||||
},
|
||||
"required": ["name", "population", "country"],
|
||||
"additionalProperties": False
|
||||
},
|
||||
"strict": True
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
print(response.choices[0].message.content)
|
||||
# Output: {"name":"Tokyo","population":37000000,"country":"Japan"}
|
||||
```
|
||||
|
||||
#### JSON Object Format
|
||||
|
||||
For flexible JSON output without schema validation:
|
||||
|
||||
```python showLineNumbers title="JSON Object Response"
|
||||
from litellm import completion
|
||||
|
||||
response = completion(
|
||||
model="sap/gpt-4o",
|
||||
messages=[{
|
||||
"role": "user",
|
||||
"content": "Generate a person object in JSON format with name and age"
|
||||
}],
|
||||
response_format={"type": "json_object"}
|
||||
)
|
||||
|
||||
print(response.choices[0].message.content)
|
||||
```
|
||||
|
||||
:::note SAP Platform Requirement
|
||||
When using `json_object` type, SAP's orchestration service requires the word "json" to appear in your prompt. This ensures explicit intent for JSON formatting. For schema-validated output without this requirement, use `json_schema` instead (recommended).
|
||||
:::
|
||||
|
||||
### Multi-turn Conversations
|
||||
|
||||
Maintain conversation context across multiple turns:
|
||||
|
||||
```python showLineNumbers title="Multi-turn Conversation"
|
||||
from litellm import completion
|
||||
|
||||
response = completion(
|
||||
model="sap/gpt-4o",
|
||||
messages=[
|
||||
{"role": "user", "content": "My name is Alice"},
|
||||
{"role": "assistant", "content": "Hello Alice! Nice to meet you."},
|
||||
{"role": "user", "content": "What is my name?"}
|
||||
]
|
||||
)
|
||||
|
||||
print(response.choices[0].message.content)
|
||||
# Output: Your name is Alice.
|
||||
```
|
||||
|
||||
### Embeddings
|
||||
|
||||
Generate vector embeddings for semantic search and retrieval:
|
||||
|
||||
```python showLineNumbers title="Create Embeddings"
|
||||
from litellm import embedding
|
||||
|
||||
response = embedding(
|
||||
model="sap/text-embedding-3-small",
|
||||
input=["Hello world", "Machine learning is fascinating"]
|
||||
)
|
||||
|
||||
print(response.data[0]["embedding"]) # Vector representation
|
||||
```
|
||||
|
||||
## Reference
|
||||
|
||||
### Supported Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `model` | string | Model identifier (with `sap/` prefix for SDK) |
|
||||
| `messages` | array | Conversation messages |
|
||||
| `temperature` | float | Controls randomness (0-2) |
|
||||
| `max_tokens` | integer | Maximum tokens in response |
|
||||
| `top_p` | float | Nucleus sampling threshold |
|
||||
| `stream` | boolean | Enable streaming responses |
|
||||
| `response_format` | object | Output format (`json_object`, `json_schema`) |
|
||||
| `tools` | array | Function calling tool definitions |
|
||||
| `tool_choice` | string/object | Tool selection behavior |
|
||||
|
||||
### Supported Models
|
||||
|
||||
For the complete and up-to-date list of available models provided by SAP Gen AI Hub, please refer to the [SAP AI Core Generative AI Hub documentation](https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/models-and-scenarios-in-generative-ai-hub).
|
||||
|
||||
:::info Model Availability
|
||||
Model availability varies by SAP deployment region and your subscription. Contact your SAP administrator to confirm which models are available in your environment.
|
||||
:::
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
**Authentication Errors**
|
||||
|
||||
If you receive authentication errors:
|
||||
|
||||
1. Verify all required environment variables are set correctly
|
||||
2. Check that your service key hasn't expired
|
||||
3. Confirm your resource group has access to the desired models
|
||||
4. Ensure the `AICORE_AUTH_URL` and `AICORE_BASE_URL` match your SAP region
|
||||
|
||||
**Model Not Found**
|
||||
|
||||
If a model returns "not found":
|
||||
|
||||
1. Verify the model is available in your SAP deployment
|
||||
2. Check you're using the correct model name format (`sap/` prefix for SDK)
|
||||
3. Confirm your resource group has access to that specific model
|
||||
4. For Anthropic models, ensure you're using the `anthropic--` double-dash prefix
|
||||
|
||||
**Rate Limiting**
|
||||
|
||||
SAP Gen AI Hub enforces rate limits based on your subscription. If you hit limits:
|
||||
|
||||
1. Implement exponential backoff retry logic
|
||||
2. Consider using the proxy's built-in rate limiting features
|
||||
3. Contact your SAP administrator to review quota allocations
|
||||
|
|
|
|||
|
|
@ -416,7 +416,6 @@ response = image_edit(
|
|||
image=open("original_image.png", "rb"),
|
||||
mask=open("mask_image.png", "rb"),
|
||||
prompt="Add flowers in the masked area",
|
||||
size="1024x1024",
|
||||
)
|
||||
print(response)
|
||||
```
|
||||
|
|
|
|||
|
|
@ -73,8 +73,21 @@ GOOGLE_CLIENT_SECRET=
|
|||
```shell
|
||||
MICROSOFT_CLIENT_ID="84583a4d-"
|
||||
MICROSOFT_CLIENT_SECRET="nbk8Q~"
|
||||
MICROSOFT_TENANT="5a39737
|
||||
MICROSOFT_TENANT="5a39737"
|
||||
```
|
||||
|
||||
**Optional: Custom Microsoft SSO Endpoints**
|
||||
|
||||
If you need to use custom Microsoft SSO endpoints (e.g., for a custom identity provider, sovereign cloud, or proxy), you can override the default endpoints:
|
||||
|
||||
```shell
|
||||
MICROSOFT_AUTHORIZATION_ENDPOINT="https://your-custom-url.com/oauth2/v2.0/authorize"
|
||||
MICROSOFT_TOKEN_ENDPOINT="https://your-custom-url.com/oauth2/v2.0/token"
|
||||
MICROSOFT_USERINFO_ENDPOINT="https://your-custom-graph-api.com/v1.0/me"
|
||||
```
|
||||
|
||||
If these are not set, the default Microsoft endpoints are used based on your tenant.
|
||||
|
||||
- Set Redirect URI on your App Registration on https://portal.azure.com/
|
||||
- Set a redirect url = `<your proxy base url>/sso/callback`
|
||||
```shell
|
||||
|
|
@ -98,6 +111,42 @@ To set up app roles:
|
|||
4. Assign users to these roles in your Enterprise Application
|
||||
5. When users sign in via SSO, LiteLLM will automatically assign them the corresponding role
|
||||
|
||||
**Advanced: Custom User Attribute Mapping**
|
||||
|
||||
For certain Microsoft Entra ID configurations, you may need to override the default user attribute field names. This is useful when your organization uses custom claims or non-standard attribute names in the SSO response.
|
||||
|
||||
**Step 1: Debug SSO Response**
|
||||
|
||||
First, inspect the JWT fields returned by your Microsoft SSO provider using the [SSO Debug Route](#debugging-sso-jwt-fields).
|
||||
|
||||
1. Add `/sso/debug/callback` as a redirect URL in your Azure App Registration
|
||||
2. Navigate to `https://<proxy_base_url>/sso/debug/login`
|
||||
3. Complete the SSO flow to see the returned user attributes
|
||||
|
||||
**Step 2: Identify Field Attribute Names**
|
||||
|
||||
From the debug response, identify the field names used for email, display name, user ID, first name, and last name.
|
||||
|
||||
**Step 3: Set Environment Variables**
|
||||
|
||||
Override the default attribute names by setting these environment variables:
|
||||
|
||||
| Environment Variable | Description | Default Value |
|
||||
|---------------------|-------------|---------------|
|
||||
| `MICROSOFT_USER_EMAIL_ATTRIBUTE` | Field name for user email | `userPrincipalName` |
|
||||
| `MICROSOFT_USER_DISPLAY_NAME_ATTRIBUTE` | Field name for display name | `displayName` |
|
||||
| `MICROSOFT_USER_ID_ATTRIBUTE` | Field name for user ID | `id` |
|
||||
| `MICROSOFT_USER_FIRST_NAME_ATTRIBUTE` | Field name for first name | `givenName` |
|
||||
| `MICROSOFT_USER_LAST_NAME_ATTRIBUTE` | Field name for last name | `surname` |
|
||||
|
||||
**Step 4: Restart the Proxy**
|
||||
|
||||
After setting the environment variables, restart the proxy:
|
||||
|
||||
```bash
|
||||
litellm --config /path/to/config.yaml
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="Generic" label="Generic SSO Provider">
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ router_settings:
|
|||
cooldown_time: 30 # (in seconds) how long to cooldown model if fails/min > allowed_fails
|
||||
disable_cooldowns: True # bool - Disable cooldowns for all models
|
||||
enable_tag_filtering: True # bool - Use tag based routing for requests
|
||||
tag_filtering_match_any: True # bool - Tag matching behavior (only when enable_tag_filtering=true). `true`: match if deployment has ANY requested tag; `false`: match only if deployment has ALL requested tags
|
||||
retry_policy: { # Dict[str, int]: retry policy for different types of exceptions
|
||||
"AuthenticationErrorRetries": 3,
|
||||
"TimeoutErrorRetries": 3,
|
||||
|
|
@ -293,6 +294,7 @@ router_settings:
|
|||
cooldown_time: 30 # (in seconds) how long to cooldown model if fails/min > allowed_fails
|
||||
disable_cooldowns: True # bool - Disable cooldowns for all models
|
||||
enable_tag_filtering: True # bool - Use tag based routing for requests
|
||||
tag_filtering_match_any: True # bool - Tag matching behavior (only when enable_tag_filtering=true). `true`: match if deployment has ANY requested tag; `false`: match only if deployment has ALL requested tags
|
||||
retry_policy: { # Dict[str, int]: retry policy for different types of exceptions
|
||||
"AuthenticationErrorRetries": 3,
|
||||
"TimeoutErrorRetries": 3,
|
||||
|
|
@ -322,6 +324,7 @@ router_settings:
|
|||
| content_policy_fallbacks | array of objects | Specifies fallback models for content policy violations. [More information here](reliability) |
|
||||
| fallbacks | array of objects | Specifies fallback models for all types of errors. [More information here](reliability) |
|
||||
| enable_tag_filtering | boolean | If true, uses tag based routing for requests [Tag Based Routing](tag_routing) |
|
||||
| tag_filtering_match_any | boolean | Tag matching behavior (only when enable_tag_filtering=true). `true`: match if deployment has ANY requested tag; `false`: match only if deployment has ALL requested tags |
|
||||
| cooldown_time | integer | The duration (in seconds) to cooldown a model if it exceeds the allowed failures. |
|
||||
| disable_cooldowns | boolean | If true, disables cooldowns for all models. [More information here](reliability) |
|
||||
| retry_policy | object | Specifies the number of retries for different types of exceptions. [More information here](reliability) |
|
||||
|
|
@ -578,6 +581,18 @@ router_settings:
|
|||
| FIREWORKS_AI_56_B_MOE | Size parameter for Fireworks AI 56B MOE model. Default is 56
|
||||
| FIREWORKS_AI_80_B | Size parameter for Fireworks AI 80B model. Default is 80
|
||||
| FIREWORKS_AI_176_B_MOE | Size parameter for Fireworks AI 176B MOE model. Default is 176
|
||||
| FOCUS_PROVIDER | Destination provider for Focus exports (e.g., `s3`). Defaults to `s3`.
|
||||
| FOCUS_FORMAT | Output format for Focus exports. Defaults to `parquet`.
|
||||
| FOCUS_FREQUENCY | Frequency for scheduled Focus exports (`hourly`, `daily`, or `interval`). Defaults to `hourly`.
|
||||
| FOCUS_CRON_OFFSET | Minute offset used when scheduling hourly/daily Focus exports. Defaults to `5` minutes.
|
||||
| FOCUS_INTERVAL_SECONDS | Interval (in seconds) for Focus exports when `frequency` is `interval`.
|
||||
| FOCUS_PREFIX | Object key prefix (or folder) used when uploading Focus export files. Defaults to `focus_exports`.
|
||||
| FOCUS_S3_BUCKET_NAME | S3 bucket to upload Focus export files when using the S3 destination.
|
||||
| FOCUS_S3_REGION_NAME | AWS region for the Focus export S3 bucket.
|
||||
| FOCUS_S3_ENDPOINT_URL | Custom endpoint for the Focus export S3 client (optional; useful for S3-compatible storage).
|
||||
| FOCUS_S3_ACCESS_KEY | AWS access key ID used by the Focus export S3 client.
|
||||
| FOCUS_S3_SECRET_KEY | AWS secret access key used by the Focus export S3 client.
|
||||
| FOCUS_S3_SESSION_TOKEN | AWS session token used by the Focus export S3 client (optional).
|
||||
| FUNCTION_DEFINITION_TOKEN_COUNT | Token count for function definitions. Default is 9
|
||||
| GALILEO_BASE_URL | Base URL for Galileo platform
|
||||
| GALILEO_PASSWORD | Password for Galileo authentication
|
||||
|
|
@ -729,6 +744,7 @@ router_settings:
|
|||
| LITELLM_PRINT_STANDARD_LOGGING_PAYLOAD | If true, prints the standard logging payload to the console - useful for debugging
|
||||
| LITELM_ENVIRONMENT | Environment for LiteLLM Instance. This is currently only logged to DeepEval to determine the environment for DeepEval integration.
|
||||
| LOGFIRE_TOKEN | Token for Logfire logging service
|
||||
| LOGFIRE_BASE_URL | Base URL for Logfire logging service (useful for self hosted deployments)
|
||||
| LOGGING_WORKER_CONCURRENCY | Maximum number of concurrent coroutine slots for the logging worker on the asyncio event loop. Default is 100. Setting too high will flood the event loop with logging tasks which will lower the overall latency of the requests.
|
||||
| LOGGING_WORKER_MAX_QUEUE_SIZE | Maximum size of the logging worker queue. When the queue is full, the worker aggressively clears tasks to make room instead of dropping logs. Default is 50,000
|
||||
| LOGGING_WORKER_MAX_TIME_PER_COROUTINE | Maximum time in seconds allowed for each coroutine in the logging worker before timing out. Default is 20.0
|
||||
|
|
@ -756,10 +772,18 @@ router_settings:
|
|||
| MINIMUM_PROMPT_CACHE_TOKEN_COUNT | Minimum token count for caching a prompt. Default is 1024
|
||||
| MISTRAL_API_BASE | Base URL for Mistral API. Default is https://api.mistral.ai
|
||||
| MISTRAL_API_KEY | API key for Mistral API
|
||||
| MICROSOFT_AUTHORIZATION_ENDPOINT | Custom authorization endpoint URL for Microsoft SSO (overrides default Microsoft OAuth authorization endpoint)
|
||||
| MICROSOFT_CLIENT_ID | Client ID for Microsoft services
|
||||
| MICROSOFT_CLIENT_SECRET | Client secret for Microsoft services
|
||||
| MICROSOFT_TENANT | Tenant ID for Microsoft Azure
|
||||
| MICROSOFT_SERVICE_PRINCIPAL_ID | Service Principal ID for Microsoft Enterprise Application. (This is an advanced feature if you want litellm to auto-assign members to Litellm Teams based on their Microsoft Entra ID Groups)
|
||||
| MICROSOFT_TENANT | Tenant ID for Microsoft Azure
|
||||
| MICROSOFT_TOKEN_ENDPOINT | Custom token endpoint URL for Microsoft SSO (overrides default Microsoft OAuth token endpoint)
|
||||
| MICROSOFT_USER_DISPLAY_NAME_ATTRIBUTE | Field name for user display name in Microsoft SSO response. Default is `displayName`
|
||||
| MICROSOFT_USER_EMAIL_ATTRIBUTE | Field name for user email in Microsoft SSO response. Default is `userPrincipalName`
|
||||
| MICROSOFT_USER_FIRST_NAME_ATTRIBUTE | Field name for user first name in Microsoft SSO response. Default is `givenName`
|
||||
| MICROSOFT_USER_ID_ATTRIBUTE | Field name for user ID in Microsoft SSO response. Default is `id`
|
||||
| MICROSOFT_USER_LAST_NAME_ATTRIBUTE | Field name for user last name in Microsoft SSO response. Default is `surname`
|
||||
| MICROSOFT_USERINFO_ENDPOINT | Custom userinfo endpoint URL for Microsoft SSO (overrides default Microsoft Graph userinfo endpoint)
|
||||
| NO_DOCS | Flag to disable Swagger UI documentation
|
||||
| NO_REDOC | Flag to disable Redoc documentation
|
||||
| NO_PROXY | List of addresses to bypass proxy
|
||||
|
|
|
|||
|
|
@ -22,19 +22,22 @@ Customer Usage enables you to track spend and usage for individual customers (en
|
|||
|
||||
## How to Track Spend
|
||||
|
||||
Track customer spend by including a `user` field in your API requests. The customer ID will be automatically tracked and associated with all spend from that request.
|
||||
Track customer spend by including a `user` field in your API requests or by passing a customer ID header. The customer ID will be automatically tracked and associated with all spend from that request.
|
||||
|
||||
### Example using cURL
|
||||
<Tabs>
|
||||
<TabItem value="body" label="Request Body" default>
|
||||
|
||||
### Using Request Body
|
||||
|
||||
Make a `/chat/completions` call with the `user` field containing your customer ID:
|
||||
|
||||
```bash showLineNumbers title="Track spend with customer ID"
|
||||
```bash showLineNumbers title="Track spend with customer ID in body"
|
||||
curl -X POST 'http://0.0.0.0:4000/chat/completions' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--header 'Authorization: Bearer sk-1234' \ # 👈 YOUR PROXY KEY
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--data '{
|
||||
"model": "gpt-3.5-turbo",
|
||||
"user": "customer-123", # 👈 CUSTOMER ID
|
||||
"user": "customer-123",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
|
|
@ -44,7 +47,49 @@ curl -X POST 'http://0.0.0.0:4000/chat/completions' \
|
|||
}'
|
||||
```
|
||||
|
||||
The customer ID (`customer-123`) will be automatically upserted into the database with the new spend. If the customer ID already exists, spend will be incremented.
|
||||
</TabItem>
|
||||
<TabItem value="header" label="Request Header">
|
||||
|
||||
### Using Request Headers
|
||||
|
||||
You can also pass the customer ID via HTTP headers. This is useful for tools that support custom headers but don't allow modifying the request body (like Claude Code with `ANTHROPIC_CUSTOM_HEADERS`).
|
||||
|
||||
LiteLLM automatically recognizes these standard headers (no configuration required):
|
||||
- `x-litellm-customer-id`
|
||||
- `x-litellm-end-user-id`
|
||||
|
||||
```bash showLineNumbers title="Track spend with customer ID in header"
|
||||
curl -X POST 'http://0.0.0.0:4000/chat/completions' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header 'x-litellm-customer-id: customer-123' \
|
||||
--data '{
|
||||
"model": "gpt-3.5-turbo",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "What is the capital of France?"
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
#### Using with Claude Code
|
||||
|
||||
Claude Code supports custom headers via the `ANTHROPIC_CUSTOM_HEADERS` environment variable. Set it to pass your customer ID:
|
||||
|
||||
```bash title="Configure Claude Code with customer tracking"
|
||||
export ANTHROPIC_BASE_URL="http://0.0.0.0:4000/v1/messages"
|
||||
export ANTHROPIC_API_KEY="sk-1234"
|
||||
export ANTHROPIC_CUSTOM_HEADERS="x-litellm-customer-id: my-customer-id"
|
||||
```
|
||||
|
||||
Now all requests from Claude Code will automatically track spend under `my-customer-id`.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The customer ID will be automatically upserted into the database with the new spend. If the customer ID already exists, spend will be incremented.
|
||||
|
||||
### Example using OpenWebUI
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,12 @@ import TabItem from '@theme/TabItem';
|
|||
|
||||
# High Availability Setup (Resolve DB Deadlocks)
|
||||
|
||||
:::tip Essential for Production
|
||||
|
||||
This configuration is **required** for production deployments handling 1000+ requests per second. Without Redis configured, you may experience PostgreSQL connection exhaustion (`FATAL: sorry, too many clients already`).
|
||||
|
||||
:::
|
||||
|
||||
Resolve any Database Deadlocks you see in high traffic by using this setup
|
||||
|
||||
## What causes the problem?
|
||||
|
|
|
|||
|
|
@ -359,6 +359,26 @@ LiteLLM is compatible with several SDKs - including OpenAI SDK, Anthropic SDK, M
|
|||
### Deploy with Database
|
||||
##### Docker, Kubernetes, Helm Chart
|
||||
|
||||
:::warning High Traffic Deployments (1000+ RPS)
|
||||
|
||||
If you expect high traffic (1000+ requests per second), **Redis is required** to prevent database connection exhaustion and deadlocks.
|
||||
|
||||
Add this to your config:
|
||||
```yaml
|
||||
general_settings:
|
||||
use_redis_transaction_buffer: true
|
||||
|
||||
litellm_settings:
|
||||
cache: true
|
||||
cache_params:
|
||||
type: redis
|
||||
host: your-redis-host
|
||||
```
|
||||
|
||||
See [Resolve DB Deadlocks](/docs/proxy/db_deadlocks) for details.
|
||||
|
||||
:::
|
||||
|
||||
Requirements:
|
||||
- Need a postgres database (e.g. [Supabase](https://supabase.com/), [Neon](https://neon.tech/), etc) Set `DATABASE_URL=postgresql://<user>:<password>@<host>:<port>/<dbname>` in your env
|
||||
- Set a `LITELLM_MASTER_KEY`, this is your Proxy Admin key - you can use this to create other keys (🚨 must start with `sk-`)
|
||||
|
|
|
|||
117
docs/my-website/docs/proxy/endpoint_activity.md
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
import Image from '@theme/IdealImage';
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Endpoint Activity
|
||||
|
||||
Track and visualize API endpoint usage directly in the dashboard. Monitor endpoint-level activity analytics, spend breakdowns, and performance metrics to understand which endpoints are receiving the most traffic and how they're performing.
|
||||
|
||||
## Overview
|
||||
|
||||
Endpoint Activity enables you to track spend and usage for individual API endpoints automatically. Every time you call an endpoint through the LiteLLM proxy, activity is automatically tracked and aggregated. This allows you to:
|
||||
|
||||
- Track spend per endpoint automatically
|
||||
- View endpoint-level usage analytics in the Admin UI
|
||||
- Monitor token consumption by endpoint
|
||||
- Analyze success and failure rates per endpoint
|
||||
- Identify which endpoints are getting the most activity
|
||||
- View trend data showing endpoint usage over time
|
||||
|
||||
<Image img={require('../../img/ui_endpoint_activity.png')} />
|
||||
|
||||
## How Endpoint Activity Works
|
||||
|
||||
Endpoint activity is **automatically tracked** whenever you make API calls through the LiteLLM proxy. No additional configuration is required - simply call your endpoints as usual and activity will be tracked.
|
||||
|
||||
### Example API Call
|
||||
|
||||
When you make a request to any endpoint, activity is automatically recorded:
|
||||
|
||||
```bash showLineNumbers title="Endpoint activity is automatically tracked"
|
||||
curl -X POST 'http://0.0.0.0:4000/chat/completions' \ # 👈 ENDPOINT AUTOMATICALLY TRACKED
|
||||
--header 'Content-Type: application/json' \
|
||||
--header 'Authorization: Bearer sk-1234' \ # 👈 YOUR PROXY KEY
|
||||
--data '{
|
||||
"model": "gpt-3.5-turbo",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "What is the capital of France?"
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
The endpoint (`/chat/completions`) will be automatically tracked with:
|
||||
|
||||
- Token counts (prompt tokens, completion tokens, total tokens)
|
||||
- Spend for the request
|
||||
- Request status (success or failure)
|
||||
- Timestamp and other metadata
|
||||
|
||||
## How to View Endpoint Activity
|
||||
|
||||
### View Activity in Admin UI
|
||||
|
||||
Navigate to the Endpoint Activity tab in the Admin UI to view endpoint-level analytics:
|
||||
|
||||
#### 1. Access Endpoint Activity
|
||||
|
||||
Go to the Usage page in the Admin UI (`PROXY_BASE_URL/ui/?login=success&page=new_usage`) and click on the **Endpoint Activity** tab.
|
||||
|
||||

|
||||
|
||||
#### 2. View Endpoint Analytics
|
||||
|
||||
The Endpoint Activity dashboard provides:
|
||||
|
||||
- **Endpoint usage table**: View all endpoints with aggregated metrics including:
|
||||
- Total requests (successful and failed)
|
||||
- Success rate percentage
|
||||
- Total tokens consumed
|
||||
- Total spend per endpoint
|
||||
- **Success vs Failed requests chart**: Visualize request success and failure rates by endpoint
|
||||
- **Usage trends**: See how endpoint activity changes over time with daily trend data
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
#### 3. Understand Endpoint Metrics
|
||||
|
||||
Each endpoint displays the following metrics:
|
||||
|
||||
- **Successful Requests**: Number of requests that completed successfully
|
||||
- **Failed Requests**: Number of requests that encountered errors
|
||||
- **Total Requests**: Sum of successful and failed requests
|
||||
- **Success Rate**: Percentage of successful requests
|
||||
- **Total Tokens**: Sum of prompt and completion tokens
|
||||
- **Spend**: Total cost for all requests to that endpoint
|
||||
|
||||
## Use Cases
|
||||
|
||||
### Performance Monitoring
|
||||
|
||||
Monitor endpoint health and performance:
|
||||
|
||||
- Identify endpoints with high failure rates
|
||||
- Track which endpoints are receiving the most traffic
|
||||
- Monitor token consumption patterns by endpoint
|
||||
- Detect anomalies in endpoint usage
|
||||
|
||||
### Cost Optimization
|
||||
|
||||
Understand spend distribution across endpoints:
|
||||
|
||||
- Identify high-cost endpoints
|
||||
- Optimize expensive endpoints
|
||||
- Allocate budget based on endpoint usage
|
||||
- Track cost trends over time
|
||||
|
||||
---
|
||||
|
||||
## Related Features
|
||||
|
||||
- [Customer Usage](./customer_usage.md) - Track spend and usage for individual customers
|
||||
- [Cost Tracking](./cost_tracking.md) - Comprehensive cost tracking and analytics
|
||||
- [Spend Logs](./spend_logs.md) - Detailed request-level spend logs
|
||||
273
docs/my-website/docs/proxy/fallback_management.md
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
# [New] Fallback Management Endpoints
|
||||
|
||||
Dedicated endpoints for managing model fallbacks separately from the general configuration.
|
||||
|
||||
## Overview
|
||||
|
||||
These endpoints allow you to configure, retrieve, and delete fallback models without modifying the entire proxy configuration. This provides a cleaner and safer way to manage fallbacks compared to using the `/config/update` endpoint.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Database storage must be enabled: Set `STORE_MODEL_IN_DB=True` in your environment
|
||||
- Models must exist in the router before configuring fallbacks
|
||||
|
||||
## Endpoints
|
||||
|
||||
### POST /fallback
|
||||
|
||||
Create or update fallbacks for a specific model.
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"model": "gpt-3.5-turbo",
|
||||
"fallback_models": ["gpt-4", "claude-3-haiku"],
|
||||
"fallback_type": "general"
|
||||
}
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
- `model` (string, required): The primary model name to configure fallbacks for
|
||||
- `fallback_models` (array of strings, required): List of fallback model names in priority order
|
||||
- `fallback_type` (string, optional): Type of fallback. Options:
|
||||
- `"general"` (default): Standard fallbacks for any error
|
||||
- `"context_window"`: Fallbacks for context window exceeded errors
|
||||
- `"content_policy"`: Fallbacks for content policy violations
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"model": "gpt-3.5-turbo",
|
||||
"fallback_models": ["gpt-4", "claude-3-haiku"],
|
||||
"fallback_type": "general",
|
||||
"message": "Fallback configuration created successfully"
|
||||
}
|
||||
```
|
||||
|
||||
**Example using cURL:**
|
||||
```bash
|
||||
curl -X POST "http://localhost:4000/fallback" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "gpt-3.5-turbo",
|
||||
"fallback_models": ["gpt-4", "claude-3-haiku"],
|
||||
"fallback_type": "general"
|
||||
}'
|
||||
```
|
||||
|
||||
**Example using Python:**
|
||||
```python
|
||||
import requests
|
||||
|
||||
response = requests.post(
|
||||
"http://localhost:4000/fallback",
|
||||
headers={
|
||||
"Authorization": "Bearer sk-1234",
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
json={
|
||||
"model": "gpt-3.5-turbo",
|
||||
"fallback_models": ["gpt-4", "claude-3-haiku"],
|
||||
"fallback_type": "general"
|
||||
}
|
||||
)
|
||||
|
||||
print(response.json())
|
||||
```
|
||||
|
||||
### GET /fallback/{model}
|
||||
|
||||
Get fallback configuration for a specific model.
|
||||
|
||||
**Parameters:**
|
||||
- `model` (path parameter, required): The model name to get fallbacks for
|
||||
- `fallback_type` (query parameter, optional): Type of fallback to retrieve (default: "general")
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"model": "gpt-3.5-turbo",
|
||||
"fallback_models": ["gpt-4", "claude-3-haiku"],
|
||||
"fallback_type": "general"
|
||||
}
|
||||
```
|
||||
|
||||
**Example using cURL:**
|
||||
```bash
|
||||
curl -X GET "http://localhost:4000/fallback/gpt-3.5-turbo?fallback_type=general" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
```
|
||||
|
||||
**Example using Python:**
|
||||
```python
|
||||
import requests
|
||||
|
||||
response = requests.get(
|
||||
"http://localhost:4000/fallback/gpt-3.5-turbo",
|
||||
headers={"Authorization": "Bearer sk-1234"},
|
||||
params={"fallback_type": "general"}
|
||||
)
|
||||
|
||||
print(response.json())
|
||||
```
|
||||
|
||||
### DELETE /fallback/{model}
|
||||
|
||||
Delete fallback configuration for a specific model.
|
||||
|
||||
**Parameters:**
|
||||
- `model` (path parameter, required): The model name to delete fallbacks for
|
||||
- `fallback_type` (query parameter, optional): Type of fallback to delete (default: "general")
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"model": "gpt-3.5-turbo",
|
||||
"fallback_type": "general",
|
||||
"message": "Fallback configuration deleted successfully"
|
||||
}
|
||||
```
|
||||
|
||||
**Example using cURL:**
|
||||
```bash
|
||||
curl -X DELETE "http://localhost:4000/fallback/gpt-3.5-turbo?fallback_type=general" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
```
|
||||
|
||||
**Example using Python:**
|
||||
```python
|
||||
import requests
|
||||
|
||||
response = requests.delete(
|
||||
"http://localhost:4000/fallback/gpt-3.5-turbo",
|
||||
headers={"Authorization": "Bearer sk-1234"},
|
||||
params={"fallback_type": "general"}
|
||||
)
|
||||
|
||||
print(response.json())
|
||||
```
|
||||
|
||||
### Test fallback
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="proxy" label="PROXY">
|
||||
|
||||
```bash
|
||||
curl -X POST 'http://0.0.0.0:4000/chat/completions' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'Authorization: Bearer sk-1234' \
|
||||
-d '{
|
||||
"model": "gpt-3.5-turbo",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "ping"
|
||||
}
|
||||
],
|
||||
"mock_testing_fallbacks": true
|
||||
}
|
||||
'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
|
||||
## Validation
|
||||
|
||||
The endpoints perform the following validations:
|
||||
|
||||
1. **Model Existence**: Verifies that the primary model exists in the router
|
||||
2. **Fallback Model Existence**: Ensures all fallback models exist in the router
|
||||
3. **No Self-Fallback**: Prevents a model from being its own fallback
|
||||
4. **No Duplicates**: Ensures no duplicate models in the fallback list
|
||||
5. **Database Enabled**: Requires `STORE_MODEL_IN_DB=True` to be set
|
||||
|
||||
## Error Responses
|
||||
|
||||
### 400 Bad Request
|
||||
```json
|
||||
{
|
||||
"detail": {
|
||||
"error": "Invalid fallback models: ['non-existent-model']",
|
||||
"available_models": ["gpt-3.5-turbo", "gpt-4", "claude-3-haiku"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 404 Not Found
|
||||
```json
|
||||
{
|
||||
"detail": {
|
||||
"error": "Model 'gpt-3.5-turbo' not found in router",
|
||||
"available_models": ["gpt-4", "claude-3-haiku"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 500 Internal Server Error
|
||||
```json
|
||||
{
|
||||
"detail": {
|
||||
"error": "Router not initialized"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Fallback Types Explained
|
||||
|
||||
### General Fallbacks
|
||||
Used for any type of error that occurs during model invocation. This is the most common type of fallback.
|
||||
|
||||
**Use Case:** When a model is unavailable, rate-limited, or returns an error.
|
||||
|
||||
```json
|
||||
{
|
||||
"model": "gpt-3.5-turbo",
|
||||
"fallback_models": ["gpt-4", "claude-3-haiku"],
|
||||
"fallback_type": "general"
|
||||
}
|
||||
```
|
||||
|
||||
### Context Window Fallbacks
|
||||
Specifically triggered when a context window exceeded error occurs.
|
||||
|
||||
**Use Case:** When the input is too long for the primary model, fallback to a model with a larger context window.
|
||||
|
||||
```json
|
||||
{
|
||||
"model": "gpt-3.5-turbo",
|
||||
"fallback_models": ["gpt-4-32k", "claude-3-opus"],
|
||||
"fallback_type": "context_window"
|
||||
}
|
||||
```
|
||||
|
||||
### Content Policy Fallbacks
|
||||
Specifically triggered when content policy violations occur.
|
||||
|
||||
**Use Case:** When the primary model rejects content due to safety filters, fallback to a model with different content policies.
|
||||
|
||||
```json
|
||||
{
|
||||
"model": "gpt-4",
|
||||
"fallback_models": ["claude-3-haiku"],
|
||||
"fallback_type": "content_policy"
|
||||
}
|
||||
```
|
||||
|
||||
## Benefits Over /config/update
|
||||
|
||||
1. **Safety**: Only modifies fallback configuration, won't accidentally change other settings
|
||||
2. **Simplicity**: Focused API with clear validation messages
|
||||
3. **Granularity**: Manage fallbacks per model and per type
|
||||
4. **Validation**: Comprehensive checks ensure configuration is valid before applying
|
||||
5. **Clarity**: Clear error messages with available models listed
|
||||
|
||||
## Notes
|
||||
|
||||
- Fallbacks are triggered after the configured number of retries fails
|
||||
- Fallbacks are attempted in the order specified in `fallback_models`
|
||||
- The maximum number of fallbacks attempted is controlled by the router's `max_fallbacks` setting
|
||||
- Changes take effect immediately and are persisted to the database
|
||||
|
|
@ -8,13 +8,7 @@ Use [Qualifire](https://qualifire.ai) to evaluate LLM outputs for quality, safet
|
|||
|
||||
## Quick Start
|
||||
|
||||
### 1. Install the Qualifire SDK
|
||||
|
||||
```bash
|
||||
pip install qualifire
|
||||
```
|
||||
|
||||
### 2. Define Guardrails on your LiteLLM config.yaml
|
||||
### 1. Define Guardrails on your LiteLLM config.yaml
|
||||
|
||||
Define your guardrails under the `guardrails` section:
|
||||
|
||||
|
|
@ -61,13 +55,13 @@ guardrails:
|
|||
- `post_call` Run **after** LLM call, on **input & output**
|
||||
- `during_call` Run **during** LLM call, on **input**. Same as `pre_call` but runs in parallel as LLM call. Response not returned until guardrail check completes
|
||||
|
||||
### 3. Start LiteLLM Gateway
|
||||
### 2. Start LiteLLM Gateway
|
||||
|
||||
```shell
|
||||
litellm --config config.yaml --detailed_debug
|
||||
```
|
||||
|
||||
### 4. Test request
|
||||
### 3. Test request
|
||||
|
||||
**[Langchain, OpenAI SDK Usage Examples](../proxy/user_keys#request-format)**
|
||||
|
||||
|
|
@ -142,7 +136,7 @@ guardrails:
|
|||
evaluation_id: eval_abc123 # Your evaluation ID from Qualifire dashboard
|
||||
```
|
||||
|
||||
When `evaluation_id` is provided, LiteLLM will use `invoke_evaluation()` instead of `evaluate()`, running the pre-configured evaluation from your dashboard.
|
||||
When `evaluation_id` is provided, LiteLLM will use the invoke evaluation API endpoint instead of the evaluate endpoint, running the pre-configured evaluation from your dashboard.
|
||||
|
||||
## Available Checks
|
||||
|
||||
|
|
@ -213,19 +207,19 @@ guardrails:
|
|||
|
||||
### Parameter Reference
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| ------------------------------ | ----------- | --------------------------- | -------------------------------------------------------- |
|
||||
| `api_key` | `str` | `QUALIFIRE_API_KEY` env var | Your Qualifire API key |
|
||||
| `api_base` | `str` | `None` | Custom API base URL (optional) |
|
||||
| `evaluation_id` | `str` | `None` | Pre-configured evaluation ID from Qualifire dashboard |
|
||||
| `prompt_injections` | `bool` | `true` (if no other checks) | Enable prompt injection detection |
|
||||
| `hallucinations_check` | `bool` | `None` | Enable hallucination detection |
|
||||
| `grounding_check` | `bool` | `None` | Enable grounding verification |
|
||||
| `pii_check` | `bool` | `None` | Enable PII detection |
|
||||
| `content_moderation_check` | `bool` | `None` | Enable content moderation |
|
||||
| `tool_selection_quality_check` | `bool` | `None` | Enable tool selection quality check |
|
||||
| `assertions` | `List[str]` | `None` | Custom assertions to validate |
|
||||
| `on_flagged` | `str` | `"block"` | Action when content is flagged: `"block"` or `"monitor"` |
|
||||
| Parameter | Type | Default | Description |
|
||||
| ------------------------------ | ----------- | ---------------------------- | -------------------------------------------------------- |
|
||||
| `api_key` | `str` | `QUALIFIRE_API_KEY` env var | Your Qualifire API key |
|
||||
| `api_base` | `str` | `https://proxy.qualifire.ai` | Custom API base URL (optional) |
|
||||
| `evaluation_id` | `str` | `None` | Pre-configured evaluation ID from Qualifire dashboard |
|
||||
| `prompt_injections` | `bool` | `true` (if no other checks) | Enable prompt injection detection |
|
||||
| `hallucinations_check` | `bool` | `None` | Enable hallucination detection |
|
||||
| `grounding_check` | `bool` | `None` | Enable grounding verification |
|
||||
| `pii_check` | `bool` | `None` | Enable PII detection |
|
||||
| `content_moderation_check` | `bool` | `None` | Enable content moderation |
|
||||
| `tool_selection_quality_check` | `bool` | `None` | Enable tool selection quality check |
|
||||
| `assertions` | `List[str]` | `None` | Custom assertions to validate |
|
||||
| `on_flagged` | `str` | `"block"` | Action when content is flagged: `"block"` or `"monitor"` |
|
||||
|
||||
### Default Behavior
|
||||
|
||||
|
|
@ -261,4 +255,3 @@ This evaluates whether the LLM selected the appropriate tools and provided corre
|
|||
|
||||
- [Qualifire Documentation](https://docs.qualifire.ai)
|
||||
- [Qualifire Dashboard](https://app.qualifire.ai)
|
||||
- [Qualifire Python SDK](https://github.com/qualifire-dev/qualifire-python-sdk)
|
||||
|
|
|
|||
|
|
@ -264,8 +264,15 @@ model_list:
|
|||
model: azure/gpt-4-fallback
|
||||
api_key: os.environ/AZURE_API_KEY_2
|
||||
order: 2 # 👈 Used when order=1 is unavailable
|
||||
|
||||
router_settings:
|
||||
enable_pre_call_checks: true # 👈 Required for 'order' to work
|
||||
```
|
||||
|
||||
:::important
|
||||
The `order` parameter requires `enable_pre_call_checks: true` in `router_settings`.
|
||||
:::
|
||||
|
||||
If `order=1` deployment is unavailable (e.g., rate-limited), the router falls back to `order=2` deployments.
|
||||
|
||||
### When You'll See Load Balancing in Action
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ Set `litellm.turn_off_message_logging=True` This will prevent the messages and r
|
|||
|
||||
<TabItem value="global" label="Global">
|
||||
|
||||
**1. Setup config.yaml **
|
||||
**1. Setup config.yaml**
|
||||
```yaml
|
||||
model_list:
|
||||
- model_name: gpt-3.5-turbo
|
||||
|
|
@ -1827,6 +1827,64 @@ This approach allows you to:
|
|||
- Share callbacks across different environments
|
||||
- Version control callback files in cloud storage
|
||||
|
||||
#### Step 2c - Mounting Custom Callbacks in Helm/Kubernetes (Alternative)
|
||||
|
||||
When deploying with Helm or Kubernetes, you can mount custom callback Python files alongside your `config.yaml` using `subPath` to avoid overwriting the config directory.
|
||||
|
||||
**The Problem:**
|
||||
Mounting a volume to a directory (e.g., `/app/`) would normally hide all existing files in that directory, including your `config.yaml`.
|
||||
|
||||
**The Solution:**
|
||||
Use `subPath` in your `volumeMounts` to mount individual files without overwriting the entire directory.
|
||||
|
||||
**Example - Helm values.yaml:**
|
||||
|
||||
```yaml
|
||||
# values.yaml
|
||||
volumes:
|
||||
- name: callback-files
|
||||
configMap:
|
||||
name: litellm-callback-files
|
||||
|
||||
volumeMounts:
|
||||
- name: callback-files
|
||||
mountPath: /app/custom_callbacks.py # Mount to specific FILE path
|
||||
subPath: custom_callbacks.py # Required to avoid overwriting directory
|
||||
```
|
||||
|
||||
**Create the ConfigMap with your callback file:**
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: litellm-callback-files
|
||||
data:
|
||||
custom_callbacks.py: |
|
||||
from litellm.integrations.custom_logger import CustomLogger
|
||||
|
||||
class MyCustomHandler(CustomLogger):
|
||||
async def async_log_success_event(self, kwargs, response_obj, start_time, end_time):
|
||||
print(f"Success! Model: {kwargs.get('model')}")
|
||||
|
||||
proxy_handler_instance = MyCustomHandler()
|
||||
```
|
||||
|
||||
**Reference in your config.yaml:**
|
||||
|
||||
```yaml
|
||||
litellm_settings:
|
||||
callbacks: custom_callbacks.proxy_handler_instance
|
||||
```
|
||||
|
||||
**How it works:**
|
||||
1. The `subPath` parameter tells Kubernetes to mount only the specific file
|
||||
2. This places `custom_callbacks.py` in `/app/` alongside your existing `config.yaml`
|
||||
3. LiteLLM automatically finds the callback file in the same directory as the config
|
||||
4. No files are overwritten or hidden
|
||||
|
||||
**Note:** You can mount multiple callback files by adding more `volumeMounts` entries, each with its own `subPath`.
|
||||
|
||||
#### Step 3 - Start proxy + test request
|
||||
|
||||
```shell
|
||||
|
|
|
|||
|
|
@ -165,6 +165,7 @@ general_settings:
|
|||
target: string # Target URL for forwarding
|
||||
auth: boolean # Enable LiteLLM authentication (Enterprise)
|
||||
forward_headers: boolean # Forward all incoming headers
|
||||
include_subpath: boolean # If true, forwards requests to sub-paths (default: false)
|
||||
headers: # Custom headers to add
|
||||
Authorization: string # Auth header for target API
|
||||
content-type: string # Request content type
|
||||
|
|
@ -181,6 +182,23 @@ general_settings:
|
|||
- **LANGFUSE_PUBLIC_KEY/SECRET_KEY**: For Langfuse integration
|
||||
- **Custom headers**: Any additional key-value pairs
|
||||
|
||||
### Sub-path Routing
|
||||
|
||||
By default, pass-through endpoints only match the **exact path** specified. To forward requests to sub-paths, set `include_subpath: true`:
|
||||
|
||||
```yaml
|
||||
general_settings:
|
||||
pass_through_endpoints:
|
||||
- path: "/custom-api" # Any path prefix you choose
|
||||
target: "https://api.example.com"
|
||||
include_subpath: true # Forward /custom-api/*, not just /custom-api
|
||||
```
|
||||
|
||||
| Setting | Behavior |
|
||||
|---------|----------|
|
||||
| `include_subpath: false` (default) | Only `/custom-api` is forwarded |
|
||||
| `include_subpath: true` | `/custom-api`, `/custom-api/v1/chat`, `/custom-api/anything` are all forwarded |
|
||||
|
||||
---
|
||||
|
||||
## Advanced: Custom Adapters
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@ general_settings:
|
|||
# Optional: set how frequently cleanup should run - default is daily
|
||||
maximum_spend_logs_retention_interval: "1d" # Run cleanup daily
|
||||
|
||||
# Optional: set exact time for cleanup (Cron syntax)
|
||||
maximum_spend_logs_cleanup_cron: "0 4 * * *" # Run at 04:00 AM daily
|
||||
|
||||
litellm_settings:
|
||||
cache: true
|
||||
cache_params:
|
||||
|
|
@ -51,6 +54,15 @@ How long logs should be kept before deletion. Supported formats:
|
|||
|
||||
How often the cleanup job should run. Uses the same format as above. If not set, cleanup will run every 24 hours if and only if `maximum_spend_logs_retention_period` is set.
|
||||
|
||||
#### `maximum_spend_logs_cleanup_cron` (optional)
|
||||
|
||||
Schedule the cleanup using standard cron syntax. This takes precedence over `maximum_spend_logs_retention_interval`.
|
||||
|
||||
Examples:
|
||||
- `"0 4 * * *"` – Run at 04:00 AM daily
|
||||
- `"0 0 * * 0"` – Run at midnight every Sunday
|
||||
- `"*/30 * * * *"` – Run every 30 minutes
|
||||
|
||||
## How it works
|
||||
|
||||
### Step 1. Lock Acquisition (Optional with Redis)
|
||||
|
|
|
|||
|
|
@ -861,9 +861,13 @@ model_list = [
|
|||
},
|
||||
]
|
||||
|
||||
router = Router(model_list=model_list)
|
||||
router = Router(model_list=model_list, enable_pre_call_checks=True) # 👈 Required for 'order' to work
|
||||
```
|
||||
|
||||
:::important
|
||||
The `order` parameter requires `enable_pre_call_checks=True` to be set on the Router.
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="proxy" label="PROXY">
|
||||
|
||||
|
|
@ -880,6 +884,9 @@ model_list:
|
|||
model: azure/gpt-4-fallback
|
||||
api_key: os.environ/AZURE_API_KEY_2
|
||||
order: 2 # 👈 Used when order=1 is unavailable
|
||||
|
||||
router_settings:
|
||||
enable_pre_call_checks: true # 👈 Required for 'order' to work
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,60 @@
|
|||
# Support & Talk with founders
|
||||
# Troubleshooting & Support
|
||||
|
||||
## Information to Provide When Seeking Help
|
||||
|
||||
When reporting issues, please include as much of the following as possible. It's okay if you can't provide everything—especially in production scenarios where the trigger might be unknown. Sharing most of this information will help us assist you more effectively.
|
||||
|
||||
### 1. LiteLLM Configuration File
|
||||
|
||||
Your `config.yaml` file (redact sensitive info like API keys). Include number of workers if not in config.
|
||||
|
||||
### 2. Initialization Command
|
||||
|
||||
The command used to start LiteLLM (e.g., `litellm --config config.yaml --num_workers 8 --detailed_debug`).
|
||||
|
||||
### 3. LiteLLM Version
|
||||
|
||||
- Current version
|
||||
- Version when the issue first appeared (if different)
|
||||
- If upgraded, the version changed from → to
|
||||
|
||||
### 4. Environment Variables
|
||||
|
||||
Non-sensitive environment variables not in your config (e.g., `NUM_WORKERS`, `LITELLM_LOG`, `LITELLM_MODE`). Do not include passwords or API keys.
|
||||
|
||||
### 5. Server Specifications
|
||||
|
||||
CPU cores, RAM, OS, number of instances/replicas, etc.
|
||||
|
||||
### 6. Database and Redis Usage
|
||||
|
||||
- **Database:** Using database? (`DATABASE_URL` set), database type and version
|
||||
- **Redis:** Using Redis? Redis version, configuration type (Standalone/Cluster/Sentinel).
|
||||
|
||||
### 7. Endpoints
|
||||
|
||||
The endpoint(s) you're using that are experiencing issues (e.g., `/chat/completions`, `/embeddings`).
|
||||
|
||||
### 8. Request Example
|
||||
|
||||
A realistic example of the request causing issues, including expected vs. actual response and any error messages.
|
||||
|
||||
### 9. Error Logs, Stack Traces, and Metrics
|
||||
|
||||
Full error logs, stack traces, and any images from service metrics (CPU, memory, request rates, etc.) that might help diagnose the issue.
|
||||
|
||||
---
|
||||
|
||||
## Support Channels
|
||||
|
||||
[Schedule Demo 👋](https://calendly.com/d/4mp-gd3-k5k/berriai-1-1-onboarding-litellm-hosted-version)
|
||||
|
||||
[Community Discord 💭](https://discord.gg/wuPM9dRgDw)
|
||||
[Community Slack 💭](https://www.litellm.ai/support)
|
||||
|
||||
Our numbers 📞 +1 (770) 8783-106 / +1 (412) 618-6238
|
||||
Our numbers 📞 +1 (770) 8783-106 / +1 (412) 618-6238
|
||||
|
||||
Our emails ✉️ ishaan@berri.ai / krrish@berri.ai
|
||||
|
||||
[](https://wa.link/huol9n) [](https://discord.gg/wuPM9dRgDw)
|
||||
[](https://wa.link/huol9n) [](https://discord.gg/wuPM9dRgDw)
|
||||
|
||||
|
|
|
|||
31
docs/my-website/docs/troubleshoot/cpu_issues.md
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# CPU Issue Classification & Reproduction
|
||||
|
||||
## 1. Classify the CPU Issue
|
||||
|
||||
Select the options that best describes the CPU behavior observed.
|
||||
|
||||
- [ ] CPU scales with traffic (RPS-driven)
|
||||
- [ ] CPU increases without a traffic increase
|
||||
- [ ] CPU increases after a LiteLLM upgrade
|
||||
|
||||
## 2. Can you reproduce the issue?
|
||||
|
||||
Before escalating, verify whether the CPU issue can be reproduced in a test environment that mirrors your production setup.
|
||||
|
||||
If reproducible, provide **detailed reproduction steps** along with any relevant requests or configuration used.
|
||||
For guidance on the type of information we're looking for, see the [LiteLLM Troubleshooting Guide](../troubleshoot).
|
||||
|
||||
## 3. Issue Cannot Be Reproduced
|
||||
|
||||
If the CPU issue cannot be reproduced in a test environment that mirrors your production setup, please provide:
|
||||
|
||||
1. **Information from Section 1 and 2**
|
||||
- CPU classification (Section 1)
|
||||
- Reproduction attempts and environment details (Section 2)
|
||||
|
||||
2. **Additional context** to help investigate:
|
||||
- **Workload:** A realistic sample of requests processed before and during the spike, including any recent configuration changes.
|
||||
- **Metrics:** CPU usage, P50/P99 latency, memory usage. Please include **screenshots** of the metrics whenever possible.
|
||||
- **Logs / Alerts:** Any relevant logs or alerts captured **before and during the spike**.
|
||||
|
||||
> Providing this information allows the team to analyze patterns, correlate spikes with traffic or configuration, and attempt to reproduce the issue internally. Without it, our engineers won't have enough information to look into the problem.
|
||||
37
docs/my-website/docs/troubleshoot/memory_issues.md
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# Memory Issue Classification & Reproduction
|
||||
|
||||
## 1. Classify the Memory Issue
|
||||
|
||||
Select the option(s) that best describe the memory behavior observed:
|
||||
|
||||
- [ ] Memory scales with traffic (RPS-driven)
|
||||
- [ ] Memory increases without a traffic increase
|
||||
- [ ] Memory increases after a LiteLLM upgrade
|
||||
- [ ] Memory leak (memory continuously grows over time)
|
||||
- [ ] Out of Memory (OOM) events or pod restarts
|
||||
|
||||
---
|
||||
|
||||
## 2. Can you reproduce the issue?
|
||||
|
||||
Before escalating, verify whether the memory or OOM issue can be reproduced in a test environment that mirrors your production deployment.
|
||||
|
||||
If reproducible, provide **detailed reproduction steps** along with any relevant requests, workloads, or configuration used.
|
||||
For guidance on the type of information we’re looking for, see the [LiteLLM Troubleshooting Guide](../troubleshoot).
|
||||
|
||||
---
|
||||
|
||||
## 3. Issue Cannot Be Reproduced
|
||||
|
||||
If the memory or OOM issue cannot be reproduced in a test environment that mirrors production, please provide:
|
||||
|
||||
1. **Information from Sections 1 and 2**
|
||||
- Memory/issue classification (Section 1)
|
||||
- Reproduction attempts and environment details (Section 2)
|
||||
|
||||
2. **Additional context** to help investigate:
|
||||
- **Workload:** A realistic sample of requests processed before and during the spike, including any recent configuration changes.
|
||||
- **Metrics:** Memory usage, CPU usage, P50/P99 latency, and any pod restarts or OOM events. Please include **screenshots** of the metrics whenever possible.
|
||||
- **Logs / Alerts:** Any relevant logs or alerts captured **before and during the spike**, including OOM errors or stack traces if available.
|
||||
|
||||
> Providing this information allows the team to analyze patterns, correlate memory spikes or OOMs with traffic or configuration, and attempt to reproduce the issue internally. Without it, our engineers will not have enough information to investigate the problem.
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
# Claude Code - Granular Cost Tracking
|
||||
|
||||
Track Claude Code usage by customer or tags using LiteLLM proxy. This enables granular cost attribution for billing, budgeting, and analytics.
|
||||
|
||||
## How It Works
|
||||
|
||||
Claude Code supports custom headers via `ANTHROPIC_CUSTOM_HEADERS`. LiteLLM automatically tracks requests with specific headers for cost attribution.
|
||||
|
||||
## Tracking Options
|
||||
|
||||
Choose how you want to attribute costs:
|
||||
|
||||
| Track By | Header | Use Case |
|
||||
|----------|--------|----------|
|
||||
| Customer | `x-litellm-customer-id` | Bill customers, per-user budgets |
|
||||
| Tags | `x-litellm-tags` | Project tracking, cost centers, environments |
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Description | Example |
|
||||
|----------|-------------|---------|
|
||||
| `ANTHROPIC_BASE_URL` | LiteLLM proxy URL | `http://localhost:4000` |
|
||||
| `ANTHROPIC_API_KEY` | LiteLLM API key | `sk-1234` |
|
||||
| `ANTHROPIC_CUSTOM_HEADERS` | Custom headers (`header-name: value` format) | See examples below |
|
||||
|
||||
## Option 1: Track by Customer
|
||||
|
||||
Use this to attribute costs to specific customers or end-users.
|
||||
|
||||
```bash
|
||||
export ANTHROPIC_BASE_URL=http://localhost:4000
|
||||
export ANTHROPIC_API_KEY=sk-1234
|
||||
export ANTHROPIC_CUSTOM_HEADERS="x-litellm-customer-id: claude-ishaan-local"
|
||||
```
|
||||
|
||||
## Option 2: Track by Tags
|
||||
|
||||
Use this to attribute costs to projects, cost centers, or environments. Pass comma-separated tags.
|
||||
|
||||
```bash
|
||||
export ANTHROPIC_BASE_URL=http://localhost:4000
|
||||
export ANTHROPIC_API_KEY=sk-1234
|
||||
export ANTHROPIC_CUSTOM_HEADERS="x-litellm-tags: project:acme,env:prod,team:backend"
|
||||
```
|
||||
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Set Environment Variables
|
||||
|
||||
```bash
|
||||
export ANTHROPIC_BASE_URL=http://localhost:4000
|
||||
export ANTHROPIC_API_KEY=sk-1234
|
||||
export ANTHROPIC_CUSTOM_HEADERS="x-litellm-customer-id: claude-ishaan-local"
|
||||
```
|
||||
|
||||
### 2. Use Claude Code
|
||||
|
||||
```bash
|
||||
claude
|
||||
```
|
||||
|
||||
All requests will now be tracked under the customer ID `claude-ishaan-local`.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### 3. View Usage in LiteLLM UI
|
||||
|
||||
Navigate to the **Logs** tab in the LiteLLM UI.
|
||||
|
||||

|
||||
|
||||
Click on a request to see details.
|
||||
|
||||

|
||||
|
||||
Filter by customer ID to see all requests for that customer.
|
||||
|
||||

|
||||
|
||||
## Supported Headers
|
||||
|
||||
| Header | Description |
|
||||
|--------|-------------|
|
||||
| `x-litellm-customer-id` | Track by customer/end-user ID |
|
||||
| `x-litellm-end-user-id` | Alternative customer ID header |
|
||||
| `x-litellm-tags` | Comma-separated tags for cost attribution |
|
||||
|
||||
## Related
|
||||
|
||||
- [Claude Code Quickstart](./claude_responses_api.md)
|
||||
- [Customer Budgets](../proxy/customers.md)
|
||||
- [Tag Budgets](../proxy/tag_budgets.md)
|
||||
- [Track Usage for Coding Tools](./cost_tracking_coding.md)
|
||||
|
||||
93
docs/my-website/docs/tutorials/claude_mcp.md
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Use Claude Code with MCPs
|
||||
|
||||
This tutorial shows how to connect MCP servers to Claude Code via LiteLLM Proxy.
|
||||
|
||||
Note: LiteLLM supports OAuth for MCP servers as well. [Learn more](https://docs.litellm.ai/docs/mcp#mcp-oauth)
|
||||
|
||||
## Connecting MCP Servers
|
||||
|
||||
You can also connect MCP servers to Claude Code via LiteLLM Proxy.
|
||||
|
||||
|
||||
1. Add the MCP server to your `config.yaml`
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="github" label="GitHub MCP">
|
||||
|
||||
In this example, we'll add the Github MCP server to our `config.yaml`
|
||||
|
||||
```yaml title="config.yaml" showLineNumbers
|
||||
mcp_servers:
|
||||
github_mcp:
|
||||
url: "https://api.githubcopilot.com/mcp"
|
||||
auth_type: oauth2
|
||||
client_id: os.environ/GITHUB_OAUTH_CLIENT_ID
|
||||
client_secret: os.environ/GITHUB_OAUTH_CLIENT_SECRET
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="atlassian" label="Atlassian MCP">
|
||||
|
||||
In this example, we'll add the Atlassian MCP server to our `config.yaml`
|
||||
|
||||
```yaml title="config.yaml" showLineNumbers
|
||||
atlassian_mcp:
|
||||
server_id: atlassian_mcp_id
|
||||
url: "https://mcp.atlassian.com/v1/sse"
|
||||
transport: "sse"
|
||||
auth_type: oauth2
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
2. Start LiteLLM Proxy
|
||||
|
||||
```bash
|
||||
litellm --config /path/to/config.yaml
|
||||
|
||||
# RUNNING on http://0.0.0.0:4000
|
||||
```
|
||||
|
||||
3. Use the MCP server in Claude Code
|
||||
|
||||
```bash
|
||||
claude mcp add --transport http litellm_proxy http://0.0.0.0:4000/github_mcp/mcp --header "Authorization: Bearer sk-LITELLM_VIRTUAL_KEY"
|
||||
```
|
||||
|
||||
For MCP servers that require dynamic client registration (such as Atlassian), please set `x-litellm-api-key: Bearer sk-LITELLM_VIRTUAL_KEY` instead of using `Authorization: Bearer LITELLM_VIRTUAL_KEY`.
|
||||
|
||||
4. Authenticate via Claude Code
|
||||
|
||||
a. Start Claude Code
|
||||
|
||||
```bash
|
||||
claude
|
||||
```
|
||||
|
||||
b. Authenticate via Claude Code
|
||||
|
||||
```bash
|
||||
/mcp
|
||||
```
|
||||
|
||||
c. Select the MCP server
|
||||
|
||||
```bash
|
||||
> litellm_proxy
|
||||
```
|
||||
|
||||
d. Start Oauth flow via Claude Code
|
||||
|
||||
```bash
|
||||
> 1. Authenticate
|
||||
2. Reconnect
|
||||
3. Disable
|
||||
```
|
||||
|
||||
e. Once completed, you should see this success message:
|
||||
|
||||
<img src={require('../../img/oauth_2_success.png').default} alt="OAuth 2.0 Success" style={{ width: '500px', height: 'auto' }} />
|
||||
316
docs/my-website/docs/tutorials/claude_non_anthropic_models.md
Normal file
|
|
@ -0,0 +1,316 @@
|
|||
import Image from '@theme/IdealImage';
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Use Claude Code with Non-Anthropic Models
|
||||
|
||||
This tutorial shows how to use Claude Code with non-Anthropic models like OpenAI, Gemini, and other LLM providers through LiteLLM proxy.
|
||||
|
||||
:::info
|
||||
|
||||
LiteLLM automatically translates between different provider formats, allowing you to use any supported LLM provider with Claude Code while maintaining the Anthropic Messages API format.
|
||||
|
||||
:::
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) installed
|
||||
- API keys for your chosen providers (OpenAI, Vertex AI, etc.)
|
||||
|
||||
## Installation
|
||||
|
||||
First, install LiteLLM with proxy support:
|
||||
|
||||
```bash
|
||||
pip install 'litellm[proxy]'
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### 1. Setup config.yaml
|
||||
|
||||
Create a configuration file with your preferred non-Anthropic models:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="openai" label="OpenAI">
|
||||
|
||||
```yaml
|
||||
model_list:
|
||||
# OpenAI GPT-4o
|
||||
- model_name: gpt-4o
|
||||
litellm_params:
|
||||
model: openai/gpt-4o
|
||||
api_key: os.environ/OPENAI_API_KEY
|
||||
|
||||
# OpenAI GPT-4o-mini
|
||||
- model_name: gpt-4o-mini
|
||||
litellm_params:
|
||||
model: openai/gpt-4o-mini
|
||||
api_key: os.environ/OPENAI_API_KEY
|
||||
```
|
||||
|
||||
Set your environment variables:
|
||||
|
||||
```bash
|
||||
export OPENAI_API_KEY="your-openai-api-key"
|
||||
export LITELLM_MASTER_KEY="sk-1234567890" # Generate a secure key
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="gemini" label="Google AI Studio">
|
||||
|
||||
```yaml
|
||||
model_list:
|
||||
# Google Gemini
|
||||
- model_name: gemini-3.0-flash-exp
|
||||
litellm_params:
|
||||
model: gemini/gemini-3.0-flash-exp
|
||||
api_key: os.environ/GEMINI_API_KEY
|
||||
```
|
||||
|
||||
Set your environment variables:
|
||||
|
||||
```bash
|
||||
export GEMINI_API_KEY="your-gemini-api-key"
|
||||
export LITELLM_MASTER_KEY="sk-1234567890" # Generate a secure key
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="vertex_ai" label="Vertex AI">
|
||||
|
||||
```yaml
|
||||
model_list:
|
||||
# Google Gemini
|
||||
- model_name: vertex-gemini-3-flash-preview
|
||||
litellm_params:
|
||||
model: vertex_ai/gemini-3-flash-preview
|
||||
vertex_credentials: os.environ/VERTEX_FILE_PATH_ENV_VAR # os.environ["VERTEX_FILE_PATH_ENV_VAR"] = "/path/to/service_account.json"
|
||||
vertex_project: "my-test-project"
|
||||
vertex_location: "us-east-1"
|
||||
|
||||
# Anthropic Claude
|
||||
- model_name: anthropic-vertex
|
||||
litellm_params:
|
||||
model: vertex_ai/claude-3-sonnet@20240229
|
||||
vertex_ai_project: "my-test-project"
|
||||
vertex_ai_location: "us-east-1"
|
||||
vertex_credentials: os.environ/VERTEX_FILE_PATH_ENV_VAR # os.environ["VERTEX_FILE_PATH_ENV_VAR"] = "/path/to/service_account.json"
|
||||
```
|
||||
|
||||
Set your environment variables:
|
||||
|
||||
```bash
|
||||
export VERTEX_FILE_PATH_ENV_VAR="/path/to/service_account.json"
|
||||
export LITELLM_MASTER_KEY="sk-1234567890"
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="multi" label="Azure OpenAI">
|
||||
|
||||
```yaml
|
||||
model_list:
|
||||
# Azure OpenAI
|
||||
- model_name: azure-gpt-4
|
||||
litellm_params:
|
||||
model: azure/gpt-4
|
||||
api_key: os.environ/AZURE_API_KEY
|
||||
api_base: os.environ/AZURE_API_BASE
|
||||
api_version: "2024-02-01"
|
||||
```
|
||||
|
||||
Set your environment variables:
|
||||
|
||||
```bash
|
||||
export AZURE_API_KEY="your-azure-api-key"
|
||||
export AZURE_API_BASE="https://your-resource.openai.azure.com"
|
||||
export LITELLM_MASTER_KEY="sk-1234567890"
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### 2. Start LiteLLM Proxy
|
||||
|
||||
```bash
|
||||
litellm --config /path/to/config.yaml
|
||||
|
||||
# RUNNING on http://0.0.0.0:4000
|
||||
```
|
||||
|
||||
### 3. Verify Setup
|
||||
|
||||
Test that your proxy is working correctly:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="openai-test" label="OpenAI">
|
||||
|
||||
```bash
|
||||
curl -X POST http://0.0.0.0:4000/v1/messages \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "gpt-4o",
|
||||
"max_tokens": 1000,
|
||||
"messages": [{"role": "user", "content": "What is the capital of France?"}]
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="gemini-test" label="Google AI Studio">
|
||||
|
||||
```bash
|
||||
curl -X POST http://0.0.0.0:4000/v1/messages \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "gemini-3.0-flash-exp",
|
||||
"max_tokens": 1000,
|
||||
"messages": [{"role": "user", "content": "What is the capital of France?"}]
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="vertex-test" label="Vertex AI">
|
||||
|
||||
```bash
|
||||
curl -X POST http://0.0.0.0:4000/v1/messages \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "gemini-3.0-flash-exp",
|
||||
"max_tokens": 1000,
|
||||
"messages": [{"role": "user", "content": "What is the capital of France?"}]
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="azure-test" label="Azure OpenAI">
|
||||
|
||||
```bash
|
||||
curl -X POST http://0.0.0.0:4000/v1/messages \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "azure-gpt-4",
|
||||
"max_tokens": 1000,
|
||||
"messages": [{"role": "user", "content": "What is the capital of France?"}]
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### 4. Configure Claude Code
|
||||
|
||||
Configure Claude Code to use your LiteLLM proxy:
|
||||
|
||||
```bash
|
||||
export ANTHROPIC_BASE_URL="http://0.0.0.0:4000"
|
||||
export ANTHROPIC_AUTH_TOKEN="$LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
:::tip
|
||||
The `LITELLM_MASTER_KEY` gives Claude Code access to all proxy models. You can also create virtual keys in the LiteLLM UI to limit access to specific models.
|
||||
:::
|
||||
|
||||
### 5. Use Claude Code with Non-Anthropic Models
|
||||
|
||||
Start Claude Code and specify which model to use:
|
||||
|
||||
```bash
|
||||
# Use OpenAI GPT-4o
|
||||
claude --model gpt-4o
|
||||
|
||||
# Use OpenAI GPT-4o-mini for faster responses
|
||||
claude --model gpt-4o-mini
|
||||
|
||||
# Use Google Gemini
|
||||
claude --model gemini-3.0-flash-exp
|
||||
|
||||
# Use Vertex AI Gemini
|
||||
claude --model vertex-gemini-3-flash-preview
|
||||
|
||||
# Use Vertex AI Anthropic Claude
|
||||
claude --model anthropic-vertex
|
||||
|
||||
# Use Azure OpenAI
|
||||
claude --model azure-gpt-4
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
LiteLLM acts as a unified interface that:
|
||||
|
||||
1. **Receives requests** from Claude Code in Anthropic Messages API format
|
||||
2. **Translates** the request to the target provider's format (OpenAI, Gemini, etc.)
|
||||
3. **Forwards** the request to the actual provider
|
||||
4. **Translates** the response back to Anthropic Messages API format
|
||||
5. **Returns** the response to Claude Code
|
||||
|
||||
This allows you to use Claude Code's interface with any LLM provider supported by LiteLLM.
|
||||
|
||||
## Advanced Features
|
||||
|
||||
### Load Balancing and Fallbacks
|
||||
|
||||
Configure multiple deployments with automatic fallback:
|
||||
|
||||
```yaml
|
||||
model_list:
|
||||
- model_name: gpt-4o # virtual model name
|
||||
litellm_params:
|
||||
model: openai/gpt-4o
|
||||
api_key: os.environ/OPENAI_API_KEY
|
||||
|
||||
- model_name: gpt-4o # same virtual name
|
||||
litellm_params:
|
||||
model: azure/gpt-4o
|
||||
api_key: os.environ/AZURE_API_KEY
|
||||
api_base: os.environ/AZURE_API_BASE
|
||||
|
||||
router_settings:
|
||||
routing_strategy: simple-shuffle # Load balance between deployments
|
||||
num_retries: 2
|
||||
timeout: 30
|
||||
```
|
||||
|
||||
### Usage Tracking and Budgets
|
||||
|
||||
Track usage and set budgets through the LiteLLM UI:
|
||||
|
||||
```yaml
|
||||
litellm_settings:
|
||||
master_key: os.environ/LITELLM_MASTER_KEY
|
||||
database_url: "postgresql://..." # Enable database for tracking
|
||||
|
||||
general_settings:
|
||||
store_model_in_db: true
|
||||
```
|
||||
|
||||
Start the proxy with the UI:
|
||||
|
||||
```bash
|
||||
litellm --config /path/to/config.yaml --detailed_debug
|
||||
```
|
||||
|
||||
Access the UI at `http://0.0.0.0:4000/ui` to:
|
||||
- View usage analytics
|
||||
- Set budget limits per user/key
|
||||
- Monitor costs across different providers
|
||||
- Create virtual keys with specific permissions
|
||||
|
||||
|
||||
## Supported Providers
|
||||
|
||||
LiteLLM supports 100+ providers. Here are some popular ones for use with Claude Code:
|
||||
|
||||
- **OpenAI**: GPT-4o, GPT-4o-mini, o1, o3-mini
|
||||
- **Google**: Gemini 2.0 Flash, Gemini 1.5 Pro/Flash
|
||||
- **Azure OpenAI**: All OpenAI models via Azure
|
||||
- **AWS Bedrock**: Llama, Mistral, and other models
|
||||
- **Vertex AI**: Gemini, Claude, and other models on Google Cloud
|
||||
- **Groq**: Fast inference for Llama and Mixtral
|
||||
- **Together AI**: Llama, Mixtral, and other open source models
|
||||
- **Deepseek**: Deepseek-chat, Deepseek-coder
|
||||
|
||||
[View full list of supported providers →](https://docs.litellm.ai/docs/providers)
|
||||
|
|
@ -2,7 +2,7 @@ import Image from '@theme/IdealImage';
|
|||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Claude Code
|
||||
# Claude Code Quickstart
|
||||
|
||||
This tutorial shows how to call Claude models through LiteLLM proxy from Claude Code.
|
||||
|
||||
|
|
@ -142,7 +142,7 @@ Common issues and solutions:
|
|||
- Ensure the model name in Claude Code matches exactly with your `config.yaml`
|
||||
- Check LiteLLM logs for detailed error messages
|
||||
|
||||
## Using Multiple Models
|
||||
## Using Bedrock/Vertex AI/Azure Foundry Models
|
||||
|
||||
Expand your configuration to support multiple providers and models:
|
||||
|
||||
|
|
@ -151,25 +151,6 @@ Expand your configuration to support multiple providers and models:
|
|||
|
||||
```yaml
|
||||
model_list:
|
||||
# OpenAI models
|
||||
- model_name: codex-mini
|
||||
litellm_params:
|
||||
model: openai/codex-mini
|
||||
api_key: os.environ/OPENAI_API_KEY
|
||||
api_base: https://api.openai.com/v1
|
||||
|
||||
- model_name: o3-pro
|
||||
litellm_params:
|
||||
model: openai/o3-pro
|
||||
api_key: os.environ/OPENAI_API_KEY
|
||||
api_base: https://api.openai.com/v1
|
||||
|
||||
- model_name: gpt-4o
|
||||
litellm_params:
|
||||
model: openai/gpt-4o
|
||||
api_key: os.environ/OPENAI_API_KEY
|
||||
api_base: https://api.openai.com/v1
|
||||
|
||||
# Anthropic models
|
||||
- model_name: claude-3-5-sonnet-20241022
|
||||
litellm_params:
|
||||
|
|
@ -189,6 +170,24 @@ model_list:
|
|||
aws_secret_access_key: os.environ/AWS_SECRET_ACCESS_KEY
|
||||
aws_region_name: us-east-1
|
||||
|
||||
# Azure Foundry
|
||||
- model_name: claude-4-azure
|
||||
litellm_params:
|
||||
model: azure_ai/claude-opus-4-1
|
||||
api_key: os.environ/AZURE_AI_API_KEY
|
||||
api_base: os.environ/AZURE_AI_API_BASE # https://my-resource.services.ai.azure.com/anthropic
|
||||
|
||||
# Google Vertex AI
|
||||
- model_name: anthropic-vertex
|
||||
litellm_params:
|
||||
model: vertex_ai/claude-haiku-4-5@20251001
|
||||
vertex_ai_project: "my-test-project"
|
||||
vertex_ai_location: "us-east-1"
|
||||
vertex_credentials: os.environ/VERTEX_FILE_PATH_ENV_VAR # os.environ["VERTEX_FILE_PATH_ENV_VAR"] = "/path/to/service_account.json"
|
||||
|
||||
|
||||
|
||||
|
||||
litellm_settings:
|
||||
master_key: os.environ/LITELLM_MASTER_KEY
|
||||
```
|
||||
|
|
@ -204,6 +203,12 @@ claude --model claude-3-5-haiku-20241022
|
|||
|
||||
# Use Bedrock deployment
|
||||
claude --model claude-bedrock
|
||||
|
||||
# Use Azure Foundry deployment
|
||||
claude --model claude-4-azure
|
||||
|
||||
# Use Vertex AI deployment
|
||||
claude --model anthropic-vertex
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
|
@ -211,96 +216,3 @@ claude --model claude-bedrock
|
|||
|
||||
<Image img={require('../../img/release_notes/claude_code_demo.png')} style={{ width: '500px', height: 'auto' }} />
|
||||
|
||||
|
||||
## Connecting MCP Servers
|
||||
|
||||
You can also connect MCP servers to Claude Code via LiteLLM Proxy.
|
||||
|
||||
:::note
|
||||
|
||||
Limitations:
|
||||
|
||||
- Currently, only HTTP MCP servers are supported
|
||||
|
||||
:::
|
||||
|
||||
1. Add the MCP server to your `config.yaml`
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="github" label="GitHub MCP">
|
||||
|
||||
In this example, we'll add the Github MCP server to our `config.yaml`
|
||||
|
||||
```yaml title="config.yaml" showLineNumbers
|
||||
mcp_servers:
|
||||
github_mcp:
|
||||
url: "https://api.githubcopilot.com/mcp"
|
||||
auth_type: oauth2
|
||||
client_id: os.environ/GITHUB_OAUTH_CLIENT_ID
|
||||
client_secret: os.environ/GITHUB_OAUTH_CLIENT_SECRET
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="atlassian" label="Atlassian MCP">
|
||||
|
||||
In this example, we'll add the Atlassian MCP server to our `config.yaml`
|
||||
|
||||
```yaml title="config.yaml" showLineNumbers
|
||||
atlassian_mcp:
|
||||
server_id: atlassian_mcp_id
|
||||
url: "https://mcp.atlassian.com/v1/sse"
|
||||
transport: "sse"
|
||||
auth_type: oauth2
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
2. Start LiteLLM Proxy
|
||||
|
||||
```bash
|
||||
litellm --config /path/to/config.yaml
|
||||
|
||||
# RUNNING on http://0.0.0.0:4000
|
||||
```
|
||||
|
||||
3. Use the MCP server in Claude Code
|
||||
|
||||
```bash
|
||||
claude mcp add --transport http litellm_proxy http://0.0.0.0:4000/github_mcp/mcp --header "Authorization: Bearer sk-LITELLM_VIRTUAL_KEY"
|
||||
```
|
||||
|
||||
For MCP servers that require dynamic client registration (such as Atlassian), please set `x-litellm-api-key: Bearer sk-LITELLM_VIRTUAL_KEY` instead of using `Authorization: Bearer LITELLM_VIRTUAL_KEY`.
|
||||
|
||||
4. Authenticate via Claude Code
|
||||
|
||||
a. Start Claude Code
|
||||
|
||||
```bash
|
||||
claude
|
||||
```
|
||||
|
||||
b. Authenticate via Claude Code
|
||||
|
||||
```bash
|
||||
/mcp
|
||||
```
|
||||
|
||||
c. Select the MCP server
|
||||
|
||||
```bash
|
||||
> litellm_proxy
|
||||
```
|
||||
|
||||
d. Start Oauth flow via Claude Code
|
||||
|
||||
```bash
|
||||
> 1. Authenticate
|
||||
2. Reconnect
|
||||
3. Disable
|
||||
```
|
||||
|
||||
e. Once completed, you should see this success message:
|
||||
|
||||
<Image img={require('../../img/oauth_2_success.png')} style={{ width: '500px', height: 'auto' }} />
|
||||
|
||||
|
|
|
|||
BIN
docs/my-website/img/mcp_playground.png
Normal file
|
After Width: | Height: | Size: 406 KiB |
BIN
docs/my-website/img/mcp_tool_testing_playground.png
Normal file
|
After Width: | Height: | Size: 284 KiB |
BIN
docs/my-website/img/ui_endpoint_activity.png
Normal file
|
After Width: | Height: | Size: 503 KiB |
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
title: "[Preview] v1.80.11 - Google Interactions API"
|
||||
title: "v1.80.11-stable - Google Interactions API"
|
||||
slug: "v1-80-11"
|
||||
date: 2025-12-20T10:00:00
|
||||
authors:
|
||||
|
|
@ -27,7 +27,7 @@ import TabItem from '@theme/TabItem';
|
|||
docker run \
|
||||
-e STORE_MODEL_IN_DB=True \
|
||||
-p 4000:4000 \
|
||||
docker.litellm.ai/berriai/litellm:v1.80.11.rc.1
|
||||
docker.litellm.ai/berriai/litellm:v1.80.11-stable
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
|
|
|||
643
docs/my-website/release_notes/v1.80.15/index.md
Normal file
|
|
@ -0,0 +1,643 @@
|
|||
---
|
||||
title: "[Preview] v1.80.15.rc.1 - Manus API Support"
|
||||
slug: "v1-80-15"
|
||||
date: 2026-01-10T10:00:00
|
||||
authors:
|
||||
- name: Krrish Dholakia
|
||||
title: CEO, LiteLLM
|
||||
url: https://www.linkedin.com/in/krish-d/
|
||||
image_url: https://pbs.twimg.com/profile_images/1298587542745358340/DZv3Oj-h_400x400.jpg
|
||||
- name: Ishaan Jaff
|
||||
title: CTO, LiteLLM
|
||||
url: https://www.linkedin.com/in/reffajnaahsi/
|
||||
image_url: https://pbs.twimg.com/profile_images/1613813310264340481/lz54oEiB_400x400.jpg
|
||||
hide_table_of_contents: false
|
||||
---
|
||||
|
||||
import Image from '@theme/IdealImage';
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
## Deploy this version
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="docker" label="Docker">
|
||||
|
||||
``` showLineNumbers title="docker run litellm"
|
||||
docker run \
|
||||
-e STORE_MODEL_IN_DB=True \
|
||||
-p 4000:4000 \
|
||||
docker.litellm.ai/berriai/litellm:v1.80.15.rc.1
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="pip" label="Pip">
|
||||
|
||||
``` showLineNumbers title="pip install litellm"
|
||||
pip install litellm==1.80.15
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
---
|
||||
|
||||
## Key Highlights
|
||||
|
||||
- **Manus API Support** - [New provider support for Manus API on /responses and GET /responses endpoints](../../docs/providers/manus)
|
||||
- **MiniMax Provider** - [Full support for MiniMax chat completions, TTS, and Anthropic native endpoint](../../docs/providers/minimax)
|
||||
- **AWS Polly TTS** - [New TTS provider using AWS Polly API](../../docs/providers/aws_polly)
|
||||
- **SSO Role Mapping** - Configure role mappings for SSO providers directly in the UI
|
||||
- **Cost Estimator** - New UI tool for estimating costs across multiple models and requests
|
||||
- **MCP Global Mode** - [Configure MCP servers globally with visibility controls](../../docs/mcp)
|
||||
- **Interactions API Bridge** - [Use all LiteLLM providers with the Interactions API](../../docs/interactions)
|
||||
- **RAG Query Endpoint** - [New RAG Search/Query endpoint for retrieval-augmented generation](../../docs/search/index)
|
||||
- **UI Usage - Endpoint Activity** - [Users can now see Endpoint Activity Metrics in the UI](../../docs/proxy/endpoint_activity.md)
|
||||
- **50% Overhead Reduction** - LiteLLM now sends 2.5× more requests to LLM providers
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Performance - 50% Overhead Reduction
|
||||
|
||||
LiteLLM now sends 2.5× more requests to LLM providers by replacing sequential if/elif chains with O(1) dictionary lookups for provider configuration resolution (92.7% faster). This optimization has a high impact because it runs inside the client decorator, which is invoked on every HTTP request made to the proxy server.
|
||||
|
||||
### Before
|
||||
|
||||
> **Note:** Worse-looking provider metrics are a good sign here—they indicate requests spend less time inside LiteLLM.
|
||||
|
||||
```
|
||||
============================================================
|
||||
Fake LLM Provider Stats (When called by LiteLLM)
|
||||
============================================================
|
||||
Total Time: 0.56s
|
||||
Requests/Second: 10746.68
|
||||
|
||||
Latency Statistics (seconds):
|
||||
Mean: 0.2039s
|
||||
Median (p50): 0.2310s
|
||||
Min: 0.0323s
|
||||
Max: 0.3928s
|
||||
Std Dev: 0.1166s
|
||||
p95: 0.3574s
|
||||
p99: 0.3748s
|
||||
|
||||
Status Codes:
|
||||
200: 6000
|
||||
```
|
||||
|
||||
### After
|
||||
|
||||
```
|
||||
============================================================
|
||||
Fake LLM Provider Stats (When called by LiteLLM)
|
||||
============================================================
|
||||
Total Time: 1.42s
|
||||
Requests/Second: 4224.49
|
||||
|
||||
Latency Statistics (seconds):
|
||||
Mean: 0.5300s
|
||||
Median (p50): 0.5871s
|
||||
Min: 0.0885s
|
||||
Max: 1.0482s
|
||||
Std Dev: 0.3065s
|
||||
p95: 0.9750s
|
||||
p99: 1.0444s
|
||||
|
||||
Status Codes:
|
||||
200: 6000
|
||||
```
|
||||
|
||||
> The benchmarks run LiteLLM locally with a lightweight LLM provider to eliminate network latency, isolating internal overhead and bottlenecks so we can focus on reducing pure LiteLLM overhead on a single instance.
|
||||
|
||||
---
|
||||
|
||||
### UI Usage - Endpoint Activity
|
||||
|
||||
<Image
|
||||
img={require('../../img/ui_endpoint_activity.png')}
|
||||
style={{width: '100%', display: 'block', margin: '2rem auto'}}
|
||||
/>
|
||||
|
||||
Users can now see Endpoint Activity Metrics in the UI.
|
||||
|
||||
---
|
||||
|
||||
## New Providers and Endpoints
|
||||
|
||||
### New Providers (11 new providers)
|
||||
|
||||
| Provider | Supported LiteLLM Endpoints | Description |
|
||||
| -------- | ------------------- | ----------- |
|
||||
| [Manus](../../docs/providers/manus) | `/responses` | Manus API for agentic workflows |
|
||||
| [Manus](../../docs/providers/manus) | `GET /responses` | Manus API for retrieving responses |
|
||||
| [Manus](../../docs/providers/manus) | `/files` | Manus API for file management |
|
||||
| [MiniMax](../../docs/providers/minimax) | `/chat/completions` | MiniMax chat completions |
|
||||
| [MiniMax](../../docs/providers/minimax) | `/audio/speech` | MiniMax text-to-speech |
|
||||
| [AWS Polly](../../docs/providers/aws_polly) | `/audio/speech` | AWS Polly text-to-speech API |
|
||||
| [GigaChat](../../docs/providers/gigachat) | `/chat/completions` | GigaChat provider for Russian language AI |
|
||||
| [LlamaGate](../../docs/providers/llamagate) | `/chat/completions` | LlamaGate chat completions |
|
||||
| [LlamaGate](../../docs/providers/llamagate) | `/embeddings` | LlamaGate embeddings |
|
||||
| [Abliteration AI](../../docs/providers/abliteration) | `/chat/completions` | Abliteration.ai provider support |
|
||||
| [Bedrock](../../docs/providers/bedrock) | `/v1/messages/count_tokens` | Bedrock as new provider for token counting |
|
||||
|
||||
### New LLM API Endpoints (3 new endpoints)
|
||||
|
||||
| Endpoint | Method | Description | Documentation |
|
||||
| -------- | ------ | ----------- | ------------- |
|
||||
| `/responses/compact` | POST | Compact responses API endpoint | [Docs](../../docs/response_api) |
|
||||
| `/rag/query` | POST | RAG Search/Query endpoint | [Docs](../../docs/search/index) |
|
||||
| `/containers/{id}/files` | POST | Upload files to containers | [Docs](../../docs/container_files) |
|
||||
|
||||
---
|
||||
|
||||
## New Models / Updated Models
|
||||
|
||||
#### New Model Support (100+ new models)
|
||||
|
||||
| Provider | Model | Context Window | Input ($/1M tokens) | Output ($/1M tokens) | Features |
|
||||
| -------- | ----- | -------------- | ------------------- | -------------------- | -------- |
|
||||
| Azure | `azure/gpt-5.2` | 400K | $1.75 | $14.00 | Reasoning, vision, caching |
|
||||
| Azure | `azure/gpt-5.2-chat` | 128K | $1.75 | $14.00 | Reasoning, vision |
|
||||
| Azure | `azure/gpt-5.2-pro` | 400K | $21.00 | $168.00 | Reasoning, vision, web search |
|
||||
| Azure | `azure/gpt-image-1.5` | - | Token-based | Token-based | Image generation/editing |
|
||||
| Azure AI | `azure_ai/gpt-oss-120b` | 131K | $0.15 | $0.60 | Function calling |
|
||||
| Azure AI | `azure_ai/flux.2-pro` | - | - | $0.04/image | Image generation |
|
||||
| Azure AI | `azure_ai/deepseek-v3.2` | 164K | $0.58 | $1.68 | Reasoning, function calling |
|
||||
| Bedrock | `amazon.nova-2-multimodal-embeddings-v1:0` | 8K | $0.135 | - | Multimodal embeddings |
|
||||
| Bedrock | `writer.palmyra-x4-v1:0` | 128K | $2.50 | $10.00 | Function calling, PDF |
|
||||
| Bedrock | `writer.palmyra-x5-v1:0` | 1M | $0.60 | $6.00 | Function calling, PDF |
|
||||
| Bedrock | `moonshot.kimi-k2-v1:0` | - | - | - | Kimi K2 model |
|
||||
| Cerebras | `cerebras/zai-glm-4.6` | 128K | $2.25 | $2.75 | Reasoning, function calling |
|
||||
| GigaChat | `gigachat/GigaChat-2-Lite` | - | - | - | Chat completions |
|
||||
| GigaChat | `gigachat/GigaChat-2-Max` | - | - | - | Chat completions |
|
||||
| GigaChat | `gigachat/GigaChat-2-Pro` | - | - | - | Chat completions |
|
||||
| Gemini | `gemini/veo-3.1-generate-001` | - | - | - | Video generation |
|
||||
| Gemini | `gemini/veo-3.1-fast-generate-001` | - | - | - | Video generation |
|
||||
| GitHub Copilot | 25+ models | Various | - | - | Chat completions |
|
||||
| LlamaGate | 15+ models | Various | - | - | Chat, vision, embeddings |
|
||||
| MiniMax | `minimax/abab7-chat-preview` | - | - | - | Chat completions |
|
||||
| Novita | 80+ models | Various | Various | Various | Chat, vision, embeddings |
|
||||
| OpenRouter | `openrouter/google/gemini-3-flash-preview` | - | - | - | Chat completions |
|
||||
| Together AI | Multiple models | Various | Various | Various | Response schema support |
|
||||
| Vertex AI | `vertex_ai/zai-glm-4.7` | - | - | - | GLM 4.7 support |
|
||||
|
||||
#### Features
|
||||
|
||||
- **[Gemini](../../docs/providers/gemini)**
|
||||
- Add image tokens in chat completion - [PR #18327](https://github.com/BerriAI/litellm/pull/18327)
|
||||
- Add usage object in image generation - [PR #18328](https://github.com/BerriAI/litellm/pull/18328)
|
||||
- Add thought signature support via tool call id - [PR #18374](https://github.com/BerriAI/litellm/pull/18374)
|
||||
- Add thought signature for non tool call requests - [PR #18581](https://github.com/BerriAI/litellm/pull/18581)
|
||||
- Preserve system instructions - [PR #18585](https://github.com/BerriAI/litellm/pull/18585)
|
||||
- Fix Gemini 3 images in tool response - [PR #18190](https://github.com/BerriAI/litellm/pull/18190)
|
||||
- Support snake_case for google_search tool parameters - [PR #18451](https://github.com/BerriAI/litellm/pull/18451)
|
||||
- Google GenAI adapter inline data support - [PR #18477](https://github.com/BerriAI/litellm/pull/18477)
|
||||
- Add deprecation_date for discontinued Google models - [PR #18550](https://github.com/BerriAI/litellm/pull/18550)
|
||||
- **[Vertex AI](../../docs/providers/vertex)**
|
||||
- Add centralized get_vertex_base_url() helper for global location support - [PR #18410](https://github.com/BerriAI/litellm/pull/18410)
|
||||
- Convert image URLs to base64 for Vertex AI Anthropic - [PR #18497](https://github.com/BerriAI/litellm/pull/18497)
|
||||
- Separate Tool objects for each tool type per API spec - [PR #18514](https://github.com/BerriAI/litellm/pull/18514)
|
||||
- Add thought_signatures to VertexGeminiConfig - [PR #18853](https://github.com/BerriAI/litellm/pull/18853)
|
||||
- Add support for Vertex AI API keys - [PR #18806](https://github.com/BerriAI/litellm/pull/18806)
|
||||
- Add zai glm-4.7 model support - [PR #18782](https://github.com/BerriAI/litellm/pull/18782)
|
||||
- **[Azure](../../docs/providers/azure/azure)**
|
||||
- Add Azure gpt-image-1.5 pricing to cost map - [PR #18347](https://github.com/BerriAI/litellm/pull/18347)
|
||||
- Add azure/gpt-5.2-chat model - [PR #18361](https://github.com/BerriAI/litellm/pull/18361)
|
||||
- Add support for image generation via Azure AD token - [PR #18413](https://github.com/BerriAI/litellm/pull/18413)
|
||||
- Add logprobs support for Azure OpenAI GPT-5.2 model - [PR #18856](https://github.com/BerriAI/litellm/pull/18856)
|
||||
- Add Azure BFL Flux 2 models for image generation and editing - [PR #18764](https://github.com/BerriAI/litellm/pull/18764), [PR #18766](https://github.com/BerriAI/litellm/pull/18766)
|
||||
- **[Bedrock](../../docs/providers/bedrock)**
|
||||
- Add Bedrock Kimi K2 model support - [PR #18797](https://github.com/BerriAI/litellm/pull/18797)
|
||||
- Add support for model id in bedrock passthrough - [PR #18800](https://github.com/BerriAI/litellm/pull/18800)
|
||||
- Fix Nova model detection for Bedrock provider - [PR #18250](https://github.com/BerriAI/litellm/pull/18250)
|
||||
- Ensure toolUse.input is always a dict when converting from OpenAI format - [PR #18414](https://github.com/BerriAI/litellm/pull/18414)
|
||||
- **[Databricks](../../docs/providers/databricks)**
|
||||
- Add enhanced authentication, security features, and custom user-agent support - [PR #18349](https://github.com/BerriAI/litellm/pull/18349)
|
||||
- **[MiniMax](../../docs/providers/minimax)**
|
||||
- Add MiniMax chat completion support - [PR #18380](https://github.com/BerriAI/litellm/pull/18380)
|
||||
- Add Anthropic native endpoint support for MiniMax - [PR #18377](https://github.com/BerriAI/litellm/pull/18377)
|
||||
- Add support for MiniMax TTS - [PR #18334](https://github.com/BerriAI/litellm/pull/18334)
|
||||
- Add MiniMax provider support to UI dashboard - [PR #18496](https://github.com/BerriAI/litellm/pull/18496)
|
||||
- **[Together AI](../../docs/providers/togetherai)**
|
||||
- Add supports_response_schema to all supported Together AI models - [PR #18368](https://github.com/BerriAI/litellm/pull/18368)
|
||||
- **[OpenRouter](../../docs/providers/openrouter)**
|
||||
- Add OpenRouter embeddings API support - [PR #18391](https://github.com/BerriAI/litellm/pull/18391)
|
||||
- **[Anthropic](../../docs/providers/anthropic)**
|
||||
- Pass server_tool_use and tool_search_tool_result blocks - [PR #18770](https://github.com/BerriAI/litellm/pull/18770)
|
||||
- Add Anthropic cache control option to image tool call results - [PR #18674](https://github.com/BerriAI/litellm/pull/18674)
|
||||
- **[Ollama](../../docs/providers/ollama)**
|
||||
- Add dimensions for ollama embedding - [PR #18536](https://github.com/BerriAI/litellm/pull/18536)
|
||||
- Extract pure base64 data from data URLs for Ollama - [PR #18465](https://github.com/BerriAI/litellm/pull/18465)
|
||||
- **[Watsonx](../../docs/providers/watsonx/index)**
|
||||
- Add Watsonx fields support - [PR #18569](https://github.com/BerriAI/litellm/pull/18569)
|
||||
- Fix Watsonx Audio Transcription - filter model field - [PR #18810](https://github.com/BerriAI/litellm/pull/18810)
|
||||
- **[SAP](../../docs/providers/sap)**
|
||||
- Add SAP creds for list in proxy UI - [PR #18375](https://github.com/BerriAI/litellm/pull/18375)
|
||||
- Pass through extra params from allowed_openai_params - [PR #18432](https://github.com/BerriAI/litellm/pull/18432)
|
||||
- Add client header for SAP AI Core Tracking - [PR #18714](https://github.com/BerriAI/litellm/pull/18714)
|
||||
- **[Fireworks AI](../../docs/providers/fireworks_ai)**
|
||||
- Correct deepseek-v3p2 pricing - [PR #18483](https://github.com/BerriAI/litellm/pull/18483)
|
||||
- **[ZAI](../../docs/providers/zai)**
|
||||
- Add GLM-4.7 model with reasoning support - [PR #18476](https://github.com/BerriAI/litellm/pull/18476)
|
||||
- **[Codestral](../../docs/providers/codestral)**
|
||||
- Correctly route codestral chat and FIM endpoints - [PR #18467](https://github.com/BerriAI/litellm/pull/18467)
|
||||
- **[Azure AI](../../docs/providers/azure_ai)**
|
||||
- Fix authentication errors at messages API via azure_ai - [PR #18500](https://github.com/BerriAI/litellm/pull/18500)
|
||||
|
||||
#### New Provider Support
|
||||
|
||||
- **[AWS Polly](../../docs/providers/aws_polly)** - Add AWS Polly API for TTS - [PR #18326](https://github.com/BerriAI/litellm/pull/18326)
|
||||
- **[GigaChat](../../docs/providers/gigachat)** - Add GigaChat provider support - [PR #18564](https://github.com/BerriAI/litellm/pull/18564)
|
||||
- **[LlamaGate](../../docs/providers/llamagate)** - Add LlamaGate as a new provider - [PR #18673](https://github.com/BerriAI/litellm/pull/18673)
|
||||
- **[Abliteration AI](../../docs/providers/abliteration)** - Add abliteration.ai provider - [PR #18678](https://github.com/BerriAI/litellm/pull/18678)
|
||||
- **[Manus](../../docs/providers/manus)** - Add Manus API support on /responses, GET /responses - [PR #18804](https://github.com/BerriAI/litellm/pull/18804)
|
||||
- **5 AI Providers via openai_like** - Add 5 AI providers using openai_like - [PR #18362](https://github.com/BerriAI/litellm/pull/18362)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **[Gemini](../../docs/providers/gemini)**
|
||||
- Properly catch context window exceeded errors - [PR #18283](https://github.com/BerriAI/litellm/pull/18283)
|
||||
- Remove prompt caching headers as support has been removed - [PR #18579](https://github.com/BerriAI/litellm/pull/18579)
|
||||
- Fix generate content request with audio file id - [PR #18745](https://github.com/BerriAI/litellm/pull/18745)
|
||||
- Fix google_genai streaming adapter provider handling - [PR #18845](https://github.com/BerriAI/litellm/pull/18845)
|
||||
- **[Groq](../../docs/providers/groq)**
|
||||
- Remove deprecated Groq models and update model registry - [PR #18062](https://github.com/BerriAI/litellm/pull/18062)
|
||||
- **[Vertex AI](../../docs/providers/vertex)**
|
||||
- Handle unsupported region for Vertex AI count tokens endpoint - [PR #18665](https://github.com/BerriAI/litellm/pull/18665)
|
||||
- **General**
|
||||
- Fix request body for image embedding request - [PR #18336](https://github.com/BerriAI/litellm/pull/18336)
|
||||
- Fix lost tool_calls when streaming has both text and tool_calls - [PR #18316](https://github.com/BerriAI/litellm/pull/18316)
|
||||
- Add all resolution for gpt-image-1.5 - [PR #18586](https://github.com/BerriAI/litellm/pull/18586)
|
||||
- Fix gpt-image-1 cost calculation using token-based pricing - [PR #17906](https://github.com/BerriAI/litellm/pull/17906)
|
||||
- Fix response_format leaking into extra_body - [PR #18859](https://github.com/BerriAI/litellm/pull/18859)
|
||||
- Align max_tokens with max_output_tokens for consistency - [PR #18820](https://github.com/BerriAI/litellm/pull/18820)
|
||||
|
||||
---
|
||||
|
||||
## LLM API Endpoints
|
||||
|
||||
#### Features
|
||||
|
||||
- **[Responses API](../../docs/response_api)**
|
||||
- Add new compact endpoint (v1/responses/compact) - [PR #18697](https://github.com/BerriAI/litellm/pull/18697)
|
||||
- Support more streaming callback hooks - [PR #18513](https://github.com/BerriAI/litellm/pull/18513)
|
||||
- Add mapping for reasoning effort to summary param - [PR #18635](https://github.com/BerriAI/litellm/pull/18635)
|
||||
- Add output_text property to ResponsesAPIResponse - [PR #18491](https://github.com/BerriAI/litellm/pull/18491)
|
||||
- Add annotations to completions responses API bridge - [PR #18754](https://github.com/BerriAI/litellm/pull/18754)
|
||||
- **[Interactions API](../../docs/interactions)**
|
||||
- Allow using all LiteLLM providers (interactions -> responses API bridge) - [PR #18373](https://github.com/BerriAI/litellm/pull/18373)
|
||||
- **[RAG Search API](../../docs/search/index)**
|
||||
- Add RAG Search/Query endpoint - [PR #18376](https://github.com/BerriAI/litellm/pull/18376)
|
||||
- **[CountTokens API](../../docs/anthropic_count_tokens)**
|
||||
- Add Bedrock as a new provider for `/v1/messages/count_tokens` - [PR #18858](https://github.com/BerriAI/litellm/pull/18858)
|
||||
- **[Generate Content](../../docs/providers/gemini)**
|
||||
- Add generate content in LLM route - [PR #18405](https://github.com/BerriAI/litellm/pull/18405)
|
||||
- **General**
|
||||
- Enable async_post_call_failure_hook to transform error responses - [PR #18348](https://github.com/BerriAI/litellm/pull/18348)
|
||||
- Calculate total_tokens manually if missing and can be calculated - [PR #18445](https://github.com/BerriAI/litellm/pull/18445)
|
||||
- Add custom llm provider to get_llm_provider when sent via UI - [PR #18638](https://github.com/BerriAI/litellm/pull/18638)
|
||||
|
||||
#### Bugs
|
||||
|
||||
- **General**
|
||||
- Handle empty error objects in response conversion - [PR #18493](https://github.com/BerriAI/litellm/pull/18493)
|
||||
- Preserve client error status codes in streaming mode - [PR #18698](https://github.com/BerriAI/litellm/pull/18698)
|
||||
- Return json error response instead of SSE format for initial streaming errors - [PR #18757](https://github.com/BerriAI/litellm/pull/18757)
|
||||
- Fix auth header for custom api base in generateContent request - [PR #18637](https://github.com/BerriAI/litellm/pull/18637)
|
||||
- Tool content should be string for Deepinfra - [PR #18739](https://github.com/BerriAI/litellm/pull/18739)
|
||||
- Fix incomplete usage in response object passed - [PR #18799](https://github.com/BerriAI/litellm/pull/18799)
|
||||
- Unify model names to provider-defined names - [PR #18573](https://github.com/BerriAI/litellm/pull/18573)
|
||||
|
||||
---
|
||||
|
||||
## Management Endpoints / UI
|
||||
|
||||
#### Features
|
||||
|
||||
- **SSO Configuration**
|
||||
- Add SSO Role Mapping feature - [PR #18090](https://github.com/BerriAI/litellm/pull/18090)
|
||||
- Add SSO Settings Page - [PR #18600](https://github.com/BerriAI/litellm/pull/18600)
|
||||
- Allow adding role mappings for SSO - [PR #18593](https://github.com/BerriAI/litellm/pull/18593)
|
||||
- SSO Settings Page Add Role Mappings - [PR #18677](https://github.com/BerriAI/litellm/pull/18677)
|
||||
- SSO Settings Loading State + Deprecate Previous SSO Flow - [PR #18617](https://github.com/BerriAI/litellm/pull/18617)
|
||||
- **Virtual Keys**
|
||||
- Allow deleting key expiry - [PR #18278](https://github.com/BerriAI/litellm/pull/18278)
|
||||
- Add optional query param "expand" to /key/list - [PR #18502](https://github.com/BerriAI/litellm/pull/18502)
|
||||
- Key Table Loading Skeleton - [PR #18527](https://github.com/BerriAI/litellm/pull/18527)
|
||||
- Allow column resizing on Keys Table - [PR #18424](https://github.com/BerriAI/litellm/pull/18424)
|
||||
- Virtual Keys Table Loading State Between Pages - [PR #18619](https://github.com/BerriAI/litellm/pull/18619)
|
||||
- Key and Team Router Setting - [PR #18790](https://github.com/BerriAI/litellm/pull/18790)
|
||||
- Allow router_settings on Keys and Teams - [PR #18675](https://github.com/BerriAI/litellm/pull/18675)
|
||||
- Use timedelta to calculate key expiry on generate - [PR #18666](https://github.com/BerriAI/litellm/pull/18666)
|
||||
- **Models + Endpoints**
|
||||
- Add Model Clearer Flow For Team Admins - [PR #18532](https://github.com/BerriAI/litellm/pull/18532)
|
||||
- Model Page Loading State - [PR #18574](https://github.com/BerriAI/litellm/pull/18574)
|
||||
- Model Page Model Provider Select Performance - [PR #18425](https://github.com/BerriAI/litellm/pull/18425)
|
||||
- Model Page Sorting Sorts Entire Set - [PR #18420](https://github.com/BerriAI/litellm/pull/18420)
|
||||
- Refactor Model Hub Page - [PR #18568](https://github.com/BerriAI/litellm/pull/18568)
|
||||
- Add request provider form on UI - [PR #18704](https://github.com/BerriAI/litellm/pull/18704)
|
||||
- **Organizations & Teams**
|
||||
- Allow Organization Admins to See Organization Tab - [PR #18400](https://github.com/BerriAI/litellm/pull/18400)
|
||||
- Resolve Organization Alias on Team Table - [PR #18401](https://github.com/BerriAI/litellm/pull/18401)
|
||||
- Resolve Team Alias in Organization Info View - [PR #18404](https://github.com/BerriAI/litellm/pull/18404)
|
||||
- Allow Organization Admins to View Their Organization Info - [PR #18417](https://github.com/BerriAI/litellm/pull/18417)
|
||||
- Allow editing team_member_budget_duration in /team/update - [PR #18735](https://github.com/BerriAI/litellm/pull/18735)
|
||||
- Reusable Duration Select + Team Update Member Budget Duration - [PR #18736](https://github.com/BerriAI/litellm/pull/18736)
|
||||
- **Usage & Spend**
|
||||
- Add Error Code Filtering on Spend Logs - [PR #18359](https://github.com/BerriAI/litellm/pull/18359)
|
||||
- Add Error Code Filtering on UI - [PR #18366](https://github.com/BerriAI/litellm/pull/18366)
|
||||
- Usage Page User Max Budget fix - [PR #18555](https://github.com/BerriAI/litellm/pull/18555)
|
||||
- Add endpoint to Daily Activity Tables - [PR #18729](https://github.com/BerriAI/litellm/pull/18729)
|
||||
- Endpoint Activity in Usage - [PR #18798](https://github.com/BerriAI/litellm/pull/18798)
|
||||
- **Cost Estimator**
|
||||
- Add Cost Estimator for AI Gateway - [PR #18643](https://github.com/BerriAI/litellm/pull/18643)
|
||||
- Add view for estimating costs across requests - [PR #18645](https://github.com/BerriAI/litellm/pull/18645)
|
||||
- Allow selecting many models for cost estimator - [PR #18653](https://github.com/BerriAI/litellm/pull/18653)
|
||||
- **CloudZero**
|
||||
- Improve Create and Delete Path for CloudZero - [PR #18263](https://github.com/BerriAI/litellm/pull/18263)
|
||||
- Add CloudZero UI Docs - [PR #18350](https://github.com/BerriAI/litellm/pull/18350)
|
||||
- **Playground**
|
||||
- Add MCP test support to completions on Playground - [PR #18440](https://github.com/BerriAI/litellm/pull/18440)
|
||||
- Add selectable MCP servers to the playground - [PR #18578](https://github.com/BerriAI/litellm/pull/18578)
|
||||
- Add custom proxy base URL support to Playground - [PR #18661](https://github.com/BerriAI/litellm/pull/18661)
|
||||
- **General UI**
|
||||
- UI styling improvements and fixes - [PR #18310](https://github.com/BerriAI/litellm/pull/18310)
|
||||
- Add reusable "New" badge component for feature highlights - [PR #18537](https://github.com/BerriAI/litellm/pull/18537)
|
||||
- Hide New Badges - [PR #18547](https://github.com/BerriAI/litellm/pull/18547)
|
||||
- Change Budget page to Have Tabs - [PR #18576](https://github.com/BerriAI/litellm/pull/18576)
|
||||
- Clicking on Logo Directs to Correct URL - [PR #18575](https://github.com/BerriAI/litellm/pull/18575)
|
||||
- Add UI support for configuring meta URLs - [PR #18580](https://github.com/BerriAI/litellm/pull/18580)
|
||||
- Expire Previous UI Session Tokens on Login - [PR #18557](https://github.com/BerriAI/litellm/pull/18557)
|
||||
- Add license endpoint - [PR #18311](https://github.com/BerriAI/litellm/pull/18311)
|
||||
- Router Fields Endpoint + React Query for Router Fields - [PR #18880](https://github.com/BerriAI/litellm/pull/18880)
|
||||
|
||||
#### Bugs
|
||||
|
||||
- **UI Fixes**
|
||||
- Fix Key Creation MCP Settings Submit Form Unintentionally - [PR #18355](https://github.com/BerriAI/litellm/pull/18355)
|
||||
- Fix UI Disappears in Development Environments - [PR #18399](https://github.com/BerriAI/litellm/pull/18399)
|
||||
- Fix Disable Admin UI Flag - [PR #18397](https://github.com/BerriAI/litellm/pull/18397)
|
||||
- Remove Model Analytics From Model Page - [PR #18552](https://github.com/BerriAI/litellm/pull/18552)
|
||||
- Useful Links Remove Modal on Adding Links - [PR #18602](https://github.com/BerriAI/litellm/pull/18602)
|
||||
- SSO Edit Modal Clear Role Mapping Values on Provider Change - [PR #18680](https://github.com/BerriAI/litellm/pull/18680)
|
||||
- UI Login Case Sensitivity fix - [PR #18877](https://github.com/BerriAI/litellm/pull/18877)
|
||||
- **API Fixes**
|
||||
- Fix User Invite & Key Generation Email Notification Logic - [PR #18524](https://github.com/BerriAI/litellm/pull/18524)
|
||||
- Normalize Proxy Config Callback - [PR #18775](https://github.com/BerriAI/litellm/pull/18775)
|
||||
- Return empty data array instead of 500 when no models configured - [PR #18556](https://github.com/BerriAI/litellm/pull/18556)
|
||||
- Enforce org level max budget - [PR #18813](https://github.com/BerriAI/litellm/pull/18813)
|
||||
|
||||
---
|
||||
|
||||
## AI Integrations
|
||||
|
||||
### New Integrations (4 new integrations)
|
||||
|
||||
| Integration | Type | Description |
|
||||
| ----------- | ---- | ----------- |
|
||||
| [Focus](../../docs/observability/focus) | Logging | Focus export support for observability - [PR #18802](https://github.com/BerriAI/litellm/pull/18802) |
|
||||
| [SigNoz](../../docs/observability/signoz) | Logging | SigNoz integration for observability - [PR #18726](https://github.com/BerriAI/litellm/pull/18726) |
|
||||
| [Qualifire](../../docs/proxy/guardrails/qualifire) | Guardrails | Qualifire guardrails and eval webhook - [PR #18594](https://github.com/BerriAI/litellm/pull/18594) |
|
||||
| [Levo AI](../../docs/observability/levo_integration) | Guardrails | Levo AI integration for security - [PR #18529](https://github.com/BerriAI/litellm/pull/18529) |
|
||||
|
||||
### Logging
|
||||
|
||||
- **[DataDog](../../docs/proxy/logging#datadog)**
|
||||
- Fix span kind fallback when parent_id missing - [PR #18418](https://github.com/BerriAI/litellm/pull/18418)
|
||||
- **[Langfuse](../../docs/proxy/logging#langfuse)**
|
||||
- Map Gemini cached_tokens to Langfuse cache_read_input_tokens - [PR #18614](https://github.com/BerriAI/litellm/pull/18614)
|
||||
- **[Prometheus](../../docs/proxy/logging#prometheus)**
|
||||
- Align prometheus metric names with DEFINED_PROMETHEUS_METRICS - [PR #18463](https://github.com/BerriAI/litellm/pull/18463)
|
||||
- Add Prometheus metrics for request queue time and guardrails - [PR #17973](https://github.com/BerriAI/litellm/pull/17973)
|
||||
- Add caching metrics for cache hits, misses, and tokens - [PR #18755](https://github.com/BerriAI/litellm/pull/18755)
|
||||
- Skip metrics for invalid API key requests - [PR #18788](https://github.com/BerriAI/litellm/pull/18788)
|
||||
- **[Braintrust](../../docs/proxy/logging#braintrust)**
|
||||
- Pass span_attributes in async logging and skip tags on non-root spans - [PR #18409](https://github.com/BerriAI/litellm/pull/18409)
|
||||
- **[CloudZero](../../docs/proxy/logging#cloudzero)**
|
||||
- Add user email to CloudZero - [PR #18584](https://github.com/BerriAI/litellm/pull/18584)
|
||||
- **[OpenTelemetry](../../docs/proxy/logging#opentelemetry)**
|
||||
- Use already configured opentelemetry providers - [PR #18279](https://github.com/BerriAI/litellm/pull/18279)
|
||||
- Prevent LiteLLM from closing external OTEL spans - [PR #18553](https://github.com/BerriAI/litellm/pull/18553)
|
||||
- Allow configuring arize project name for OpenTelemetry service name - [PR #18738](https://github.com/BerriAI/litellm/pull/18738)
|
||||
- **[LangSmith](../../docs/proxy/logging#langsmith)**
|
||||
- Add support for LangSmith organization-scoped API keys with tenant ID - [PR #18623](https://github.com/BerriAI/litellm/pull/18623)
|
||||
- **[Generic API Logger](../../docs/proxy/logging#generic-api-logger)**
|
||||
- Add log_format option to GenericAPILogger - [PR #18587](https://github.com/BerriAI/litellm/pull/18587)
|
||||
|
||||
### Guardrails
|
||||
|
||||
- **[Content Filter](../../docs/proxy/guardrails/litellm_content_filter)**
|
||||
- Add content filter logs page - [PR #18335](https://github.com/BerriAI/litellm/pull/18335)
|
||||
- Log actual event type for guardrails - [PR #18489](https://github.com/BerriAI/litellm/pull/18489)
|
||||
- **[Qualifire](../../docs/proxy/guardrails/qualifire)**
|
||||
- Add Qualifire eval webhook - [PR #18836](https://github.com/BerriAI/litellm/pull/18836)
|
||||
- **[Lasso Security](../../docs/proxy/guardrails/lasso_security)**
|
||||
- Add Lasso guardrail API docs - [PR #18652](https://github.com/BerriAI/litellm/pull/18652)
|
||||
- **[Noma Security](../../docs/proxy/guardrails/noma_security)**
|
||||
- Add MCP guardrail support for Noma - [PR #18668](https://github.com/BerriAI/litellm/pull/18668)
|
||||
- **[Bedrock Guardrails](../../docs/proxy/guardrails/bedrock)**
|
||||
- Remove redundant Bedrock guardrail block handling - [PR #18634](https://github.com/BerriAI/litellm/pull/18634)
|
||||
- **General**
|
||||
- Generic guardrail API update - [PR #18647](https://github.com/BerriAI/litellm/pull/18647)
|
||||
- Prevent proxy startup failures from case-sensitive tool permission guardrail validation - [PR #18662](https://github.com/BerriAI/litellm/pull/18662)
|
||||
- Extend case normalization to ALL guardrail types - [PR #18664](https://github.com/BerriAI/litellm/pull/18664)
|
||||
- Fix MCP handling in unified guardrail - [PR #18630](https://github.com/BerriAI/litellm/pull/18630)
|
||||
- Fix embeddings calltype for guardrail precallhook - [PR #18740](https://github.com/BerriAI/litellm/pull/18740)
|
||||
|
||||
---
|
||||
|
||||
## Spend Tracking, Budgets and Rate Limiting
|
||||
|
||||
- **Platform Fee / Margins** - Add support for Platform Fee / Margins - [PR #18427](https://github.com/BerriAI/litellm/pull/18427)
|
||||
- **Negative Budget Validation** - Add validation for negative budget - [PR #18583](https://github.com/BerriAI/litellm/pull/18583)
|
||||
- **Cost Calculation Fixes**
|
||||
- Correct cost calculation when reasoning_tokens are without text_tokens - [PR #18607](https://github.com/BerriAI/litellm/pull/18607)
|
||||
- Fix background cost tracking tests - [PR #18588](https://github.com/BerriAI/litellm/pull/18588)
|
||||
- **Tag Routing** - Support toggling tag matching between ANY and ALL - [PR #18776](https://github.com/BerriAI/litellm/pull/18776)
|
||||
|
||||
---
|
||||
|
||||
## MCP Gateway
|
||||
|
||||
- **MCP Global Mode** - Add MCP global mode - [PR #18639](https://github.com/BerriAI/litellm/pull/18639)
|
||||
- **MCP Server Visibility** - Add configurable MCP server visibility - [PR #18681](https://github.com/BerriAI/litellm/pull/18681)
|
||||
- **MCP Registry** - Add MCP registry - [PR #18850](https://github.com/BerriAI/litellm/pull/18850)
|
||||
- **MCP Stdio Header** - Support MCP stdio header env overrides - [PR #18324](https://github.com/BerriAI/litellm/pull/18324)
|
||||
- **Parallel Tool Fetching** - Parallelize tool fetching from multiple MCP servers - [PR #18627](https://github.com/BerriAI/litellm/pull/18627)
|
||||
- **Optimize MCP Server Listing** - Separate health checks for optimized listing - [PR #18530](https://github.com/BerriAI/litellm/pull/18530)
|
||||
- **Auth Improvements**
|
||||
- Require auth for MCP connection test endpoint - [PR #18290](https://github.com/BerriAI/litellm/pull/18290)
|
||||
- Fix MCP gateway OAuth2 auth issues and ClosedResourceError - [PR #18281](https://github.com/BerriAI/litellm/pull/18281)
|
||||
- **Bug Fixes**
|
||||
- Fix MCP server health status reporting - [PR #18443](https://github.com/BerriAI/litellm/pull/18443)
|
||||
- Fix OpenAPI to MCP tool conversion - [PR #18597](https://github.com/BerriAI/litellm/pull/18597)
|
||||
- Remove exec() usage and handle invalid OpenAPI parameter names for security - [PR #18480](https://github.com/BerriAI/litellm/pull/18480)
|
||||
- Fix MCP error when using multiple servers simultaneously - [PR #18855](https://github.com/BerriAI/litellm/pull/18855)
|
||||
- **Migrate MCP Fetching Logic to React Query** - [PR #18352](https://github.com/BerriAI/litellm/pull/18352)
|
||||
|
||||
---
|
||||
|
||||
## Performance / Loadbalancing / Reliability improvements
|
||||
|
||||
- **92.7% Faster Provider Config Lookup** - LiteLLM now stresses LLM providers 2.5x more - [PR #18867](https://github.com/BerriAI/litellm/pull/18867)
|
||||
- **Lazy Loading Improvements**
|
||||
- Consolidate lazy import handlers with registry pattern - [PR #18389](https://github.com/BerriAI/litellm/pull/18389)
|
||||
- Complete lazy loading migration for all 180+ LLM config classes - [PR #18392](https://github.com/BerriAI/litellm/pull/18392)
|
||||
- Lazy load additional components (types, callbacks, utilities) - [PR #18396](https://github.com/BerriAI/litellm/pull/18396)
|
||||
- Add lazy loading for get_llm_provider - [PR #18591](https://github.com/BerriAI/litellm/pull/18591)
|
||||
- Lazy-load heavy audio library and loggers - [PR #18592](https://github.com/BerriAI/litellm/pull/18592)
|
||||
- Lazy load 9 heavy imports in litellm/utils.py - [PR #18595](https://github.com/BerriAI/litellm/pull/18595)
|
||||
- Lazy load heavy imports to improve import time and memory usage - [PR #18610](https://github.com/BerriAI/litellm/pull/18610)
|
||||
- Implement lazy loading for provider configs, model info classes, streaming handlers - [PR #18611](https://github.com/BerriAI/litellm/pull/18611)
|
||||
- Lazy load 15 additional imports - [PR #18613](https://github.com/BerriAI/litellm/pull/18613)
|
||||
- Lazy load 15+ unused imports - [PR #18616](https://github.com/BerriAI/litellm/pull/18616)
|
||||
- Lazy load DatadogLLMObsInitParams - [PR #18658](https://github.com/BerriAI/litellm/pull/18658)
|
||||
- Migrate utils.py lazy imports to registry pattern - [PR #18657](https://github.com/BerriAI/litellm/pull/18657)
|
||||
- Lazy load get_llm_provider and remove_index_from_tool_calls - [PR #18608](https://github.com/BerriAI/litellm/pull/18608)
|
||||
- **Router Improvements**
|
||||
- Validate routing_strategy at startup to fail fast with helpful error - [PR #18624](https://github.com/BerriAI/litellm/pull/18624)
|
||||
- Correct num_retries tracking in retry logic - [PR #18712](https://github.com/BerriAI/litellm/pull/18712)
|
||||
- Improve error messages and validation for wildcard routing with multiple credentials - [PR #18629](https://github.com/BerriAI/litellm/pull/18629)
|
||||
- **Memory Improvements**
|
||||
- Add memory pattern detection test and fix bad memory patterns - [PR #18589](https://github.com/BerriAI/litellm/pull/18589)
|
||||
- Add unbounded data structure detection to memory test - [PR #18590](https://github.com/BerriAI/litellm/pull/18590)
|
||||
- Add memory leak detection tests with CI integration - [PR #18881](https://github.com/BerriAI/litellm/pull/18881)
|
||||
- **Database**
|
||||
- Add idx on LOWER(user_email) for faster duplicate email checks - [PR #18828](https://github.com/BerriAI/litellm/pull/18828)
|
||||
- Proactive RDS IAM token refresh to prevent 15-min connection failed - [PR #18795](https://github.com/BerriAI/litellm/pull/18795)
|
||||
- Clarify database_connection_pool_limit applies per worker - [PR #18780](https://github.com/BerriAI/litellm/pull/18780)
|
||||
- Make base_connection_pool_limit default value the same - [PR #18721](https://github.com/BerriAI/litellm/pull/18721)
|
||||
- **Docker**
|
||||
- Add libsndfile to database Docker image for audio processing - [PR #18612](https://github.com/BerriAI/litellm/pull/18612)
|
||||
- Add line_profiler support for performance analysis and fix Windows CRLF issues - [PR #18773](https://github.com/BerriAI/litellm/pull/18773)
|
||||
- **Helm**
|
||||
- Add lifecycle support to Helm charts - [PR #18517](https://github.com/BerriAI/litellm/pull/18517)
|
||||
- **Authentication**
|
||||
- Add Kubernetes ServiceAccount JWT authentication support - [PR #18055](https://github.com/BerriAI/litellm/pull/18055)
|
||||
- Use async anthropic client to prevent event loop blocking - [PR #18435](https://github.com/BerriAI/litellm/pull/18435)
|
||||
- **Logging Worker**
|
||||
- Handle event loop changes in multiprocessing - [PR #18423](https://github.com/BerriAI/litellm/pull/18423)
|
||||
- **Security**
|
||||
- Prevent expired key plaintext leak in error response - [PR #18860](https://github.com/BerriAI/litellm/pull/18860)
|
||||
- Mask extra header secrets in model info - [PR #18822](https://github.com/BerriAI/litellm/pull/18822)
|
||||
- Prevent duplicate User-Agent tags in request_tags - [PR #18723](https://github.com/BerriAI/litellm/pull/18723)
|
||||
- Properly use litellm api keys - [PR #18832](https://github.com/BerriAI/litellm/pull/18832)
|
||||
- **Misc**
|
||||
- Remove double imports in main.py - [PR #18406](https://github.com/BerriAI/litellm/pull/18406)
|
||||
- Add LITELLM_DISABLE_LAZY_LOADING env var to fix VCR cassette creation issue - [PR #18725](https://github.com/BerriAI/litellm/pull/18725)
|
||||
- Add xiaomi_mimo to LlmProviders enum to fix router support - [PR #18819](https://github.com/BerriAI/litellm/pull/18819)
|
||||
- Allow installation with current grpcio on old Python - [PR #18473](https://github.com/BerriAI/litellm/pull/18473)
|
||||
- Add Custom CA certificates to boto3 clients - [PR #18852](https://github.com/BerriAI/litellm/pull/18852)
|
||||
- Fix bedrock_cache, metadata and max_model_budget - [PR #18872](https://github.com/BerriAI/litellm/pull/18872)
|
||||
- Fix LiteLLM SDK embedding headers missing field - [PR #18844](https://github.com/BerriAI/litellm/pull/18844)
|
||||
- Put automatic reasoning summary inclusion behind feat flag - [PR #18688](https://github.com/BerriAI/litellm/pull/18688)
|
||||
- turn_off_message_logging Does Not Redact Request Messages in proxy_server_request Field - [PR #18897](https://github.com/BerriAI/litellm/pull/18897)
|
||||
|
||||
---
|
||||
|
||||
## Documentation Updates
|
||||
|
||||
- **Provider Documentation**
|
||||
- Update MiniMax docs to be in proper format - [PR #18403](https://github.com/BerriAI/litellm/pull/18403)
|
||||
- Add docs for 5 AI providers - [PR #18388](https://github.com/BerriAI/litellm/pull/18388)
|
||||
- Fix gpt-5-mini reasoning_effort supported values - [PR #18346](https://github.com/BerriAI/litellm/pull/18346)
|
||||
- Fix PDF documentation inconsistency in Anthropic page - [PR #18816](https://github.com/BerriAI/litellm/pull/18816)
|
||||
- Update OpenRouter docs to include embedding support - [PR #18874](https://github.com/BerriAI/litellm/pull/18874)
|
||||
- Add LITELLM_REASONING_AUTO_SUMMARY in doc - [PR #18705](https://github.com/BerriAI/litellm/pull/18705)
|
||||
- **MCP Documentation**
|
||||
- Agentcore MCP server docs - [PR #18603](https://github.com/BerriAI/litellm/pull/18603)
|
||||
- Mention MCP prompt/resources types in overview - [PR #18669](https://github.com/BerriAI/litellm/pull/18669)
|
||||
- Add Focus docs - [PR #18837](https://github.com/BerriAI/litellm/pull/18837)
|
||||
- **Guardrails Documentation**
|
||||
- Qualifire docs hotfix - [PR #18724](https://github.com/BerriAI/litellm/pull/18724)
|
||||
- **Infrastructure Documentation**
|
||||
- IAM Roles Anywhere docs - [PR #18559](https://github.com/BerriAI/litellm/pull/18559)
|
||||
- Fix formatting in proxy configs documentation - [PR #18498](https://github.com/BerriAI/litellm/pull/18498)
|
||||
- Fix GCS cache docs missing for proxy mode - [PR #13328](https://github.com/BerriAI/litellm/pull/13328)
|
||||
- Fix how to execute cloudzero sql - [PR #18841](https://github.com/BerriAI/litellm/pull/18841)
|
||||
- **General**
|
||||
- LiteLLM adopters section - [PR #18605](https://github.com/BerriAI/litellm/pull/18605)
|
||||
- Remove redundant comments about setting litellm.callbacks - [PR #18711](https://github.com/BerriAI/litellm/pull/18711)
|
||||
- Update header to be markdown bold by removing space - [PR #18846](https://github.com/BerriAI/litellm/pull/18846)
|
||||
- Manus docs - new provider - [PR #18817](https://github.com/BerriAI/litellm/pull/18817)
|
||||
|
||||
---
|
||||
|
||||
## New Contributors
|
||||
|
||||
* @prasadkona made their first contribution in [PR #18349](https://github.com/BerriAI/litellm/pull/18349)
|
||||
* @lucasrothman made their first contribution in [PR #18283](https://github.com/BerriAI/litellm/pull/18283)
|
||||
* @aggeentik made their first contribution in [PR #18317](https://github.com/BerriAI/litellm/pull/18317)
|
||||
* @mihidumh made their first contribution in [PR #18361](https://github.com/BerriAI/litellm/pull/18361)
|
||||
* @Prazeina made their first contribution in [PR #18498](https://github.com/BerriAI/litellm/pull/18498)
|
||||
* @systec-dk made their first contribution in [PR #18500](https://github.com/BerriAI/litellm/pull/18500)
|
||||
* @xuan07t2 made their first contribution in [PR #18514](https://github.com/BerriAI/litellm/pull/18514)
|
||||
* @RensDimmendaal made their first contribution in [PR #18190](https://github.com/BerriAI/litellm/pull/18190)
|
||||
* @yurekami made their first contribution in [PR #18483](https://github.com/BerriAI/litellm/pull/18483)
|
||||
* @agertz7 made their first contribution in [PR #18556](https://github.com/BerriAI/litellm/pull/18556)
|
||||
* @yudelevi made their first contribution in [PR #18550](https://github.com/BerriAI/litellm/pull/18550)
|
||||
* @smallp made their first contribution in [PR #18536](https://github.com/BerriAI/litellm/pull/18536)
|
||||
* @kevinpauer made their first contribution in [PR #18569](https://github.com/BerriAI/litellm/pull/18569)
|
||||
* @cansakiroglu made their first contribution in [PR #18517](https://github.com/BerriAI/litellm/pull/18517)
|
||||
* @dee-walia20 made their first contribution in [PR #18432](https://github.com/BerriAI/litellm/pull/18432)
|
||||
* @luxinfeng made their first contribution in [PR #18477](https://github.com/BerriAI/litellm/pull/18477)
|
||||
* @cantalupo555 made their first contribution in [PR #18476](https://github.com/BerriAI/litellm/pull/18476)
|
||||
* @andersk made their first contribution in [PR #18473](https://github.com/BerriAI/litellm/pull/18473)
|
||||
* @majiayu000 made their first contribution in [PR #18467](https://github.com/BerriAI/litellm/pull/18467)
|
||||
* @amangupta-20 made their first contribution in [PR #18529](https://github.com/BerriAI/litellm/pull/18529)
|
||||
* @hamzaq453 made their first contribution in [PR #18480](https://github.com/BerriAI/litellm/pull/18480)
|
||||
* @ktsaou made their first contribution in [PR #18627](https://github.com/BerriAI/litellm/pull/18627)
|
||||
* @FlibbertyGibbitz made their first contribution in [PR #18624](https://github.com/BerriAI/litellm/pull/18624)
|
||||
* @drorIvry made their first contribution in [PR #18594](https://github.com/BerriAI/litellm/pull/18594)
|
||||
* @urainshah made their first contribution in [PR #18524](https://github.com/BerriAI/litellm/pull/18524)
|
||||
* @mangabits made their first contribution in [PR #18279](https://github.com/BerriAI/litellm/pull/18279)
|
||||
* @0717376 made their first contribution in [PR #18564](https://github.com/BerriAI/litellm/pull/18564)
|
||||
* @nmgarza5 made their first contribution in [PR #17330](https://github.com/BerriAI/litellm/pull/17330)
|
||||
* @wileykestner made their first contribution in [PR #18445](https://github.com/BerriAI/litellm/pull/18445)
|
||||
* @minijeong-log made their first contribution in [PR #14440](https://github.com/BerriAI/litellm/pull/14440)
|
||||
* @Isaac4real made their first contribution in [PR #18710](https://github.com/BerriAI/litellm/pull/18710)
|
||||
* @marukaz made their first contribution in [PR #18711](https://github.com/BerriAI/litellm/pull/18711)
|
||||
* @rohitravirane made their first contribution in [PR #18712](https://github.com/BerriAI/litellm/pull/18712)
|
||||
* @lizzzcai made their first contribution in [PR #18714](https://github.com/BerriAI/litellm/pull/18714)
|
||||
* @hkd987 made their first contribution in [PR #18673](https://github.com/BerriAI/litellm/pull/18673)
|
||||
* @Mr-Pepe made their first contribution in [PR #18674](https://github.com/BerriAI/litellm/pull/18674)
|
||||
* @gkarthi-signoz made their first contribution in [PR #18726](https://github.com/BerriAI/litellm/pull/18726)
|
||||
* @Tianduo16 made their first contribution in [PR #18723](https://github.com/BerriAI/litellm/pull/18723)
|
||||
* @wilsonjr made their first contribution in [PR #18721](https://github.com/BerriAI/litellm/pull/18721)
|
||||
* @abliteration-ai made their first contribution in [PR #18678](https://github.com/BerriAI/litellm/pull/18678)
|
||||
* @danialkhan02 made their first contribution in [PR #18770](https://github.com/BerriAI/litellm/pull/18770)
|
||||
* @ihower made their first contribution in [PR #18409](https://github.com/BerriAI/litellm/pull/18409)
|
||||
* @elkkhan made their first contribution in [PR #18391](https://github.com/BerriAI/litellm/pull/18391)
|
||||
* @runixer made their first contribution in [PR #18435](https://github.com/BerriAI/litellm/pull/18435)
|
||||
* @choby-shun made their first contribution in [PR #18776](https://github.com/BerriAI/litellm/pull/18776)
|
||||
* @jutaz made their first contribution in [PR #18853](https://github.com/BerriAI/litellm/pull/18853)
|
||||
* @sjmatta made their first contribution in [PR #18250](https://github.com/BerriAI/litellm/pull/18250)
|
||||
* @andres-ortizl made their first contribution in [PR #18856](https://github.com/BerriAI/litellm/pull/18856)
|
||||
* @gauthiermartin made their first contribution in [PR #18844](https://github.com/BerriAI/litellm/pull/18844)
|
||||
* @mel2oo made their first contribution in [PR #18845](https://github.com/BerriAI/litellm/pull/18845)
|
||||
* @DominikHallab made their first contribution in [PR #18846](https://github.com/BerriAI/litellm/pull/18846)
|
||||
* @ji-chuan-che made their first contribution in [PR #18540](https://github.com/BerriAI/litellm/pull/18540)
|
||||
* @raghav-stripe made their first contribution in [PR #18858](https://github.com/BerriAI/litellm/pull/18858)
|
||||
* @akraines made their first contribution in [PR #18629](https://github.com/BerriAI/litellm/pull/18629)
|
||||
* @otaviofbrito made their first contribution in [PR #18665](https://github.com/BerriAI/litellm/pull/18665)
|
||||
* @chetanchoudhary-sumo made their first contribution in [PR #18587](https://github.com/BerriAI/litellm/pull/18587)
|
||||
* @pascalwhoop made their first contribution in [PR #13328](https://github.com/BerriAI/litellm/pull/13328)
|
||||
* @orgersh92 made their first contribution in [PR #18652](https://github.com/BerriAI/litellm/pull/18652)
|
||||
* @DevajMody made their first contribution in [PR #18497](https://github.com/BerriAI/litellm/pull/18497)
|
||||
* @matt-greathouse made their first contribution in [PR #18247](https://github.com/BerriAI/litellm/pull/18247)
|
||||
* @emerzon made their first contribution in [PR #18290](https://github.com/BerriAI/litellm/pull/18290)
|
||||
* @Eric84626 made their first contribution in [PR #18281](https://github.com/BerriAI/litellm/pull/18281)
|
||||
* @LukasdeBoer made their first contribution in [PR #18055](https://github.com/BerriAI/litellm/pull/18055)
|
||||
* @LingXuanYin made their first contribution in [PR #18513](https://github.com/BerriAI/litellm/pull/18513)
|
||||
* @krisxia0506 made their first contribution in [PR #18698](https://github.com/BerriAI/litellm/pull/18698)
|
||||
* @LouisShark made their first contribution in [PR #18414](https://github.com/BerriAI/litellm/pull/18414)
|
||||
|
||||
---
|
||||
|
||||
## Full Changelog
|
||||
|
||||
**[View complete changelog on GitHub](https://github.com/BerriAI/litellm/compare/v1.80.11.rc.1...v1.80.14.rc.1)**
|
||||
|
||||
|
||||
|
|
@ -55,6 +55,7 @@ const sidebars = {
|
|||
"proxy/guardrails/test_playground",
|
||||
"proxy/guardrails/litellm_content_filter",
|
||||
...[
|
||||
"proxy/guardrails/qualifire",
|
||||
"proxy/guardrails/aim_security",
|
||||
"proxy/guardrails/onyx_security",
|
||||
"proxy/guardrails/aporia_api",
|
||||
|
|
@ -107,15 +108,30 @@ const sidebars = {
|
|||
{
|
||||
type: "category",
|
||||
label: "AI Tools (OpenWebUI, Claude Code, etc.)",
|
||||
link: {
|
||||
type: "generated-index",
|
||||
title: "AI Tools",
|
||||
description: "Integrate LiteLLM with AI tools like OpenWebUI, Claude Code, and more",
|
||||
slug: "/ai_tools"
|
||||
},
|
||||
items: [
|
||||
"tutorials/claude_responses_api",
|
||||
"tutorials/openweb_ui",
|
||||
{
|
||||
type: "category",
|
||||
label: "Claude Code",
|
||||
items: [
|
||||
"tutorials/claude_responses_api",
|
||||
"tutorials/claude_code_customer_tracking",
|
||||
"tutorials/claude_mcp",
|
||||
"tutorials/claude_non_anthropic_models",
|
||||
]
|
||||
},
|
||||
"tutorials/cost_tracking_coding",
|
||||
"tutorials/cursor_integration",
|
||||
"tutorials/github_copilot_integration",
|
||||
"tutorials/litellm_gemini_cli",
|
||||
"tutorials/litellm_qwen_code_cli",
|
||||
"tutorials/openai_codex",
|
||||
"tutorials/openweb_ui"
|
||||
"tutorials/openai_codex"
|
||||
]
|
||||
},
|
||||
|
||||
|
|
@ -487,6 +503,7 @@ const sidebars = {
|
|||
"mcp_control",
|
||||
"mcp_cost",
|
||||
"mcp_guardrail",
|
||||
"mcp_troubleshoot",
|
||||
]
|
||||
},
|
||||
"anthropic_unified",
|
||||
|
|
@ -601,6 +618,7 @@ const sidebars = {
|
|||
label: "Azure AI",
|
||||
items: [
|
||||
"providers/azure_ai",
|
||||
"providers/azure_ai/azure_model_router",
|
||||
"providers/azure_ai_agents",
|
||||
"providers/azure_ocr",
|
||||
"providers/azure_document_intelligence",
|
||||
|
|
@ -653,12 +671,13 @@ const sidebars = {
|
|||
"providers/bedrock_writer",
|
||||
"providers/bedrock_batches",
|
||||
"providers/aws_polly",
|
||||
"providers/bedrock_vector_store",
|
||||
]
|
||||
},
|
||||
"providers/litellm_proxy",
|
||||
"providers/ai21",
|
||||
"providers/aiml",
|
||||
"providers/bedrock_vector_store",
|
||||
]
|
||||
},
|
||||
"providers/litellm_proxy",
|
||||
"providers/abliteration",
|
||||
"providers/ai21",
|
||||
"providers/aiml",
|
||||
"providers/aleph_alpha",
|
||||
"providers/amazon_nova",
|
||||
"providers/anyscale",
|
||||
|
|
@ -710,6 +729,7 @@ const sidebars = {
|
|||
"providers/llamafile",
|
||||
"providers/llamagate",
|
||||
"providers/lm_studio",
|
||||
"providers/manus",
|
||||
"providers/meta_llama",
|
||||
"providers/milvus_vector_stores",
|
||||
"providers/mistral",
|
||||
|
|
@ -802,6 +822,7 @@ const sidebars = {
|
|||
"completion/knowledgebase",
|
||||
"guides/code_interpreter",
|
||||
"completion/message_trimming",
|
||||
"completion/message_sanitization",
|
||||
"completion/model_alias",
|
||||
"completion/mock_requests",
|
||||
"completion/predict_outputs",
|
||||
|
|
@ -838,6 +859,7 @@ const sidebars = {
|
|||
"proxy/load_balancing",
|
||||
"proxy/provider_budget_routing",
|
||||
"proxy/reliability",
|
||||
"proxy/fallback_management",
|
||||
"proxy/tag_routing",
|
||||
"proxy/timeout",
|
||||
"wildcard_routing"
|
||||
|
|
@ -857,10 +879,11 @@ const sidebars = {
|
|||
type: "category",
|
||||
label: "Tutorials",
|
||||
items: [
|
||||
"tutorials/openweb_ui",
|
||||
"tutorials/openai_codex",
|
||||
"tutorials/litellm_gemini_cli",
|
||||
"tutorials/litellm_qwen_code_cli",
|
||||
{
|
||||
type: "link",
|
||||
label: "AI Coding Tools (OpenWebUI, Claude Code, Gemini CLI, OpenAI Codex, etc.)",
|
||||
href: "/docs/ai_tools",
|
||||
},
|
||||
"tutorials/anthropic_file_usage",
|
||||
"tutorials/default_team_self_serve",
|
||||
"tutorials/msft_sso",
|
||||
|
|
@ -870,7 +893,6 @@ const sidebars = {
|
|||
"tutorials/presidio_pii_masking",
|
||||
"tutorials/elasticsearch_logging",
|
||||
"tutorials/gemini_realtime_with_audio",
|
||||
"tutorials/claude_responses_api",
|
||||
{
|
||||
type: "category",
|
||||
label: "LiteLLM Python SDK Tutorials",
|
||||
|
|
@ -967,6 +989,14 @@ const sidebars = {
|
|||
],
|
||||
},
|
||||
"troubleshoot",
|
||||
{
|
||||
type: "category",
|
||||
label: "Issue Reporting",
|
||||
items: [
|
||||
"troubleshoot/cpu_issues",
|
||||
"troubleshoot/memory_issues",
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
|
|
|||
19
document.txt
|
|
@ -1,19 +0,0 @@
|
|||
LiteLLM provides a unified interface for calling 100+ different LLM providers.
|
||||
|
||||
Key capabilities:
|
||||
- Translate requests to provider-specific formats
|
||||
- Consistent OpenAI-compatible responses
|
||||
- Retry and fallback logic across deployments
|
||||
- Proxy server with authentication and rate limiting
|
||||
- Support for streaming, function calling, and embeddings
|
||||
|
||||
Popular providers supported:
|
||||
- OpenAI (GPT-4, GPT-3.5)
|
||||
- Anthropic (Claude)
|
||||
- AWS Bedrock
|
||||
- Azure OpenAI
|
||||
- Google Vertex AI
|
||||
- Cohere
|
||||
- And 95+ more
|
||||
|
||||
This allows developers to easily switch between providers without code changes.
|
||||
1
enterprise/litellm_enterprise/proxy/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Package marker for enterprise proxy components.
|
||||
|
|
@ -0,0 +1 @@
|
|||
# Package marker for enterprise proxy common utilities.
|
||||
|
|
@ -8,6 +8,7 @@ from typing import TYPE_CHECKING, Any, Dict, List, Literal, Optional, Union, cas
|
|||
|
||||
from fastapi import HTTPException
|
||||
|
||||
import litellm
|
||||
from litellm import Router, verbose_logger
|
||||
from litellm._uuid import uuid
|
||||
from litellm.caching.caching import DualCache
|
||||
|
|
@ -836,15 +837,36 @@ class _PROXY_LiteLLMManagedFiles(CustomLogger, BaseFileEndpoints):
|
|||
return response
|
||||
|
||||
async def afile_retrieve(
|
||||
self, file_id: str, litellm_parent_otel_span: Optional[Span]
|
||||
self, file_id: str, litellm_parent_otel_span: Optional[Span], llm_router=None
|
||||
) -> OpenAIFileObject:
|
||||
stored_file_object = await self.get_unified_file_id(
|
||||
file_id, litellm_parent_otel_span
|
||||
)
|
||||
if stored_file_object:
|
||||
return stored_file_object.file_object
|
||||
else:
|
||||
|
||||
# Case 1 : This is not a managed file
|
||||
if not stored_file_object:
|
||||
raise Exception(f"LiteLLM Managed File object with id={file_id} not found")
|
||||
|
||||
# Case 2: Managed file and the file object exists in the database
|
||||
if stored_file_object and stored_file_object.file_object:
|
||||
return stored_file_object.file_object
|
||||
|
||||
# Case 3: Managed file exists in the database but not the file object (for. e.g the batch task might not have run)
|
||||
# So we fetch the file object from the provider. We deliberately do not store the result to avoid interfering with batch cost tracking code.
|
||||
if not llm_router:
|
||||
raise Exception(
|
||||
f"LiteLLM Managed File object with id={file_id} has no file_object "
|
||||
f"and llm_router is required to fetch from provider"
|
||||
)
|
||||
|
||||
try:
|
||||
model_id, model_file_id = next(iter(stored_file_object.model_mappings.items()))
|
||||
credentials = llm_router.get_deployment_credentials_with_provider(model_id) or {}
|
||||
response = await litellm.afile_retrieve(file_id=model_file_id, **credentials)
|
||||
response.id = file_id # Replace with unified ID
|
||||
return response
|
||||
except Exception as e:
|
||||
raise Exception(f"Failed to retrieve file {file_id} from provider: {str(e)}") from e
|
||||
|
||||
async def afile_list(
|
||||
self,
|
||||
|
|
@ -868,10 +890,11 @@ class _PROXY_LiteLLMManagedFiles(CustomLogger, BaseFileEndpoints):
|
|||
[file_id], litellm_parent_otel_span
|
||||
)
|
||||
|
||||
delete_response = None
|
||||
specific_model_file_id_mapping = model_file_id_mapping.get(file_id)
|
||||
if specific_model_file_id_mapping:
|
||||
for model_id, model_file_id in specific_model_file_id_mapping.items():
|
||||
await llm_router.afile_delete(model=model_id, file_id=model_file_id, **data) # type: ignore
|
||||
delete_response = await llm_router.afile_delete(model=model_id, file_id=model_file_id, **data) # type: ignore
|
||||
|
||||
stored_file_object = await self.delete_unified_file_id(
|
||||
file_id, litellm_parent_otel_span
|
||||
|
|
@ -879,6 +902,9 @@ class _PROXY_LiteLLMManagedFiles(CustomLogger, BaseFileEndpoints):
|
|||
|
||||
if stored_file_object:
|
||||
return stored_file_object
|
||||
elif delete_response:
|
||||
delete_response.id = file_id
|
||||
return delete_response
|
||||
else:
|
||||
raise Exception(f"LiteLLM Managed File object with id={file_id} not found")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[tool.poetry]
|
||||
name = "litellm-enterprise"
|
||||
version = "0.1.27"
|
||||
version = "0.1.28"
|
||||
description = "Package for LiteLLM Enterprise features"
|
||||
authors = ["BerriAI"]
|
||||
readme = "README.md"
|
||||
|
|
@ -22,7 +22,7 @@ requires = ["poetry-core"]
|
|||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
[tool.commitizen]
|
||||
version = "0.1.27"
|
||||
version = "0.1.28"
|
||||
version_files = [
|
||||
"pyproject.toml:version",
|
||||
"../requirements.txt:litellm-enterprise==",
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 172 KiB |
BIN
litellm-proxy-extras/dist/litellm_proxy_extras-0.4.21-py3-none-any.whl
vendored
Normal file
BIN
litellm-proxy-extras/dist/litellm_proxy_extras-0.4.21.tar.gz
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
-- CreateIndex
|
||||
-- Fixes performance issue in _check_duplicate_user_email function
|
||||
-- by enabling fast case-insensitive email lookups.
|
||||
--
|
||||
-- Without this index, queries with mode: "insensitive" cause full table scans.
|
||||
-- With this index, PostgreSQL can use an Index Scan for O(log n) performance.
|
||||
--
|
||||
-- Related: GitHub Issue #18411
|
||||
CREATE INDEX "LiteLLM_UserTable_user_email_lower_idx" ON "LiteLLM_UserTable"(LOWER("user_email"));
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
[tool.poetry]
|
||||
name = "litellm-proxy-extras"
|
||||
version = "0.4.20"
|
||||
version = "0.4.21"
|
||||
description = "Additional files for the LiteLLM Proxy. Reduces the size of the main litellm package."
|
||||
authors = ["BerriAI"]
|
||||
readme = "README.md"
|
||||
|
|
@ -22,7 +22,7 @@ requires = ["poetry-core"]
|
|||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
[tool.commitizen]
|
||||
version = "0.4.20"
|
||||
version = "0.4.21"
|
||||
version_files = [
|
||||
"pyproject.toml:version",
|
||||
"../requirements.txt:litellm-proxy-extras==",
|
||||
|
|
|
|||