Commit graph

48256 commits

Author SHA1 Message Date
ryan-crabbe-berri
9bdaa54643 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_internal_user_spend_log_detail_route 2026-09-10 15:13:59 -07:00
Mateo Wang
4866be56b0
Merge pull request #40626 from BerriAI/litellm_fix_marketplace_test_request
test(proxy): pass the request to get_marketplace in the archive marketplace test
2026-09-10 15:13:06 -07:00
Kishorekarthik P
6632e8b74f fix(proxy): let internal users read request/response for their own spend logs
The Logs drawer gets messages/response from GET /spend/logs/ui/{request_id};
the list endpoint omits those heavy columns for every caller, admins included.
That detail route was missing from LiteLLMRoutes.spend_tracking_routes, and
check_route_access anchors patterns, so /spend/logs/ui never matched it. Every
internal_user got a 403 before the handler ran and the UI fell back to the
"Request/Response Data Not Available" banner, even on their own requests

Adds the route to spend_tracking_routes so internal_user, internal_user_view_only,
admin_viewer and org_admin all inherit it, and drops the now-redundant explicit
entry from admin_viewer_routes. The handler already authorizes non-admins per row
via _assert_user_can_view_request_id, so no handler-side scoping change is needed

That helper returned silently when no spend-log row existed, which the detail
handler treats as authorized before asking every custom logger for the payload by
raw request_id. With retention pruning the row can be gone while the payload is
still in cold storage, so opening the route would have let a non-admin read
another tenant's prompt out of S3/GCS. A missing row now falls through to the
same 403 as a foreign row, which also removes the exists-but-not-yours oracle

Fixes #34099
2026-09-10 15:04:15 -07:00
ryan-crabbe-berri
7262887ca6
Merge pull request #38413 from eugene-yao-zocdoc/litellm_redis_elasticache_iam_auth
feat(redis): add ElastiCache IAM authentication
2026-09-10 15:03:27 -07:00
Mateo Wang
6b264815ac
Merge pull request #39296 from BerriAI/litellm_fix_v1_models_alias_resolution
fix(proxy): resolve /v1/models limits from the deployment, not the alias
2026-09-10 14:57:19 -07:00
mateo-berri
1987e6e290 test(proxy): pass the request to get_marketplace in the archive marketplace test 2026-09-10 14:54:46 -07:00
ryan-crabbe-berri
33fa195949
Merge pull request #39539 from BerriAI/litellm_fix_health_check_db_storm
fix(proxy): dedup latest health checks in SQL and gate the DB save per window
2026-09-10 14:45:59 -07:00
joshua-berri
4d067b56af
Merge pull request #38724 from BerriAI/litellm_mcp_oauth_identity_binding
fix(mcp): bind per-user OAuth credentials to the authenticated LiteLLM caller
2026-09-10 14:44:11 -07:00
Mateo Wang
56b51db451
Merge pull request #35091 from fzowl/feat/voyage-context-4
fix(voyage): accept flat list[str] input for contextual embeddings
2026-09-10 14:29:23 -07:00
devin-ai-integration[bot]
6cc13e07a6
feat(proxy): granular key/team access control for Claude Code marketplace plugins (#40518)
Adds object_permission.skills to keys and teams, enforces it on
/claude-code/marketplace.json?key=, /claude-code/plugins and
/claude-code/plugins/{name}, and exposes an Allowed Skills selector in
the key and team create/edit forms of the Admin UI

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-10 14:26:09 -07:00
devin-ai-integration[bot]
03815cf9f6
feat(claude-code): accept https zip archive plugin sources for skills (#40496)
Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-10 14:25:42 -07:00
devin-ai-integration[bot]
c59fc6dc28
fix(mcp): reject initialize with 403 when the key grants no MCP servers (#40616)
* fix(mcp): reject initialize with 403 when the key grants no MCP servers

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

* test(mcp): e2e expects 403 initialize for a key with no MCP servers

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

* fix(mcp): mention IP filtering in the no-servers initialize denial and keep zero-grant tool coverage

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

---------

Co-authored-by: mateo <mateo@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-10 14:25:30 -07:00
moe-berri
bc77aa05d2
Merge pull request #40608 from BerriAI/moe/lit-7493-zocdocauto-router-encrypted-codex-sub-agent-task-is
fix(router): classify encrypted delegated tasks with native Responses
2026-09-10 14:08:31 -07:00
ryan-crabbe-berri
2f114d44ed
Merge pull request #39190 from WolframRavenwolf/litellm_wandb_reasoning_effort
fix(wandb): preserve reasoning_effort in chat completions
2026-09-10 14:02:49 -07:00
devin-ai-integration[bot]
46a185d3cd
feat(rust_bridge): count budget-check input tokens in Rust on all LLM routes (#40381)
* feat(rust_bridge): count budget-check input tokens in Rust on all LLM routes

Rust counts input tokens from the raw JSON body with the GIL released inside the existing budget reservation, covering every LLM route the auth dependency guards. It only fires for models on the Anthropic tokenizer when a budget is set, and Python counts whenever Rust is off, missing, or declines a body shape.

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

* perf(rust): count byte-level BPE tokens without the GPT-2 split regex (#40594)

The oniguruma run of the ByteLevel pre-tokenizer regex is about 90% of
encode_fast on a 100k token body (100 ms of the ~110 ms Rust admission
count in the gateway pod). A hand-written scanner that yields the same
pieces, then feeds the model directly, counts the same text in 10 ms.
It only engages for tokenizers with the Anthropic shape (optional NFKC,
ByteLevel without prefix space, no post-processor) and falls back to the
full encoder when the text contains an added token. Parity with
encode_fast is tested on random texts, the pieces are compared with the
real pre-tokenizer, and the \p{L}/\p{N}/\s tables are checked against
oniguruma for every code point.

NFKC runs through unicode-normalization-alignments, the crate and
Unicode tables NormalizedString::nfkc already uses, so the fast path
normalizes exactly what the full encoder would. Using the newer
unicode-normalization crate changed the count for 171 code points that
gained compatibility decompositions after Unicode 9 (U+32FF, U+A7F1..).
The fast normalizer is compared with the tokenizer's for every scalar
value and on random texts.

The scanner is built without mutable state: byte_char and mapped_len replace the const table builders and the reusable mapped buffer, and iter::successors replaces the stateful piece iterator. byte_chars_match_the_byte_level_alphabet checks the byte mapping against ByteLevel for every scalar value.

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(rust_bridge): bound concurrent token-count encodes and share the Anthropic tokenizer predicate

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-10 13:56:30 -07:00
mateo-berri
065ab11f0b Merge remote-tracking branch 'origin/litellm_internal_staging' into HEAD 2026-09-10 13:55:11 -07:00
devin-ai-integration[bot]
0e35c8fee9
fix(proxy): recreate the Prisma client when the writer session turns read-only (#40610)
The writer health probe only ran SELECT 1, which a read-only Postgres
session answers fine, so a pooled connection left pointing at a demoted
primary kept failing every write with SQLSTATE 25006 until the pod was
restarted. Probe transaction_read_only instead, treat a 25006 on the
request path as a signal to recreate the client, and back off
exponentially while the database as a whole stays read-only so a replica
or an in-progress failover does not get its engine killed every cycle.

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-10 13:53:42 -07:00
devin-ai-integration[bot]
9cd1c4c29c
feat(terraform): prometheus metrics sidecar for the GCP Cloud Run gateway (#40614)
* feat(terraform): Prometheus metrics sidecar for the GCP Cloud Run gateway

gateway_metrics_port adds a metrics container running
litellm.proxy.prometheus_metrics_server next to the gateway, sharing the
PROMETHEUS_MULTIPROC_DIR over an in-memory volume, plus a Managed Service
for Prometheus collector sidecar that scrapes it over localhost and writes
to Cloud Monitoring. The gateway stays on port 4000 and the load balancer
routing is unchanged.

Resolves LIT-7502

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

* fix(terraform): reject fractional and collector health ports for gateway_metrics_port

Greptile review on #40614: 4000.5 fails integer port parsing and 13133 collides with the
gmp sidecar liveness listener. Also stop claiming the load balancer's own /metrics goes away

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-10 13:51:59 -07:00
mateo-berri
d3a0b0d45b fix(voyage): let caller params win for contextual auto-chunking and drop duplicate cost map entries
A flat list[str] sent to voyage-context-4 is treated as independent inputs and forwarded flat with
enable_auto_chunking=True, chunk_size=32000, and input_type=document unless the caller already set
input_type=query. Caller-supplied params now override the defaults instead of being clobbered.

The voyage-4 family and voyage-context-4 cost map entries already exist on litellm_internal_staging,
and voyage-4-nano is not served by the Voyage API, so those additions and their pricing test are dropped.
2026-09-10 13:51:45 -07:00
moe-berri
d266b76a8b fix(router): honor Codex reminders and map classifier failures 2026-09-10 13:48:21 -07:00
devin-ai-integration[bot]
a9cec50960
feat(infra): scale gateway on per-pod RPS and TPS in Helm and Terraform (#40479)
* feat(infra): scale gateway on per-pod RPM and TPM in Helm and Terraform

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

* fix(helm): require the metrics server before rendering the gateway ServiceMonitor

The http port serves /metrics/ behind virtual-key auth, so a ServiceMonitor
pointed at it only collects 401s and the RPM/TPM HPA metrics never appear

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

* feat(infra): express gateway HPA, KEDA and ECS workload targets per second

Rename the per-pod request and token targets in both Helm charts and the
AWS module from per minute to per second, and shorten the recommended
Prometheus rate window to [1m] with no * 60 so the adapter and KEDA
signals are what the HPA compares against. ECS keeps CloudWatch's
60-second aggregation: the ALB target is 60x the per-second variable and
the token metric math divides the period Sum by 60 before dividing by
the running task count.

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-10 13:36:23 -07:00
Joshua Valluru
93bd3d61b5 fix(mcp): preserve verified identity when warming OAuth cache 2026-09-10 13:20:49 -07:00
yujonglee
b0d66a15b8
feat(ocr): add core foundation and Mistral adapter (#40530)
* feat(ocr): add core foundation and transport primitives

* fix(ocr): decline missing Mistral credentials

* fix(rust): compile trace parity on Rust 1.98

* refactor(ocr): define native response capability

* refactor(auth): generalize missing API key errors

* refactor(core): keep URL helpers usage scoped

* refactor(ocr): support native responses across adapters

* refactor(ocr): preserve unmapped provider params

* refactor(ocr): distinguish request preparation from payload transforms

* refactor(ocr): trace payload transformation at codec boundary
2026-09-10 13:18:41 -07:00
Joshua Valluru
55ab5ee53d fix(mcp): preserve identity checks across cached OAuth credentials 2026-09-10 13:08:46 -07:00
moe-berri
208d554c00 fix(router): validate encrypted classifiers after deployment selection 2026-09-10 13:04:36 -07:00
moe-berri
488bf6f596 Merge remote-tracking branch 'origin/litellm_internal_staging' into moe/lit-7493-zocdocauto-router-encrypted-codex-sub-agent-task-is
# Conflicts:
#	tests/test_litellm/router_strategy/test_complexity_router.py
2026-09-10 12:55:53 -07:00
moe-berri
692a311efb
Merge pull request #40599 from BerriAI/litellm_lit7492_codex_envelopes
fix(router): strip Codex harness envelopes before classification
2026-09-10 12:45:35 -07:00
moe-berri
f4ebcef0a1 fix(router): classify encrypted delegated tasks with native Responses 2026-09-10 12:32:09 -07:00
moe-berri
181b3fd94a fix(router): classify new asks before reminder-only tails 2026-09-10 12:24:42 -07:00
moe-berri
1697684b68 fix(router): scope Codex envelope defaults to Codex clients 2026-09-10 12:01:04 -07:00
Wolfram Ravenwolf
13ddd1ec64 fix(wandb): gate reasoning effort on model capabilities 2026-09-10 20:47:13 +02:00
moe-berri
5d6fec94b7 fix(router): strip Codex harness envelopes before classification 2026-09-10 11:33:21 -07:00
devin-ai-integration[bot]
6c69dd0f72
perf(proxy): reuse cached model group and deployment info in budget reservation (#40593)
Profiling the sidecar-enabled gateway at 700 rps showed ~2.4% of all samples
in get_model_group_info called per request from budget reservation, plus
get_deployment_model_info for tiered pricing tables. Both are read-only lookups
over the model list, so serve them from the Router's lru caches and clear the
deployment cache alongside the group cache when the model list changes.

The deployment-info cache is a per-router lru_cache built in __init__ rather
than a class-level decorated method, so it does not pin Router instances in a
process-wide cache and is dropped with the router.

A price data reload replaces litellm.model_cost without touching model_list, so
the reload replay also clears both caches; otherwise reservation would keep
pricing against the old catalog until an unrelated model-list change.

Co-authored-by: yassin <yassin@berri.ai>
2026-09-10 11:22:46 -07:00
devin-ai-integration[bot]
f84034f500
feat(mock): report admission-time input token count in mock_response usage (#40590)
* feat(mock): report admission-time input token count in mock_response usage

Mock completions always reported prompt_tokens=10, so spend tracking, TPM metrics, budgets and the tokens-per-minute autoscaling signal saw 10 tokens for a 100k-token request. Budget reservation now carries the admission-time input token count in the reservation record, and mock_completion reads it back so mock traffic exercises the same spend and TPM paths as real traffic without any extra tokenizer work.

* fix(mock): keep a zero admission input token count instead of falling back to 10

---------

Co-authored-by: yassin <yassin@berri.ai>
2026-09-10 11:22:26 -07:00
mrinal
10a5761bb9 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_fix_health_check_db_storm 2026-09-10 18:14:25 +00:00
devin-ai-integration[bot]
2bf065f97d
fix(terraform): restore d.Partial(true) on a rejected /key/update (#40527)
The squash of #40512 onto a base that already carried #40514 left the Partial call on the metadata pre-read error path only, so a rejected /key/update again persisted the planned values into state and TestResourceKeyUpdateFailureKeepsPriorState fails on the default branch.

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-10 11:09:18 -07:00
Mateo Wang
e907e5ee9b
Merge pull request #39237 from BerriAI/litellm_fix_dashscope_rerank_endpoint
fix(dashscope): remap chat-shaped api_base to the live rerank route
2026-09-10 10:31:48 -07:00
ryan-crabbe-berri
11ec6f7a36
Merge pull request #38509 from yinonkahta-p5/litellm_pointfive_logger
feat(pointfive): add the pointfive logging integration
2026-09-10 10:26:51 -07:00
Mateo Wang
218b3280d1
Merge pull request #39272 from BerriAI/litellm_fix_e2e_lint_pathspec
ci(lint): gate top-level tests/e2e and litellm files in the diff-scoped lint steps
2026-09-10 10:13:56 -07:00
ryan-crabbe-berri
c79c73f859
Merge pull request #40446 from BerriAI/litellm_bedrock_aws_session_tags
feat(bedrock): thread aws_session_tags into STS AssumeRole
2026-09-10 09:53:29 -07:00
ryan-crabbe-berri
3ddb920028 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_bedrock_aws_session_tags 2026-09-10 09:42:22 -07:00
Mateo Wang
c1a83fc005
Merge pull request #40581 from BerriAI/litellm_registry_audit_2026_09_10
fix(model_prices): registry audit 2026-09-10, absorb open pricing PRs
2026-09-10 07:43:29 -07:00
eugene-yao-zocdoc
f0e3e031c3 test(redis): pin ElastiCache IAM signing and TLS coercion invariants
Strengthens the serverless test to assert ResourceType is signed rather
than merely present, ties _uses_tls to the redis-py kwarg coercion so the
two cannot drift, locks the stripped-kwarg name tuple to the test's
expectations, and adds "off" and "True" sentinel flag values.

Renames the provider builder's parameter to redis_settings.
2026-09-10 10:13:03 -04:00
eugene-yao-zocdoc
c4fc20bcf9 fix(redis): accept every truthy flag and sign serverless ElastiCache caches
The ElastiCache IAM gate read `aws_iam_auth` and `ssl` with a helper that
only accepted the literal string "true", while the kwarg coercion that runs
later accepts "true", "1" and "yes". Type coercion happens after the gate, so
`REDIS_AWS_IAM_AUTH=1` silently skipped IAM auth and `REDIS_SSL=1` made the
"requires TLS" check fail closed on a connection that was in fact TLS. Both
helpers now share `_str_to_bool`.

AWS signs serverless cache tokens with an extra `ResourceType=ServerlessCache`
query parameter, so tokens minted for a serverless cache were rejected. Adds an
`aws_iam_serverless` setting (`REDIS_AWS_IAM_SERVERLESS`) that puts the
parameter into the signed URL, and lowercases the cache name because
ElastiCache lowercases it at creation time.
2026-09-10 10:13:03 -04:00
eugene-yao-zocdoc
bf73c49d73 refactor(redis): drop unreachable frozen credentials guard 2026-09-10 10:13:03 -04:00
eugene-yao-zocdoc
2b0711e4f5 style(redis): restore the Azure AD marker comment
The comment documents that the raw Azure client id, tenant id and secret
are deliberately kept off the connect function, so this branch should
never have dropped it
2026-09-10 10:13:03 -04:00
eugene-yao-zocdoc
cd4073895f refactor(redis): type botocore credentials without Any
Deferred annotation evaluation keeps the type-checking-only botocore
import off the runtime path, so the alias only reintroduced typing.Any,
which the strict ruff budget now bans
2026-09-10 10:13:03 -04:00
eugene-yao-zocdoc
aca81c263c fix(redis): validate signed ElastiCache IAM URL 2026-09-10 10:13:03 -04:00
eugene-yao-zocdoc
f1cd2b03ca fix(redis): type signed ElastiCache IAM URL 2026-09-10 10:13:03 -04:00
eugene-yao-zocdoc
0217a137fe fix(redis): require TLS for ElastiCache IAM auth 2026-09-10 10:13:03 -04:00