Commit Graph
36424 Commits
Author SHA1 Message Date
Krish DholakiaandGitHub 8d92d8637d Merge branch 'main' into litellm_oss_staging_03_18_2026 2026-03-19 17:57:55 -07:00
Krish DholakiaandGitHub d4857f682d Merge pull request #24135 from michelligabriele/fix/deferred-guardrail-logging-v2
fix(proxy): defer logging until post-call guardrails complete
2026-03-19 17:57:00 -07:00
Krish DholakiaandGitHub b1731b6798 Merge pull request #24168 from BerriAI/cursor/litellm-license-key-environment-16b4
docs: add LiteLLM license key environment variable instructions
2026-03-19 17:35:33 -07:00
Cursor AgentandKrish Dholakia e668ca310d docs: add LiteLLM license key environment variable instructions
Added a new section to the config.yaml documentation explaining how to
set the LITELLM_LICENSE environment variable for enterprise features.

Co-authored-by: Krish Dholakia <krrishdholakia@gmail.com>
2026-03-20 00:28:21 +00:00
yuneng-jiangandGitHub 35d4984033 Merge pull request #24167 from joereyna/fix/black-format-types
chore: apply black formatting to proxy/_types.py to fix lint CI
2026-03-19 17:25:08 -07:00
joereyna 6f1bac07e5 chore: apply black formatting to proxy/_types.py to fix lint CI 2026-03-19 17:11:04 -07:00
yuneng-jiangandGitHub 0781f68b8a Merge pull request #24150 from BerriAI/litellm_yj_march_18_2026
[Infra] Merge daily internal branch with main
2026-03-19 16:43:47 -07:00
yuneng-jiang 7b600cdbfe linting 2026-03-19 16:31:50 -07:00
yuneng-jiang f60e3cfd34 remove returning key in error message 2026-03-19 16:29:51 -07:00
Jonathan Barazany 32cb6f0cd9 fix: guard short-circuit against providers with native agentic loop
- Skip short-circuit for providers that have a BaseAnthropicMessagesConfig
  (bedrock, vertex_ai, azure_ai, anthropic) — they use the agentic loop
  which includes a follow-up LLM synthesis step. Short-circuiting would
  return raw search text instead of an LLM-synthesized answer.
- Add fallback to litellm.get_llm_provider() for custom_llm_provider
  derivation when litellm_params is overwritten by kwargs.
- Add test for bedrock guard.

Addresses Greptile review comments #3 and #4.
2026-03-20 01:07:20 +02:00
yuneng-jiangandClaude Opus 4.6 05620c87e3 [Fix] Update bulk key update tests for find_unique refactor
Tests were outdated after _get_and_validate_existing_key was refactored
to use prisma_client.db.litellm_verificationtoken.find_unique() and
ProxyException. Also add ProxyException handling in bulk_update_keys
error extractor so error messages aren't empty.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 15:34:44 -07:00
yuneng-jiangandGitHub 2d3cff99fe Merge pull request #24159 from joereyna/fix/add-poetry-lock-check
chore: add poetry check --lock to lint CI to prevent stale lockfile merges
2026-03-19 14:48:11 -07:00
yuneng-jiangandGitHub 3565059d32 Merge pull request #24155 from BerriAI/litellm_api_reference_path_routing
[Refactor] UI - API Reference: Migrate to Path-Based Routing
2026-03-19 14:39:22 -07:00
joereyna d118bf4818 chore: add poetry check --lock to lint CI to prevent stale lockfile merges 2026-03-19 14:36:02 -07:00
yuneng-jiang e86ca7f34d Revert "[Fix] Update tests for _get_and_validate_existing_key refactor"
This reverts commit cf63697703.
2026-03-19 14:32:14 -07:00
yuneng-jiangandClaude Opus 4.6 2e70c23307 Gate legacy redirect on authLoading to ensure proxyBaseUrl is resolved
The redirect useEffect fires before getUiConfig() completes, so
proxyBaseUrl is always "" on first render. Gate on !authLoading so
the redirect only fires after config is fetched, matching the pattern
used by the login redirect.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 14:05:56 -07:00
yuneng-jiangandClaude Opus 4.6 e9e5ed989c Move legacy redirect from render phase to useEffect
router.replace was called directly during render, which is unsafe in
React 18 concurrent mode. Move it into a useEffect and use a computed
flag (isLegacyRedirect) to show LoadingScreen while redirecting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 13:59:45 -07:00
yuneng-jiangandClaude Opus 4.6 895951744d Fix leftnav navigation regression and useProxySettings initial state
The leftnav was updated to emit page="api-reference" but only "api_ref"
was in LEGACY_REDIRECTS, causing clicks to fall through to the default
Usage page. Add "api-reference" entry to the redirect map. Also include
LITELLM_UI_API_DOC_BASE_URL in the hook's initial state to avoid a
brief flash of incorrect base URL.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 13:36:21 -07:00
yuneng-jiangandClaude Opus 4.6 519afa494c [Refactor] UI - API Reference: Migrate to path-based routing
Move the API Reference page from query-param routing (?page=api_ref) to
Next.js path-based routing (/ui/api-reference). Add a LEGACY_REDIRECTS
map in the root page.tsx so users with old bookmarks are seamlessly
redirected. Future page migrations only need one new map entry.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 12:57:17 -07:00
Joe ReynaandGitHub 2df965513e Merge pull request #24153 from joereyna/fix/black-format-lint-2
chore: apply black formatting to fix lint CI (batch 2)
2026-03-19 12:56:48 -07:00
Krish DholakiaandGitHub 739356640b Merge pull request #24120 from BerriAI/litellm_proxy-azure-api-version-bump
feat(proxy): use AZURE_DEFAULT_API_VERSION for proxy --api_version default
2026-03-19 12:54:14 -07:00
yuneng-jiangandClaude Opus 4.6 cf63697703 [Fix] Update tests for _get_and_validate_existing_key refactor
Tests were outdated after _get_and_validate_existing_key was refactored
to use prisma_client.db.litellm_verificationtoken.find_unique() instead
of prisma_client.get_data(), and to raise ProxyException instead of
HTTPException. Also fix bulk_update_keys error handler to extract
ProxyException.message (str(ProxyException) returns empty string).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 12:41:11 -07:00
joereyna 004d8d01f6 chore: apply black formatting to fix lint CI 2026-03-19 12:39:39 -07:00
f784da41af Fix get_complete_url to honour ANTHROPIC_BASE_URL in experimental passthrough
Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-19 12:37:12 -07:00
yuneng-jiangandClaude Opus 4.6 c2b8ba8b1b [Fix] Resolve mypy errors in key_management_endpoints.py
Add None guard for prisma_client before calling update_data, and add
"unblocked" to AUDIT_ACTIONS literal type.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 12:28:56 -07:00
yuneng-jiangandGitHub dfcf978745 Merge pull request #24092 from joereyna/fix/black-format-lint
chore: apply black formatting to fix lint CI
2026-03-19 12:22:48 -07:00
b7e2269942 Address review feedback: fix OAuth routing in get_auth_header and self-contained validate_environment
Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-19 12:17:00 -07:00
michelligabriele 92b8e1acf8 address greptile review: async sleep, SIGKILL Windows guard, trailing newlines 2026-03-19 20:03:07 +01:00
yuneng-jiang afb35204ce Merge remote-tracking branch 'origin' into litellm_yj_march_18_2026 2026-03-19 11:53:58 -07:00
michelligabriele 1f04fa2461 fix(proxy): kill orphaned prisma engine subprocess on failed disconnect 2026-03-19 19:50:39 +01:00
michelligabriele 573f6b78ea fix(proxy): split orphan cleanup into separate try blocks for resilience
Split the single try/except in the _exception_raised cleanup path into
separate try blocks for asyncio.create_task and executor.submit, matching
the pattern used in _run_deferred_stream_guardrails. If create_task
raises, sync logging via executor.submit still fires.
2026-03-19 19:29:42 +01:00
yuneng-jiangandGitHub b13ba1ddcc Merge pull request #24144 from BerriAI/litellm_add_vitest_coverage
[Test] UI: Add vitest coverage for 10 untested components
2026-03-19 11:24:42 -07:00
michelligabriele ee17ef3029 fix(proxy): replace sys.exc_info with boolean sentinel for orphan detection
Replace sys.exc_info()[1] check with an explicit _exception_raised boolean
sentinel. The flag is function-scoped, immune to outer exception context,
and only set when an exception actually occurs in base_process_llm_request.
This prevents false positives when called from a caller's except block.
2026-03-19 19:14:01 +01:00
Jonathan Barazany 141ad04955 refactor: reuse get_last_user_message, fix UUID convention, move import
- Replace hand-rolled _extract_search_query with existing
  get_last_user_message from common_utils
- Use full UUID (str(uuid.uuid4())) to match codebase convention
- Move uuid import to module level per CLAUDE.md
2026-03-19 19:56:42 +02:00
Jonathan Barazany 3b129260f5 fix: use original_stream for short-circuit, propagate derived provider
Addresses Greptile review feedback:
- Save original stream flag before pre-request hooks convert it, so
  streaming callers get SSE events instead of a plain dict
- Propagate custom_llm_provider derived inside _execute_pre_request_hooks
  when it was not explicitly passed by the caller
- Add tests covering both scenarios
2026-03-19 19:52:16 +02:00
michelligabriele 97e17faa51 fix(proxy): guard lazy imports inside try, clean up orphaned streaming closure
Move non-essential lazy imports (llm_router, _check_and_merge,
unified_guardrail) inside the try block of _run_deferred_stream_guardrails
so that import failures are caught and the finally block still fires
logging. Only executor stays outside since the finally block needs it.

Add _on_deferred_stream_complete orphan cleanup in the finally block of
base_process_llm_request. If an exception propagates after the streaming
closure is stored but before a StreamingResponse is returned, the closure
is orphaned (CSW never consumes the stream). Detect this via
sys.exc_info() and fire logging directly to prevent silent loss.
2026-03-19 18:50:20 +01:00
Jonathan Barazany b5a775d54e style: fix Black formatting in test file 2026-03-19 19:47:13 +02:00
Devin PetersohnandClaude 41d9ecfebc Address feedback
Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-19 10:36:04 -07:00
yuneng-jiangandClaude Opus 4.6 0b07f628ff [Test] UI: Add vitest coverage for 10 previously untested components
Add unit tests for:
- SimpleToolCallBlock, SimpleMessageBlock, CollapsibleMessage, HistoryTree (log details drawer)
- OnboardingForm (onboarding flow)
- TeamsHeaderTabs, TeamsTable (teams page)
- transform_key_info, filter_helpers (key/team helpers)
- queryKeysFactory (query key generation utility)

47 new tests covering conditional rendering, user interactions, data transformation, and error handling.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 10:30:03 -07:00
Jonathan Barazany 6d0763b8ba fix: short-circuit websearch for non-Anthropic providers (github_copilot)
For providers like github_copilot that don't natively support web search,
Claude Code's search sub-conversations were falling through to the adapter
path which strips the web_search tool and has no stream reconversion.

Instead of routing search requests through the full LLM pipeline, detect
web-search-only requests early (all tools are web_search, simple prompt)
and execute the search directly via Tavily/Perplexity, returning a
synthetic Anthropic response. No adapter, no backend LLM call needed.

Fixes #21733
2026-03-19 19:28:05 +02:00
michelligabriele b34231dc95 refactor(proxy): reuse unified_guardrail singleton, rename shadowing variable
Reuse the module-level unified_guardrail singleton from proxy/utils.py
in _run_deferred_stream_guardrails instead of creating a new instance
per call, matching the pattern used by post_call_success_hook.

Rename local variable _has_post_call_guardrails to
_post_call_guardrails_active to avoid shadowing the static method name.
2026-03-19 18:20:42 +01:00
81dadb698a Ishaan - March 18th changes (#24056)
* add DD Tracing (#24033)

* feat(models): add Azure GPT-5.4 mini and nano variants (#24045)

Add `azure/gpt-5.4-mini` and `azure/gpt-5.4-nano` to the model
database with official pricing from Azure OpenAI:

- GPT-5.4 mini: $0.75/M input, $0.075/M cached, $4.5/M output
- GPT-5.4 nano: $0.20/M input, $0.02/M cached, $1.25/M output

Both models support:
- 1.05M input / 128K output context window
- Chat, batch, and responses endpoints
- Function calling, tools, vision, reasoning
- Prompt caching with automatic tiered pricing

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* Add new model pricing details for volcengine Doubao-Seed-2.0 series (#23871)

Add entries for volcengine Doubao-Seed-2.0 series

* fix(mcp): support refresh_token grant type in OAuth token endpoint (#23701)

* fix(mcp): support refresh_token grant type in OAuth token endpoint (#23700)

The .well-known/oauth-authorization-server metadata advertises
refresh_token as a supported grant type, but the token endpoint
rejected it with HTTP 400. This adds refresh_token grant support
so MCP clients can refresh expired tokens without re-authenticating.

* test(mcp): add tests for refresh_token grant type in OAuth token endpoint

* fix(mcp): move code_verifier guard into authorization_code branch

code_verifier is only relevant for authorization_code grants (PKCE).
Move it inside the else branch so it doesn't apply to refresh_token.

* fix(mcp): guard None client_secret and forward scope in token exchange

- Conditionally include client_secret in form data to prevent httpx
  from sending the literal string "None" (applies to both
  authorization_code and refresh_token branches)
- Forward optional scope parameter per RFC 6749 §6, allowing clients
  to request a subset of originally-granted scopes on refresh

* fix(mcp): validate code param in authorization_code grant

Guard against None code being form-encoded as literal string "None"
by httpx, symmetric with the existing refresh_token guard.

* docs: add incident report for guardrail logging secret exposure (#24059)

Add blog post documenting the guardrail logging path exposing internal
request data (e.g. Authorization headers) in spend logs and OTEL traces.
Fix available in LiteLLM 1.82.3+.

Made-with: Cursor

* [Fix] Datadog LLM Observability tags format (env, service, version missing) (#23673)

* tag fix

* greptile comment

* fix(ci): stabilize 6 failing CI jobs

1. mypy: remove duplicate type annotation for token_data in discoverable_endpoints.py
2. integrations tests: add parameterized to CI test deps
3. doc quality: document OTEL_IGNORE_CONTEXT_PROPAGATION env key
4. security: allowlist CVE-2026-2673, CVE-2026-3644, CVE-2026-4224 (no fix available)
5. proxy_store_model_in_db: fix missing x-litellm-call-id header on error responses
6. google tests: add --retries 3 for transient Vertex AI rate limits

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* fix(streaming): handle RuntimeError during model_copy in streaming handler

The race condition occurs when model_copy(deep=True) tries to deepcopy
_hidden_params dict while it's being concurrently modified by logging
callbacks. Fall back to shallow copy if the deep copy fails.

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* fix(cost): handle non-string traffic_type in cost calculator + add retries

1. Fix AttributeError in _map_traffic_type_to_service_tier when traffic_type
   is an integer (cast to str before calling .upper()). This was causing
   pass-through vertex spend logging to fail silently.
2. Add --retries to llm_translation_testing for flaky external API calls.

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

---------

Co-authored-by: Emerson Gomes <emerson.gomes@thalesgroup.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: ExMatics HydrogenC <33123710+HydrogenC@users.noreply.github.com>
Co-authored-by: Jack Venberg <jack.venberg@rover.com>
Co-authored-by: milan-berri <milan@berri.ai>
Co-authored-by: Shivam Rawat <161387515+shivamrawat1@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
2026-03-19 10:20:35 -07:00
f415b72bcf feat(anthropic): support ANTHROPIC_AUTH_TOKEN and ANTHROPIC_BASE_URL env vars
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Devin Petersohn <devin.petersohn@gmail.com>
2026-03-19 10:16:30 -07:00
michelligabriele 0057452485 fix(proxy): guard streaming deferred init with try/finally, fix test imports
Wrap _run_deferred_stream_guardrails initialization (UnifiedLLMGuardrails
constructor and _check_and_merge_model_level_guardrails) in try/finally
so logging always fires even if init throws. Prevents silent logging loss
on transient errors.

Move fastapi.HTTPException import from module-level to local test-function
scope. Add test_logging_fires_even_if_guardrail_init_raises to verify the
try/finally guard.
2026-03-19 18:00:49 +01:00
michelligabriele 4b8c532ba8 fix(proxy): pass guardrail_data to hooks in streaming deferred path
Use the merged guardrail_data dict (from _check_and_merge_model_level_guardrails)
for hook invocations in _run_deferred_stream_guardrails, instead of the original
captured_data. This ensures model-level non-default guardrails are visible to
inner should_run_guardrail re-checks inside UnifiedLLMGuardrails.

Rewrite three hand-crafted closure tests to exercise the production
_run_deferred_stream_guardrails exception-handling path. Add three new tests
that use deep-copy mocks to prove hooks receive the merged dict.
2026-03-19 17:39:06 +01:00
Ryan Crabbe 1d7cff22cb feat(ui): add click-to-copy icon on User ID in internal users table
Add a CopyOutlined icon next to the truncated User ID that copies
the full UUID to clipboard on click. Follows the existing pattern
used in model_hub_table_columns.tsx.
2026-03-19 08:57:42 -07:00
michelligabriele 001501fb31 fix(proxy): defer logging until post-call guardrails complete
guardrail_information is None in StandardLoggingPayload because logging
fires before post-call guardrails write to metadata.

Non-streaming: wrapper_async stores a closure instead of calling
create_task immediately. The proxy fires it in a try/finally after
post_call_success_hook so the SLP is built with guardrail info.

Streaming: a closure on logging_obj is called by CSW.__anext__ at
stream end. The closure runs only guardrail hooks (not all callbacks)
on the assembled response, then fires both logging handlers. This
avoids behavioral changes for non-guardrail callbacks on streaming.
2026-03-19 16:49:30 +01:00
Ephrim StanleyandClaude ae0769b1df fix: guard empty-dict team limits and malformed int in deployment default limits
- Change `if team_limit:` to `if team_limit is not None:` in both
  get_key_model_rpm_limit and get_key_model_tpm_limit so that an
  explicitly-empty team rate-limit map ({}) is returned as-is instead
  of silently falling through to deployment defaults (P1 fix).
- Replace the bare `int()` list comprehension in _get_deployment_default_limit
  with a loop that catches ValueError/TypeError so malformed config strings
  do not raise an unhandled exception during request handling (P2 fix).
- Add corresponding unit tests for both edge cases.

Co-Authored-By: Claude (claude-sonnet-4-6) <noreply@anthropic.com>
2026-03-19 07:40:47 -04:00
Ephrim StanleyandClaude e562c1d064 refactor: consolidate duplicate helpers and eliminate success-handler double lookup
- Merge _get_deployment_default_rpm_limit and _get_deployment_default_tpm_limit
  into a single _get_deployment_default_limit(model_name, field) helper; the two
  thin wrappers are preserved for callers but share one implementation
- Compute _success_tpm_limit / _success_rpm_limit once before the guard condition
  in async_log_success_event, eliminating the previous two unconditional
  get_key_model_* calls (each of which could hit llm_router.get_model_list)
- Replace fragile llm_model_list=[{}] sentinel in test with []

Co-Authored-By: Claude (claude-sonnet-4-6) <noreply@anthropic.com>
2026-03-19 07:26:43 -04:00
Sameer Kankute 6146196c6a Fix tests 2026-03-19 16:43:39 +05:30