Support missing base64 padding in managed character/video IDs so copied encoded IDs still decode to the original upstream character ID.
Made-with: Cursor
All Dockerfiles were pinning PyJWT 2.9.0 (Dockerfile, Dockerfile.database,
Dockerfile.dev) or had a stale wheel build for 2.9.0 (Dockerfile.non_root).
Updated to 2.12.0 to match pyproject.toml. Also bumps tar to 7.5.11 in
Dockerfile.non_root for security.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The wheels directory contains 2.12.0 after the pyproject.toml bump,
so the hardcoded 2.10.1 pin fails at build time.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix __main__ block: test returns None now, so always exited 1
- Close litellm_async_client in test_ssl_verification_with_aiohttp_transport
- Save/restore litellm.force_ipv4 and litellm.disable_aiohttp_transport
in test_force_ipv4_transport and test_aiohttp_disabled_transport
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
count_aiohttp_sessions() iterates every object in the Python GC,
which hangs in CI when xdist workers have millions of loaded objects.
Replace with direct session.closed checks — same coverage, no hang.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove real HTTP call to example.com in test_force_ipv4_transport
(hangs in CI when network is slow/unavailable)
- Close leaked aiohttp.ClientSession in test_ssl_verification_with_aiohttp_transport
- Add cleanup for transports in test_aiohttp_transport_trust_env_setting
- Add cleanup for handler in test_ssl_security_level
- Add cleanup for transport in test_ssl_context_transport
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: prisma migrate deploy failures on pre-existing instances
Fixes failed migrations due to idempotent schema changes on pre-existing litellm instances.
Problems:
1. P3018 recovery handler never returned True on successful resolution, causing "Database setup failed after multiple retries" even when the final recovery succeeded
2. _roll_back_migration exceptions escaped the P3018 handler, preventing _resolve_specific_migration from running
3. Migration SQL used ADD COLUMN/DROP COLUMN without IF [NOT] EXISTS, failing if schema was already modified
Changes:
- Add return True after successful P3018 idempotent error recovery
- Wrap _roll_back_migration in try/except to allow recovery continuation even if rollback fails
- Make migration.sql idempotent with IF NOT EXISTS / IF EXISTS clauses
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* test: add migration SQL idempotency safety tests
Adds TestMigrationSQLIdempotency test class that statically validates all
migration SQL files created after 2026-03-11 use idempotent DDL:
- ADD COLUMN must use IF NOT EXISTS
- DROP COLUMN must use IF EXISTS
- DROP INDEX must use IF EXISTS
- CREATE INDEX must use IF NOT EXISTS
This prevents the class of errors where prisma migrate deploy fails on
pre-existing instances because the schema was already modified.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: also catch TimeoutExpired in P3018 rollback handler
_roll_back_migration uses subprocess.run with timeout=60, so it can raise
subprocess.TimeoutExpired in addition to CalledProcessError. Without
catching this, a slow database during rollback would escape the handler
and bypass _resolve_specific_migration — the same class of bug.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: make all 85 migration SQL files idempotent, remove test cutoff
Fixed all existing migration files to use IF [NOT] EXISTS for DDL
statements (ADD COLUMN, DROP COLUMN, DROP INDEX, CREATE INDEX).
Removed the date cutoff from the idempotency tests so they now
validate all migrations, not just recent ones.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: make migration failure non-fatal by default, add --require_db_migration flag
By default the proxy now warns and continues when database migration
fails. Pass --require_db_migration (or set REQUIRE_DB_MIGRATION=true)
to restore the previous behavior of exiting with an error.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: wrap _resolve_specific_migration in try/except, guard RENAME COLUMN and ADD CONSTRAINT
Three fixes:
1. _resolve_specific_migration in the P3018 handler was not wrapped in
try/except, so failures there would bypass the return True and
propagate unexpectedly — partially defeating the rollback fix.
2. Bare RENAME COLUMN in 20260303000000_update_tool_table_policies was
non-idempotent. Wrapped in DO $$ IF EXISTS block. Also wrapped all
28 bare ADD CONSTRAINT statements across 9 migration files in
DO $$ IF NOT EXISTS (pg_constraint) blocks.
3. Added test_rename_column_is_guarded and test_add_constraint_is_guarded
to TestMigrationSQLIdempotency for full DDL coverage.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: retry after resolving idempotent migration, guard DROP CONSTRAINT
Three fixes:
1. Both P3009 and P3018 idempotent handlers returned True after
resolving a single migration, exiting before remaining pending
migrations were applied. Now they continue the retry loop so
prisma migrate deploy runs again for any remaining migrations.
2. Two migration files had bare DROP CONSTRAINT without a DO $$ IF
EXISTS guard, which fails if the constraint was already dropped.
Wrapped both in idempotent DO $$ blocks.
3. Added test_drop_constraint_is_guarded to catch unguarded DROP
CONSTRAINT in future migrations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: P3009 try/except, CREATE TABLE IF NOT EXISTS, restore fail-fast default
Four fixes:
1. P3009 idempotent handler now has the same try/except around
_roll_back_migration and _resolve_specific_migration as the P3018
handler. Previously a rollback or resolve failure in the P3009 path
would propagate and leave the migration unresolved.
2. Added IF NOT EXISTS to all 57 bare CREATE TABLE statements across
34 migration files. Added test_create_table_uses_if_not_exists to
catch this pattern.
3. Reverted the backwards-incompatible default behavior change: the
proxy now fails fast on migration failure (original behavior).
Added --skip_db_migration_check / SKIP_DB_MIGRATION_CHECK to
opt into warn-and-continue instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
When scope_user_search_to_org flag is ON, team admins (non-org-admins) were
getting 403 because the code only checked for ORG_ADMIN role in org memberships.
Now checks all org memberships (any role) and falls back to the API key's team_id
to resolve the org.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add SecretRedactionFilter to scrub API keys, tokens, and credentials
from all log records (messages, args, tracebacks, extra fields).
- Enable redaction by default; opt out with LITELLM_DISABLE_REDACT_SECRETS=true
- Redact patterns: sk-*, Bearer tokens, x-api-key values, base64 creds
- Handle JSON formatter exception hooks and percent-style format args
- Snapshot dict iteration to avoid RuntimeError during concurrent logging
The second `responses_api_bridge_check` call unconditionally overwrote
`responses_api_model_info` set by the first call. For models using the
`responses/` prefix (e.g. `azure/responses/<deployment>`), the first
check correctly detected `mode: "responses"` and stripped the prefix,
but the second check then overwrote it with an empty dict since the
model no longer started with `responses/`.
Skip the second check when the first already detected responses mode.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add sagemaker_nova provider for Nova models on SageMaker
Add support for custom/fine-tuned Amazon Nova models (Nova Micro, Nova Lite,
Nova 2 Lite) deployed on SageMaker Inference real-time endpoints.
Nova uses OpenAI-compatible request/response format with additional
Nova-specific parameters (top_k, reasoning_effort, allowed_token_ids,
truncate_prompt_tokens) and requires stream:true in the request body.
Nova endpoints also reject 'model' in the request body.
Changes:
- New provider: sagemaker_nova/<endpoint-name>
- SagemakerNovaConfig inherits from SagemakerChatConfig
- Override transform_request to strip 'model' from request body
- Override supports_stream_param_in_request_body (True for Nova)
- Extend get_supported_openai_params with Nova-specific params
- Refactored SagemakerChatConfig to use custom_llm_provider param
instead of hardcoded strings (backwards-compatible)
- Consolidated main.py routing for sagemaker_chat and sagemaker_nova
- 22 unit tests + 9 integration tests (skip-gated)
- Documentation with SDK, streaming, multimodal, and proxy examples
- All tests verified against live SageMaker Nova endpoint
* fix: move integration tests to tests/local_testing/ per test directory policy
* fix: remove unused module-level SagemakerNovaConfig instance
The sagemaker_nova_config singleton was never imported or used — the
ProviderConfigManager creates its own instance via the lambda registered
in utils.py. Removing this leftover boilerplate.
---------
Co-authored-by: Krish Dholakia <krrishdholakia@gmail.com>
* docs: add Claude Code skills page for litellm-skills
* docs: move skills page to new 'Manage with AI Agents' section
* docs: simplify install to one-liner, rename to LiteLLM Skills
- Fix mypy arg-type error in background_streaming.py by adding proper
type annotation and cast for terminal_status
- Fix ruff F401 false positive for httpx import in vantage_destination.py
caused by from __future__ import annotations
- Fix flaky test_arouter_responses_api_bridge by providing a properly
structured mock response to prevent exception mapping errors
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The default timeout (600s) from AsyncHTTPHandler is sufficient.
Removes the explicit timeout param to keep the call simple.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace per-request `httpx.AsyncClient` with `get_async_httpx_client`
to avoid the +500ms latency penalty from creating new clients per
request. Updates tests to mock the cached client factory.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The documentation test checks that all env vars used in code are
documented. The Vantage integration added 5 new env vars without
updating the reference table.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix genuine regression in responses_api_bridge_check where the second
call assigned to `model_info` instead of `responses_api_model_info`,
preventing gpt-5.4 + tools + reasoning_effort from routing to the
Responses API bridge.
Also update outdated tests:
- Vantage tests: match "csv" file key and use supported column names
- Anthropic caching test: add "type": "custom" to expected tool payload
- Claude Agent SDK test: remove non-deterministic LLM content assertion
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Reduce RENDER_BATCH_SIZE from 5 to 3 for more frequent chart updates
- Add LoadingOutlined spinner at the start of all fetching Alert banners
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace subtle loading text with antd Alert banners that clearly communicate
pagination status, and batch state flushes to reduce chart re-renders.
- Replace inline loading text with warning Alert banners showing progress,
"open a new tab" link with ExportOutlined icon, and primary Stop button
- Batch setData calls every 5 pages instead of per-page to cut re-renders ~80%
- Reduce fetch delay from 500ms to 300ms for faster data loading
- Add "Charts will update periodically" messaging to set expectations
- Fix pre-existing TS error: Button icon prop was using render function instead of ReactNode
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Map provider finish_reason "content_filtered" to the OpenAI-compatible "content_filter" and extend core_helpers tests to cover this case.
Made-with: Cursor
* fix: restore offline tiktoken cache for non-root envs
Made-with: Cursor
* chore: mkdir for custom tiktoken cache dir
Made-with: Cursor
* test: patch tiktoken.get_encoding in custom-dir test to avoid network
Made-with: Cursor
* test: clear CUSTOM_TIKTOKEN_CACHE_DIR in helper for test isolation
Made-with: Cursor
* test: restore default_encoding module state after custom-dir test
Made-with: Cursor