Commit graph

10107 commits

Author SHA1 Message Date
Sameer Kankute
2484d202f8
address greptile review feedback (greploop iteration 1)
- Move trainingType injection to AzureOpenAIFineTuningAPI handler
- Guard normalization with is_azure flag to only apply to Azure responses
- Override acreate_fine_tuning_job in Azure handler to use is_azure=True
- Update test to directly test _ensure_training_type method
- Add test for OpenAI unchanged behavior

Made-with: Cursor
2026-03-27 20:04:41 +05:30
Sameer Kankute
265f2eb090
feat(fine-tuning): fix Azure OpenAI fine-tuning job creation
- Default trainingType=1 for Azure when omitted to avoid misleading "base model does not support fine-tuning" error
- Normalize Azure FineTuningJob responses (pending→queued, null fields→defaults) to match OpenAI schema
- Add pending status support to OpenAIFileObject for Azure file uploads
- Add test coverage for trainingType default and response normalization

Made-with: Cursor
2026-03-27 20:04:41 +05:30
Sameer Kankute
06c8476544
feat(gemini): add gemini-3.1-flash-live-preview to model cost map
Made-with: Cursor
2026-03-27 11:04:29 +05:30
Nicholas Gigliotti
92654bad37 Refactor _supports_native_structured_outputs to use standard supports_* utility pattern
Addresses Greptile review feedback: replace direct litellm.model_cost
lookup with the standard _supports_factory infrastructure used by
supports_reasoning, supports_native_streaming, etc.

- Add supports_native_structured_output() utility in litellm/utils.py
- Add supports_native_structured_output field to ModelInfoBase type
- Wire field into _get_model_info_helper return dict
- Delegate from Bedrock _supports_native_structured_outputs to utility
- Add field to JSON schema validator in test_utils.py
2026-03-26 21:49:03 -04:00
Nicholas Gigliotti
0ef8eb6121 Add test assertion for deepseek.v3-v1:0 native structured output 2026-03-26 20:23:12 -04:00
Nicholas Gigliotti
d7e55bf105 Fix test state leakage: restore env and model_cost after each test
Wrap cost-map-dependent tests in try/finally to restore
os.environ["LITELLM_LOCAL_MODEL_COST_MAP"] and litellm.model_cost,
preventing test-ordering sensitivity.
2026-03-26 20:23:12 -04:00
Nicholas Gigliotti
aba027beed Remove native structured output flag from models broken on Bedrock
Integration testing confirmed gemma-3 (4b/12b/27b) ignores the JSON
schema and returns free text, and nemotron-nano (9b/12b) errors with
"Tool calling is not supported in streaming mode" even on sync calls.
Remove the flag so these models fall back to the tool-call approach.
Also fix test assertions to match (nemotron-nano-3-30b is supported,
gemma-3 and nemotron-nano-12b are not).
2026-03-26 20:23:12 -04:00
Nicholas Gigliotti
cb66672017 Replace hardcoded Bedrock native structured output model set with cost JSON lookup
Move the source of truth for which Bedrock models support native structured
outputs (outputConfig.textFormat) from a hardcoded substring set
(BEDROCK_NATIVE_STRUCTURED_OUTPUT_MODELS) to the cost JSON via a new
"supports_native_structured_output" flag. This makes it possible to add
support for new models (including Claude Sonnet 4.6, which was missing)
by updating the JSON alone, with no code changes needed.
2026-03-26 20:23:12 -04:00
Ryan Crabbe
0aadf51342 fix(proxy): ignore return_to in SSO when control_plane_url is not configured
Instead of returning a 400 error when return_to is passed without
control_plane_url configured, silently ignore it and proceed with
the normal same-origin SSO flow.
2026-03-23 21:54:29 -07:00
Krish Dholakia
14fffc2770
Merge pull request #24432 from BerriAI/krrishdholakia/project-id-tracking
feat(proxy): add project_alias tracking in callbacks
2026-03-23 19:24:44 -07:00
Krrish Dholakia
26d162ccf4 fix(test): add user_api_key_project_alias to spend logs expected keys
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 18:12:50 -07:00
Josh
8a58281cbf Add org budget metrics initialization at startup 2026-03-23 19:33:57 -04:00
Lei Nie
1716956520 test(responses): update expected events and add mock test for content_part.added
- Update test_anthropic_via_responses_api expected_events to include
  CONTENT_PART_ADDED between OUTPUT_ITEM_ADDED and OUTPUT_TEXT_DELTA
- Add TestEnsureOutputItemContentPartAdded with 3 mock tests:
  message item emits content_part.added, reasoning item does not,
  and the event is only emitted once
2026-03-23 22:29:50 +00:00
Krrish Dholakia
dd0e7dcca8 test(prometheus): add tests for spend_logs_metadata in custom labels
Verify that spend_logs_metadata is correctly merged into combined_metadata
and flows through to Prometheus custom labels. Tests cover: basic extraction,
precedence when keys overlap, all three metadata sources combined, and None
handling.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 11:02:21 -07:00
Krrish Dholakia
6809213957 feat(proxy): add project_alias tracking through callback metadata pipeline
Thread project_alias alongside project_id through the metadata pipeline so
callbacks receive the human-readable project name. DRY up duplicate metadata
dict construction in proxy_track_cost_callback and pass_through_endpoints by
reusing get_sanitized_user_information_from_key — future metadata fields only
need adding in one place.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 10:44:17 -07:00
Cesar Garcia
b8189ea1de
Merge pull request #24164 from dongyu-turo/feat/update-bedrock-claude-price-above-200k
fix: update bedrock claude sonnet/opus 4.6 above 200k token pricing and sonnet 4.6 max_input_tokens to 1M
2026-03-23 14:40:26 -03:00
Chesars
da0c6c14bb fix: align claude 4.6 pricing tests 2026-03-23 14:23:29 -03:00
Cesar Garcia
3f3d275e67
Merge pull request #24417 from Chesars/refactor/shared-format-mapping
refactor(responses): extract shared format mapping between Responses API and Chat Completions bridges
2026-03-23 12:55:18 -03:00
Cesar Garcia
498c113933
Merge pull request #24415 from Chesars/fix/multimodal-embedding-dimensions
fix(vertex_ai): forward dimensions parameter in multimodalembedding requests
2026-03-23 12:52:27 -03:00
Cesar Garcia
4399b7614d
Merge pull request #24410 from Chesars/fix/gemini-document-modality-cost
fix(gemini): include DOCUMENT modality tokens in cost calculation
2026-03-23 12:51:05 -03:00
michelligabriele
fa7ccf0893 fix(test): add request_data param to test mock + black formatting 2026-03-23 15:43:05 +01:00
michelligabriele
4625ccbaa2 fix(proxy): anchor metadata dict in _process_response/_process_error so pop() mutates the real dict 2026-03-23 15:39:23 +01:00
michelligabriele
d8fd9a20ed fix(proxy): address Greptile review — streaming request_data, OCR backward compat, test coverage
- Pass request_data to end-of-stream process_output_streaming_response call
- Restore inputs.update() in OCR handler for third-party guardrail providers
- Add streaming end-to-end test for guardrail logging passthrough
2026-03-23 15:39:23 +01:00
michelligabriele
ae454fd700 fix(proxy): OpenAI Moderation post-call guardrail response not captured for logging
Two independent bugs prevented post-call OpenAI Moderation guardrail
results from reaching downstream logging callbacks (Langfuse, Datadog).

Bug 1: process_output_response() created a throwaway request_data dict,
so guardrail info written by @log_guardrail_information was discarded.
Fixed by threading the real request_data from the unified guardrail
dispatcher through all 13 BaseTranslation handlers, with litellm_metadata
injection preserved for third-party guardrails (Zscaler, Prompt Security).
Also extended to process_output_streaming_response for consistency.

Bug 2: The @log_guardrail_information decorator collapsed the full
moderation API response (categories, scores, flagged status) to "allow".
Fixed by overriding _process_response/_process_error on
OpenAIModerationGuardrail to stash and log the full response, following
the established Model Armor pattern.
2026-03-23 15:39:22 +01:00
Chesars
a53ef4b574 fix: rename test to match actual API parameter name (dimension) 2026-03-23 11:38:07 -03:00
Chesars
2afa65dd65 refactor(responses): extract shared format mapping between Responses API and Chat Completions bridges
Both bridges (Responses→CC and CC→Responses) independently encoded the
same field mapping knowledge. This extracts 4 shared mappings into a
single module so future changes only need to happen in one place.

Shared mappings:
- status ↔ finish_reason bidirectional dicts and functions
- response_format ↔ text.format paired conversion functions
- provider_specific_fields normalization helper
- usage field name translation (input_tokens ↔ prompt_tokens, etc.)

No behavioral changes — bridge methods now delegate to the shared module.
2026-03-23 11:20:19 -03:00
Chesars
265e096a53 fix: use correct parameter name 'dimension' for Vertex AI multimodalembedding
The Vertex AI multimodalembedding predict endpoint expects 'dimension'
(not 'outputDimensionality') in the parameters field.
2026-03-23 11:06:52 -03:00
Chesars
7805f38cce fix(vertex_ai): forward dimensions parameter in multimodalembedding requests
The `dimensions` parameter was correctly mapped to `outputDimensionality`
in `optional_params` but never placed in the request body. The Vertex AI
predict endpoint expects it under a `parameters` field.

Add `parameters` dict to `VertexMultimodalEmbeddingRequest` TypedDict and
populate it from `optional_params` in `transform_embedding_request`.

Fixes #24392
2026-03-23 11:01:15 -03:00
Chesars
446456b855 fix(gemini): include DOCUMENT modality tokens in cost calculation
Gemini API returns a DOCUMENT modality in promptTokensDetails for PDF
inputs, but the token parser only handled TEXT, IMAGE, AUDIO, and VIDEO.
DOCUMENT tokens were silently dropped, causing cost to be undercounted
by up to 99% for PDF-heavy requests.

Map DOCUMENT tokens to text_tokens since Gemini bills documents at the
text token rate. Applied to all four modality parser loops:
promptTokensDetails, cacheTokensDetails, responseTokensDetails, and
candidatesTokensDetails.

Fixes #24375
2026-03-23 10:39:23 -03:00
Cesar Garcia
d233d6694d
Merge pull request #24372 from Chesars/fix/gemini-web-search-cost
fix(gemini): read web search cost from model_info instead of hardcode
2026-03-22 18:48:08 -03:00
Cesar Garcia
335f4e8c6e
Merge pull request #24370 from Chesars/fix/gemini-embedding-drop-unsupported-params
fix(gemini): filter unsupported params from embedding requests
2026-03-22 18:46:10 -03:00
Cesar Garcia
4e604d6723
Merge pull request #24368 from Chesars/fix/bedrock-converse-content-block-ordering
fix(bedrock): sort assistant content blocks so text precedes toolUse
2026-03-22 18:45:22 -03:00
Cesar Garcia
16c48b4a98
Merge pull request #24371 from Chesars/fix/responses-api-gpt5-temperature-drop-params
fix(responses-api): apply GPT-5 temperature validation
2026-03-22 18:44:12 -03:00
Cesar Garcia
de91bbb9ff
Merge pull request #24373 from Chesars/fix/zhipu-finish-reason-mapping
fix: map Zhipu GLM non-standard finish_reason values
2026-03-22 18:42:04 -03:00
Chesars
6a466913fc fix: map Zhipu GLM non-standard finish_reason values
Zhipu GLM returns non-standard finish_reason values during streaming
when inference fails mid-request, causing Pydantic validation crash:
- "network_error" (inference interrupted) → map to "stop"
- "sensitive" (content policy violation) → map to "content_filter"

Fixes #23386
2026-03-22 18:36:13 -03:00
Chesars
e82d3f6d2e refactor(gemini): use web_search_billing_unit field instead of hardcoded model name check
Replace _is_gemini_3_model() substring check with a
web_search_billing_unit field in model_prices JSON:
- "per_query": each search query billed individually (Gemini 3.x)
- "per_prompt" (default): flat fee per grounded API call (Gemini 2.x)

Add web_search_billing_unit to 23 Gemini 3.x model entries.
Update docs and tests accordingly.
2026-03-22 18:29:38 -03:00
Chesars
f8a9bbd537 test: add supports_none branch coverage for Responses API GPT-5 temperature
Add tests for the gpt-5.1/5.2/5.4 reasoning.effort interaction:
- gpt-5.1 with no reasoning allows flexible temperature
- gpt-5.1 with effort='high' drops temperature
- gpt-5.4 with effort='none' allows flexible temperature
2026-03-22 18:22:11 -03:00
Chesars
4c99f3ddd8 fix(gemini): differentiate billing model and extract web search requests
- Gemini 2.x charges per grounded prompt (flat $0.035), clamped to 1
  regardless of internal query count
- Gemini 3.x charges per search query ($0.014 each)
- Extract web_search_requests from groundingMetadata in non-streaming
  responses (parity with streaming path)
- Add search_context_cost_per_query to vertex_ai and base Gemini entries
- Move tests to tests/test_litellm/ (CI directory)
2026-03-22 18:20:00 -03:00
Chesars
040c6fe920 fix(gemini): read web search cost from model_info instead of hardcode
The Gemini web search cost calculator hardcoded $0.035 per request,
which is only correct for Gemini 2.x models. Gemini 3.x models
charge $0.014 per request.

Read from search_context_cost_per_query in model_info (same field
used by Anthropic, OpenAI, and Perplexity) with fallback to the
legacy $0.035 for models not yet updated in the JSON.

Also add search_context_cost_per_query to all 25 Gemini models
that support web search in model_prices_and_context_window.json.

Fixes #24369
2026-03-22 18:00:13 -03:00
Chesars
fff83dd8a5 fix(responses-api): apply GPT-5 temperature validation in Responses API
The Responses API map_openai_params passed all params through without
applying model-specific validation. GPT-5 models (except gpt-5-chat)
only accept temperature=1 unless reasoning.effort="none" on models
that support it (5.1, 5.2, 5.4).

Reuse the existing OpenAIGPT5Config logic from chat completions to
validate temperature in the Responses API path. With drop_params=True,
unsupported temperature values are silently dropped; without it,
UnsupportedParamsError is raised.

Fixes #16090
2026-03-22 17:51:07 -03:00
Chesars
db0d85eefd fix(gemini): filter unsupported params from embedding requests
The Gemini batch embedding transformation was spreading all
optional_params into the request body via **gemini_params. Params
like max_tokens (injected by add_provider_specific_params_to_optional_params)
would reach the Gemini API and cause a 400 BadRequestError.

Extract _filter_embed_params() that maps dimensions/task_type and
keeps only the fields Gemini embeddings actually accept
(outputDimensionality, taskType, title). Applied to both
transform_openai_input_gemini_content and
transform_openai_input_gemini_embed_content.

This also fixes drop_params: true not preventing the error, since
the param was re-injected after the drop_params check.

Fixes #24293
2026-03-22 17:41:09 -03:00
Chesars
dd7269ee14 fix(bedrock): sort assistant content blocks so text precedes toolUse
When the Responses API converts function_call and message output items
into chat completion messages, they can become two consecutive assistant
messages. The Bedrock Converse transformer merges these into one, but
the merge preserves input order — so if function_call came first, the
toolUse block ends up before the text block.

Claude models (Sonnet 4, Haiku 3.5+) reject this ordering with:
"tool_use ids were found without tool_result blocks immediately after"

Add _sort_bedrock_assistant_content_blocks() that reorders content
blocks within assistant messages: reasoningContent → text → toolUse.
Applied in both sync and async Bedrock Converse transformation paths.

Fixes #24361
2026-03-22 17:18:40 -03:00
Cesar Garcia
2132db4f60
Merge pull request #24354 from Chesars/fix/azure-streaming-role-include-usage
fix: preserve role='assistant' in Azure streaming with include_usage
2026-03-22 11:19:53 -03:00
Cesar Garcia
5847c6166d
Merge pull request #24355 from Chesars/fix/anthropic-adapter-tool-args-dropped
fix: preserve tool_use input args in Anthropic adapter streaming
2026-03-22 11:19:12 -03:00
Chesars
e5de1ecd92 chore: remove unused _parse_sse_events helper in test 2026-03-22 11:18:50 -03:00
Chesars
84b8c652e4 fix: preserve tool_use input args in Anthropic adapter streaming
When Gemini sends tool call arguments in the same streaming chunk as a
content block transition, the Anthropic adapter discarded the
processed_chunk containing the input_json_delta. This caused tool_use
blocks to arrive with empty input: {}.

Queue the processed_chunk alongside the block transition events when it
contains input_json_delta data. Applied to both sync and async paths.

Fixes #24134
2026-03-22 10:33:21 -03:00
Chesars
ce16db1a40 fix: preserve role='assistant' in Azure streaming with include_usage
When Azure sends stream_options.include_usage=True, it emits an initial
chunk with choices=[] (prompt_filter_results) before the first content
chunk. Previously, LiteLLM inflated this empty-choices chunk with a
default StreamingChoices, which consumed the sent_first_chunk flag and
caused strip_role_from_delta to strip role from the real first chunk.
Additionally, the first real chunk with role='assistant' and content=''
was discarded by is_chunk_non_empty as "empty".

This fix:
- Forwards chunks with choices=[] faithfully (no inflated default)
- Only marks sent_first_chunk for chunks with real choices
- Treats chunks with role in delta as non-empty
- Guards choices[0] access in __next__/__anext__ and stream_chunk_builder

Fixes #24221
2026-03-22 10:12:07 -03:00
Chesars
7091f87a7a fix: rename test method 2026-03-22 01:37:59 -03:00
yuneng-jiang
9963b31e07 Revert "fix(proxy): restore per-entity breakdown in aggregated daily activity endpoint"
This reverts commit 9c3fab24ad.
2026-03-21 21:37:29 -07:00
Chesars
11e4ec00f7 fix: resolve file refs in nested lists, only flag truly multimodal nested inputs 2026-03-22 01:37:18 -03:00