Commit graph

52808 commits

Author SHA1 Message Date
devin-ai-integration[bot]
ecce7cdd9c
fix(proxy_cli): import proxy_server once on script-style boot (#42584)
Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-09-22 14:29:50 -07:00
joshua-berri
b277be0867
fix(mcp): preserve discovery attribution and sanitize logging headers (#42541)
Co-authored-by: Joshua Valluru <326636767+joshua-berri@users.noreply.github.com>
2026-09-22 14:26:48 -07:00
devin-ai-integration[bot]
6764868861
fix(otel): keep text completion choice fields beside the synthesized message (#42537)
Co-authored-by: yucheng <yucheng@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 14:24:32 -07:00
devin-ai-integration[bot]
c37fe46534
test(vcr): guard leaked cassette patches and make injected-transport embedding tests immune (#42542)
* test(vcr): guard leaked cassette patches and make injected-transport embedding tests immune

* test(vcr): derive the leak guard's patch points from vcrpy's own reset list

* test(vcr): share CapturingTransport and switch the encoding_format embedding test to it

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-09-22 14:20:18 -07:00
devin-ai-integration[bot]
075536eca1
chore(cost-map): remove models past their deprecation date (#42435)
* chore(cost-map): remove models past their deprecation date

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

* test(cost-calc): drop the empty parametrize left behind by the gemini web search removal

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

* fix(cost-map): drop merge base block left by conflict resolution

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

* test(cost-calc): drop gemini image cost tests pinned on removed model

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

---------

Co-authored-by: kerry <kerry@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 21:19:26 +00:00
devin-ai-integration[bot]
989d7b87b2
fix(proxy): attribute provider and model_info on pre_call_hook rejections (#41077)
* fix(proxy): attribute provider and model info on pre-call rejected requests

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

* fix(proxy): keep pre-call rejections out of deployment cooldown and prometheus deployment state

Stamp model_info only into the logging metadata so the router's failure callbacks do not
count a key-level 429 or guardrail 403 against the deployment, treat a resolved plus an
unresolved deployment as ambiguous provider attribution, and stop the prometheus deployment
counters and deployment_state from treating a proxy-side reject as a selected deployment

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

* fix(proxy): skip deployment attribution when the rejected body's model is not a string

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

* fix(prometheus): bucket non-string request models as other instead of raising in failure hook

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

* fix(proxy): resolve team deployments and treat guardrail rejects as proxy-side in failure attribution

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

* fix(prometheus): flag pre-routing rejects instead of matching exception names

Post-call GuardrailRaisedException failures kept their deployment labels on main but lost them
on this branch because every GuardrailRaisedException was treated as a pre-routing reject.
The proxy failure path now flags litellm_params with proxy_rejected_before_routing only when
it adds deployment attribution itself, and the Prometheus logger keys deployment selection
off that flag

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

* fix(proxy): key pre-routing reject flag off provider handoff, not caller metadata

Caller-supplied metadata.model_info (kept for keys allowed to override pricing) no longer
suppresses proxy_rejected_before_routing. The hook now checks the logging object's
first_api_call_start_time, which only the provider handoff sets, so Prometheus never
records a deployment failure for a request that was rejected before routing.

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

* test(e2e): poll for both served and rejected spend rows before asserting attribution

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: yucheng <yucheng@berri.ai>
2026-09-22 14:14:13 -07:00
berriai-litellm-provider-info-sync[bot]
cd69342eef
chore(prices): sync Vertex AI prices: 20 models (#42577)
deep-research-pro-preview-12-2025: cache_read_input_token_cost_batches
vertex_ai/deep-research-pro-preview-12-2025: cache_read_input_token_cost_batches
gemini-3-pro-image: cache_read_input_token_cost_batches
vertex_ai/gemini-3-pro-image: cache_read_input_token_cost_batches
gemini-3.1-flash-image: cache_read_input_token_cost_batches
vertex_ai/gemini-3.1-flash-image: cache_read_input_token_cost_batches
gemini-3.1-flash-lite: cache_read_input_token_cost_batches
vertex_ai/gemini-3.1-flash-lite: cache_read_input_token_cost_batches
gemini-3.1-flash-lite-image: cache_read_input_token_cost_batches
vertex_ai/gemini-3.1-flash-lite-image: cache_read_input_token_cost_batches
gemini-3.5-flash: cache_read_input_token_cost_batches
vertex_ai/gemini-3.5-flash: cache_read_input_token_cost_batches
gemini-3.5-flash-lite: cache_read_input_token_cost_batches
vertex_ai/gemini-3.5-flash-lite: cache_read_input_token_cost_batches
gemini-3.6-flash: cache_read_input_token_cost_batches
vertex_ai/gemini-3.6-flash: cache_read_input_token_cost_batches
gemini-3.7-flash: cache_read_input_token_cost_batches
vertex_ai/gemini-3.7-flash: cache_read_input_token_cost_batches
gemini-3.8-flash: cache_read_input_token_cost_batches
vertex_ai/gemini-3.8-flash: cache_read_input_token_cost_batches

Co-authored-by: berriai-litellm-provider-info-sync[bot] <328147090+berriai-litellm-provider-info-sync[bot]@users.noreply.github.com>
2026-09-22 14:11:31 -07:00
devin-ai-integration[bot]
12dffbafd6
fix(proxy): honor DATABASE_DISABLE_PREPARED_STATEMENTS in the litellm CLI (#42556)
* fix(proxy): honor DATABASE_DISABLE_PREPARED_STATEMENTS in the litellm CLI

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

* test(proxy): pooled pgbouncer url keeps a single pgbouncer=true when the upstream already carries it

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

* fix(proxy): reject a malformed DATABASE_DISABLE_PREPARED_STATEMENTS even when the config already enables it

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

---------

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 16:10:49 -05:00
devin-ai-integration[bot]
bbc702cd8b
fix(gateway): expose /api/event_logging/batch on the gateway allowlist (#42572)
* fix(gateway): expose /api/event_logging/batch on the gateway allowlist

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

* fix(gateway): route /api/event_logging to gateway pods in helm and terraform

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

* test(proxy): stop max_budget leaking between proxy_server and native_compaction tests

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

---------

Co-authored-by: kerry <kerry@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 14:09:40 -07:00
devin-ai-integration[bot]
e30f9f578c
fix(model_prices): registry audit 2026-09-22, absorb open pricing PRs (#42543)
* fix(model_prices): registry audit 2026-09-22, absorb open pricing PRs

Rolls the open registry-only PRs into one PR after re-verifying every value against the official provider source: OpenAI, Azure, Vertex AI and Gemini batch cache-read prices, Baseten model metadata from the authenticated inference API, Bedrock eu-west-2 Nemotron Super 3 pricing from the AWS offer file, and OpenRouter prices refreshed from the live OpenRouter models API

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

* fix(model_prices): add groq/llama-guard-3-8b from the Groq model page

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

* fix(model_prices): refresh openrouter deepseek aliases from live api and drop stale off-peak windows

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

* fix(model_prices): resolve baseten merge conflicts against main

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: sinksilk <785976238@qq.com>
2026-09-22 14:05:33 -07:00
devin-ai-integration[bot]
0e6a288458
fix(ssrf): point the blocked-address remediation at litellm_settings (#42508)
* fix(ssrf): point the blocked-address remediation at litellm_settings

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

* test(ssrf): pin the block message's named section to litellm_settings

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

* test(compaction): pin litellm.max_budget so leaked proxy budget cannot 401 the child auth

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-09-22 14:04:16 -07:00
berriai-litellm-provider-info-sync[bot]
b73696a15d
chore(prices): sync OpenAI prices: 3 models (#42557)
gpt-5-2025-08-07: cache_read_input_token_cost_batches
gpt-5-mini-2025-08-07: cache_read_input_token_cost_batches
gpt-5-nano-2025-08-07: cache_read_input_token_cost_batches

Co-authored-by: berriai-litellm-provider-info-sync[bot] <328147090+berriai-litellm-provider-info-sync[bot]@users.noreply.github.com>
2026-09-22 13:52:30 -07:00
devin-ai-integration[bot]
b5b116a519
fix(otel): honor SSL_CERT_FILE and ssl_verify in OTLP HTTP exporters (#42106)
* fix(otel): honor SSL_CERT_FILE and ssl_verify in OTLP HTTP exporters

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

* test(otel): assert OTLP HTTP TLS behavior against a real TLS sink

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

* test(otel): assert rejected exports by outcome, not by exception type

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

* fix(otel): honor SSL_CERT_FILE and ssl_verify in the v2 OTLP HTTP exporters

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

* refactor(otel): hoist otlp_tls imports and type the TLS sink fixture

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

* test(e2e): gate the OTLP TLS export test behind an otel_tls opt-in

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

* docs(e2e): drop CONTRIBUTING.md edit

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: yucheng <yucheng@berri.ai>
2026-09-22 20:50:53 +00:00
berriai-litellm-provider-info-sync[bot]
e54f228ed8
chore(prices): sync Baseten prices: 4 models, 4 new [enrichment failed: Baseten, 3 held] (#42578)
baseten/deepseek-ai/DeepSeek-V4-Flash-0731: max_tokens, supports_vision, max_input_tokens, max_output_tokens, supports_reasoning, supports_tool_choice, supports_prompt_caching, supports_response_schema, supports_function_calling, input_cost_per_token, output_cost_per_token, cache_read_input_token_cost
baseten/deepseek-ai/DeepSeek-V4-Pro: max_tokens, supports_vision, max_input_tokens, max_output_tokens, supports_reasoning, supports_tool_choice, supports_prompt_caching, supports_response_schema, supports_function_calling, input_cost_per_token, output_cost_per_token, cache_read_input_token_cost
baseten/deepseek-ai/DeepSeek-V4-Pro-0813: max_tokens, supports_vision, max_input_tokens, max_output_tokens, supports_reasoning, supports_tool_choice, supports_prompt_caching, supports_response_schema, supports_function_calling, input_cost_per_token, output_cost_per_token, cache_read_input_token_cost
baseten/zai-org/GLM-5.2-Fast: max_tokens, supports_vision, max_input_tokens, max_output_tokens, supports_reasoning, supports_tool_choice, supports_prompt_caching, supports_response_schema, supports_function_calling, input_cost_per_token, output_cost_per_token, cache_read_input_token_cost

Co-authored-by: berriai-litellm-provider-info-sync[bot] <328147090+berriai-litellm-provider-info-sync[bot]@users.noreply.github.com>
2026-09-22 13:46:15 -07:00
devin-ai-integration[bot]
7210403e23
fix(mcp): apply post-call rewrites without stale structured output (#41530)
* fix(mcp): apply async_post_mcp_tool_call_hook content changes to the tool result

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

* fix(mcp): drop structuredContent when a post-call hook rewrites tool content

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

* fix(mcp): satisfy type discipline and result contract

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

* test(mcp): document internal logging patch

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

* fix(mcp): avoid Final assignments inside callback loops

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

* fix(mcp): run every post-call hook and chain the rewritten content

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

* chore(mcp): credit the original fix from #33403

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

* test(mcp): cover post-call logging fallback paths

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

* test(mcp): cover proxy hook logging context

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

* fix(mcp): preserve native structured guardrail replacements

* fix(mcp): invalidate stale structure after direct content edits

* fix(mcp): reconcile direct edits after callback exceptions

* fix(mcp): preserve successful in-place callback rewrites

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: eric <mitrecx@163.com>
Co-authored-by: Joshua Valluru <326636767+joshua-berri@users.noreply.github.com>
2026-09-22 13:44:25 -07:00
devin-ai-integration[bot]
1c602334ee
test(e2e): one request lands the same spend on every surface (#42540)
* test(e2e): one request lands the same spend on every surface

One priced chat request must show the same response_cost on the spend log row, /key/info, /team/info, the usage export's /user/daily/activity/aggregated row, and the litellm_spend_metric Prometheus sample; each is a separate writer, so the test fails naming the surface that drifted

* fix(e2e): scrape every replica's /metrics/ and enable prometheus in the replay lane

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-09-22 13:42:00 -07:00
devin-ai-integration[bot]
c6c3881d7f
fix(proxy): share model rate-limit buckets between a model_group_alias and its target (#42516)
* fix(proxy): share model rate-limit buckets between a model_group_alias and its target

A request sent under a model_group_alias counted in its own per-key, per-team,
per-org, and per-project model bucket, so a key could double a deployment's
default_api_key_rpm_limit / tpm_limit by alternating the alias and the model
group name, and a metadata model_rpm_limit / model_tpm_limit keyed by the
model group never applied to alias requests. The limiter now resolves the
requested name to its model group before keying any model bucket, looks the
limit up by the requested name first and the model group second, and charges
post-call tokens to the same bucket.

* fix(proxy): charge the model group resolved at admission when reconciling reserved tokens

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-09-22 13:31:58 -07:00
togear
fc0055497c
feat: add configurable provider affinity header mapping (#41033)
* feat: add configurable provider affinity header mapping

* fix: sync provider affinity API types

* fix: harden provider affinity header mapping

* fix: avoid provider affinity import cycle

* fix: preserve input callback header mutations

* fix: address provider affinity code scanning findings

* fix: satisfy provider affinity type discipline gate

* test: cover omitted pre-call argument isolation

* fix: resolve remaining provider affinity codeql alerts

* fix: redact provider affinity headers after calls

* refactor: drop provider affinity header log redaction

* fix: reject control characters in affinity session ids as a bad request

* chore: regenerate the openapi snapshot on python 3.12 and reuse the session marker constant

* fix(responses): read the affinity session from the named metadata argument

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-09-22 13:31:33 -07:00
yuneng-jiang
666f6b01b4
fix: enforce disable_custom_api_keys from general_settings (#42437)
* fix: enforce disable_custom_api_keys from general_settings

The gate in _check_custom_key_allowed read the persisted UI settings row
through get_ui_settings_cached, which had two consequences.

A config-file general_settings.disable_custom_api_keys was never enforced,
because the gate only ever looked at the stored ui_settings row. POST
/key/generate with a custom key value returned 200 even with the flag set
to true in config.yaml.

The read went through a DualCache with a 600s TTL, which is per worker
without Redis, and only the worker that served PATCH /update/ui_settings
refreshed it. A gate flipped through the UI was then a coin flip across
workers for up to ten minutes.

Both go away by routing the flag the way the other runtime UI flags are
already routed. Adding it to _RUNTIME_GENERAL_SETTINGS_FLAGS and to the
settings rules' _UI_SETTINGS_FIELDS makes SettingsStore resolve it from the
ui_settings row with the config file winning, and every pod re-reads it on
its own settings sync rather than holding a private cached copy. The two
lists have to stay in step: a flag in one and not the other resolves
against the wrong stored row and silently never reaches a reader, so there
is a test for that invariant.

Writes to the ui_settings table did not publish on the config-sync channel,
so other pods only discovered a change on their next periodic reload. Adding
litellm_uisettings to _CONFIG_SYNCED_TABLE_NAMES puts it on the same pubsub
path model and SSO config writes already use, which cuts cross-pod
propagation from tens of seconds to a few.

The value reaching the gate is run through coerce_bool first. Resolution
hands back the raw YAML value, so a quoted "true" in config.yaml is a str
and the old `is True` check let custom keys straight through.

* test: assert both directions of the coerced config value

* test: assert the runtime flags read back instead of inspecting the registry
2026-09-22 13:28:31 -07:00
berriai-litellm-provider-info-sync[bot]
2727359a9e
chore(prices): sync Baseten prices: 12 models, 9 new [enrichment failed: Baseten, 15 held] (#42558)
baseten/deepseek-ai/DeepSeek-V4.1-Flash: max_tokens, supports_vision, max_input_tokens, max_output_tokens, supports_reasoning, supports_tool_choice, supports_prompt_caching, supports_response_schema, supports_function_calling, input_cost_per_token, output_cost_per_token, cache_read_input_token_cost
baseten/moonshotai/Kimi-K2.6: max_tokens, supports_vision, max_input_tokens, max_output_tokens, supports_reasoning, supports_tool_choice, supports_prompt_caching, supports_response_schema, supports_function_calling, input_cost_per_token, output_cost_per_token, cache_read_input_token_cost
baseten/moonshotai/Kimi-K2.7-Code: max_tokens, supports_vision, max_input_tokens, max_output_tokens, supports_reasoning, supports_tool_choice, supports_prompt_caching, supports_response_schema, supports_function_calling, input_cost_per_token, output_cost_per_token, cache_read_input_token_cost
baseten/moonshotai/Kimi-K3: max_tokens, supports_vision, max_input_tokens, max_output_tokens, supports_reasoning, supports_tool_choice, supports_prompt_caching, supports_response_schema, supports_function_calling, input_cost_per_token, output_cost_per_token, cache_read_input_token_cost
baseten/nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B: max_tokens, supports_vision, max_input_tokens, max_output_tokens, supports_reasoning, supports_tool_choice, supports_prompt_caching, supports_response_schema, supports_function_calling, input_cost_per_token, output_cost_per_token, cache_read_input_token_cost
baseten/openai/gpt-oss-120b: max_tokens, supports_vision, max_input_tokens, max_output_tokens, supports_reasoning, supports_tool_choice, supports_prompt_caching, supports_response_schema, supports_function_calling, cache_read_input_token_cost
baseten/thinkingmachines/inkling: max_tokens, supports_vision, max_input_tokens, max_output_tokens, supports_reasoning, supports_tool_choice, supports_prompt_caching, supports_response_schema, supports_function_calling, input_cost_per_token, output_cost_per_token, cache_read_input_token_cost
baseten/thinkingmachines/inkling-small: max_tokens, supports_vision, max_input_tokens, max_output_tokens, supports_reasoning, supports_tool_choice, supports_prompt_caching, supports_response_schema, supports_function_calling, input_cost_per_token, output_cost_per_token, cache_read_input_token_cost
baseten/zai-org/GLM-4.7: max_tokens, supports_vision, max_input_tokens, max_output_tokens, supports_reasoning, supports_tool_choice, supports_prompt_caching, supports_response_schema, supports_function_calling, cache_read_input_token_cost
baseten/zai-org/GLM-5.2: max_tokens, supports_vision, max_input_tokens, max_output_tokens, supports_reasoning, supports_tool_choice, supports_prompt_caching, supports_response_schema, supports_function_calling, input_cost_per_token, output_cost_per_token, cache_read_input_token_cost
baseten/zai-org/GLM-5.3: supports_reasoning
baseten/zai-org/GLM-5.3-Flash: max_tokens, supports_vision, max_input_tokens, max_output_tokens, supports_reasoning, supports_tool_choice, supports_prompt_caching, supports_response_schema, supports_function_calling, input_cost_per_token, output_cost_per_token, cache_read_input_token_cost

Co-authored-by: berriai-litellm-provider-info-sync[bot] <328147090+berriai-litellm-provider-info-sync[bot]@users.noreply.github.com>
2026-09-22 13:24:49 -07:00
tin-berri
e841f32e50
fix(ui): rename reminder markers to Ignore Custom Tags (#42370) 2026-09-22 13:16:18 -07:00
devin-ai-integration[bot]
9be3c1b168
fix(fal_ai): honour global api_base for image generation and reject non-string reasoning_effort with 400 (#42512)
* fix(fal_ai): honour global api_base for image generation and reject non-string reasoning_effort with 400

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

* test(fal_ai): add return annotations to reasoning_effort regression tests

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

* test(fal_ai): move the LIT-8340 repro from tests/e2e to tests/integration

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

---------

Co-authored-by: kerry <kerry@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 13:13:54 -07:00
devin-ai-integration[bot]
4677f1028e
refactor(rust): align the cache crates with Python and wire every native backend (#42530)
* refactor(rust): align the cache crates with Python and activate every backend

The cache port had drifted: lifecycle and Redis-only operations sat on
`BaseCache`, counters were pinned to `f64`, each semantic backend defined its
own embedder and prompt handling, and only the in-memory backend could be
selected natively.

- Split `disconnect` and `test_connection` out of `BaseCache` into optional
  capabilities, implemented only where the Python class defines them, and give
  every Redis-only operation its own capability trait.
- Decouple counters from the stored value type, so one backend can serve both
  responses and counters as Python's `RedisCache` does.
- Share one `Embedder` and prompt contract in `litellm_cache::semantic`, and
  make the Redis and Valkey semantic backends generic over their codec.
- Port the Python operations that were missing: `async_refresh_ttl`,
  `async_rpush_and_trim`, `async_set_cache_pipeline_with_ttls`, the DualCache
  pipeline, sadd, bulk delete and TTL reads, and the semantic-similarity
  write-back.
- Take the HTTP client from the host pool in the GCS, S3 and Azure backends.
- Activate all nine backends through the Rust catalog, whose rules all stay
  `PYTHON_ONLY`, and route the `Cache` facade's storage calls to the native
  runtime when one is selected.
- Give every crate the same layout, move all tests to `tests/` on rstest, and
  add the shared `litellm-cache-testing` contract suite.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix: freeze native cache request kwargs and batch entries for type discipline

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

* fix: declare semantic lookup methods in the native stub

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

* refactor(rust): align the cache crates with Python and activate every backend

The cache port had drifted: lifecycle and Redis-only operations sat on
`BaseCache`, counters were pinned to `f64`, each semantic backend defined its
own embedder and prompt handling, and only the in-memory backend could be
selected natively.

- Split `disconnect` and `test_connection` out of `BaseCache` into optional
  capabilities, implemented only where the Python class defines them, and give
  every Redis-only operation its own capability trait.
- Decouple counters from the stored value type, so one backend can serve both
  responses and counters as Python's `RedisCache` does.
- Share one `Embedder` and prompt contract in `litellm_cache::semantic`, and
  make the Redis and Valkey semantic backends generic over their codec.
- Port the Python operations that were missing: `async_refresh_ttl`,
  `async_rpush_and_trim`, `async_set_cache_pipeline_with_ttls`, the DualCache
  pipeline, sadd, bulk delete and TTL reads, and the semantic-similarity
  write-back.
- Take the HTTP client from the host pool in the GCS, S3 and Azure backends.
- Activate all nine backends through the Rust catalog, whose rules all stay
  `PYTHON_ONLY`, and route the `Cache` facade's storage calls to the native
  runtime when one is selected.
- Give every crate the same layout, move all tests to `tests/` on rstest, and
  add the shared `litellm-cache-testing` contract suite.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix: freeze native cache request kwargs and batch entries for type discipline

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

* fix: declare semantic lookup methods in the native stub

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

* test(rust): opt the native Messages and tokenizer suites into Rust explicitly

#42517 made the Messages, token counter and tokenizer routes Python-only, so
tests/test_litellm_rust silently exercised the Python path or failed outright.
Each suite now prepends a RUST_OPT_IN rule for its route, keeping native
coverage without changing the shipped default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(rust): pop one at a time in the Redis 6 lpop pipeline and drop explanatory comments

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

---------

Co-authored-by: Yujong Lee <yujong@berri.ai>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 13:13:02 -07:00
devin-ai-integration[bot]
153e5ed185
fix(fal_ai): reuse the status client and headers on the video result probe (#42511)
* fix(fal_ai): reuse the status client and headers on the video result probe

The Fal result GET issued after a COMPLETED status poll built its own default
client and only carried Authorization and Content-Type, so an injected client,
a request-level ssl_verify and extra_headers were honored on the status GET but
not on the result GET, and a transport failure on that probe escaped as a 500.
The handler now hands the selected sync or async client to the provider status
transform, Fal reuses it with the full validated header set, and a probe
transport error stays non-terminal like the existing 429 and 5xx handling

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

* fix(fal_ai): mark the result probe header dict as mutable-ok for the type discipline gate

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

* test(fal_ai): move the result probe repro to tests/integration

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

* test(e2e): restore the shared e2e helpers to the merge base

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

---------

Co-authored-by: kerry <kerry@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 13:12:51 -07:00
devin-ai-integration[bot]
5d3b31fb02
fix(fal_ai): align /fal_ai queue gate with the pricer and normalise resolution type (#42505)
* fix(fal_ai): align /fal_ai queue gate with the pricer and normalise resolution type

The /fal_ai gate admitted catalog keys the Fal pricer cannot price, so
those jobs were forwarded and logged at 0.0 spend. The gate now reuses
the pricer as its eligibility predicate. Resolution is normalised to a
string before the keyed price lookup so int and str spellings bill the
same.

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

* test(fal_ai): assert passthrough pricing invariants on synthetic catalog entries

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

* fix(fal_ai): price the submitted body in the /fal_ai queue gate so keyed-only entries are admitted

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

* test(fal_ai): move the queue gate repro to tests/integration

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

---------

Co-authored-by: kerry <kerry@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 13:12:07 -07:00
tin-berri
3b9c9e0523
feat(router): add group-scoped priority routing strategy (#42378)
* feat(router): add group-scoped priority routing strategy

* fix(router): satisfy priority routing type-discipline checks
2026-09-22 13:09:38 -07:00
devin-ai-integration[bot]
e48f813d4d
test(google_genai): move unified_google_tests to gemini-3.5-flash-lite (#42520)
gemini-2.5-flash-lite retires on 2026-10-20 per Google's Vertex model
lifecycle table, which would turn the google_generate_content_endpoint_testing
CircleCI job red on every PR from that day. gemini-3.5-flash-lite is the newest
flash-lite on both AI Studio and Vertex, with a retirement of 2027-07-21 or
later.

Vertex serves gemini-3.5-flash-lite only on the global, us, and eu endpoints,
never on a single region, so the direct SDK Vertex tests now pass
vertex_location global like the suite's proxy config already does.

The 429 backoff test derives its mocked generateContent URL from litellm's own
Gemini URL builder, since litellm routes Gemini 3 and newer models to v1alpha
instead of v1beta.

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-09-22 13:07:37 -07:00
devin-ai-integration[bot]
e02d5a990c
fix(e2e): route credential, cost map, and UI login calls to the control plane (#42506)
* fix(e2e): route credential, cost map, and UI login calls to the control plane

* test(e2e): stop pinning the upstream model name in the credential-backed messages test

* test(e2e): drop the harness unit test, the split stack run proves the routing live

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-09-22 12:59:56 -07:00
devin-ai-integration[bot]
1373322e0c
feat(logs): add span type filter to request logs (#42491)
* feat(logs): add span type filter to request logs

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

* fix(logs): look up span type sql conditions from a mapping

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

---------

Co-authored-by: Mubashir Osmani <mubashir@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 12:44:03 -07:00
devin-ai-integration[bot]
cb2f22533c
feat(proxy): opt-in include_guardrail_response returns guardrail_information in the response (#42327)
* feat(proxy): opt-in include_guardrail_response returns guardrail_information in the response

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

* fix(proxy): read include_guardrail_response from the request metadata bucket the router did not reseed

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

* style(proxy): format common request processing

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

* fix(proxy): redact matched content in guardrail_information and stop mutating cached responses

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

* fix(proxy): traverse guardrail diagnostics iteratively

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

* fix(proxy): annotate guardrail traversal cast

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

* refactor(proxy): reuse core redaction helper for guardrail_information

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

* chore(proxy): justify response rebind when attaching guardrail information

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

---------

Co-authored-by: yucheng <yucheng@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 12:43:30 -07:00
devin-ai-integration[bot]
7516327898
test(e2e): assert a cooldown reaches a sibling replica within the 1s Redis read interval (#42422)
* test(e2e): assert a cooldown reaches a sibling replica within the 1s Redis read interval

* test(e2e): skip the sibling replica cooldown cell when one gateway URL is named

* test(e2e): collapse repeated gateway addresses so the sibling cooldown cell skips instead of erroring

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-09-22 12:42:41 -07:00
devin-ai-integration[bot]
b6d4133e41
fix(websearch_interception): keep intercepted searches under the parent request's session and trace (#41711)
* fix(websearch_interception): propagate parent session/trace ids into intercepted searches

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

* fix(websearch_interception): let parent correlation win over configured search params and type test params

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

* test(e2e): bill an intercepted web search under the parent request session

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

* test(e2e): drop unrelated reformatting from the websearch session harness change

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

* ci(e2e): keep the websearch interception session suite out of the stage-mirror gate

The stage-mirror stack runs no websearch_interception callback or search tool, so the suite is deselected there and the changed-tests gate fails on a file that executed nothing

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

* ci(e2e): run the websearch interception session suite on the stage-mirror stack

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

* docs(e2e): leave CONTRIBUTING.md untouched

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-09-22 12:35:27 -07:00
devin-ai-integration[bot]
97a6c27bee
test(rust_bridge): drop route dispatch assertions, test the bridge directly (#42536)
Co-authored-by: ryan <ryan@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 19:21:32 +00:00
devin-ai-integration[bot]
569ccaece9
fix(proxy): make the lazy OpenAPI snapshot byte-identical on every Python version (#42519)
Python 3.13+ strips the common indentation of docstrings at compile time and 3.12
keeps it, and the 429 error description in ERROR_RESPONSES came straight from
RateLimitError.__doc__, so regenerating litellm/proxy/_lazy_openapi_snapshot.json
on a 3.13+ venv produced a one-line diff that the check-ui-api-types job (Python
3.12) rejected. Run the docstring through inspect.cleandoc before it lands in the
spec, regenerate the snapshot once, and pin the behavior with a test

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-09-22 12:21:20 -07:00
devin-ai-integration[bot]
2ef710e3d5
fix(langsmith): json.dumps with default=str so non-serializable metadata does not crash batch flush (#42424)
* fix(langsmith): json.dumps with default=str so non-serializable metadata does not crash batch flush

Serialize the runs/batch payload with json.dumps(default=str, allow_nan=False) and send it as content= with an explicit Content-Type, so datetime, Decimal and similar metadata values no longer raise TypeError and drop the batch. Forward content= on the AsyncHTTPHandler retry path so a retried batch re-sends the identical body

Replaces #39133, which was cut from the retired staging branch and conflicts with main

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

* test(langsmith): drop test docstrings and replace monkeypatch with a client-injecting handler

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

* test(langsmith): add live e2e for non-native metadata reaching LangSmith

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

* test(langsmith): scope the e2e docstring to the values the test injects

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

* test(http_handler): close injected retry clients

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

* test(e2e): deselect the LangSmith live e2e on the stage-mirror stack

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

---------

Co-authored-by: yucheng <yucheng@berri.ai>
Co-authored-by: Damien Smrt <dsmrt@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 12:21:11 -07:00
devin-ai-integration[bot]
05d7fb24bd
feat(rust): add python-compat crate for Python data formats (#42510)
* feat(rust): add python-compat crate for Python data formats

Add litellm-python-compat, a PyO3-free crate that reproduces the Python
data formats LiteLLM persists, so Rust readers and writers can interoperate
with state written by the Python proxy:

- literal::literal_eval: a linear recursive-descent port of
  ast.literal_eval (prefixes, escapes, implicit concatenation, numeric
  underscores and radixes, single unary sign, real +/- complex with 3.14
  mixed-mode rules, set(), Python-equality key dedup)
- repr::{repr, to_str}: byte-exact repr()/str(), with a printable table
  generated from CPython's str.isprintable (Unicode 16.0.0)
- json::{dumps, from_json, to_json}: json.dumps defaults and the
  json.loads mapping
- pickle::{loads, dumps}: plain-data pickles via serde-pickle's serde
  interface, which keeps dict insertion order
- truthy::truthy: bool() for plain data

Tests replay fixtures generated by CPython 3.14 (values across every
format and pickle protocol 0-5, plus 154 literal_eval source texts).
Accepted divergences are pinned in a KNOWN table that fails once one
starts matching. A criterion bench covers each format and literal_eval
cost by nesting depth, guarding the linear parse: the py_literal grammar
doubled per nested bracket (105 ms at 16 nested dicts; 19 us at 128 now).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* refactor(rust): split python-compat modules and harden the pickle verifier

- Disable class resolution in scripts/verify_rust_pickles.py, and truncate
  the export file once instead of removing and appending to it, so the
  verifier cannot be pointed at a pre-created file whose rows execute code
  through pickle.loads
- Move Error to error.rs and Value to value.rs, leaving lib.rs as the crate
  overview, module list and MAX_DEPTH
- Move the generator and verifier to scripts/, beside the Unicode table
  generator, leaving tests/ to the Rust tests
- Group the bench by measured surface, give every case a Throughput so
  criterion reports bytes per second, and document baseline comparison

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Yujong Lee <yujong@berri.ai>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 12:16:56 -07:00
devin-ai-integration[bot]
64456ce103
fix(aws_secret_manager_v2): restore secret scheduled for deletion instead of failing CreateSecret (#42454)
* fix(aws_secret_manager_v2): restore secret scheduled for deletion instead of failing CreateSecret

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

* fix(aws_secret_manager_v2): reapply CreateSecret metadata and reschedule deletion when in-place restore fails

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

---------

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 14:12:20 -05:00
devin-ai-integration[bot]
5035c458fb
feat(proxy): admin-only /debug/report sharing the bug report environment (#42440)
* feat(proxy): add admin-only /debug/report sharing the bug report environment fields

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

* feat(proxy): add verbose=true to /debug/report listing every config key with typed values

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

* fix(proxy): inject auth into /debug/report through Annotated to keep the B008 budget flat

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

* fix(proxy): bound the verbose config walk, drop nested-list recursion from the safe renderer, regenerate schema.d.ts

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

* fix(proxy): count pass-through and mcp header maps plus operator-named budget maps in verbose /debug/report, single-exit scalar renderers

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

* chore(ui): regenerate schema.d.ts after dropping the verbose query from /debug/report

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

---------

Co-authored-by: ryan <ryan@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 12:05:23 -07:00
devin-ai-integration[bot]
9d299d016a
chore(pricing): remove retired models flagged by the provider sync (#42521)
Co-authored-by: kerry <kerry@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 19:03:40 +00:00
devin-ai-integration[bot]
85ed18e8f2
fix(rust_bridge): keep the Messages route on Python until the Rust path is ready (#42517)
* fix(rust_bridge): keep the Messages route on Python until the Rust path is ready

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

* fix(rust_bridge): keep token counter and tokenizer routes on Python

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

---------

Co-authored-by: ryan <ryan@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 19:02:43 +00:00
devin-ai-integration[bot]
f3a0bb7249
fix(proxy): write key deleted audit logs for cascade and alias key deletions (#42446)
* fix(proxy): write key deleted audit logs for cascade and alias key deletions

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

* test(proxy): assert persisted key deleted audit rows for cascade paths

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

* test(e2e): route /audit and /v2/login to the control plane in split transport

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

---------

Co-authored-by: yucheng <yucheng@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 11:52:08 -07:00
devin-ai-integration[bot]
5af9b0136c
fix(fal_ai): handle seconds=auto and oversized sizes for minimax h3 videos (#42504)
* test(fal_ai): e2e for minimax h3 auto duration and oversized size

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

* fix(fal_ai): keep auto duration literal and make h3 tier lookup total

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

* fix(fal_ai): omit duration for h3 when seconds is auto

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

* test(fal_ai): move the minimax h3 auto duration and oversized size repro to tests/integration

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

---------

Co-authored-by: kerry <kerry@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 18:51:30 +00:00
devin-ai-integration[bot]
ee3f5a8bdf
fix(streaming): let a later usage event zero out stale cache counts (#40736) (#42330)
* fix(streaming): let a later usage event zero out stale cache counts (#40736)

The usage merger only replaced cache_creation_input_tokens and
cache_read_input_tokens with a positive value, so when Anthropic's
message_delta restated the cache block with a 0 write, the 58k write from
message_start survived next to the 58k read. prompt_tokens minus both cache
counts then went negative and the write was billed twice

A usage event that reports any prompt-side count is now authoritative for both
cache fields, zeros included. An event with no prompt-side counts, such as an
output-only message_delta, still leaves the earlier values alone

* test(streaming): cover an input-only message_delta and the derived uncached input in the cache count merger test

---------

Co-authored-by: muhammadwaqar12 <m_waqar@live.com>
Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
Co-authored-by: shrey kharbanda <shreshth@berri.ai>
2026-09-22 11:50:19 -07:00
Meet Patel
4bcdaf3d4b
fix(cost): honor deployment pricing for image generation (#39311)
* fix image cost: honor deployment pricing

* fix types: coerce fal deployment price, drop private import

* fix: forward every custom pricing field through get_litellm_params

* test: assert optional keys are absent, not merely None, in get_litellm_params

* test: type the deployment image pricing test parameters

* fix: bill deployment per-image and per-pixel prices on unlisted image models

* test: type the remaining image cost test parameters

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-09-22 11:40:39 -07:00
devin-ai-integration[bot]
a788c4ab2b
fix(router): explain fallback outcome in plain words in the raised error (#42509)
* fix(router): explain fallback outcome in plain words in the raised error

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

* fix(router): keep the fallback outcome trailer on the outermost hop only

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

* fix(router): explain failed context-window and content-policy fallbacks too

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

* fix(router): name both Router and proxy fallback config in the no-fallback hint

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

---------

Co-authored-by: ryan <ryan@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 18:37:42 +00:00
devin-ai-integration[bot]
e0c2cbff21
feat(openai): add GPT-6 Sol and GPT-6 Luna (#42515)
Add gpt-6-sol and gpt-6-luna to the model cost map with pricing from the OpenAI pricing page and reasoning effort levels none through max. Extend the long-context priority pricing and reasoning effort capability tests to cover both models

Co-authored-by: kerry <kerry@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 11:34:01 -07:00
devin-ai-integration[bot]
2bab39e374
fix(realtime): surface an upstream handshake refusal as an error event and policy close (#42388)
* fix(realtime): surface an upstream handshake refusal as an error event and policy close

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

* test(realtime): tidy the handshake refusal e2e

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

* fix(realtime): keep upstream exception text out of the Azure client error

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

* refactor(realtime): map handshake refusal close codes with a lookup

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 11:31:15 -07:00
berriai-litellm-provider-info-sync[bot]
8332f0848a
chore(prices): sync Google Gemini prices: 13 models (#42500)
gemini/gemini-2.5-flash: cache_read_input_token_cost_batches
gemini/gemini-2.5-flash-lite: cache_read_input_token_cost_batches
gemini/gemini-2.5-pro: cache_read_input_token_cost_batches
gemini/gemini-3-flash-preview: cache_read_input_token_cost_batches
gemini/gemini-3.1-flash-lite: cache_read_input_token_cost_batches
gemini/gemini-3.1-pro-preview: cache_read_input_token_cost_batches
gemini/gemini-3.1-pro-preview-customtools: cache_read_input_token_cost_batches
gemini/gemini-3.5-flash: cache_read_input_token_cost_batches
gemini/gemini-3.5-flash-lite: cache_read_input_token_cost_batches
gemini/gemini-3.6-flash: cache_read_input_token_cost_batches
gemini/gemini-3.7-flash: cache_read_input_token_cost_batches
gemini/gemini-3.8-flash: cache_read_input_token_cost_batches
gemini/gemini-robotics-er-2-preview: cache_read_input_token_cost_batches

Co-authored-by: berriai-litellm-provider-info-sync[bot] <328147090+berriai-litellm-provider-info-sync[bot]@users.noreply.github.com>
2026-09-22 11:29:38 -07:00
joshua-berri
0d0f73cd14
fix(mcp): restore legacy SSE and bounded cancellation cleanup (#42382)
* fix(mcp): restore legacy SSE and bounded cancellation cleanup

* fix(mcp): drain termination despite repeated task cancellation

* fix(mcp): admit virtual keys on legacy SSE message routes

* fix(mcp): preserve cancellation through late transport failures

* fix(mcp): preserve process exits during cleanup

* test(mcp): drain idle sockets before server shutdown

---------

Co-authored-by: Joshua Valluru <326636767+joshua-berri@users.noreply.github.com>
2026-09-22 11:27:50 -07:00
devin-ai-integration[bot]
2ea43214c9
feat(terraform): expose server_metadata on litellm_key so undeclared metadata is visible (#42453)
Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 13:22:43 -05:00