Commit graph

42355 commits

Author SHA1 Message Date
yuneng-jiang
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-jiang
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
Devin Petersohn
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-jiang
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
kothamah
ead822b698
Added test cases for the null type handling 2026-03-19 13:55:36 -04:00
kothamah
a5dd01d8ac
added bedrock guardrail API exception 2026-03-19 13:52:23 -04: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 Petersohn
41d9ecfebc Address feedback
Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-19 10:36:04 -07:00
yuneng-jiang
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
Ishaan Jaff
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
Devin Petersohn
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 Stanley
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 Stanley
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
Sameer Kankute
1284e4ebe5 Fix cicd fialing tests 2026-03-19 16:32:35 +05:30
Sameer Kankute
b9564834e6 Fix mypy errors 2026-03-19 16:18:06 +05:30
Sameer Kankute
067dab42e6 refactor: reduce statement count in langsmith and anthropic methods
- Extract helper methods in langsmith._prepare_log_data to reduce from 51 to <50 statements
- Extract helper methods in anthropic.transform_parsed_response to reduce from 57 to <50 statements
- Fixes PLR0915 linter errors
- All existing tests pass (10 langsmith tests, 126 anthropic tests)

Made-with: Cursor
2026-03-19 16:16:23 +05:30
Sameer Kankute
532e0d13df feat(proxy): use AZURE_DEFAULT_API_VERSION for proxy --api_version default
Aligns proxy default with litellm.AZURE_DEFAULT_API_VERSION (2025-02-01-preview)
so Azure response_format + json_schema works without tools fallback.

Made-with: Cursor
2026-03-19 15:57:03 +05:30
Sameer Kankute
ecfcf241c6
Merge pull request #24119 from BerriAI/main
merge main
2026-03-19 15:53:32 +05:30
Sameer Kankute
e2e4f9ed33
Merge branch 'main' into litellm_oss_staging_03_17_2026 2026-03-19 15:53:06 +05:30
Sameer Kankute
a14122c28e docs: add per-model-group affinity configuration docs
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 15:50:43 +05:30
Sameer Kankute
6af74f6594 fix(router): restore debug log for missing deployment_model_name; warn on unknown affinity flags
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 15:39:35 +05:30
Sameer Kankute
528daa8cf4 feat(router): add per-model-group deployment affinity configuration
Enable deployment_affinity, responses_api_deployment_check, and session_affinity to be configured per model group via router_settings.model_group_affinity_config, falling back to global settings for unconfigured groups.

- Add model_group_affinity_config parameter to Router and DeploymentAffinityCheck
- Add _get_effective_flags helper to resolve flags per model group
- Update async_filter_deployments and async_pre_call_deployment_hook to use per-group config
- Add 4 comprehensive tests covering per-group config, fallback, and override scenarios

This allows fine-grained control of affinity behavior across model groups, e.g., enabling stickiness only for cross-provider deployments while leaving other groups free to load-balance.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 14:44:01 +05:30
Sameer Kankute
66f97a00a4 fix(test): rewrite polling pre-call guard test to call responses_api() directly
Previously the test called common_processing_pre_call_logic in isolation,
making generate_polling_id.assert_not_called() vacuously true. Now the test
calls responses_api() end-to-end so it actually verifies that a rate-limited
request never receives a polling ID.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 14:30:29 +05:30
Sameer Kankute
c12717f494 fix: address Greptile review comments
- Guard logging_obj for None when skip_pre_call_logic=True: raise ValueError
  if litellm_logging_obj not in data, preventing AttributeError downstream
- Add model=None to common_processing_pre_call_logic call in endpoints.py
  to match style of other call sites
- Add test verifying rate-limited request never receives polling ID
2026-03-19 14:10:58 +05:30
Sameer Kankute
4dc645fc33 feat(polling): check rate limits before creating polling ID
Move pre-call checks (rate limits, guardrails, budget) to run BEFORE
polling ID creation in the background streaming flow. This prevents the
edge case where a rate-limited request receives a polling ID that
immediately fails.

Changes:
- Add skip_pre_call_logic parameter to base_process_llm_request to allow
  skipping pre-call checks (avoiding double-counting of RPM/parallel requests)
- Run common_processing_pre_call_logic before generating polling ID in the
  responses API endpoint. If rate limits/guardrails fail, return error
  immediately without creating a polling ID
- Background streaming task passes skip_pre_call_logic=True to avoid re-running
  pre-call checks that were already done before polling ID creation
- Add tests verifying skip_pre_call_logic parameter works correctly

Fixes the edge case where polling_via_cache would return a polling ID
for a request that immediately fails due to rate limiting.
2026-03-19 13:59:59 +05:30
superpoussin22
e19a717b53
Add IF NOT EXISTS to index creation in migration 2026-03-19 09:22:10 +01:00
chengyongru
b20c448188
fix(openai): handle missing 'id' field in streaming chunks for MiniMax (#23931)
- Change chunk["id"] to chunk.get("id") for compatibility with MiniMax
- ModelResponseStream auto-generates id when None is passed
- Add regression test test_chunk_parser_without_id_field
2026-03-19 13:04:47 +05:30
joereyna
d5ef754950 docs(release-notes): align v1.82.3 notes with release notes guide
- Add MCP Gateway section (moved from Management per guide rule §11)
- Rename Spend Tracking → Spend Tracking, Budgets and Rate Limiting
- Fix Hashicorp Vault doc link: docs/secret → docs/secret_managers
- Fix LLM API section: #### Bug Fixes → #### Bugs (matches guide)
- Add Documentation Updates section (required by guide §11)
- Update Diff Summary: correct section names, add MCP Gateway and
  Documentation Updates counts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 23:35:40 -07:00
joereyna
61df7471ba docs(release-notes): complete v1.82.3 changelog with 30+ missing features
Full audit of 371 PRs in v1.82.0-stable...v1.82.3-stable range.
Adds previously undocumented user-facing changes:

- Key Highlights: Hashicorp Vault, Responses WebSocket, Org Admin RBAC,
  guardrail mode defaults
- New Providers: Google Search API, Bedrock Mantle (7 total, was 5)
- LLM API: Anthropic Files API, Mistral Voxtral transcription, WebRTC,
  Responses WebSocket, litellm.acount_tokens() public API, OpenRouter
  image edit, Vertex AI VIDEO token tracking, input_fidelity image edit,
  model cost aliases, per-request json schema validation, 15+ bug fixes
- Management: RBAC expansion for Org Admins, Vector Store CRUD, MCP
  token auth + team scoping, BYOK key precedence, virtual key spend reset,
  batch expiry for teams, Admin Viewer audit log access, 12+ bug fixes
- Guardrails: mode default list, tag-based modes, presidio fix, OTEL fix
- Secret Managers: Hashicorp Vault (was "no changes")
- Spend Tracking: new section — budget-linked reset fix, flex pricing,
  spend log cleanup, WebSearch dedup fix
- Performance: 4 additional reliability fixes
- Diff summary counts updated to reflect actual scope

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 23:30:42 -07:00
Ephrim Stanley
477c54184b perf: avoid unconditional router lookups in success handler
Replace bare _get_deployment_default_tpm/rpm_limit calls in the
async_log_success_event condition with get_key_model_tpm/rpm_limit
(model_name=model_group). The higher-level getters short-circuit on
key/team metadata hits before ever reaching the router, so requests
that don't use deployment defaults incur no extra router lookup. Remove
the now-unused bare helper imports.

Also fix invalid `int = None` type hints in test helper signatures
to `Optional[int] = None`.

Co-Authored-By: Claude (claude-sonnet-4-6) <noreply@anthropic.com>
2026-03-19 02:07:50 -04:00
Ephrim Stanley
48cb4a8343 fix: update success-event handler to track tokens for deployment-default limits
async_log_success_event only updated the per-model cache counter when
model_rpm_limit / model_tpm_limit were present in key metadata or
model_max_budget was set. For the new deployment-default path
(default_api_key_tpm_limit / default_api_key_rpm_limit), none of those
conditions held, so current_tpm stayed at zero and tpm enforcement was
never applied across multiple requests.

Extend the guard condition to also trigger when the model group has a
deployment-default tpm or rpm limit, and import the two helpers at
module level.

Co-Authored-By: Claude (claude-sonnet-4-6) <noreply@anthropic.com>
2026-03-19 01:59:41 -04:00
joereyna
dab8721ba3 chore: apply black formatting to fix lint CI 2026-03-18 22:57:38 -07:00
Ephrim Stanley
b90f520748 perf: eliminate redundant router lookups in v1 parallel request limiter
Compute get_key_model_tpm/rpm_limit once before the guard condition
instead of calling each function twice (once to check non-None, once to
retrieve). Removes 2 extra llm_router.get_model_list() calls per request
when deployment defaults are active.

Co-Authored-By: Claude (claude-sonnet-4-6) <noreply@anthropic.com>
2026-03-19 01:57:09 -04:00
Ephrim Stanley
36dc893770 fix: address review feedback on default tpm/rpm limits
- Use min() across all matching deployments instead of first-wins when
  resolving default_api_key_tpm/rpm_limit for a model group, so
  load-balanced setups with different per-deployment limits always apply
  the most conservative value
- Replace the global SensitiveDataMasker non_sensitive_overrides change
  with a targeted excluded_keys set at the remove_sensitive_info_from_deployment
  call site, avoiding unintended suppression of other fields
- Update the v1 parallel request limiter to pass model_name to
  get_key_model_tpm/rpm_limit so deployment defaults apply there too
- Add 4 tests covering multi-deployment min semantics

Co-Authored-By: Claude (claude-sonnet-4-6) <noreply@anthropic.com>
2026-03-19 01:43:27 -04:00
joereyna
bba3b1fe4c docs(release-notes): add missing Helicone and Langfuse entries to v1.82.3 changelog
Helicone (PRs #19288, #22603) and Langfuse (#22390) were present in the
v1.82.0-stable...v1.82.3-stable diff but omitted from the AI Integrations
logging section. Also updates the AI Integrations diff summary count from 2 to 4.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 22:42:25 -07:00