Commit graph

5863 commits

Author SHA1 Message Date
Urain Ahmad Shah
bf33e639ef
Fix User Invite & Key Generation Email Notification Logic (#18524)
* Fix email notification

* Update email notification tests

* moved test file
2026-01-06 01:35:52 +05:30
drorIvry
b6a64ff99a
feature/ add qualifire guardrails (#18594)
* init guardrails

* init guardrails

* some fixes

* some fixes

* ruff

* some fixes

* some fixes

* some fixes

* some fixes

* some fixes

* some fixes

* docs
2026-01-06 01:34:43 +05:30
Cesar Garcia
0e601d0bfe
Fix: Map Gemini cached_tokens to Langfuse cache_read_input_tokens (#18614)
* Fix: Map Gemini cached_tokens to Langfuse cache_read_input_tokens

Fixes #18520

## Problem
Langfuse integration was not capturing cached tokens from Gemini models.
Gemini returns cached tokens in `usage.prompt_tokens_details.cached_tokens`,
but Langfuse only read from top-level `usage.cache_read_input_tokens`
(which only Anthropic populates).

## Solution
Updated langfuse.py to check both locations:
1. First check top-level cache_read_input_tokens (for Anthropic)
2. Then check prompt_tokens_details.cached_tokens (for Gemini, OpenAI, others)

This ensures all providers' cached tokens are properly reported to Langfuse.

## Changes
- Modified litellm/integrations/langfuse/langfuse.py (lines 742-761)
- Added 3 unit tests in tests/test_litellm/integrations/langfuse/test_gemini_cached_tokens.py
- All existing Langfuse tests still pass (11/11)

## Testing
- test_cached_tokens_extraction: Verifies Gemini cached_tokens extraction
- test_cached_tokens_not_present: Backward compatibility (no cached_tokens)
- test_cached_tokens_is_zero: Edge case when cached_tokens = 0

* Refactor: Extract cache token logic into helper function

Address review feedback from @officer47p

- Created _extract_cache_read_input_tokens() helper function
- Reduces code bloat in _log_langfuse_v2 method
- Improves testability and reusability
- All tests still passing (11/11)
2026-01-06 01:34:09 +05:30
Alexsander Hamir
85a357c7e5
fix: extend case normalization to ALL guardrail types (not just tool_permission) (#18664)
This extends the previous fix to handle capitalized fields across ALL guardrail types,
including Presidio, Azure, Lakera, Bedrock, etc.

Discovery:
- Database investigation revealed the issue affects multiple guardrail types
- Found 4 affected guardrails in staging: 3 Presidio + 1 Azure
- All had default_action: 'Deny' causing the same validation failures
- The initial fix only covered ToolPermissionGuardrailConfigModel

Root Cause (Deeper):
- LitellmParams inherits from 13+ different guardrail config models
- Models use ConfigDict(extra="allow") allowing any field to be set
- Users can set default_action/on_disallowed_action on ANY guardrail type
- Only ToolPermissionGuardrailConfigModel was validating these fields

Solution:
- Added field validators to LitellmParams class (parent of all guardrails)
- Validators run for ALL guardrail types: Presidio, Azure, Bedrock, Lakera, etc.
- Added comprehensive tests covering multiple guardrail types

Changes:
- litellm/types/guardrails.py:
  * Added @field_validator for default_action in LitellmParams
  * Added @field_validator for on_disallowed_action in LitellmParams
  * Added normalization in LitellmParams.__init__ as backup
  * Imported field_validator from pydantic

- tests/test_litellm/types/test_guardrails_case_normalization.py:
  * New test file with 7 tests covering multiple guardrail types
  * Tests verify Presidio, Azure, Tool Permission, Lakera, Bedrock
  * All tests passing

Impact:
- Previous fix: Only tool_permission guardrails protected
- This fix: ALL guardrail types now protected (13+ types)
- Handles both new writes and existing database records
- Tested against actual database with Presidio/Azure guardrails

Testing:
- 7 new cross-guardrail tests (all passing)
- 27 existing tool_permission tests (all passing)
- Verified fix works for real database records
2026-01-05 11:59:00 -08:00
FlibbertyGibbitz
3f4a9d8d08
fix(router): Validate routing_strategy at startup to fail fast with helpful error. (#18624)
Invalid routing_strategy values (e.g., "simple" instead of "simple-shuffle") previously failed silently, causing confusing "No deployments available" errors downstream. This change adds upfront validation in routing_strategy_init() to:

- Check if the provided strategy matches valid string values or RoutingStrategy enum
- Raise a clear ValueError listing valid options if invalid
- Fail fast at startup instead of at request time

Fixes behavior reported in #11330 where users had to debug cryptic errors.

Valid strategies: simple-shuffle, least-busy, usage-based-routing, latency-based-routing, cost-based-routing, usage-based-routing-v2

Co-authored-by: Flibbert E. Gibbitz <flibbertygibbitz@runelabs.ai>
2026-01-06 01:22:09 +05:30
Shivam Rawat
8c21fcb957
added the option of adding langsmith tenant id in the env (#18623) 2026-01-06 01:19:27 +05:30
Krish Dholakia
b5aa7d1838
feat: Add api_key to GenericGuardrailAPI and set x-api-key header (#18647)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-01-06 01:05:51 +05:30
Alexsander Hamir
0b0a9abd90
fix: normalize case for tool permission guardrail fields to prevent validation errors (#18662)
This fixes a critical issue where capitalized values in tool_permission guardrail
configurations (e.g., "Deny" instead of "deny") caused Pydantic validation errors
during proxy startup, leading to repeated initialization failures and latency issues.

Problem:
- Users could save guardrails with capitalized values through UI/API
- Data was written to database without validation (e.g., default_action: "Deny")
- On proxy startup, loading from DB triggered strict Pydantic validation
- ValidationError caused guardrail initialization to fail in a retry loop
- This resulted in startup delays and repeated error logging

Root Cause:
- Write path had no case normalization
- Read path enforced strict lowercase Literal validation
- Asymmetry between write and read caused latent data corruption

Solution:
Added field validators to normalize case before Pydantic validation:

1. ToolPermissionRule.decision ("allow"/"deny")
   - Normalizes decision field in rules array

2. ToolPermissionGuardrailConfigModel.default_action ("allow"/"deny")
   - Normalizes default fallback action

3. ToolPermissionGuardrailConfigModel.on_disallowed_action ("block"/"rewrite")
   - Normalizes disallowed tool behavior

4. ToolPermissionGuardrail.__init__ normalization
   - Defensive normalization for direct instantiation
   - Ensures normalization regardless of code path

Impact:
- Prevents validation errors during guardrail initialization
- Eliminates startup retry loops and latency issues
- Handles existing database records with capitalized values
- Accepts case-insensitive input from all sources (UI, API, direct calls)
- Fully backward compatible with existing lowercase configurations

Testing:
- Added 3 comprehensive tests for case-insensitive handling
- All 27 existing tests still pass
- Tests verify normalization across all affected fields

Files Changed:
- litellm/types/proxy/guardrails/guardrail_hooks/tool_permission.py
  Added @field_validator decorators for case normalization
- litellm/proxy/guardrails/guardrail_hooks/tool_permission.py
  Added runtime normalization in __init__ method
- tests/test_litellm/proxy/guardrails/guardrail_hooks/test_tool_permission.py
  Added case-insensitive validation tests
2026-01-05 11:24:19 -08:00
Nik
13db8e10dc feat: add display_name, model_vendor, and model_version metadata 2026-01-05 11:01:36 -08:00
Alexsander Hamir
3b847e0d9d
refactor: migrate utils.py lazy imports to registry pattern (#18657)
* refactor: migrate utils.py lazy imports to registry pattern

- Refactored utils.py __getattr__ to use cached registry pattern (similar to __init__.py)
- Added UTILS_MODULE_NAMES tuple and _UTILS_MODULE_IMPORT_MAP to _lazy_imports_registry.py
- Added _get_utils_globals() helper function to _lazy_imports.py
- Added _lazy_import_utils_module() handler function for utils module lazy imports
- Updated _get_lazy_import_registry() to include utils module lazy imports
- Removed redundant _get_utils_globals() from utils.py (now in _lazy_imports.py)
- Added comprehensive tests for utils module lazy imports in test_lazy_imports.py

This refactoring:
- Reduces code duplication (from 670+ lines to ~10 lines in __getattr__)
- Improves maintainability (new lazy imports just need registry entry)
- Maintains consistency with __init__.py lazy import pattern
- All existing functionality preserved and tested

* Fix NameError: get_coroutine_checker not defined in check_coroutine function

* Fix lazy loading for get_coroutine_checker in function_setup and check_coroutine

- Add lazy loading for get_coroutine_checker at start of function_setup to ensure all calls use lazy-loaded version
- Fix check_coroutine function to use lazy loading pattern via getattr
- All direct calls to get_coroutine_checker() now properly use lazy import mechanism
2026-01-05 09:55:48 -08:00
Sameer Kankute
d0a26dd4bc
Merge pull request #18644 from BerriAI/litellm_fix_mapped_tests_05012026
Fix mapped tests 05012026
2026-01-05 17:53:17 +05:30
Sameer Kankute
3c60b930e2
Merge pull request #18635 from BerriAI/litellm_completions_api_summary_param
(feat) Add mapping for reasoning effort to summary param of responses API
2026-01-05 17:36:21 +05:30
Sameer Kankute
30096ffe5c
Merge pull request #18637 from BerriAI/litellm_gemini_api_base_auth_fix
fix: auth header for custom api base in generate Content request
2026-01-05 17:35:47 +05:30
Sameer Kankute
23fa88f64e
Merge pull request #18638 from BerriAI/litellm_fix_custom_llm_providers_ui_testing
fix: Add custom llm provider to get_llm_provider when sent via UI
2026-01-05 17:34:50 +05:30
Sameer Kankute
2d7f0a1351 fix: test_create_simple_string_input 2026-01-05 17:15:12 +05:30
Sameer Kankute
c0f74c994a Fix: test_transform_request_image_extraction 2026-01-05 17:02:54 +05:30
Ishaan Jaff
7f4dba2a01
[Feat] Add Cost Estimator for AI Gateway (#18643)
* add estimate_cost endpoint

* TestCostEstimateEndpoint

* fix estimate_cost

* add /cost/estimate to spend tracking routes

* fix code QA checks

* fixes endpoint
2026-01-05 16:51:23 +05:30
Sameer Kankute
28c7659d3d
Potential fix for code scanning alert no. 3954: Clear-text logging of sensitive information
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-01-05 16:06:10 +05:30
YutaSaito
165d5f3af1
Merge pull request #18640 from BerriAI/litellm_fix_cloudzero_integration_test
tests: mock LiteLLM_UserTable for CloudZero export
2026-01-05 17:41:22 +09:00
Yuta Saito
bdc35b4cd2 tests: mock LiteLLM_UserTable for CloudZero export 2026-01-05 17:23:04 +09:00
Sameer Kankute
6337ea876b fix: Add custom llm provider to get_llm_provider when sent via UI 2026-01-05 12:57:30 +05:30
Sameer Kankute
0730a74dda fix: auth header for custom api base in generate Content request 2026-01-05 12:25:13 +05:30
Yuta Saito
f1d77ae14d feat: allow_all_keys to mcp server 2026-01-05 15:49:09 +09:00
Sameer Kankute
0f8e4364d6 Replace summary param as detailed 2026-01-05 11:24:35 +05:30
Sameer Kankute
42d4aab3e7 Add mapping for reasoning effort to summary of responses API 2026-01-05 11:21:34 +05:30
YutaSaito
b6664669d2
Merge pull request #18480 from hamzaq453/fix/openapi-parameter-names-security
Fix: Remove exec() usage and handle invalid OpenAPI parameter names
2026-01-05 14:34:57 +09:00
YutaSaito
c405135c2b
Merge pull request #18584 from BerriAI/feat/add_user_email_to_cloudzero
feat: add user email to cloudzero
2026-01-05 14:22:46 +09:00
hamzaq453
9ca7b1ad9b Resolve merge conflicts: integrate path validation with **kwargs approach
- Keep **kwargs approach (no exec()) for security
- Integrate path traversal validation from main branch
- Add URL encoding for path parameters
- Merge both test suites (edge cases + security tests)
- All 14 tests passing
2026-01-05 10:20:26 +05:00
YutaSaito
fcabc059ca
Merge pull request #18630 from BerriAI/litellm_fix_mcp_guardrail
fix: MCP handling in unified guardrail
2026-01-05 12:25:14 +09:00
amangupta-20
399579f8ea
feat: Add Levo AI integration (#18529) 2026-01-05 08:49:21 +05:30
Yuta Saito
0509fc79da fix: move code from litellm/llms to the mcp_server dir 2026-01-05 12:05:16 +09:00
Yuta Saito
c8c73e6fa5 fix: MCP handling in unified guardrail 2026-01-05 10:41:24 +09:00
lif
7d81d245fb
fix: align prometheus metric names with DEFINED_PROMETHEUS_METRICS (#18463)
Fix metric name inconsistency for litellm_remaining_requests_metric
and litellm_remaining_tokens_metric. The factory received names
without the _metric suffix, causing _is_metric_enabled to fail when
users configured these metrics in prometheus_metrics_config.

Fixes #18221

Signed-off-by: majiayu000 <1835304752@qq.com>
2026-01-04 00:48:09 +05:30
lif
64cfe75bfd
fix: extract pure base64 data from data URLs for Ollama (#18465)
Fix Ollama_chatException "illegal base64 data at input byte 4" error
when using images with ollama_chat provider. Ollama expects pure base64
data, not the full data URL format (data:image/png;base64,...).

Fixes #18338

Signed-off-by: majiayu000 <1835304752@qq.com>
2026-01-04 00:47:38 +05:30
lif
099e108b51
fix: correctly route codestral chat and FIM endpoints (#18467)
Fixed duplicate condition that made text-completion-codestral provider
unreachable. Now:
- codestral.mistral.ai/v1/chat/completions -> codestral
- codestral.mistral.ai/v1/fim/completions -> text-completion-codestral

Fixes #18464

Signed-off-by: majiayu000 <1835304752@qq.com>
2026-01-04 00:45:45 +05:30
cantalupo555
9b1c5f7e36
feat(zai): Add GLM-4.7 model with reasoning support (#18476)
Add support for Z.AI GLM-4.7, latest flagship model with enhanced reasoning capabilities.

Changes:
- Add zai/glm-4.7 to model pricing with /bin/bash.60/M input, .20/M output
- Add cached input pricing (/bin/bash.11/M) for GLM-4.7
- Add supports_reasoning flag to enable thinking parameter
- Update ZAIChatConfig to support thinking parameter for models with reasoning
- Update documentation with GLM-4.7 as latest flagship model
- Add cached input column to pricing table (GLM-4.7 only)
- Add tests for GLM-4.7 reasoning support and cost calculation
- Update all examples to use GLM-4.7

Model specifications:
- Context: 200K input, 128K output
- Supports: reasoning, function calling, tool choice, prompt caching
- Pricing: Same as GLM-4.6 with cache support

See: https://docs.z.ai/guides/llm/glm-4.7
2026-01-04 00:44:19 +05:30
Lu
37c908caf9
google genai adapter inline data support (#18477)
* support inline data

* add test
2026-01-04 00:43:22 +05:30
ゆり
9ba27d85ce
feat(types): add output_text property to ResponsesAPIResponse (#18491)
Add the output_text convenience property to ResponsesAPIResponse that
aggregates all output_text items from the output list, matching the
OpenAI SDK's Response.output_text behavior.

The property iterates through output items, collects text content from
message-type outputs, and returns them concatenated into a single
string. Returns empty string if no output_text content exists.

Handles both dict and Pydantic model access patterns for compatibility
with different output formats.

Fixes #18470

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: yurekami <yurekami@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 00:38:32 +05:30
ゆり
dc62cdb300
fix: handle empty error objects in response conversion (#18493)
Some OpenAI-compatible providers (e.g., Apertis) return empty error
objects even on successful responses. The previous check only verified
that error was not None, causing spurious APIErrors.

Now the code checks if the error object contains meaningful data:
- For dict errors: non-empty message OR non-null code
- For string errors: non-empty string
- Other truthy values are still treated as errors

Fixes #18407

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: yurekami <yurekami@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 00:37:52 +05:30
Cesar Garcia
bdd05475bc
fix: correct cost calculation when reasoning_tokens present without text_tokens (#18607)
Fixes #18599

When OpenAI models (gpt-5-nano, o1-*, o3-*) and other providers return
reasoning_tokens in completion_tokens_details but don't provide text_tokens,
LiteLLM was incorrectly calculating costs using only reasoning_tokens,
ignoring the remaining completion tokens.

Changes:
- Modified generic_cost_per_token() in llm_cost_calc/utils.py to calculate
  text_tokens as: completion_tokens - reasoning_tokens - audio_tokens - image_tokens
  when text_tokens is not explicitly provided
- Added comprehensive test case test_reasoning_tokens_without_text_tokens_gpt5_nano()
  to verify all completion_tokens are billed correctly

Example:
- completion_tokens: 977
- reasoning_tokens: 768
- Before: only 768 tokens billed (21% less)
- After: all 977 tokens billed correctly

Affected models:
- OpenAI: gpt-5-nano, o1-*, o3-*
- Perplexity: sonar-reasoning*
- Any model returning reasoning_tokens without text_tokens
2026-01-04 00:09:00 +05:30
YutaSaito
61e666c457
Merge pull request #18597 from BerriAI/litellm_fix_openapi_to_mcp
fix openapi to mcp
2026-01-03 09:43:06 +09:00
Yuta Saito
8e633ab513 fix: reuse shared async client in mcp openapi generator 2026-01-03 09:33:12 +09:00
Yuta Saito
6168e500a8 fix: add checking path param 2026-01-03 08:57:54 +09:00
kevinpauer
705b54bf04
Feat/add watsonx fields (#18569) 2026-01-03 02:53:17 +05:30
Alexsander Hamir
44d309f270
refactor: Add lazy loading for get_llm_provider (#18591) 2026-01-02 13:18:57 -08:00
Alexsander Hamir
e2f3eaefab
Add UnboundedDataStructurePattern to memory test detector (#18590) 2026-01-02 11:49:32 -08:00
Alexsander Hamir
b732710ed0
Add memory pattern detection test and fix bad memory patterns (#18589) 2026-01-02 10:52:25 -08:00
Harshit Jain
cc659b8702
fix(logging_worker): handle event loop changes in multiprocessing by checking bound_loop (#18423) 2026-01-03 00:19:14 +05:30
Alex Gertz
3bd309f808
fix: return empty data array instead of 500 when no models configured (#18556)
- /v2/model/info now returns {"data": []} when llm_router is None or model_list is empty
- /model_group/info now returns {"data": []} when llm_model_list is None or empty
- Fixes UI crash on fresh installs with STORE_MODEL_IN_DB=True
- Added 4 unit tests for empty model list scenarios
2026-01-02 23:36:05 +05:30
Chetan Choudhary
687adc6024
Add log_format parameter to GenericAPILogger (#18587)
Adds log_format parameter supporting json_array (default), ndjson, and single formats. NDJSON format enables webhook integrations like Sumo Logic to parse individual log records at ingest time. Defaults to json_array for backward compatibility.
2026-01-02 23:28:30 +05:30