Skip to content

Commit 6bd7cd7

Browse files
authored
Merge branch 'main' into litellm_oss_staging_03_11_2026
2 parents fa68d69 + 291e6e1 commit 6bd7cd7

File tree

125 files changed

+7139
-855
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+7139
-855
lines changed

.circleci/config.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4337,7 +4337,8 @@ jobs:
43374337
name: Check for expected error
43384338
command: |
43394339
if grep -q "Error: P1001: Can't reach database server at" docker_output.log && \
4340-
grep -q "ERROR: Application startup failed. Exiting." docker_output.log; then
4340+
(grep -q "Database setup failed after multiple retries" docker_output.log || \
4341+
grep -q "ERROR: Application startup failed. Exiting." docker_output.log); then
43414342
echo "Expected error found. Test passed."
43424343
else
43434344
echo "Expected error not found. Test failed."

.github/workflows/create_daily_staging_branch.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,39 @@ jobs:
4141
git push origin $BRANCH_NAME
4242
echo "Successfully created and pushed branch: $BRANCH_NAME"
4343
fi
44+
45+
create-internal-dev-branch:
46+
runs-on: ubuntu-latest
47+
48+
steps:
49+
- name: Checkout repository
50+
uses: actions/checkout@v3
51+
with:
52+
fetch-depth: 0
53+
54+
- name: Create internal dev branch
55+
env:
56+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
57+
run: |
58+
# Configure Git user
59+
git config user.name "github-actions[bot]"
60+
git config user.email "github-actions[bot]@users.noreply.github.com"
61+
62+
# Generate branch name with MM_DD_YYYY format
63+
BRANCH_NAME="litellm_internal_dev_$(date +'%m_%d_%Y')"
64+
echo "Creating branch: $BRANCH_NAME"
65+
66+
# Fetch all branches
67+
git fetch --all
68+
69+
# Check if the branch already exists
70+
if git show-ref --verify --quiet refs/remotes/origin/$BRANCH_NAME; then
71+
echo "Branch $BRANCH_NAME already exists. Skipping creation."
72+
else
73+
echo "Creating new branch: $BRANCH_NAME"
74+
# Create the new branch from main
75+
git checkout -b $BRANCH_NAME origin/main
76+
# Push the new branch
77+
git push origin $BRANCH_NAME
78+
echo "Successfully created and pushed branch: $BRANCH_NAME"
79+
fi

CLAUDE.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,22 @@ LiteLLM is a unified interface for 100+ LLM providers with two main components:
102102
### UI / Backend Consistency
103103
- When wiring a new UI entity type to an existing backend endpoint, verify the backend API contract (single value vs. array, required vs. optional params) and ensure the UI controls match — e.g., use a single-select dropdown when the backend accepts a single value, not a multi-select
104104

105+
### MCP OAuth / OpenAPI Transport Mapping
106+
- `TRANSPORT.OPENAPI` is a UI-only concept. The backend only accepts `"http"`, `"sse"`, or `"stdio"`. Always map it to `"http"` before any API call (including pre-OAuth temp-session calls).
107+
- FastAPI validation errors return `detail` as an array of `{loc, msg, type}` objects. Error extractors must handle: array (map `.msg`), string, nested `{error: string}`, and fallback.
108+
- When an MCP server already has `authorization_url` stored, skip OAuth discovery (`_discovery_metadata`) — the server URL for OpenAPI MCPs is the spec file, not the API base, and fetching it causes timeouts.
109+
- `client_id` should be optional in the `/authorize` endpoint — if the server has a stored `client_id` in credentials, use that. Never require callers to re-supply it.
110+
111+
### MCP Credential Storage
112+
- OAuth credentials and BYOK credentials share the `litellm_mcpusercredentials` table, distinguished by a `"type"` field in the JSON payload (`"oauth2"` vs plain string).
113+
- When deleting OAuth credentials, check type before deleting to avoid accidentally deleting a BYOK credential for the same `(user_id, server_id)` pair.
114+
- Always pass the raw `expires_at` timestamp to the client — never set it to `None` for expired credentials. Let the frontend compute the "Expired" display state from the timestamp.
115+
- Use `RecordNotFoundError` (not bare `except Exception`) when catching "already deleted" in credential delete endpoints.
116+
117+
### Browser Storage Safety (UI)
118+
- Never write LiteLLM access tokens or API keys to `localStorage` — use `sessionStorage` only. `localStorage` survives browser close and is readable by any injected script (XSS).
119+
- Shared utility functions (e.g. `extractErrorMessage`) belong in `src/utils/` — never define them inline in hooks or duplicate them across files.
120+
105121
### Database Migrations
106122
- Prisma handles schema migrations
107123
- Migration files auto-generated with `prisma migrate dev`

docs/my-website/docs/proxy/config_settings.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -944,7 +944,7 @@ router_settings:
944944
| QDRANT_URL | Connection URL for Qdrant database
945945
| QDRANT_VECTOR_SIZE | Vector size for Qdrant operations. Default is 1536
946946
| REDIS_CONNECTION_POOL_TIMEOUT | Timeout in seconds for Redis connection pool. Default is 5
947-
| REDIS_CLUSTER_NODES | JSON-formatted list of Redis cluster startup nodes for Redis Cluster mode. Example: '[{"host": "node1", "port": 6379}]'
947+
| REDIS_CLUSTER_NODES | JSON-formatted list of Redis cluster startup nodes for Redis Cluster mode. Example: `[{"host": "node1", "port": 6379}]`
948948
| REDIS_HOST | Hostname for Redis server
949949
| REDIS_PASSWORD | Password for Redis service
950950
| REDIS_PORT | Port number for Redis server

docs/my-website/docs/proxy/guardrails/guardrail_policies.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,10 @@ Response:
309309
</TabItem>
310310
</Tabs>
311311

312+
## Policy Flow Builder
313+
314+
For conditional execution (e.g., run a second guardrail only if the first fails), use the [Policy Flow Builder](./policy_flow_builder) to define pipelines with per-step pass/fail actions.
315+
312316
## Config Reference
313317

314318
### `policies`
@@ -323,6 +327,7 @@ policies:
323327
remove: [...]
324328
condition:
325329
model: ...
330+
pipeline: ... # optional; see Policy Flow Builder
326331
```
327332

328333
| Field | Type | Description |
@@ -332,6 +337,7 @@ policies:
332337
| `guardrails.add` | `list[string]` | Guardrails to enable. |
333338
| `guardrails.remove` | `list[string]` | Guardrails to disable (useful with inheritance). |
334339
| `condition.model` | `string` or `list[string]` | Optional. Only apply when model matches. Supports regex. |
340+
| `pipeline` | `object` | Optional. Ordered guardrail execution with per-step actions. See [Policy Flow Builder](./policy_flow_builder). |
335341

336342
### `policy_attachments`
337343

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
# Policy Flow Builder
2+
3+
The Policy Flow Builder lets you design guardrail pipelines with **conditional execution**. Instead of running guardrails independently, you chain them into ordered steps and control what happens when each guardrail passes or fails.
4+
5+
Two powerful patterns it enables: **guardrail fallbacks** (try a different guardrail when one fails) and **retrying the same guardrail** (run the same guardrail again if it fails, e.g. to handle transient errors).
6+
7+
## When to use the Flow Builder
8+
9+
| Approach | Use case |
10+
|----------|----------|
11+
| **Simple policy** (`guardrails.add`) | All guardrails run in parallel; any failure blocks the request. |
12+
| **Flow Builder** (pipeline) | Guardrails run in sequence; you choose actions per step (next, block, allow, custom response). |
13+
14+
Use the Flow Builder when you need:
15+
16+
- **Guardrail fallbacks** — use `on_fail: next` to try a different guardrail when one fails (e.g., fast filter → stricter filter)
17+
- **Retrying the same guardrail** — add the same guardrail as multiple steps; if it fails, `on_fail: next` moves to the next step, which can be the same guardrail again (useful for transient API errors or rate limits)
18+
- **Conditional routing** — e.g., if a fast guardrail fails, run a more advanced one instead of blocking immediately
19+
- **Custom responses** — return a specific message when a guardrail fails instead of a generic block
20+
- **Data chaining** — pass modified data (e.g., PII-masked content) from one step to the next
21+
- **Fine-grained control** — different actions on pass vs. fail per step
22+
23+
## Concepts
24+
25+
### Pipeline
26+
27+
A pipeline has:
28+
29+
- **Mode**: `pre_call` (before the LLM) or `post_call` (after the LLM)
30+
- **Steps**: Ordered list of guardrail steps
31+
32+
### Step actions
33+
34+
Each step defines what happens when the guardrail **passes** and when it **fails**:
35+
36+
| Action | Description |
37+
|--------|-------------|
38+
| **Next Step** | Continue to the next guardrail in the pipeline |
39+
| **Allow** | Stop the pipeline and allow the request to proceed |
40+
| **Block** | Stop the pipeline and block the request |
41+
| **Custom Response** | Return a custom message instead of the default block |
42+
43+
### Step options
44+
45+
| Field | Type | Description |
46+
|-------|------|--------------|
47+
| `guardrail` | `string` | Name of the guardrail to run |
48+
| `on_pass` | `string` | Action when guardrail passes: `next`, `allow`, `block`, `modify_response` |
49+
| `on_fail` | `string` | Action when guardrail fails: `next`, `allow`, `block`, `modify_response` |
50+
| `pass_data` | `boolean` | Forward modified request data (e.g., PII-masked) to the next step |
51+
| `modify_response_message` | `string` | Custom message when using `modify_response` action |
52+
53+
## Using the Flow Builder (UI)
54+
55+
1. Go to **Policies** in the LiteLLM Admin UI
56+
2. Click **+ Create New Policy** or **Edit** on an existing policy
57+
3. Select **Flow Builder** (instead of the simple form)
58+
4. Design your flow:
59+
- **Trigger** — Incoming LLM request (runs when the policy matches)
60+
- **Steps** — Add guardrails, set ON PASS and ON FAIL actions per step
61+
- **End** — Request proceeds to the LLM
62+
5. Use the **+** between steps to insert new steps
63+
6. Use the **Test** panel to run sample messages through the pipeline before saving
64+
7. Click **Save** to create or update the policy
65+
66+
## Config (YAML)
67+
68+
Define a pipeline in your policy config:
69+
70+
```yaml showLineNumbers title="config.yaml"
71+
guardrails:
72+
- guardrail_name: pii_masking
73+
litellm_params:
74+
guardrail: presidio
75+
mode: pre_call
76+
77+
- guardrail_name: prompt_injection
78+
litellm_params:
79+
guardrail: lakera
80+
mode: pre_call
81+
82+
policies:
83+
my-pipeline-policy:
84+
description: "PII mask first, then check for prompt injection"
85+
guardrails:
86+
add:
87+
- pii_masking
88+
- prompt_injection
89+
pipeline:
90+
mode: pre_call
91+
steps:
92+
- guardrail: pii_masking
93+
on_pass: next
94+
on_fail: block
95+
pass_data: true
96+
- guardrail: prompt_injection
97+
on_pass: allow
98+
on_fail: block
99+
100+
policy_attachments:
101+
- policy: my-pipeline-policy
102+
scope: "*"
103+
```
104+
105+
## Fallbacks and retries
106+
107+
### Guardrail fallbacks
108+
109+
Use `on_fail: next` to fall back to another guardrail when one fails. Run a lightweight guardrail first; if it fails, escalate to a stricter or different provider:
110+
111+
```yaml
112+
policies:
113+
fallback-policy:
114+
guardrails:
115+
add:
116+
- fast_content_filter
117+
- strict_content_filter
118+
pipeline:
119+
mode: pre_call
120+
steps:
121+
- guardrail: fast_content_filter
122+
on_pass: allow
123+
on_fail: next
124+
- guardrail: strict_content_filter
125+
on_pass: allow
126+
on_fail: block
127+
```
128+
129+
If `fast_content_filter` passes → allow. If it fails → run `strict_content_filter`; pass → allow, fail → block.
130+
131+
### Retrying the same guardrail
132+
133+
Add the same guardrail as multiple steps to retry on failure. Useful for transient errors (API timeouts, rate limits):
134+
135+
```yaml
136+
policies:
137+
retry-policy:
138+
guardrails:
139+
add:
140+
- lakera_prompt_injection
141+
pipeline:
142+
mode: pre_call
143+
steps:
144+
- guardrail: lakera_prompt_injection
145+
on_pass: allow
146+
on_fail: next
147+
- guardrail: lakera_prompt_injection
148+
on_pass: allow
149+
on_fail: block
150+
```
151+
152+
First attempt passes → allow. First attempt fails → retry the same guardrail; second pass → allow, second fail → block.
153+
154+
## Example: Custom response on fail
155+
156+
Return a branded message instead of a generic block:
157+
158+
```yaml
159+
policies:
160+
branded-block-policy:
161+
guardrails:
162+
add:
163+
- pii_detector
164+
pipeline:
165+
mode: pre_call
166+
steps:
167+
- guardrail: pii_detector
168+
on_pass: allow
169+
on_fail: modify_response
170+
modify_response_message: "Your message contains sensitive information. Please remove PII and try again."
171+
```
172+
173+
## Test a pipeline (API)
174+
175+
Test a pipeline with sample messages before attaching it:
176+
177+
```bash
178+
curl -X POST "http://localhost:4000/policies/test-pipeline" \
179+
-H "Authorization: Bearer <your_api_key>" \
180+
-H "Content-Type: application/json" \
181+
-d '{
182+
"pipeline": {
183+
"mode": "pre_call",
184+
"steps": [
185+
{
186+
"guardrail": "pii_masking",
187+
"on_pass": "next",
188+
"on_fail": "block",
189+
"pass_data": true
190+
},
191+
{
192+
"guardrail": "prompt_injection",
193+
"on_pass": "allow",
194+
"on_fail": "block"
195+
}
196+
]
197+
},
198+
"test_messages": [
199+
{"role": "user", "content": "What is 2+2?"},
200+
{"role": "user", "content": "My SSN is 123-45-6789"}
201+
]
202+
}'
203+
```
204+
205+
Response includes per-step outcomes (pass/fail/error), actions taken, and timing.
206+
207+
## Pipeline vs simple policy
208+
209+
When a policy has a `pipeline`, the pipeline defines execution order and actions. The `guardrails.add` list must include all guardrails used in the pipeline steps.
210+
211+
| Policy type | Execution |
212+
|-------------|-----------|
213+
| Simple (`guardrails.add` only) | All guardrails run; any failure blocks |
214+
| Pipeline (`pipeline` present) | Steps run in order; actions control flow |
215+
216+
## Related docs
217+
218+
- [Guardrail Policies](./guardrail_policies) — Policy basics, attachments, inheritance
219+
- [Policy Templates](./policy_templates) — Pre-built policy templates

0 commit comments

Comments
 (0)