Commit graph

18941 commits

Author SHA1 Message Date
yucheng
4e5d8004a4 Merge remote-tracking branch 'origin/main' into litellm_llm_guard_proxy_call_types 2026-09-19 08:00:24 +00:00
mateo-berri
7133baa777 fix(vector_stores): run the full model grant check on caller-supplied model hints
The vector-store file routes accept a model hint through the ?model= query
param and the x-litellm-model header. That hint was authorized with a hand
rolled check that covered only the key allowlist and the team allowlist, so
a key restricted by its project's model grant, a team-member restriction, or a
key config still routed through the hinted deployment. Greptile flagged the
gap as a P1 on the replacement PR.

The hint now goes through the same authorize_model_for_key path the batches
and files routes use, which runs can_key_call_resolved_model with every rule
the proxy enforces elsewhere. Keys those extra rules deny now get a 403 on
these routes. The two remaining behavioral differences are edge cases the
old check tolerated: a key whose team_models is set without a team_id no
longer runs the team allowlist, and a key with a config set skips the key
allowlist, both matching the rest of the proxy.

The regression test caches a project whose grant excludes the hinted model
and asserts the request is refused before any deployment lookup. The two
patch() calls on litellm.proxy.proxy_server carry a test-quality-ok reason
because can_key_call_resolved_model reads prisma_client and
user_api_key_cache through a lazy module import with no injection seam.
2026-09-19 00:54:41 -07:00
mateo-berri
3684e5cbcb fix(gemini): drop ttl values outside the protobuf Duration range and the explanatory docstrings 2026-09-19 00:50:37 -07:00
mateo-berri
0feca8641f fix(batches): price model-encoded batch retrievals by their deployment
A batch retrieved by its model-encoded id takes the direct (non-router) path,
which resolved credentials without stamping the deployment's model_info, so a
completed batch on a deployment with its own per-page pricing was billed at
the published rate with an empty model_id on the spend row.

Extract the router's credential lookup into get_credential_deployment and
stamp the resolved deployment's model_info onto the retrieve call the way the
router does for routed calls.
2026-09-19 00:30:15 -07:00
Mateo Wang
5f1268c056
Merge pull request #41933 from BerriAI/litellm_deliver_multi_choice_stream_rewrites
fix(policy_engine): deliver guardrail text rewrites on multi-choice, unfinished, and envelope-less streams
2026-09-19 00:22:02 -07:00
yucheng
19cb6b855b test(llmguard): move call type alias tests to the mapped enterprise test file
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-19 07:15:51 +00:00
mateo-berri
2303379c20 fix(gemini): keep the 2048 cache minimum on Gemini 2.5 Pro only, per Google's live cachedContents API 2026-09-19 00:07:22 -07:00
mateo-berri
3289e22834 fix(anthropic): keep cache_control for Gemini targets on /v1/messages and normalize Anthropic ttl units 2026-09-19 00:01:42 -07:00
yucheng
31ec84862c Merge remote-tracking branch 'origin/main' into litellm_llm_guard_proxy_call_types 2026-09-19 06:58:56 +00:00
mateo-berri
f89ca64481 fix(batches): honor deployment OCR page pricing in batch cost and answer 400 for unsupported Mistral file purposes 2026-09-18 23:57:41 -07:00
yucheng-berri
8afbc51cb7
Merge pull request #41685 from BerriAI/litellm_prompt_injection_llm_api_check_dispatch
* fix(proxy): dispatch llm_api_check moderation through during_call_hook

ProxyLogging.during_call_hook only ran async_moderation_hook for CustomGuardrail callbacks, so a
CustomLogger such as the prompt injection detector with llm_api_check enabled never called the
configured moderation model. Dispatch any CustomLogger that overrides async_moderation_hook and hand
the proxy router to every registered prompt injection detector at startup so that call can route

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

* fix(enterprise): resolve openai_moderations model at call time and default to omni-moderation-latest

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

* fix(proxy): keep queued moderation running past a V1 pre_call guardrail

A V1 CustomGuardrail with moderation_check pre_call returned out of
during_call_hook before asyncio.gather, abandoning already-queued
CustomLogger moderation coroutines and skipping every later callback.
Skip only that guardrail instead.

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

* fix(utils): skip null tool_calls when formatting prompts for moderation hooks

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-18 23:53:14 -07:00
mateo-berri
4fe1549432 fix(policy_engine): keep the per-choice rebuilt response's choices a list so legacy hook rewrites survive the model_dump round-trip 2026-09-18 23:53:02 -07:00
mateo-berri
6019e451ce Merge branch 'main' into feat/gemini-cache-control-pass-through 2026-09-18 23:42:58 -07:00
mateo-berri
cb80e8773e fix(policy_engine): fail open when an unended Messages stream has no text delta to carry the rewrite 2026-09-18 23:24:49 -07:00
Mateo Wang
56116079c8
Merge pull request #41930 from BerriAI/litellm_mat602_upstream_500_error_type
fix(exceptions): keep internal_server_error as the public type of an upstream 500
2026-09-18 23:19:52 -07:00
Mateo Wang
0a792c0f6b
Merge pull request #40399 from adssoccer1/feat/websearch-multi-query-schema
feat(websearch): let the model emit objective + multi-query search shapes
2026-09-18 23:03:48 -07:00
Joshua Valluru
c91ca90477 fix(mcp): retain wire aliases in guardrail inspection payloads 2026-09-18 23:00:32 -07:00
mateo-berri
b3d9ba9e7b fix(policy_engine): deliver guardrail text rewrites on multi-choice, unfinished, and envelope-less streams
Post-call pipeline rewrites on buffered streams failed open on three shapes:
chat streams with n > 1 (the rebuilt response collapsed every choice into
index 0), streams that ended without a finish marker, and Responses streams
whose final event carried no response envelope.

The chat handler now rebuilds the ended stream one choice index at a time and
writes each choice's rewrite back to that choice's buffered deltas. The
Anthropic handler writes an unended stream's rewrite across its text deltas.
The Responses handler spreads an envelope-less rewrite over the buffered
output_text events, still failing open when a scanned event cannot be placed.

Tool-call rewrites on n > 1 chat streams keep failing open.
2026-09-18 22:59:52 -07:00
Yuneng Jiang
c9158fcc12
fix(proxy): keep a config-owned key's resolved value across a database reload
Applying a database row dropped the runtime layer for every key the row
carried, including keys the config file owns. Those runtime entries hold
the env-resolved config values, so after a reload a key written as
os.environ/<NAME> read back as that literal string. The store now keeps
the runtime entry for a key the config owns and clears only the rest.

Visible as store_model_in_db silently turning itself off: the reload read
the raw reference, coerced it to False, and overwrote the resolved global.
2026-09-18 22:58:08 -07:00
Mateo Wang
4eb13a0b2a
Merge pull request #41843 from BerriAI/litellm_lit8064_unpin_derived_pricing
fix(proxy): unpin cost-map pricing copied into model_info and report pricing overrides
2026-09-18 22:58:04 -07:00
Joshua Valluru
f5ab563499 fix(mcp): preserve session expiry signals and scope dependency CI 2026-09-18 22:52:10 -07:00
mateo-berri
5f6ffdc333 test: drop the docstring that restated the payload test's name 2026-09-18 22:48:42 -07:00
Yuneng Jiang
3a480a5d6c
Merge remote-tracking branch 'origin/main' into litellm_settings_store_immutable 2026-09-18 22:39:29 -07:00
Yuneng Jiang
a987efca2c
fix(proxy): refuse runtime writes to config-owned settings
A write into a settings store for a key the config file declares used to
land in the runtime layer and then lose to the config on every read, so
the caller saw success while nothing changed. It now raises
ConfigOwnedKeyError, and the allowed-IP routes turn that into a 400
naming the key instead of reporting success on a list they never changed.

Both allowed-IP routes now build a new list rather than mutating the one
the config layer holds, and the os.environ resolver rebuilds the config
it is given instead of writing back into it, so a reader can no longer
corrupt the raw values the store keeps for provenance.

The database reload leaves a config-owned key alone rather than writing a
normalized copy back over it, which would now raise and abort the rest of
the reconcile pass.
2026-09-18 22:39:27 -07:00
Mateo Wang
b7f07469bc
Merge pull request #41564 from BerriAI/litellm_responses_bridge_message_item_lit4622
fix(responses): announce message item before text events in the chat completions bridge
2026-09-18 22:36:28 -07:00
mateo-berri
5783a38e27 fix(proxy): enforce the unified batch model grant before the DB shortcut and skip it for registry-routed vector store models
retrieve_batch returned a terminal batch from the DB before checking that the key may use the model encoded in a unified batch id; the grant check now runs right after pre-call processing. The vector store file list helper authorized data["model"] through handle_model_based_routing even when the vector store registry set it server-side and even with no caller, which crashed on a None key; it now authorizes only a caller-supplied hint and resolves credentials directly.
2026-09-18 22:30:07 -07:00
mateo-berri
ddac683ec6 fix(exceptions): keep internal_server_error as the public type of an upstream 500
PR #40243 started carrying the upstream error body on InternalServerError so the Responses response.failed event can report the provider's code and message, and openai's APIError.__init__ took the body's type along with it. The proxy then answered an OpenAI-compatible upstream 500 with type server_error while a 502 and a 503 kept internal_server_error, and the integration contract in test_observed_routing.py went red. Pin the type the way RateLimitError pins throttling_error, keeping the body.
2026-09-18 22:28:58 -07:00
Joshua Valluru
aea13ee03b fix(mcp): preserve legacy behavior on SDK2 and streamline verification 2026-09-18 22:28:31 -07:00
mateo-berri
12f831e863 Merge origin/main into feat/websearch-multi-query-schema
Resolves handler.py against main's SearchOutcome refactor: the file is
main's version plus this PR's substantive hunks only (the RichWebSearchInput
import, the rich= wiring at the three _execute_search call sites, the
_rich_search_input and _provider_supports_rich_search helpers, and the
_execute_search forwarding), so the 88-column re-wrap noise the PR carried
is gone and the diff against main is the feature alone. RichWebSearchInput
sits beside main's new SearchSucceeded/SearchFailed types, and main's two
_execute_search test stubs accept the new rich argument.
2026-09-18 22:15:35 -07:00
yuneng-jiang
12ddb35aad
Merge pull request #41924 from BerriAI/litellm_role_permissions_normalization
fix(proxy): parse role_permissions where it is read
2026-09-18 22:15:20 -07:00
Joshua Valluru
7f4dd4eabc test(e2e): cover MCP OAuth SSO and cold restart acceptance 2026-09-18 22:02:09 -07:00
mateo-berri
f3b198c1b7 fix(mistral): accept user_data as the OCR file purpose and keep OCR cost warnings single-line 2026-09-18 21:56:43 -07:00
mateo-berri
fb76b67e78 Merge remote-tracking branch 'origin/main' into litellm_mistral_ocr_batches
# Conflicts:
#	litellm/batches/batch_utils.py
2026-09-18 21:51:33 -07:00
Mateo Wang
faed57f92c
Merge pull request #41918 from BerriAI/litellm_websearch_followup_api_base
fix(websearch): forward the deployment api_base to agentic follow-up calls on /v1/messages
2026-09-18 21:41:41 -07:00
mateo-berri
4468c9fdcb fix(responses): close the reasoning item before announcing the message item 2026-09-18 21:37:01 -07:00
Mateo Wang
078a60478f
Merge pull request #41485 from BerriAI/litellm_jwt_token_exchange_grant
feat(proxy): add RFC 8693 token exchange for IdP JWTs on the gateway token endpoint
2026-09-18 21:27:20 -07:00
Mateo Wang
b46612cfeb
Merge pull request #41893 from BerriAI/litellm_fix_responses_ws_encrypted_content_affinity
fix(responses): restore encrypted_content and apply affinity on the native WebSocket relay
2026-09-18 21:09:17 -07:00
kerry
ed0c32cdb0 test(integration): drive cost tracking from literal request/response data
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-19 04:04:40 +00:00
Yuneng Jiang
044f88ee91
fix(proxy): register transcribe as a known provider for model grants
#41515 added the cost map entry transcribe/StartTranscriptionJob under a
new litellm_provider value "transcribe" without registering that provider
anywhere else, so litellm.models_by_provider had no "transcribe" key.

test_models_by_provider derives its provider set from the cost map itself,
so it went red on main. The user-visible half is that get_provider_models
returned None for the provider, which get_known_models_from_wildcard turns
into an empty list, leaving a transcribe/* key or team grant resolving to
no models.

Mirror the aws_polly registration: an enum member, a model set, an
ingestion branch, and a models_by_provider entry. Amazon Transcribe is
reached through the pass-through route rather than the Add Model form, so
it joins the frozen unlisted set the Add Model drift test tracks.
2026-09-18 21:04:25 -07:00
Yujong Lee
1ee4b62e9c fix(rust): honor vertex_project, vertex_location and enable_azure_ad_token_refresh globals
Python resolves the Vertex project and location as call params, then the
litellm.vertex_project / litellm.vertex_location globals, then env, and
Azure AD token refresh from litellm.enable_azure_ad_token_refresh alone.
Native OCR skipped the globals, so a config.yaml litellm_settings value
silently fell through to the credential's project and us-central1, and a
managed identity setup without an API key failed. The bridge now reads
them through a provider_defaults settings group into OcrSettings, and
VertexConfig / AzureAuthInputs slot them in at Python's precedence.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 21:01:37 -07:00
Yuneng Jiang
800b09ba41
Merge remote-tracking branch 'origin/main' into litellm_role_permissions_normalization 2026-09-18 21:00:23 -07:00
Yuneng Jiang
ef34e44d8b
fix(proxy): parse role_permissions where it is read
load_config used to return a local general_settings dict that it had
normalized in place, turning the configured role_permissions entries into
RoleBasedPermissions objects. It now returns the SettingsStore, which never
saw that write, so JWT auth received raw dicts and every request failed with
"'dict' object has no attribute 'role'" whenever role_permissions was set.

Convert the entries in the consumer instead, with a TypeAdapter, so the value
is parsed wherever it comes from. load_config keeps validating at boot, so a
malformed entry still fails startup rather than the first request.
2026-09-18 21:00:18 -07:00
Yujong Lee
0d76359dc9 fix(rust): resolve OCR provider env fallbacks through the secret manager
Python reads every provider credential fallback (MISTRAL_API_KEY,
AZURE_AI_API_KEY, AZURE_DOCUMENT_INTELLIGENCE_ENDPOINT, Azure AD and
Vertex env, ...) through get_secret_str, which consults the configured
key_management_system before os.environ. Native OCR read std::env
directly, so a key held only in the vault went missing and a stale env
copy silently won. OcrClient now carries an injected secret Lookup that
the connection exposes to providers and auth crates; the bridge backs it
with settings.secret -> get_secret_str, pure Rust keeps the process env.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 20:57:24 -07:00
Yuneng Jiang
62f6ee9a16
Merge remote-tracking branch 'origin/main' into litellm_v2_migration_startup 2026-09-18 20:55:05 -07:00
Mateo Wang
c1de8665ff
Merge pull request #34267 from BerriAI/litellm_claude_code_gateway_protocol
feat(proxy): serve the Claude Code gateway protocol under /claude_code_gateway
2026-09-18 20:49:48 -07:00
Devin AI
62051ad9bc merge: bring main into litellm_mcp_oauth_happy_path_e2e
Co-Authored-By: bot_apk <apk@cognition.ai>
2026-09-19 03:42:37 +00:00
yujonglee
1c432dbc5f
Merge pull request #41921 from BerriAI/litellm_agents_md_consolidation
chore: consolidate CLAUDE.md into AGENTS.md
2026-09-18 20:40:33 -07:00
Mateo Wang
9486caf584
Merge pull request #41721 from BerriAI/litellm_vertex_chirp3_streaming_stt
feat(vertex_ai): stream Chirp speech-to-text over /v1/realtime
2026-09-18 20:34:56 -07:00
Yujong Lee
3157a8a3ca docs: replace poetry run with uv run in script instructions
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-19 03:27:17 +00:00
kerry
57d2fefa8d test(integration): derive scripted shapes from litellm provider configs
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-19 03:16:16 +00:00