Commit graph

1873 commits

Author SHA1 Message Date
Mateo Wang
4d54324515
Merge pull request #35188 from BerriAI/litellm_remove_dead_bedrock_invoke_path
refactor(bedrock): remove the dead BedrockLLM invoke code path
2026-07-29 21:21:25 -07:00
mateo-berri
a895249923 refactor(bedrock): remove the dead BedrockLLM invoke code path 2026-07-29 20:25:36 -07:00
Mateo Wang
47f1fb394e
Merge pull request #35172 from BerriAI/litellm_vertex_cache_skip_tool_final
fix(vertex_ai): skip context caching when the cached block ends on a model turn
2026-07-29 20:24:42 -07:00
mateo-berri
819dc7812a fix(vertex_ai): evaluate cached-block terminal turn after system extraction 2026-07-29 19:47:26 -07:00
Mateo Wang
9f9d72b50f
Merge pull request #34603 from ljogeiger/litellm_vertex_function_call_id
fix(vertex_ai): forward function_call id on Vertex Gemini 3+ tool turns
2026-07-29 18:51:54 -07:00
mateo-berri
dbc0d23c1e fix(vertex_ai): skip context caching when the cached block ends on a model turn 2026-07-29 18:38:29 -07:00
Mateo Wang
6fe1e73699
Merge pull request #34847 from BerriAI/litellm_fix_vertex_batch_read_per_model_bucket
fix(vertex_ai): honor per-model gcs_bucket_name on managed-file read path
2026-07-29 18:10:47 -07:00
Napuh
2f7574d7c1
fix(anthropic-adapter): open the first content block with the real upstream type so reasoning-first streams start with thinking (#34433)
* fix(anthropic-adapter): open first content block with the real upstream type

* fix(anthropic): defer blank leading stream deltas
2026-07-28 21:51:59 -07:00
tin-berri
32a4377acd
Merge pull request #34589 from BerriAI/litellm_lit4798_glm_stop_thinking
fix(anthropic-adapter): translate stop_sequences and disabled thinking for non-Claude targets
2026-07-28 17:42:27 -07:00
Yassin Kortam
caede1c5a0
fix(aiohttp): keep keep-alive connector config when a session is rebuilt (#34962) 2026-07-28 16:18:34 -07:00
shivam
5f50791e99 fix(vertex_ai): source managed-file read bucket + credentials from per-model litellm_params
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-07-27 23:33:01 +00:00
mateo-berri
8b08c31ebe test: cover volcengine responses and openai evals transformations
Exercises the streaming field-fill heuristics, model_construct fallbacks,
and the get/cancel/delete/list request and response transforms that had no
tests.
2026-07-27 12:57:21 -07:00
yucheng-berri
1776daa267
fix(bedrock): stop replaying expired Google OIDC tokens to STS on guardrail auth (#34637)
Cache web identity STS credentials in the shared IAM cache (restores the
pre-v1.85.0 behavior removed by #27125) and cap the Google OIDC token cache
TTL at the token's own exp claim minus a 60s margin, never caching an
already-expired token
2026-07-25 16:27:54 -07:00
ryan-crabbe-berri
998a372417
test: stop bedrock tool acompletion tests from making real network calls (#34644) 2026-07-25 19:01:22 +00:00
devin-ai-integration[bot]
96f58fac53
fix(router): don't cool down parent deployment on advisor sub-call failure (#33792)
* fix(router): don't cool down parent deployment on advisor sub-call failure

Advisor orchestration issues a sub-call to a different provider/credentials than the selected deployment. When that sub-call fails (e.g. a 401 because no advisor API key is configured), the exception propagates up and the router's deployment_callback_on_failure attributes it to the healthy parent deployment's model_info.id, cooling it down and rejecting unrelated callers to the same model group.

Tag advisor sub-call failures on the exception and skip cooldown for them in deployment_callback_on_failure. The exception is tagged rather than wrapped so its type is preserved and retry/fallback classification and the client-facing error are unchanged. Genuine executor/deployment failures are untagged and still cool down as before.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor(router): tag advisor orchestration failures via provider-neutral util

Address review on LIT-4565: move the cooldown-exemption marker into
litellm/router_utils/cooldown_handlers.py so the router imports it at
module top instead of an in-function anthropic import, and extend the
exemption to AdvisorMaxIterationsError so a max-iterations orchestration
failure no longer cools down the healthy executor deployment.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: shivam <shivam@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-07-25 10:17:13 -07:00
Lukas Geiger
acd414f186 fix(vertex_ai): forward function_call id on Vertex Gemini 3+ tool turns
Vertex AI now accepts and returns `id` on functionCall and functionResponse parts for Gemini 3+ on the v1 endpoint, so the provider check added in #28324 is stale. It silently drops the id for every Vertex caller, which breaks strict tool-call matching

Gate the id on model version alone, which is what the code did before #28324 and what Google AI Studio already does. `_forward_gemini_function_call_id` no longer takes `custom_llm_provider`, and the decision is resolved once in `_gemini_convert_messages_with_history` and passed to both converters as a bool rather than re-derived independently in each. The context caching path is covered by the same change, since it already passes `model` and the gate needs nothing else

The `id` comments on `FunctionCall`, `FunctionResponse` and `HttpxFunctionCall` were also written by #28324 and asserted the opposite of current behaviour, so they are corrected here
2026-07-25 05:39:23 +00:00
Tin Chi Lo
5072590c27 fix(anthropic-adapter): dedupe reasoning_effort wrapping to close sibling gap
translate_thinking_for_model duplicated the same summary/auto_summary
wrapping logic as _translate_thinking_to_openai without the
disabled-thinking guard, so it could still wrap "none" into an
{effort, summary} dict when reasoning_auto_summary is enabled (caught
by Cursor Bugbot). Extract the wrapping rule into one shared
_apply_reasoning_summary_wrapping helper used by both call sites so
this invariant can't drift apart again.
2026-07-24 19:31:29 -07:00
Mateo Wang
7b019cf152
Merge pull request #34446 from BerriAI/litellm_fix_mantle_missing_usage
fix(bedrock-mantle): backfill usage on non-streaming /v1/messages responses
2026-07-24 19:05:40 -07:00
Tin Chi Lo
fed03a41d1 test(anthropic-adapter): cover empty stop_sequences edge case
Codecov flagged the empty-list early-return in
_translate_stop_sequences_to_openai as an uncovered line in the diff —
add a regression test asserting stop_sequences=[] does not set
new_kwargs["stop"].
2026-07-24 19:00:20 -07:00
Tin Chi Lo
9da21f38a9 fix(anthropic-adapter): keep disabled-thinking reasoning_effort a plain string
Guard against reasoning_auto_summary wrapping "none" into a dict when
thinking is disabled — there's no reasoning trace to summarize, and
non-Claude providers (e.g. Fireworks) expect reasoning_effort as a
plain string.
2026-07-24 18:48:07 -07:00
Tin Chi Lo
b3e27a0bc3 fix(anthropic-adapter): translate stop_sequences and disabled thinking for non-Claude targets
Claude Code's auto-mode classifier sends stop_sequences and thinking:
{type: disabled} on /v1/messages. The Anthropic adapter passed
stop_sequences through unchanged instead of mapping it to OpenAI's stop,
which Fireworks' OpenAI-compatible endpoint rejects with HTTP 400. It also
dropped disabled thinking instead of mapping it to reasoning_effort: none,
so the model spent its output budget on reasoning it was told to skip.

Resolves LIT-4798
2026-07-24 18:48:07 -07:00
yucheng-berri
76b0b10908
fix(guardrails): add /v1/messages support for Straiker plugin (#34548)
* fix(guardrails): add /v1/messages support for Straiker plugin

- Pass prepared response data to Anthropic Messages streaming post-call hooks (litellm/llms/anthropic/chat/guardrail_translation/handler.py)
- Normalize Straiker request, tool, finish-reason, and mode fields across Chat Completions, Messages, and Responses APIs

* fix(guardrails): gate cross-surface message resolution and cover streaming request data

Resolve request messages only for surfaces that have a mapped translation
handler. The unguarded fallback tried every registered handler in turn, which
raised AttributeError out of the guardrail's error handling on list-shaped
`input` bodies, and synthesized a chat message that was never sent for bodies
it happened to parse.

Prepare request data on the mid-stream Anthropic branch as well, matching the
terminal branch and the OpenAI handler, so guardrails that scan before
end-of-stream still receive identity metadata.

Read usage from Anthropic dict responses so non-streaming /v1/messages reports
token counts instead of null.

Add regression coverage for the streaming request data on both the terminal and
mid-stream branches; reverting either now fails.

---------

Co-authored-by: cs-mehta <chandra@straiker.ai>
2026-07-24 17:13:11 -07:00
Mateo Wang
cfb7edb54e
Merge pull request #34549 from BerriAI/litellm_fix_stream_options_responses_api
fix(responses): strip include_usage from stream_options instead of dropping the param
2026-07-24 17:12:26 -07:00
yuneng-jiang
7047a37f2f
Merge pull request #34475 from BerriAI/litellm_/test-coverage-mutation-analysis-e42223
test: remove tests that mutation analysis proved assert nothing
2026-07-24 16:23:34 -07:00
Yuneng Jiang
9f9714c209
test: remove five more zero-kill tests from test_http_handler
The http_handler pair only received its full mutation verdict after the
first removal batch landed; these five tests pass unchanged when every
function they execute is mutated and the owning file killed none of
their scored mutants. The ssl tests excluded from mutation scoring are
untouched.
2026-07-24 16:05:18 -07:00
yucheng-berri
61d32c9aac
fix: handle explicit outputInfo: null in Vertex AI batch response (#34473)
* fix: handle explicit outputInfo: null in Vertex AI batch response

Vertex AI can return HTTP 200 for a create_batch/get_batch call with an
explicit "outputInfo": null body (the output directory is assigned
asynchronously and may not be populated yet at response time).

_get_output_file_id_from_vertex_ai_batch_response did:

    response.get("outputInfo", OutputInfo()).get("gcsOutputDirectory", "")

dict.get(key, default) only substitutes default when the key is absent,
not when it is present but explicitly None, so this crashed with:

    AttributeError: 'NoneType' object has no attribute 'get'

surfaced to callers as an opaque openai.InternalServerError 500 from
litellm.create_batch()/retrieve_batch() for any Vertex AI batch job,
regardless of whether the job ultimately succeeds.

Fixed by guarding with `response.get("outputInfo") or OutputInfo()`,
matching the existing null-safe pattern already used by the sibling
_get_input_file_id_from_vertex_ai_batch_response for inputConfig. The
existing outputConfig fallback branch (a few lines below) already
handles this case correctly once it's reachable - it just never was.

Added 2 regression tests covering outputInfo: null with and without an
outputConfig fallback available.

* test: drop explanatory comment from regression test

---------

Co-authored-by: htourinho-clgx <htourinho@cotality.com>
2026-07-24 15:10:16 -07:00
shivam
a376f72400 fix(responses): stop treating stream_options as a Responses API param
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-07-24 20:53:05 +00:00
Yassin Kortam
f6a1050cbf
fix(vertex): incrementally parse accumulated Gemini stream JSON to prevent multi-value wedge (#34320)
The accumulated-JSON fallback ran json.loads over the whole buffer after every fragment and, on failure, kept the buffer without resetting it. A buffer that ever held more than one concatenated JSON value could never parse (json raises on trailing data), so it returned None on every subsequent chunk while growing without bound - an unrecoverable per-request CPU spin. Parse one value at a time from the front with raw_decode and keep the remainder, draining trailing values on later calls and at end of stream.
2026-07-24 11:07:02 -07:00
Yassin Kortam
692b22655e
fix(logging): stop scheduling sync failure_handler concurrently with async_failure_handler (#34306)
The async streaming error paths fired the sync failure_handler in a thread
and the async_failure_handler via create_task at the same time, so both
mutated the shared logging object concurrently and could crash pydantic-core.
Route failure logging through a single guarded dispatch_failure_handlers, so
the sync handler only runs after the async one completes.
2026-07-24 11:06:55 -07:00
Yuneng Jiang
4db6955451
Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_/test-coverage-mutation-analysis-e42223 2026-07-23 23:52:11 -07:00
Yuneng Jiang
58e87985e5
test: remove tests that mutation analysis proved assert nothing
25 test functions across three files pass unchanged when every function
they execute is mutated; the owning file killed zero of their scored
mutants. Four zero-kill tests tied to the fix in #31288 are kept for
rewrite instead of removal.
2026-07-23 23:52:09 -07:00
shivam
ee9f0db1cf fix(bedrock-mantle): backfill usage on non-streaming /v1/messages responses
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-07-23 23:37:40 +00:00
Mateo Wang
3bba3633c7
Merge pull request #34338 from BerriAI/litellm_lit_4313_sagemaker_chat_streaming_ttft
fix(sagemaker): forward stream events as they arrive to cut TTFT
2026-07-23 00:37:39 -07:00
Mateo Wang
86eee8bd05
Merge pull request #34319 from BerriAI/litellm_anthropic_output_format_remaining_keywords
fix(anthropic): strip all remaining output_format schema keywords rejected by Anthropic
2026-07-22 23:29:37 -07:00
mateo
5bc1df5e47 test(sagemaker): assert make_sync_call maps non-200 to SagemakerError
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-07-23 04:31:11 +00:00
mateo
a63884bc8d test(sagemaker): cover sync native streaming path via injectable make_sync_call
Extract the inline sync streaming post/decode into make_sync_call so it can be
exercised with an injected client, mirroring make_async_call, and add a sync
regression test that each token is forwarded after exactly one pulled frame.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-07-23 04:21:12 +00:00
mateo
27c91e6574 fix(sagemaker): forward native streaming events as they arrive to cut TTFT
Mirror the sagemaker_chat fix on the native sagemaker/ streaming path: the
sync and async completion handlers read the invocations-response-stream body
with iter_bytes(chunk_size=1024) / aiter_bytes(chunk_size=1024), so httpx
withholds bytes until 1024 accumulate and tokens arrive in gap-then-burst
waves. Drop the fixed chunk size so each decoded event is forwarded as its
bytes arrive.

Also add a boundary-agnostic decoder test proving frames reassemble correctly
regardless of where transport reads split the stream.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-07-23 04:03:25 +00:00
mateo-berri
16dad256d4 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_anthropic_output_format_remaining_keywords 2026-07-22 19:59:09 -07:00
mateo-berri
75c0e12dac fix(bedrock): let parallel_tool_calls-derived disable flag win over raw tool_choice value 2026-07-22 19:52:54 -07:00
mateo-berri
6a7454271b fix(bedrock): include type in tool_choice disable_parallel_tool_use config for Converse 2026-07-22 19:16:28 -07:00
shivam
3fb2d32f67 test(sagemaker_chat): drop redundant first-delta guard that could mask failure
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-07-23 01:50:15 +00:00
shivam
0ff3ade224 fix(sagemaker_chat): forward stream events as they arrive to cut TTFT
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-07-23 01:13:28 +00:00
Mateo Wang
9ab3847c0b
fix(tests): remove importlib.reload of http_handler that breaks client injection in later tests (#34336)
The huggingface embedding test fixture reloaded
litellm.llms.custom_httpx.http_handler, creating a new HTTPHandler class
object. llm_http_handler keeps the class captured at import time, so any
test running later in the same process that injects a client built from
the reloaded class fails the isinstance check and the mock is silently
discarded, causing a real network call. Under pytest-xdist loadscope this
surfaced as a deterministic failure of
test_accept_header_in_completion_request_jwt whenever an unrelated PR
shifted worker distribution.

Also removes the same reload pattern from the vertex rerank integration
test (both were previously removed in a6df01caec and resurrected by a
merge conflict resolution) and hardens the agentcore victim test by
dropping the bare except that swallowed the real error
2026-07-23 01:11:35 +00:00
mateo-berri
2ec2a92da2 fix(anthropic): strip all remaining output_format schema keywords rejected by Anthropic 2026-07-22 16:16:04 -07:00
Mateo Wang
46440e2df4
fix(anthropic): strip uniqueItems + other unsupported array/object constraints from output_format schema (#33981) (#34313)
* fix(anthropic): strip uniqueItems + other unsupported array/object constraints from output_format schema

Anthropic's structured outputs (`output_format`) validate the JSON schema
against a strict subset and reject cross-element / count constraints that a
constrained-decoding grammar cannot enforce, returning a 400
`invalid_request_error`.

`filter_anthropic_output_schema` already stripped the numeric / string /
item-count constraints (minimum, maximum, exclusiveMinimum/Maximum, minLength,
maxLength, minItems, maxItems) but still let these through:

- uniqueItems
- contains / minContains / maxContains
- minProperties / maxProperties

so a request using them fails with e.g. "output_format.schema: For 'array'
type, property 'uniqueItems' is not supported".

This is provider-visible: newer Claude models on the native `output_format`
path (e.g. `azure_ai`) 400, while `vertex_ai` is unaffected because it is
forced onto the permissive tool-use path (#18625 / #19201).

Add the missing keywords to the unsupported-field set and the description map,
and skip the advisory description note for a disabled boolean constraint
(`uniqueItems: false`) so it isn't misdescribed as required.



* fix(anthropic): serialize contains sub-schema in output_format advisory note

Address Greptile review: the `contains` advisory note previously discarded the
sub-schema, so the description only said an item must match "a schema" without
saying which. It now serializes the sub-schema as JSON (e.g. "array must
contain an item matching: {\"type\": \"integer\", \"const\": 1}"), matching the
other stripped constraints which carry their value. Sub-schema (dict/list)
values are json.dumps'd; scalar constraints are unchanged.



* style(anthropic): apply ruff format to output_format filter change



* style(test): ruff format anthropic schema filter tests



* test(anthropic): cover output_format array/object constraint filtering in test_litellm tree

Mirrors the schema-filter tests under tests/test_litellm/ so the coverage
job exercises the new uniqueItems/contains/min-maxProperties handling and the
uniqueItems: false branch.



---------

Co-authored-by: Darien Kindlund <darien@kindlund.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 23:09:10 +00:00
devin-ai-integration[bot]
fa6b209165
feat(guardrails): add only_scan_new_messages for per-session incremental scanning (#33278)
* feat(guardrails): add only_scan_new_messages for per-session incremental scanning

Co-Authored-By: Ishaan Jaffer <155045088+ishaan-berri@users.noreply.github.com>

* fix(guardrails): use fixed TTL constant and revert unrelated test formatting

Co-Authored-By: Ishaan Jaffer <155045088+ishaan-berri@users.noreply.github.com>

* fix(guardrails): run only_scan_new_messages in the unified apply_guardrail path

The initial wiring lived in BedrockGuardrail.async_pre_call_hook, but the proxy
routes Bedrock through the unified apply_guardrail interface, so the flag had no
effect live. Move incremental selection into apply_guardrail: filter the flat
texts list against per-session scanned hashes, skip the Bedrock call when nothing
is new, and mark hashes only after a successful (non-blocked) scan. Full-context
fallback is preserved when there is no session id, the cache is unavailable, or a
masking guardrail is configured.

Co-Authored-By: Ishaan Jaffer <155045088+ishaan-berri@users.noreply.github.com>

* test(guardrails): cover session-id fallbacks and mark_texts_scanned guards

Co-Authored-By: Ishaan Jaffer <155045088+ishaan-berri@users.noreply.github.com>

* fix(guardrails): fall back to full scan when incremental guardrail masks content, use shared cache

Co-Authored-By: Ishaan Jaffer <155045088+ishaan-berri@users.noreply.github.com>

* test(guardrails): cover generic agent multi-turn incremental scan

Co-Authored-By: Ishaan Jaffer <155045088+ishaan-berri@users.noreply.github.com>

* test(guardrails): cover incremental scan cache resolver fallbacks

Co-Authored-By: Ishaan Jaffer <155045088+ishaan-berri@users.noreply.github.com>

* test(guardrails): cover flag interactions and /v1/messages incremental scan semantics

* feat(guardrails): make GUARDRAIL_SCANNED_MESSAGES_CACHE_TTL_SECONDS env configurable

* test(guardrails): prove skip_system/skip_tool are enforced upstream of incremental scan

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Ishaan Jaffer <155045088+ishaan-berri@users.noreply.github.com>
Co-authored-by: Yucheng Zhu <yucheng@berri.ai>
2026-07-22 09:56:59 -07:00
mubashir1osmani
f1f0a0bacd
fix(bedrock): emit Nova Sonic realtime session.created on connect and session.updated on session.update (#34133) 2026-07-22 06:15:37 +00:00
yucheng-berri
065faf6e69
chore(proxy): clean up request parameter validation and provider destination handling (#34189) 2026-07-22 00:57:58 +00:00
mateo-berri
fa025fc474 chore(tests): replace a customer name and domain with neutral placeholders 2026-07-21 15:09:15 -07:00
mateo-berri
fadec17a0f Merge origin/litellm_internal_staging into litellm_mantle_codex_additional_tools (resolve overlap with #33228 hoist) 2026-07-20 20:30:34 -07:00