* fix: resolve mypy type errors in hiddenlayer guardrail and transformation
- Fix return type of apply_guardrail from str to GenericGuardrailAPIInputs
- Add None checks for logging_obj before accessing attributes
- Convert AllMessageValues to dict format for HiddenLayer API compatibility
- Fix payload type annotation in _call_hiddenlayer
- Ensure transformed_output always returns list[dict[str, Any]] in transformation.py
* fix: use litellm_call_id as trace_id fallback in langfuse logging
- Only use standard_logging_object.trace_id if explicitly set via litellm_session_id or litellm_trace_id params
- Fallback to litellm_call_id when no explicit trace_id is provided (matches test expectation)
- Return the trace_id we set instead of generation_client.trace_id for consistency
- Add warning if langfuse modifies the trace_id to help debug potential issues
Fixes test_logging_trace_id test failure where auto-generated UUID was used instead of litellm_call_id
* fix: document envs
* fix: handle None response in /spend/logs endpoint when no records found
- Return empty list [] instead of [None] when spend_log is None
- Prevents 500 errors when querying by request_id, api_key, or user_id with no matching records
- Fixes test_chat_completion_bad_model_with_spend_logs test failure
* fix: use standard_logging_object trace_id when available in langfuse logger
- Fix trace_id selection logic to use standard_logging_object.trace_id when available
- Previously only used standard_logging_object.trace_id if explicitly set via params
- Now uses standard_logging_object.trace_id whenever it's present, matching test expectations
- Falls back to litellm_call_id if no trace_id is found
- Fixes test_log_langfuse_v2_uses_standard_trace_id_when_available test failure
When using litellm.completion() with model="openai/responses/...", images
in tool message content were not being transformed from Chat Completion
format to Responses API format.
Chat Completion format: {"type": "image_url", "image_url": {"url": "..."}}
Responses API format: {"type": "input_image", "image_url": "..."}
This caused OpenAI to reject the request with error 400 since "image_url"
is not a valid type for function_call_output content.
When OpenAI Responses API returns both text AND tool_calls, the bridge
transformation was emitting is_finished=True after the text message completed,
causing subsequent tool_call chunks to be dropped.
The fix:
- response.output_item.done for messages no longer emits is_finished=True
- Added handler for response.completed to properly signal stream end
* fix(unified_guardrail.py): support during_call event type for unified guardrails
allows guardrails overriding apply_guardrails to work 'during_call'
* feat(generic_guardrail_api.py): support new 'tool_calls' field for generic guardrail api
returns the tool calls emitted by the LLM API to the user
* fix(generic_guardrail_api.py): working anthropic /v1/messages tool call response
send llm tool calls to guardrail api when called via `/v1/messages` API
* fix(responses/): run generic_guardrail_api on responses api tool call responses
* fix: fix tests
* test: fix tests
* fix: fix tests
* fix: fix getting mcp servers
* fix(litellm_logging.py): handle list objects for final response in standard logging payload
Fixes issue where mcp tool call response wouldn't show up
* fix(litellm_responses_transformation/): remove invalid item error for unmapped objects - breaks stream and there's no real value to this as outside of a few of them, not all can be mapped to chat completions
resolves error for web search calls via chat completions to responses api
* Add openai metadata filed in the request
* Add docs related to openai metadata
* Add utils
* test_completion_openai_metadata[True]
* Added support for though signature for gemini 3 in responses api (#16872)
* Added support for though signature for gemini 3
* Update docs with all supported endpoints and cost tracking
* Added config based routing support for batches and files
* fix lint errors
* Litellm anthropic image url support (#16868)
* Add image as url support to anthropic
* fix mypy errors
* fix tests
* Fix: Populate spend_logs_metadata in batch and files endpoints (#16921)
* Add spend-logs-metadata to the metadata
* Add tests for spend logs metadata in batches
* use better names
* Remove support for penalty param for gemini 3 (#16907)
* Remove support for penalty param
* remove halucinated model names
* fix mypy/test errors
* fix tests
* fix too many lines error
* fix too many lines error
* Add config for cicd test case
* Fix final tests
* fix batch tests
* fix batch tests
- Fix blank function name in completions response when using native function calling
- Fix Enum name being used instead of Enum value for comparison in chunk conversion
- Added additional tests to cover changes
Thanks to @mcowger for the invaluable assitance with figuring this issue out!
Fixed#16863
Fixes#16810
## Problem
When using completion() with models that have mode: "responses" (like o3-pro,
gpt-5-codex), the response_format parameter with JSON schemas was being ignored
or incorrectly handled, causing:
- Large schemas (>512 chars) to fail with "metadata.schema_dict_json: string too long" error
- Structured outputs to be silently dropped
- Users' code to break unexpectedly
## Root Cause
The completion -> responses bridge in
litellm/completion_extras/litellm_responses_transformation/transformation.py
was missing the conversion of response_format (Chat Completion format) to
text.format (Responses API format).
The inverse bridge (responses -> completion) already had this conversion
implemented in commit 29f0ed223a, but the completion -> responses direction
was incomplete.
## Solution
Added _transform_response_format_to_text_format() method that converts:
- response_format with json_schema → text.format with json_schema
- response_format with json_object → text.format with json_object
- response_format with text → text.format with text
Updated transform_request() to detect and convert response_format parameter
before sending to litellm.responses().
## Changes
- Added _transform_response_format_to_text_format() method (lines 592-647)
- Modified transform_request() to handle response_format (lines 199-203)
- Added comprehensive tests to validate the conversion
## Testing
- 5 new unit tests covering all conversion scenarios
- Real API test with OpenAI confirming large schemas (>512 chars) work
- No more metadata.schema_dict_json errors
## Impact
Users can now use completion() with models that have mode: "responses" and:
- Use large JSON schemas without hitting metadata 512 char limit
- Get proper structured outputs
- Have their existing code continue working
* feat(openai): Add support for reasoning_effort='none' in GPT-5.1
OpenAI's GPT-5.1 introduced a new reasoning effort parameter 'none'
which replaces the previous 'minimal' setting for faster, lower-latency
responses. This is now the default setting for GPT-5.1.
Changes:
- Updated REASONING_EFFORT type to include 'none' value
- Added GPT-5.1, GPT-5-mini, and GPT-5-nano to documentation
- Updated docs to reflect 'none' as GPT-5.1's default reasoning effort
- Added test to verify reasoning_effort='none' passes through correctly
Fixes#16633
* feat(responses): Add support for reasoning_effort='none' in Responses API transformation
* fix: Remove unused asyncio import from litellm_logging.py
- Fixes F401 linting error blocking CI
* fix: Add type ignore comments for MyPy false positives
- redis_cache.py: Add type ignore for aclose() - method exists but redis-py type stubs are incomplete
- redis_cluster_cache.py: Add type ignore for ping() and aclose() - redis-py typing issue
- responses/utils.py: Add type ignore for variable shadowing false positive
- transformation.py: Add type ignore for TypedDict expansion - runtime works correctly
- aws_secret_manager_v2.py: Add type ignore for dict[str, Any] assignment
All changes are safe - code works correctly in runtime, these are MyPy inference limitations.
Fixes 7 MyPy errors blocking CI without changing any logic.
* fix: Add type ignore for Redis async methods in cache files
- Add type: ignore[attr-defined] for aclose() in redis_cache.py
- Add type: ignore[attr-defined] for ping() and aclose() in redis_cluster_cache.py
- Methods exist but redis-py type stubs are incomplete
* refactor: Remove variable shadowing in _transform_response_api_usage_to_chat_usage
- Rename parameter 'usage' to 'usage_input' for clarity
- Rename local variable 'usage' to 'chat_usage' to avoid shadowing
- Eliminates MyPy false positive without needing type: ignore
- No functional changes - all tests pass
- Improves code readability and type safety
* Fix: Remove automatic summary field from reasoning_effort transformation
Problem:
The _map_reasoning_effort() function was automatically adding
reasoning.summary field when users specified reasoning_effort parameter,
causing 400 errors for users with unverified OpenAI organizations.
Root Cause:
According to OpenAI's official documentation, the summary field is opt-in
and requires organization verification:
"Reasoning summary output [...] will not be included unless you explicitly
opt in to including reasoning summaries."
"Before using summarizers with our latest reasoning models, you may need
to complete organization verification"
Source: https://platform.openai.com/docs/guides/reasoning#reasoning-summaries
Solution:
Remove the automatic inclusion of summary field from all reasoning_effort
levels (high, medium, low, minimal). Users who want reasoning summaries
can explicitly pass reasoning={"effort": "high", "summary": "auto"} in
their requests.
Impact:
- Fixes#16032
- Works for all organizations (verified and unverified)
- Maintains backward compatibility for users passing reasoning object directly
- Follows OpenAI's recommended opt-in approach
Testing:
- All existing tests pass (4/4 tests in transformation suite)
- Manual verification confirms only effort field is included
* test: Fix MockResponse missing headers attribute in test_openai_responses_api
The MockResponse class was missing the 'headers' attribute which caused
APIConnectionError when processing the mock response. Added headers={}
to fix the test.
* feat: Add dict support to reasoning_effort parameter
Allow users to pass reasoning_effort as either:
- String: reasoning_effort="high" (no summary, safe default)
- Dict: reasoning_effort={"effort": "high", "summary": "detailed"} (opt-in)
This preserves backward compatibility while giving users flexibility
to explicitly opt-in to the summary field when needed (for verified
OpenAI organizations).
---------
Co-authored-by: Krish Dholakia <krrishdholakia@gmail.com>
This aligns the proxy experience with other models that think
automatically (e.g. Deepseek R1 and grok3). It does so by setting
the necessary request input to return thinking, but not specifying
a budget or effort (thus defaulting to the internal automatic level).
* fix: handle reasoning parameters and response in responses bridge
Updates the OpenAI completions/responses bridge to map
reasoning_effort to reasoning parameters, and the chunk parser
to return reasoning_content.
ref: 12432
* fix: using type checked objects in responses bridge transform
ref: 12432
* fix(main.py): handle router custom azure model name for responses api bridge
* fix(responses/handler): ensure azure model name is stripped before sending to provider
Fixes model name error
* fix(google_genai/main.py): handle stream=true being set in kwargs
* docs: cleanup icons from sidebar
* fix(test-litellm.yml): add google-genai to test litellmyml
* fix(main.py): strip 'responses/' from bridge
* fix(main.py): fix linting errors
* fix(types/openai.py): allow item to be none
handle azure streaming response
* fix(base.py): allow extra fields + handle azure item = none value in response output item added event
* fix(main.py): correctly handle removing responses/
* test(test_main.py): add unit tests
* docs: track which items need docs
* docs(anthropic.md): add tool_choice="none" to docs
* docs: add docs for new anthropic + perplexity features
* docs: cleanup mistral reasoning docs
* docs: add links to docs
* docs(index.md): update docs
* docs: refactor to add a new 'integrations' tab to docs
* refactor(docs/): create separate tab for integrations
make it easier to highlight new integrations
* docs: sort sidebar
* docs: update
* feat: working claude code with openai codex mini
* docs: add responses api to docs
* feat(index.md): update docs
* fix: fix linting error
* feat(anthropic/passthrough): pass dynamic api key/api base params to litellm.completion
allows calls to work with config.yaml
* fix(responses_api/transformation): fix passing dynamic params to responses api from .completion()
Allows responses api to work with config.yaml
* fix(langfuse.py): fix responses api usage logging to langfuse
* refactor(litellm_logging.py): add more generic solution for responses api usage logging
ensures it works across all logging integrations
* fix(litellm_logging.py): patch for anthropic messages not returning a pydantic object
it should ideally return a pydantic object, which would simplify checks and reduce errors
* fix(handler.py): correctly bubble up empty choices errors to litellm.completion
causes downstream errors as it is expected there is at least one choice set
* feat(litellm_logging.py): prevent double logging litellm responses
ensures accurate spend tracking for calls when bridges are used
* fix(litellm_logging.py): ensure logging is consistently enforced across all call types
* fix: patch - set calltype before entering bridge api
ensures logging object is applying the correct logic on the event hooks
* fix(types/router.py): loosen type hint for mock response
* change space_key header to space_id for Arize (#11595)
* feat(schema): add additional indexes to LiteLLM_SpendLogs for improved query performance (#11675)
* Revert "feat(schema): add additional indexes to LiteLLM_SpendLogs for improve…" (#11683)
This reverts commit 2a7f113fde.
* [Feat] Use dedicated Rest endpoints for list, calling MCP tools (#11684)
* fix: (fix) use specific rest endpoints for MCP
* ui - use rest mcp endpoints
* fix imports
* docs DISABLE_AIOHTTP_TRUST_ENV
* docs(caching.md): remove batch redis get recommendation - old code path, no longer necessary
* fix(vertex_and_google_ai_studio_gemini.py): handle gemini not passing audio token usage data
* Chat Completions <-> Responses API Bridge Improvements (#11685)
* feat(anthropic/passthrough): pass dynamic api key/api base params to litellm.completion
allows calls to work with config.yaml
* fix(responses_api/transformation): fix passing dynamic params to responses api from .completion()
Allows responses api to work with config.yaml
* fix(langfuse.py): fix responses api usage logging to langfuse
* refactor(litellm_logging.py): add more generic solution for responses api usage logging
ensures it works across all logging integrations
* fix(litellm_logging.py): patch for anthropic messages not returning a pydantic object
it should ideally return a pydantic object, which would simplify checks and reduce errors
* fix(handler.py): correctly bubble up empty choices errors to litellm.completion
causes downstream errors as it is expected there is at least one choice set
* fix(response_metadata.py): allow model_info to be none
* fix(litellm_logging.py): copy object before mutating
* fix: fix lint check
* fix: fix linting error
* fix: fix linting error
---------
Co-authored-by: vanities <mischkeaa@gmail.com>
Co-authored-by: Cole McIntosh <82463175+colesmcintosh@users.noreply.github.com>
Co-authored-by: Ishaan Jaff <ishaanjaffer0324@gmail.com>
* feat(anthropic/passthrough): pass dynamic api key/api base params to litellm.completion
allows calls to work with config.yaml
* fix(responses_api/transformation): fix passing dynamic params to responses api from .completion()
Allows responses api to work with config.yaml
* fix(langfuse.py): fix responses api usage logging to langfuse
* refactor(litellm_logging.py): add more generic solution for responses api usage logging
ensures it works across all logging integrations
* fix(litellm_logging.py): patch for anthropic messages not returning a pydantic object
it should ideally return a pydantic object, which would simplify checks and reduce errors
* fix(handler.py): correctly bubble up empty choices errors to litellm.completion
causes downstream errors as it is expected there is at least one choice set
* fix(response_metadata.py): allow model_info to be none
* fix(litellm_logging.py): copy object before mutating
* fix: fix lint check
* refactor(responses/): refactor to move responses_to_completion in separate folder
future work to support completion_to_responses bridge
allow calling codex mini via chat completions (and other endpoints)
* Revert "refactor(responses/): refactor to move responses_to_completion in separate folder"
This reverts commit ff87cb8958.
* feat: initial responses api bridge
write it like a custom llm - requires lesser 'new' components
* style: add __init__'s and bubble up the responses api bridge
* feat(responses/transformation): working sync completion -> responses and back bridge (non-streaming)
* feat(responses/): working async (non-streaming) completion <-> responses bridge
Allows calling codex mini via proxy
* feat(responses/): working sync + async streaming for base model response iterator
* fix: reduce function size
maintain <50 LOC
* fix(main.py): safely handle responses api model check
* fix: fix linting errors