Commit graph

11158 commits

Author SHA1 Message Date
Benedikt Óskarsson
efeaf650aa
fix(proxy): improve auth exception logging levels and add structured context (#22099)
* fix(proxy): improve auth exception logging levels and add structured context

Downgrade expected auth failures (ProxyException, HTTPException < 500,
BudgetExceededError) from ERROR to WARNING log level to reduce noise from
routine rejected requests (e.g. missing/invalid API keys on polled endpoints
like /schedule/model_cost_map_reload/status).

Unexpected exceptions and HTTPException with status >= 500 still log at
ERROR with full traceback.

Enrich log messages with structured context: route, HTTP method, masked
API key (using existing abbreviate_api_key), error type, and error code.
All fields also passed via log extra dict for log aggregation tools.

Fixes #21293

* Update tests/test_litellm/proxy/auth/test_auth_exception_handler.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-26 00:08:35 -08:00
Gaurav Singh
f3e31bc8ef
fix(proxy): honor MAX_STRING_LENGTH_PROMPT_IN_DB from config env vars (#22106)
* fix(proxy): honor MAX_STRING_LENGTH_PROMPT_IN_DB from config env vars

* fix(proxy): reuse constants fallback for MAX_STRING_LENGTH_PROMPT_IN_DB runtime resolver

* test(proxy): restore PEP8 spacing between spend tracking tests
2026-02-26 00:06:18 -08:00
Sameer Kankute
4d68151d03
Merge pull request #22151 from BerriAI/litellm_fix_cicd_26_02
[Fix] CICD 26/02/26
2026-02-26 13:30:23 +05:30
Ishaan Jaff
965ca117bc
feat(realtime guardrails): end_session_after_n_fails + Endpoint Settings wizard step (#22165)
* feat(realtime guardrails): end_session_after_n_fails + Endpoint Settings wizard step

Adds per-session violation thresholds and an optional endpoint-settings step
to the guardrail wizard for /v1/realtime.

Backend:
- Add end_session_after_n_fails, on_violation, realtime_violation_message fields
  to BaseLitellmParams (no DB migration — stored in existing JSON column)
- Store same fields on CustomGuardrail instance attrs
- Pass through in litellm_content_filter initializer
- Track _violation_count per RealTimeStreaming session; close backend_ws when
  on_violation=end_session OR violation count >= end_session_after_n_fails
- Use realtime_violation_message as the spoken text (falls back to guardrail
  error string if not configured)

UI (add_guardrail_form.tsx):
- Rename "Default Categories" step to "Topics"
- Add step 5 "Endpoint Settings (Optional)" for content filter guardrails
- Call type dropdown shows /v1/realtime
- Settings are in a collapsed accordion (closed by default)
- "End session after X violations" + on_violation radio + spoken message field

Tests: 2 new tests in test_realtime_streaming.py
- test_end_session_after_n_fails_closes_connection
- test_on_violation_end_session_closes_on_first_fail

* fix(test): move inline imports to module level in realtime streaming tests

* Update ui/litellm-dashboard/src/components/guardrails/add_guardrail_form.tsx

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-25 23:49:03 -08:00
Ishaan Jaff
819581f6bf
fix(realtime): guardrails with pre_call/post_call mode now work on realtime WebSocket (#22161)
* fix(realtime): guardrails with pre_call/post_call mode now work on realtime WebSocket; return error directly to consumer

* fix(realtime guardrails): address code review feedback

- Restore session.update injection for audio/VAD path, but only when
  realtime_input_transcription guardrails are configured (not pre_call).
  Forward session.created to the client first so no error arrives before
  the client sees the session.
- Change _swallow_next_response_create bool to int counter so consecutive
  blocked items are handled correctly.
- Extract _build_litellm_metadata() helper to eliminate duplicated
  metadata-building logic across OpenAI/Azure/XAI provider branches.
- Plumb litellm_metadata and user_api_key_dict to Azure and XAI handlers
  so guardrails work for those providers too.
- Add tests for session.update injection, no-inject for pre_call-only,
  and consecutive-block counter.

* simplify: remove response.create swallowing after guardrail block

When an item is blocked, the error event is already sent to the client.
The subsequent response.create from the client is fine to forward through —
the LLM may respond to previous context which is acceptable behavior.
Removing the swallow counter eliminates unnecessary state tracking.
2026-02-25 23:43:13 -08:00
Sameer Kankute
8f8ebbec8d Fix test_vertex_passthrough_forwards_anthropic_beta_header 2026-02-26 13:06:25 +05:30
Harshit28j
14badde13c fix: custom auth budget issue 2026-02-26 13:03:01 +05:30
Sameer Kankute
143e8dfe27 Fix pass through tests 2026-02-26 12:55:59 +05:30
Sameer Kankute
0debe92605 Fix_mapped tests part 2 2026-02-26 12:43:39 +05:30
Sameer Kankute
9c7f8138e1 FIx : litellm/tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py 2026-02-26 12:43:06 +05:30
Sameer Kankute
7cda0e4edd Fix code qa 2026-02-26 12:43:06 +05:30
Sameer Kankute
5e63969ed7
Merge branch 'main' into litellm_fix_cicd_26_02 2026-02-26 12:14:49 +05:30
Sameer Kankute
a54cf53ffb Fix test_standard_logging_payload_includes_guardrail_information 2026-02-26 12:13:26 +05:30
Sameer Kankute
f34b0366a3 Fix: test_gaurdrails* 2026-02-26 12:10:49 +05:30
Sameer Kankute
af3b6f3334 Fix: litellm/tests/test_litellm/proxy/common_utils/test_http_parsing_utils.py 2026-02-26 12:09:42 +05:30
Sameer Kankute
2d231c2f1a Fix code qa 2026-02-26 12:08:40 +05:30
Ishaan Jaff
f1c9cb7e71
feat(vertex_ai): Vertex AI Gemini Live via unified /realtime endpoint (#22153)
* feat(vertex_ai): add Vertex AI Gemini Live support via unified /realtime endpoint

Adds VertexAIRealtimeConfig which translates the OpenAI Realtime WebSocket
protocol to Vertex AI BidiGenerateContent. Supports voice in/voice out
(16 kHz mic → 24 kHz speaker) and text in/text out through the proxy's
/realtime endpoint.

Key changes:
- New litellm/llms/vertex_ai/realtime/transformation.py with VertexAIRealtimeConfig
  - Builds correct wss:// URL (regional + global)
  - OAuth2 Bearer token auth (not API key)
  - Full model path (projects/.../publishers/google/models/...)
  - Ignores session.update (Vertex AI only accepts one setup message)
- realtime_api/main.py: vertex_ai branch resolves OAuth token + constructs config
- llm_http_handler.py: auto-sends session setup before bidirectional_forward
- gemini/realtime/transformation.py: fix crashes on empty turnComplete events
- realtime_streaming.py: try/except guard so bad messages don't kill the loop
- proxy_server.py: add missing websockets.exceptions import

* docs: add vertex_realtime to sidebars

* fix: drop unknown event types in Gemini transform; add vertex_ai health check

* fix: propagate UUID fallback IDs from transform_content_done_event to return_additional_content_done_events

* fix: route guardrail backend sends through provider transform; fix str.strip misuse for model prefix

* fix: handle Vertex AI full resource path in session.created; route guardrail block sends through _send_to_backend

* fix: remove unused VertexBase in transformation.py; apply UUID fallback in return_additional_content_done_events
2026-02-25 22:11:06 -08:00
Krish Dholakia
a9cb2674c0
feat(add-new-block_code_execution-guardrail): prevent agent from executing code (#22154)
Adds a new block_code_execution guardrail that detects markdown fenced code blocks
in request/response content and blocks or masks them by language. Includes full
UI integration, type definitions, compliance test dataset, and 26 unit tests.

Key guardrail capabilities:
- Regex-based fenced code block detection with configurable blocked languages
- Confidence scoring with tunable threshold
- Execution-intent heuristics (request-side only) with conflict resolution
- Block or mask actions for detected code
- Support for pre_call, post_call, and during_call event hooks

Security hardening:
- Response-side blocking skips intent heuristics (LLM output doesn't contain
  user intent phrases, so checking would silently disable post_call blocking)
- No-execution short-circuit includes conflict resolution: if both no-execution
  and execution phrases match, execution intent wins
- Tightened overly broad phrases to prevent trivial bypass
- _normalize_escaped_newlines only applies to pure-escaped payloads to avoid
  corrupting content that discusses escape sequences

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 22:02:14 -08:00
yuneng-jiang
386c148b8d use raw SQL in key_aliases to avoid loading full rows into memory
Replace Prisma ORM count/find_many calls with two query_raw calls that
only project the key_alias column. The Prisma client wrapper does not
support SELECT projection via find_many, so raw SQL is used to keep
memory usage proportional to the page size rather than total key count.
Update tests to mock query_raw instead of count/find_many.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-25 21:48:53 -08:00
yuneng-jiang
06e87eea87 remove unsupported select param from find_many call
LiteLLM_VerificationTokenActions.find_many() does not support the
select keyword argument. Remove it and drop the corresponding test.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-25 21:40:56 -08:00
Sameer Kankute
2349b51d80 Fix test_pass_through_request_logging_failure 2026-02-26 10:50:05 +05:30
Sameer Kankute
828ce40eac Fix test_async_gcs_pub_sub_v1 2026-02-26 10:46:01 +05:30
Sameer Kankute
f68cbc4c95 Fix test_perform_health_check_filters_by_model_id 2026-02-26 10:43:05 +05:30
yuneng-jiang
0b0809a3d5 optimize key_aliases to select only key_alias column and add unit tests
Add select={"key_alias": True} to the find_many call so only the alias
column is fetched from the database instead of full token rows. Add
five unit tests in test_key_management_endpoints.py covering response
shape, pagination skip/take computation, search filter injection,
absence of contains filter when no search term is given, and the
select-only-alias optimization.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-25 21:03:15 -08:00
Sameer Kankute
691927f9c9 fix(embeddings): allow dimensions param passthrough via allowed_openai_params for non-text-embedding-3 OpenAI models
When calling non-text-embedding-3 models routed through the openai provider
(e.g. nvidia/llama-3.2-nv-embedqa-1b-v2), passing `dimensions` previously
raised an UnsupportedParamsError unconditionally. This fix threads
`allowed_openai_params` through the embedding call stack so that providers
can opt-in to passing `dimensions` by including it in the list.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-26 09:59:37 +05:30
Sameer Kankute
48f549b30b Return Clear error message why no tools are available / IP Filtering occured 2026-02-26 09:56:44 +05:30
Chesars
a4fc73f892 fix(completion): unify finish_reason mapping to OpenAI-compatible values
Replace if/elif chain in map_finish_reason() with _FINISH_REASON_MAP dict
covering all known provider values. Unknown values now default to "stop"
with a warning log. Fix Gemini FINISH_REASON_UNSPECIFIED and
MALFORMED_FUNCTION_CALL returning non-OpenAI values. Add missing Gemini
values (TOO_MANY_TOOL_CALLS, MALFORMED_RESPONSE). Clean
OpenAIChatCompletionFinishReason type and OPENAI_FINISH_REASONS constant.

Fixes #21744, #21041, #16651, #19744, #21348, #22003
2026-02-26 00:12:39 -03:00
yuneng-jiang
4643685e78 [Fix] /key/aliases: Add pagination and search to prevent OOMs
The /key/aliases endpoint previously fetched all key aliases from the database without limit, causing OOM crashes with large key sets. Added page, size, and search query parameters with database-level filtering to enable paginated and searchable key alias retrieval. Updated the response to include pagination metadata (total_count, current_page, total_pages, size) matching the /v2/model/info pattern.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-25 17:55:26 -08:00
Ryan Crabbe
bfceefbb26 parameterize test 2026-02-25 17:30:59 -08:00
Ryan Crabbe
9157c1ebe2 test: redundant tests 2026-02-25 17:29:17 -08:00
Ryan Crabbe
9ea100a9f7 feat: add prometheus multiprocess directory cleanup
Adds cleanup utilities for PROMETHEUS_MULTIPROC_DIR to prevent
unbounded RAM/disk growth from stale .db files in multi-worker setups.

Three-part lifecycle aligned with upstream prometheus_client docs:
1. Startup: wipe entire directory before workers fork (clean slate)
2. Shutdown: mark_process_dead() for own PID (removes gauge_live* only)
3. Periodic (hourly): scan for dead PIDs and call mark_process_dead()

Counter/histogram files are never individually deleted at runtime to
avoid partial counter resets that cause false spikes in rate()/increase().

Also auto-creates PROMETHEUS_MULTIPROC_DIR when prometheus callback is
configured with multiple workers and the env var is not already set.
2026-02-25 17:20:46 -08:00
Steve G
9806e21871
Add Lakera v2 post-call hook and tests (fixed PII masking) (#21783)
* Add post-call hook for Lakera guardrail and mask PII in responses

* Add post-call hook for Lakera and mask PII in responses

* Fix post-call hook: pass event_type to call_v2_guard

* Address Greptile review: return ModelResponse, fix mutation, add header, test location, mask order

- PII masking path: return ModelResponse instead of dict so deployment hook accepts it
- Avoid mutating request data: deep copy original_messages and messages in _mask_pii_in_messages
- Add guardrail header in PII-only return path
- Add test in tests/test_litellm/ (test_lakera_ai_v2.py) per PR checklist
- Sort PII payload spans by (start,end) descending so multiple spans in one message mask correctly

Co-authored-by: Cursor <cursoragent@cursor.com>

* Updated ponteital for index mismatch when choices have null content and inconsistent on_flagged access pattern

* Update litellm/proxy/guardrails/guardrail_hooks/lakera_ai_v2.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Update to explicitly state supported endpoints - chat completions

* Fix minor lint error on masked_entity_count

---------

Co-authored-by: Steve <steve.giguere@lakera.ai>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-25 17:20:38 -08:00
Ishaan Jaff
adba088df2
Realtime API: spend log storage, playground UI, tools logging, and guardrail support (#22105)
Backend - Spend Log Storage for Realtime Calls:
- Collect user voice transcripts and text input during WebSocket sessions
- Store collected messages in spend logs when store_prompts_in_spend_logs enabled
- Capture tool definitions from session.update and tool calls from response.done
- Enrich proxy_server_request with tools and response with tool_calls for UI

Backend - WebSocket Auth:
- Support browser-based auth via Sec-WebSocket-Protocol subprotocol
- Echo back subprotocol on WebSocket accept

UI - Realtime Playground:
- New RealtimePlayground component with WebSocket voice+text chat
- Mic recording (PCM16 24kHz), server VAD, audio playback, text input
- Handle binary WebSocket frames (Blob/ArrayBuffer decoding)
- Add /v1/realtime endpoint option to playground endpoint selector

UI - Tools Section for Realtime Logs:
- Extract tool calls from realtime response format (response.tool_calls
  and response.results[].response.output[].type=function_call)

Tests:
- 15 new backend tests for realtime streaming and spend log storage
- 4 new UI tests for realtime tool call extraction

Fixes pre-existing build errors:
- ToolPolicies.tsx: duplicate import, antd styles type
- create_key_button.tsx: missing message import

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
2026-02-25 14:55:27 -08:00
Ryan Crabbe
1c1b9cda42 merge: resolve conflict with origin/main in test_db_spend_update_writer.py
Keep both batch update tests (from this branch) and pipeline test (from main).
2026-02-25 12:15:53 -08:00
Ryan Crabbe
e1e05d27f8 Merge remote-tracking branch 'origin/main' into litellm_batch_update_database_tasks 2026-02-25 12:12:10 -08:00
ryan-crabbe
9857643eb4
Merge pull request #22044 from ryan-crabbe/litellm_redis_pipeline_spend_updates
Litellm redis pipeline spend updates
2026-02-25 12:11:09 -08:00
yuneng-jiang
9d6f02e8b7 Merge remote-tracking branch 'origin' into litellm_spend_log_duration 2026-02-25 12:06:19 -08:00
Krish Dholakia
12c4876891
Agents - assign tools (#22064)
* feat(proxy): add max_iterations limiter for agent session loops (#22058)

Adds a new proxy hook that enforces a per-session cap on the number of
LLM calls an agentic loop can make. Callers send a session_id with each
request, and the hook counts calls per session, returning 429 when the
configured max_iterations limit is exceeded.

- Uses Redis Lua script for atomic increment (multi-instance safe)
- Falls back to in-memory cache when Redis unavailable
- Follows parallel_request_limiter_v3 pattern
- Configurable via key metadata: {"max_iterations": 25}
- Session counters auto-expire via TTL (default 1hr)

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

* feat: add new code execution dataset

* feat(agent_endpoints/): allow giving agents keys

* fix: ui fixes

* feat: allow assigning mcp servers to agents

* fix: eliminate duplicate DB queries in MCP agent auth and N+1 in agent listing (#22110)

- Extract _get_agent_object_permission helper so _get_allowed_mcp_servers_for_agent
  and _get_agent_tool_permissions_for_server share a single DB fetch instead of
  each independently querying the same agent row (was 1+N queries per MCP request)
- Use include={"object_permission": True} on find_many in get_all_agents_from_db
  to eagerly load permissions in one query instead of N+1
- Use include={"object_permission": True} on create/update/find_unique in all
  agent CRUD operations, removing attach_object_permission_to_dict follow-up calls

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 11:44:30 -08:00
Harshit Jain
10e769a5e4
feat: ability to trace metrics 2026-02-25 22:03:51 +05:30
Sameer Kankute
ebe35aad9a
Merge pull request #22080 from BerriAI/litellm_vllm_response_fix
Fix None (TypeError: 'NoneType' object is not a mapping)
2026-02-25 18:45:54 +05:30
Sameer Kankute
ec3ae25a3a
Merge pull request #22070 from BerriAI/litellm_forward_auth_headers
[Feat]Add forward auth headers of provider
2026-02-25 18:45:38 +05:30
Harshit28j
e50b4486d0 fix Unauthenticated RCE and Sandbox Escape in Custom Code Guardrail 2026-02-25 17:57:32 +05:30
Sameer Kankute
f453427264 Add v1 for anthropic responses transformation 2026-02-25 17:19:33 +05:30
Harshit Jain
d2aeb3e513
Merge pull request #22084 from Harshit28j/litellm_presidio-non-json-response-handling
fix(guardrails): prevent presidio crash on non-json responses
2026-02-25 16:37:39 +05:30
Harshit28j
6a8052295b fix(guardrails): prevent presidio crash on non-json responses 2026-02-25 16:11:24 +05:30
Sameer Kankute
45c87a714e Fix None (TypeError: 'NoneType' object is not a mapping) 2026-02-25 14:39:12 +05:30
Harshit Jain
23e84eb789 fix: Metadata / Trace ID Missing in S3 Streaming Callbacks 2026-02-25 14:16:42 +05:30
Sameer Kankute
886f9d6a70 Add support for forwarding provider's auth headers 2026-02-25 12:08:25 +05:30
yuneng-jiang
b78a30f773 [Feature] Add request_duration_ms to SpendLogs
Add a `request_duration_ms` column to `LiteLLM_SpendLogs` to track request
duration. New rows are computed at write time. Legacy rows use a COALESCE
fallback in the `/spend/logs/ui` query to compute duration on the fly from
`endTime - startTime`. The field is also sortable in the UI endpoint.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-24 21:04:53 -08:00
yuneng-jiang
ec7dc44e73
Merge pull request #22049 from BerriAI/litellm_spend_log_key_info
[Fix] Enrich Failure Spend Logs With Key/Team Metadata
2026-02-24 20:56:51 -08:00