* docs: add Prisma migration troubleshooting guide
Add troubleshooting documentation for common Prisma migration errors
encountered when upgrading/downgrading LiteLLM proxy versions.
Covers:
- 'relation does not exist' errors after version rollback
- Blocked migrations from previous failures
- Migration state mismatch after version rollback
- General tips for prisma migrate resolve, db push, and migrate deploy
* docs: simplify prisma migration troubleshooting - focus on delete + restart
Add the following SCIM v2 discovery endpoints per RFC 7643/7644:
- GET /scim/v2 - Base resource discovery (ListResponse of ResourceTypes)
- GET /scim/v2/ResourceTypes - List all supported resource types
- GET /scim/v2/ResourceTypes/{id} - Get a specific resource type (User/Group)
- GET /scim/v2/Schemas - List all supported schemas
- GET /scim/v2/Schemas/{uri} - Get a specific schema by URI
These endpoints are required by identity providers (Okta, Azure AD, etc.)
for SCIM resource discovery. Previously, GET /scim/v2 returned 404.
Also adds SCIMResourceType, SCIMSchema, and SCIMSchemaAttribute Pydantic
models to the SCIM types module.
Fixes#20295
* fix: strip stale mcp-session-id header to prevent 'Session not found' error loop
When VSCode reconnects to LiteLLM's MCP endpoint after a reload, it sends
a stale mcp-session-id header. The session was already cleaned up, causing
a 404 'Session not found' error. VSCode retries with the same stale ID,
creating an infinite error loop.
Before forwarding requests to the StreamableHTTP session manager, check if
the mcp-session-id header references a valid session. If the session doesn't
exist, strip the header so a new session is created automatically.
Fixes#20292
* refactor: extract stale session handling into _strip_stale_mcp_session_header helper
Add moonshot/kimi-k2.5 model with:
- Input cost: $0.60/M tokens (6e-07)
- Output cost: $3.00/M tokens (3e-06)
- Cache read cost: $0.10/M tokens (1e-07)
- 256K context window
- Vision, function calling, tool choice, web search support
Reference: https://huggingface.co/moonshotai/Kimi-K2.5
Note: K2.5 thinking mode is controlled via API parameters, not a separate model ID.
Co-authored-by: krauckbot <krauckbot123@gmail.com>
* Add request tags documentation for spend tracking
- Add new concise doc explaining how to tag model requests
- Include Python SDK and cURL examples
- Show where tags appear in spend logs
- Add common use cases table (AWS accounts, teams, projects)
- Include how to set default tags on API keys
- Add to Spend Tracking section in sidebar
Co-authored-by: ishaan <ishaan@berri.ai>
* Simplify request tags doc for AI Gateway usage
- Focus on config.yaml setup with default_key_generate_params
- Show both request body and header methods for sending tags
- Remove SDK examples, keep concise cURL examples
- Streamline for quick reference
Co-authored-by: ishaan <ishaan@berri.ai>
* Update request tags doc to show model-level config
- Set tags directly on model deployments in litellm_params
- Requests just specify model, tags applied automatically
- Use clear naming: AWS_IAM_PROD, AWS_IAM_DEV
Co-authored-by: ishaan <ishaan@berri.ai>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: ishaan <ishaan@berri.ai>
* docs: add FAQ for setting up and verifying LITELLM_LICENSE
Added two new FAQ entries to the Enterprise docs page:
- How to set up your Enterprise License (LITELLM_LICENSE) via .env, Docker, or docker-compose
- How to verify the license is active by checking for 'Enterprise Edition' in the Swagger UI
* docs: trim license FAQ to essential steps only
* perf: cache _get_relevant_args_to_use_for_logging() as module-level frozenset
The set of valid LLM API parameter names for logging was being rebuilt
on every request from 8 OpenAI SDK type annotations + set operations.
Since these are static TypedDict annotations that never change at
runtime, compute once at import time and store as a class-level
frozenset.
Line profiler: get_standard_logging_model_parameters() dropped from
774ms to 77ms across 12K calls (90% reduction, ~25µs/req saved).
* test: add tests for cached ModelParamHelper logging args
Verify cached frozenset matches dynamic computation and that
prompt content keys (messages, prompt, input) are excluded from
logged model parameters.
- Cache CallTypes enum values as module-level dict to avoid repeated list
comprehension and enum construction on every call
- Hoist update_response_metadata getattr lookup to top of function
- Guard verbose print_verbose call behind _is_debugging_on() check
Pass-through endpoints (like vLLM classify) were not setting
standard_logging_object because _get_assembled_streaming_response
returns None for non-ModelResponse results.
This caused model_max_budget_limiter.async_log_success_event to raise
ValueError('standard_logging_payload is required').
The fix adds an elif branch in async_success_handler that mirrors the
non-pass-through code path.
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: Krish Dholakia <krrishdholakia@gmail.com>
Add x-api-key header to CountTokens handler to match chat completion
authentication. Azure AI Anthropic requires this header per Microsoft's
native API format.
Bedrock rejects requests when toolResult or toolUse blocks within a
single message contain duplicate IDs. The Converse message transformer
merges consecutive tool/assistant messages without checking for
duplicate toolUseId values, causing BedrockException errors.
Add _deduplicate_bedrock_content_blocks() — a generalized helper that
removes duplicate blocks by ID, logs a warning for each dropped
duplicate via verbose_logger, and preserves non-tool blocks (e.g.
cachePoint). Apply it at all four merge sites (sync/async × toolResult/
toolUse).
The Anthropic /messages path was fixed in PR #19324; this applies the
equivalent fix to the Bedrock Converse path.
Fixes#20048
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Fix Nova grounding web_search_options={} not applying systemTool
Two bugs prevented web_search_options={} from working for Nova grounding:
1. Empty dict falsy check: The condition `value and isinstance(value, dict)`
short-circuits to False when value is {} (empty dict is falsy in Python).
Changed to `isinstance(value, dict)` to match Anthropic's implementation.
2. Pre-formatted tools mangled by _bedrock_tools_pt: The systemTool
(already in Bedrock format) was added to optional_params["tools"], but
_process_tools_and_beta passed all tools through _bedrock_tools_pt which
expects OpenAI-format tools. This corrupted the systemTool into an empty
toolSpec. Fixed by separating systemTool blocks before transformation
and appending them after.
Fixes follow-up to #19598
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix python-multipart Python version constraint for Poetry lock
python-multipart ^0.0.22 requires Python >=3.10 but the project supports
>=3.9. Add python = ">=3.10" marker so Poetry can resolve dependencies
for Python 3.9.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Previously, when Model Armor guardrail blocked a request/response,
the `applied_guardrails` field was not populated in the logs because
`add_guardrail_to_applied_guardrails_header()` was called after the
HTTPException was raised.
This fix moves the `add_guardrail_to_applied_guardrails_header()` call
to before the blocking check in all hooks:
- async_pre_call_hook (pre_call mode)
- async_moderation_hook (during_call mode)
- async_post_call_success_hook (post_call mode)
- async_post_call_streaming_iterator_hook (streaming)
This ensures that even when a guardrail blocks content, the guardrail
name is properly recorded in the logs for observability.
Added regression tests to verify applied_guardrails is populated when
content is blocked.
Co-authored-by: Cursor <cursoragent@cursor.com>