Commit graph

50471 commits

Author SHA1 Message Date
Yuneng Jiang
37e8b99a9f
fix(docker): ship pymongo in the proxy images for the MongoDB vector store
The MongoDB Atlas vector store provider imports pymongo lazily from the
opt-in `mongodb` extra, but none of the shipped images installed that
extra. Any image-based deployment that configured a MongoDB vector store
failed at search time with "requires the 'pymongo' package", which the
user cannot fix without extending the image

Adds `--extra mongodb` to every uv sync in the root Dockerfile,
Dockerfile.database, Dockerfile.non_root, and the gateway component
image. The backend component does not serve /vector_stores so it is left
as is. The extra resolves from the existing uv.lock to pymongo 4.17.0
plus dnspython 2.8.0, no lock change needed

(cherry picked from commit 16fd14f537)
2026-09-05 18:14:58 -07:00
ryan-crabbe-berri
eeb7732fc1
Merge pull request #39994 from BerriAI/litellm_hotfix_mongodb_extra_docker_images
Some checks failed
Unit Tests / caching-local (push) Has been cancelled
Unit Tests / core-utils (push) Has been cancelled
Unit Tests / enterprise-routing (push) Has been cancelled
Unit Tests / integrations (push) Has been cancelled
Unit Tests / All Other Providers (push) Has been cancelled
Unit Tests / Vertex AI (push) Has been cancelled
Unit Tests / misc (push) Has been cancelled
Unit Tests / proxy-auth (push) Has been cancelled
Unit Tests / proxy-infra (push) Has been cancelled
Unit Tests / proxy-server (push) Has been cancelled
Terraform Modules / fmt, validate, test (gcp) (push) Has been cancelled
Terraform Provider / gofmt, vet, build, test (push) Has been cancelled
Unit Tests: Documentation Validation / documentation (push) Has been cancelled
GitHub Actions Security Analysis / zizmor (push) Has been cancelled
Unit Tests / enterprise-package (push) Has been cancelled
Unit Tests / proxy-endpoints (push) Has been cancelled
Unit Tests / proxy-extras (push) Has been cancelled
Unit Tests / responses-caching-types (push) Has been cancelled
Unit Tests: Proxy DB Operations / auth-checks (push) Has been cancelled
Unit Tests: Proxy DB Operations / budgets (push) Has been cancelled
Unit Tests: Proxy DB Operations / custom-logging (push) Has been cancelled
Unit Tests: Proxy DB Operations / db-and-spend (push) Has been cancelled
Unit Tests: Proxy DB Operations / endpoints-and-responses (push) Has been cancelled
Unit Tests: Proxy DB Operations / guardrails-hooks (push) Has been cancelled
Unit Tests: Proxy DB Operations / jwt-and-keys (push) Has been cancelled
Unit Tests: Proxy DB Operations / key-generation (push) Has been cancelled
Unit Tests: Proxy DB Operations / logging-misc (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-runtime (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-server-core (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-utils (push) Has been cancelled
fix(docker): ship pymongo in the proxy images for the MongoDB vector store
2026-09-05 18:12:56 -07:00
ryan-crabbe-berri
09e9fd5f60
Merge pull request #39991 from BerriAI/litellm_remove_legacy_user_dashboard
refactor(ui): render the Virtual Keys page without the legacy user dashboard
2026-09-05 18:11:12 -07:00
tin-berri
60440ee4d3
feat(mcp): add opt-in per-server oauth relay discovery (#39936)
Resolves LIT-7074
2026-09-05 18:04:35 -07:00
Yuneng Jiang
16fd14f537
fix(docker): ship pymongo in the proxy images for the MongoDB vector store
The MongoDB Atlas vector store provider imports pymongo lazily from the
opt-in `mongodb` extra, but none of the shipped images installed that
extra. Any image-based deployment that configured a MongoDB vector store
failed at search time with "requires the 'pymongo' package", which the
user cannot fix without extending the image

Adds `--extra mongodb` to every uv sync in the root Dockerfile,
Dockerfile.database, Dockerfile.non_root, and the gateway component
image. The backend component does not serve /vector_stores so it is left
as is. The extra resolves from the existing uv.lock to pymongo 4.17.0
plus dnspython 2.8.0, no lock change needed
2026-09-05 18:03:24 -07:00
moe-berri
91ae13d07d
Merge pull request #39955 from BerriAI/litellm_fix_adaptive_router_bandit_prior
fix(adaptive_router): add the persisted delta to the cold-start prior on load
2026-09-05 18:02:04 -07:00
moe-berri
aee819c976
Merge pull request #39957 from BerriAI/litellm_fix_adaptive_router_cost_from_model_info
fix(adaptive_router): fall back to model_info for cost-weighted scoring
2026-09-05 18:01:36 -07:00
moe-berri
b7a48b43b3
Merge pull request #39954 from BerriAI/litellm_fix_auto_router_blocking_cold_start
fix(auto_router): build the semantic route layer off the event loop
2026-09-05 18:01:11 -07:00
tin-berri
0315dd6f58
fix(headroom): inject headroom_retrieve only for service-declared ccr_hashes and keep assistant content blocks intact (#39974)
The retrieve tool was injected whenever any hash=<24hex> string appeared in the
restored conversation, including protected rows and caller-authored text, so a
git SHA in a tool result registered a bogus hash and billed a useless retrieval
round trip on every later turn. The compression service reports the hashes it
actually stored in ccr_hashes; that field is now the only source, validated to
the service's own 12 to 24 hex grammar before it reaches the retrieve URL.

Assistant rows are no longer flattened to strings before compression: the
service protects assistant text blocks but has no gate for assistant strings,
so the model's own earlier tables came back as a schema line plus CSV.

Adds ccr_retrieval (default true) so operators on a marker-free sidecar can
turn the retrieval loop off entirely.
2026-09-05 17:58:18 -07:00
ryan-crabbe-berri
8bfaaffba5 test(ui): stub the Virtual Keys dashboard in the expired-token page test 2026-09-05 17:57:38 -07:00
tin-berri
01680d7b42
fix(anthropic): keep provider_specific_fields off the native /v1/messages wire (#39967)
The chat and Responses bridges serialize tool_use blocks with model_dump(), so every
bridged /v1/messages response carried LiteLLM's internal provider_specific_fields key
(null, or a Gemini thought signature). Clients replay the block verbatim, and the next
turn that lands on a native Anthropic deployment (auto-router tier change, model swap)
is rejected with "tool_use.provider_specific_fields: Extra inputs are not permitted"

Strip the key from replayed content blocks at the single native Anthropic dispatch so
already-poisoned transcripts self-heal on every native provider, and stop emitting the
null on new responses. The bridges keep reading the signature for the Gemini round trip

Closes #19739
2026-09-05 17:50:54 -07:00
ryan-crabbe-berri
da705c9475 refactor(ui): render the Virtual Keys page without the legacy user dashboard
The API Keys route mounted the pre-App-Router UserDashboard component,
whose beforeunload handler cleared sessionStorage on every refresh of
the Virtual Keys page. That wiped the Playground chat history and model,
the logs live-tail preference, and everything else other pages keep in
session storage. The same component also re-decoded the login token,
re-fetched teams, and wrote cache entries nothing read.

ApiKeysDashboard now renders VirtualKeysTable and the Create Key button
directly, taking identity and role from useAuthorized like every other
page. Create Key is hidden for view-only roles, which the proxy already
rejects on /key/generate. The legacy component, its test, the fetch_teams
helper, and their grandfathered eslint suppressions are removed, and the
ProxySettings type moves to useProxySettings.
2026-09-05 17:49:29 -07:00
ryan-crabbe-berri
5aedd2dcd8 chore: merge litellm_internal_staging into fix/anthropic-responses-refusal-translation
Claude-Session: https://claude.ai/code/session_01HkaXiD6gssHnx3kqu1rR8C
2026-09-05 17:48:13 -07:00
ryan-crabbe-berri
90ac77e58e test(e2e): add JWT issuer harness and first live JWT auth tests
Add tests/e2e/jwt_issuer.py, a test-only RS256 issuer that serves a JWKS
document and signs arbitrary claims over an open loopback-only /token
endpoint, so e2e tests can mint tokens without ever holding a signing key.
One key per process keeps the proxy's cached JWKS valid for the whole run.

Add the first five live JWT auth tests in tests/e2e/other: a valid token for
an existing team is accepted and its spend row carries the claimed team and
user, a tampered signature and an expired token are refused with 401, a
token naming a team that does not exist is refused with 403, and a plain
sk- virtual key keeps working with enable_jwt_auth on. Harness unit tests
cover the issuer itself. Team and user create/delete land on the shared
ProxyClient (warn-only teardown, /user/delete typed as the int it returns)
instead of a fourth per-suite copy.

Document the issuer command, the E2E_JWT_ISSUER_PORT convention (default
4190), JWT_PUBLIC_KEY_URL and the litellm_jwtauth config block in
tests/e2e/CONTRIBUTING.md, and register the new cells in other.yaml.
2026-09-05 17:44:02 -07:00
ryan-crabbe-berri
7015bf37bb fix(proxy): apply team model aliases on the JWT auth path
Team reads on the auth path never loaded the team's alias table, and the
team-based JWT branch copied a hand-picked subset of team fields onto
UserAPIKeyAuth, so aliases (and a few other team grants) never reached JWT
callers: restricted teams 403'd alias requests and open teams 400'd them

Load the alias relation where the team row is read and cached, project the
team onto every team_* token field through one shared team_grants helper
used by both JWT returns, and keep the relation when team model add/delete
rewrites the cached team. ui_sso reuses the shared alias table model

Resolves LIT-5858

Claude-Session: https://claude.ai/code/session_01EX13mWex6RaBo9PYnkAtFW
2026-09-05 17:32:17 -07:00
ryan-crabbe-berri
a9f8a8d794
Merge pull request #39978 from BerriAI/litellm_remove_migrated_pages_shim
refactor(ui): route the sidebar by pathname and shrink the ?page= shim to a redirect table
2026-09-05 17:17:34 -07:00
yucheng-berri
6e05ac5d97
feat(guardrails): add inspect_embeddings toggle for AIM and Cato (#39918)
* fix(guardrails): don't inspect embeddings in the AIM and Cato hooks

`pre_call_hook` fires for /embeddings as well as chat. An embeddings body
carries `input` — documents being indexed, not a prompt — which
`build_inspection_messages` lifts into synthetic chat messages, so both hooks
inspect it as a conversation and a policy verdict on that text breaks a request
that was never one:

- AIM, anonymize + batched `input`: `has_non_string_content` is true for any
  list, so `_anonymize_request` raises 400 "...multimodal input...".
- AIM, anonymize + single-string `input`: no error — the input is rewritten to
  redacted text and the caller embeds text it never sent.
- AIM and Cato, block: the embeddings request is blocked outright.

Gate both hooks on a new `NON_CONVERSATIONAL_CALL_TYPES` deny-list. This is
deliberately not `TEXT_CONTENT_CALL_TYPES`: that allow-list omits
`anthropic_messages`, `responses` and `call_mcp_tool`, so gating on it would
stop these guardrails inspecting real chat traffic. An unrecognised or newly
added call type is still inspected.

* feat(guardrails): add inspect_embeddings toggle for AIM and Cato

* fix(guardrails): redact batched embedding input on anonymize

A list of plain strings is the /embeddings batch shape. AIM rejected it as
multimodal and Cato forwarded the original strings, so anonymize never
reached the provider for batched input. Redactions are now written back
element-wise, one redacted message per non-empty element, so a fully
redacted element cannot shift the following documents into the wrong slot.

* fix(guardrails): reject partial embedding redactions

* fix(guardrails): avoid unnecessary batch type check

* style(tests): drop trailing blank line in cato guardrail tests

* fix(guardrails): reject malformed batch redactions

* fix(guardrails): reject malformed batch redactions

* fix(guardrails): reject aim redactions with no text content

The anonymize path read role and content off every entry of the vendor's
redacted_chat before the shared write-back helper could refuse the payload,
so a message missing content, or a bare string in place of a message, raised
out of the hook as a 500. Validate the vendor list first and return the 400
the guardrail already uses for an unusable redaction.

* fix(guardrails): validate all aim redaction paths

Validate AIM redaction containers before request or output rewrites, reject
cardinality mismatches and empty output, and cover malformed vendor payloads
with regression tests.

* fix(guardrails): preserve aim output redaction alignment

AIM returns the inspected request messages followed by the assistant output.
Validate that full response and select the final redacted message instead of
requiring a single entry.

* test(guardrails): cover aim output anonymize alignment and malformed redactions

---------

Co-authored-by: Guy Levi <guy.levi@catonetworks.com>
2026-09-05 17:15:46 -07:00
yucheng-berri
d515a285b1
fix(azure_sentinel): split batches under the 1MB ingestion cap (#39880)
* fix(azure_sentinel): split batches under the 1MB ingestion cap and keep undelivered records queued

Azure Monitor rejects any Logs Ingestion body over 1MB with a 413. The Sentinel logger
posted the whole queue as one body and cleared it in a finally block, so an oversize
batch, a transient 5xx, or a failed token call dropped every queued record, and records
logged while a send was in flight were cleared with it. Both the standard and the audit
queue share the sender.

Move Datadog's proactive size split and 413 halving into a shared helper,
litellm/integrations/batch_utils.send_batch_with_413_split, and route Sentinel through it
with a 1MB size check. A lone record that still 413s is dropped, everything a transient
failure leaves undelivered goes back to the front of its queue, and the retry queue is
capped at max_queue_size so an unreachable workspace cannot grow memory without bound

* fix(azure_sentinel): retry undelivered records on the flush timer only

Requeued records made every later event cross the batch_size threshold, so a
down ingestion endpoint got one full-queue resend per request. Threshold sends
now go through flush_queue, so they take the flush lock instead of racing the
timer, and they stand down while records are awaiting retry.

A record that cannot be serialized raised out of the size probe and killed the
periodic flush task. The probe now runs inside the failure handling, so the
batch is split and only the record that cannot be serialized is dropped.

* fix(azure_sentinel): decide threshold sends under the flush lock

Concurrent callbacks all read logs_awaiting_retry before the first send
finished, so each one resent the whole queue once that send failed. The
flag and the batch_size threshold are now rechecked while holding the
flush lock, and each queue sends only itself instead of going through
flush_queue, which was retrying the other queue too.

* test(azure_sentinel): cover successful threshold waiters

* fix(azure_sentinel): preserve cancelled batches for retry

* fix(azure_sentinel): requeue only the undelivered part of a cancelled split

A batch over the ingestion cap goes out in pieces, so a cancellation partway
through requeued pieces the destination had already accepted and sent them a
second time on the next flush

The split helper now raises a cancellation carrying the records it never
delivered, and Azure Sentinel requeues those instead of the whole batch

* fix(azure_sentinel): drop batches a permanent rejection will never accept

A non-413 4xx from the ingestion endpoint or from the OAuth token call means the request
will fail the same way on every retry, so requeueing it held the batch, and every record
logged behind it, until the queue cap dropped them. Retryable statuses (5xx, 408, 429)
still keep the whole batch, and a shared classifier gives Datadog the same rule

The serialization probe now catches any exception, not just TypeError and ValueError,
because safe_dumps hands pydantic models to model_dump and can raise anything. It also
splits on record count, so a recovery flush sends batch_size records per request instead
of serializing the whole requeued queue to measure it

Both integrations re-raise a cancelled send as exactly asyncio.CancelledError. Python
3.12's asyncio.wait_for only translates the exact class into TimeoutError, so the
BatchSendCancelled subclass escaped the logging worker as an unhandled error

The awaiting-retry flag now follows the queue that survived the max_queue_size trim, so
a deployment with the cap at zero is not left waiting for a timer flush with nothing
queued to retry

* chore(logging): document mutable queue ownership

Annotate the queue detach and requeue constructions required by the logger's appendable queue contract so the type-discipline budget stays clean

* fix(datadog): preserve non-413 retry behavior

Keep Datadog's existing contract of requeuing every non-413 HTTP failure while Azure Sentinel applies its permanent-client-error policy through the shared splitter

* fix(batch_utils): requeue by default and let Sentinel opt into dropping

The shared splitter's default non-success handler is now requeue_after_http_error, the behavior Datadog had before the extraction, so a caller that omits the argument keeps its records. Azure Sentinel passes undelivered_after_http_error explicitly to drop permanent 4xx rejections

Also drops an explicit return None the strict ruff gate flags in the test helper
2026-09-05 17:15:36 -07:00
Mateo Wang
56a61cf016
Merge pull request #39764 from BerriAI/litellm_govcloud_profiles_lit6421
feat(pricing): add GovCloud pricing for every live but unpriced Bedrock model
2026-09-05 17:15:22 -07:00
mateo-berri
d1f76e81d2 ci(ai-gateway): build the release image in its own workflow and assert the config loads
Some checks failed
ai-gateway image / ai-gateway release image (push) Has been cancelled
LiteLLM Rust / rustfmt, clippy, test (push) Has been cancelled
LiteLLM Rust / release wheel (push) Has been cancelled
Terraform Modules / fmt, validate, test (aws) (push) Has been cancelled
Terraform Modules / fmt, validate, test (gcp) (push) Has been cancelled
Terraform Provider / gofmt, vet, build, test (push) Has been cancelled
Terraform Provider / Provider endpoints vs proxy OpenAPI schema (push) Has been cancelled
2026-09-05 17:14:32 -07:00
ryan-crabbe-berri
e1fb8affe3
Merge pull request #36841 from BerriAI/litellm_lite_pi
feat(cli): add lite pi to run the pi coding agent through the proxy
2026-09-05 17:14:11 -07:00
mateo-berri
635bb3a209 feat(cost-map): add azure_ai/gpt-6-astra Foundry pricing
A gpt-6-astra deployment on a Foundry project reached through the
azure_ai route had no cost map entry of its own, so it resolved to the
OpenAI gpt-6-astra card: missing from the azure_ai/* wildcard listing,
flex and priority prices and /v1/batch it does not sell, and no none
reasoning effort. Add azure_ai/gpt-6-astra mirroring the
azure/gpt-6-astra Standard Global sheet the way azure_ai/gpt-5.5 mirrors
azure/gpt-5.5, and extend the cost, reasoning-effort, and wildcard
listing tests to the Foundry route.
2026-09-05 17:08:42 -07:00
ryan-crabbe-berri
0c45e28dbd test(ui): query sidebar links by role so the testing-library budgets stay under their ceilings 2026-09-05 17:07:27 -07:00
Mateo Wang
0aa346cba5
Merge pull request #39972 from BerriAI/litellm_lit_7027_emulated_file_search_scope
fix(file_search): scope emulated file_search to the request's vector stores
2026-09-05 17:07:04 -07:00
mateo-berri
089b4b8ff4 test: drop docstrings from the bridge id regression tests 2026-09-05 16:59:24 -07:00
mateo-berri
347ea8f7ca fix: keep provider id and metadata on Responses API bridged chat completions 2026-09-05 16:54:50 -07:00
ryan-crabbe-berri
2dfa14648a refactor(ui): drop comments that restate the redirect table and home route 2026-09-05 16:50:20 -07:00
mateo-berri
1975a54b04 fix: declare medium as the only reasoning effort chat-latest accepts
OpenAI rejects every reasoning.effort on chat-latest except medium. With supports_reasoning set and no declared levels the entry resolved to None, so /model_group/info and the dashboard effort pickers had nothing to narrow the offered levels with
2026-09-05 16:49:00 -07:00
Mateo Wang
02cbff4918
Merge pull request #39964 from BerriAI/litellm_lit_7050_redact_failure_traceback
fix(proxy): redact provider keys from pass-through failure tracebacks
2026-09-05 16:48:04 -07:00
mateo-berri
8bf03c10fd fix(file_search): escape the dropped vector_store_id in the warning
Format the model-picked id with %r so control characters in it cannot
break the log line. The regression test for the unlisted id keeps to
generic scoping wording
2026-09-05 16:44:54 -07:00
ryan-crabbe-berri
1258d84221 refactor(ui): route the sidebar by pathname and shrink the ?page= shim to a redirect table
The sidebar and header were still keyed on legacy ?page= ids and mapped
back and forth through MIGRATED_PAGES, legacyPageHref and
legacyKeyForPathname. Leaves are now plain Next links to their path
route, the active item and breadcrumb come from usePathname, and the
setPage/defaultSelectedKey prop chain is gone.

The id-to-route table moves next to the dashboard root page as its only
consumer. That redirect now forwards the remaining query params instead
of dropping them, so deep links such as the proxy's MCP env-var setup
link (?page=mcp-servers&fill_env_vars=) no longer rely on the target page
reading the pre-redirect URL during its first render. The proxy builds
that link as /ui/mcp-servers?fill_env_vars= directly, and the Playground
warnings link to the real routes instead of relative ?page= URLs.

migratedHref is renamed uiHref, the /ui base-path helper it always was.
2026-09-05 16:44:11 -07:00
yuneng-jiang
e56b26c255
Merge pull request #39849 from BerriAI/litellm_internal_staging
chore(ci): promote internal staging to main
2026-09-05 16:41:13 -07:00
yuneng-jiang
bde58f9b41
Merge pull request #39959 from BerriAI/litellm_/release-ui-build-e256a3
chore: rebuild Admin UI bundle for the next release
2026-09-05 16:40:13 -07:00
mateo-berri
43bb55d849 style(oci): wrap the Cohere tool-turn test fixtures to 120 columns 2026-09-05 16:38:23 -07:00
mateo-berri
4c00a6e189 fix(batches): account a batch's cost once, from the first retrieve that sees it final
Every retrieve of a batch through the proxy shares one spend row, the batch id
plus the batch cost suffix, and spend log inserts skip duplicates. A poll that
landed while the batch was still validating or in progress wrote that row at
$0 and no later retrieve could overwrite it, and every completed retrieve after
the first added the cost to the key, team, and user counters again with no new
row to show for it.

The cost callback now writes nothing for a batch retrieve until the batch is
final, releasing the poll's budget reservation instead, and once it is final it
charges only when no spend row for that batch is queued for flush or already
stored. Batch cost rows are flushed to the database right away so a second
instance sees them, and the logger prices a batch only once it is final, which
also covers a failed batch that never produced an output file.
2026-09-05 16:35:32 -07:00
mateo-berri
5a06845db1 fix(ci): mask only credential-length values in the e2e-changed log
A one-character value in the provider secret bundle was masked too, which
turned every 1 in the run log into ***, including the pass numbers and the
gateway addresses, so the only public diagnostics were unreadable
2026-09-05 16:33:15 -07:00
mateo-berri
55a6132b31 fix(file_search): log when a model-picked vector_store_id is dropped
Emulated file_search now warns when the model returns a vector_store_id that is
not one of the request's stores, naming the dropped id and the stores that were
searched instead. H16 asserts the warning is emitted exactly once.
2026-09-05 16:31:24 -07:00
mateo-berri
abb11a196a chore: merge litellm_internal_staging into litellm_fix_oci_cohere_stream_tool_turn_dup 2026-09-05 16:26:21 -07:00
Yuneng Jiang
0e118342ac
chore: update Next.js build artifacts (2026-09-05 23:25 UTC, node v24.19.0) 2026-09-05 16:25:57 -07:00
mateo-berri
f62130a479 fix(responses): floor reasoning support on the bundled cost map and resolve fine-tuned ids
A live cost map older than this release, or a proxy whose map fetch lags, could
strip `reasoning` from a model this release knows accepts it. The bundled map is
now the floor: any OpenAI entry it flags as reasoning keeps the param whatever
the live map says. Fine-tuned ids with an empty suffix (`ft:gpt-4o-2024-08-06:org::id`)
now resolve to their base entry instead of failing open, `chat-latest` carries
the flag, and the schema test keeps every codex, deep-research, and chat-latest
entry flagged. The none-effort check goes through a public wrapper so the
responses config stops importing a private helper.
2026-09-05 16:24:36 -07:00
mateo-berri
b64d1472e0 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_fix_ai_gateway_image_build 2026-09-05 16:23:24 -07:00
yuneng-jiang
b1e2f5bc0b
Merge pull request #39969 from BerriAI/revert-39121-litellm_lazy_sdk_import
revert: perf: lazy-load SDK symbols so import litellm stays under 60 MB RSS (#39121)
2026-09-05 16:22:55 -07:00
devin-ai-integration[bot]
9a5564f00e
fix(ui): read Usage Total Requests tile from gateway request counts (#39963) 2026-09-05 16:20:56 -07:00
mateo-berri
be9a2ea7c9 fix(router): average every latency sample and drop the cost handler's dead division
_average_latency skipped integer samples in the sum while counting them in the denominator, which contradicted its own
Sequence[float | int] signature; it now averages every sample. Both success loggers in cost-based routing computed
response_ms / completion_tokens and threw the result away, so a chat response with zero completion tokens raised
ZeroDivisionError inside the handler. The proxy swallows and logs it, but the handler then skips that request's tpm and
rpm update, so cost-based routing undercounts the deployment's usage. The QA run for the latency fix hit it on real
gpt-5.5 traffic through /v1/chat/completions and /v1/messages
2026-09-05 16:20:20 -07:00
mateo-berri
27c55a21d9 test(proxy): type the traceback-recording hook to match CustomLogger
The regression test's recording logger overrode async_post_call_failure_hook
with untyped parameters. It now mirrors the base signature, and the
UserAPIKeyAuth import moves to module level so the annotation resolves.
2026-09-05 16:19:29 -07:00
mateo-berri
babc97f562 chore: merge litellm_internal_staging into litellm_/e2e-test-performance-7d53be 2026-09-05 16:15:11 -07:00
Yuneng Jiang
eee162b317
fix(lazy_imports): type import_map as Mapping to stay under the LIT001 budget
The revert restored the dict annotation that #39121 had loosened to Mapping,
and the LIT001 ceiling has been ratcheted down since, so the gate rejected the
one reintroduced hit. Annotation only, no behavior change.
2026-09-05 16:12:45 -07:00
mateo-berri
942e6cb3cd fix(file_search): scope emulated file_search to the request's vector stores
The emulated file_search handler searched whatever vector_store_id the
model returned, so a model steered to an id outside the request's
file_search tool reached a store the per-key vector store permission
check never saw. An id outside the request's stores now falls back to
those stores; an id that is one of them still narrows the search to it.
2026-09-05 16:12:43 -07:00
mateo-berri
65d8bbb8ac fix(e2e): wait for every gateway before using a new model and keep the network rerun
The changed-tests workflow overrode the suite's `--reruns 1` with `--reruns 0`, so a
transport blip failed a pass that pytest.ini already scopes to network errors and
5xx responses. Pass 2 of run 33692484803 also went red 15s after a model write with
"no healthy deployments": the barrier only polled /v1/models through nginx, which
proves one gateway converged, and the next request rolled the other. The stack now
exports LITELLM_PROXY_REPLICA_URLS, the barrier polls every replica with the full
budget before settling, and up.sh refuses to boot without DD_API_KEY, since the
gateway config enables the datadog callback on every run
2026-09-05 16:10:40 -07:00
ryan-crabbe-berri
587311d0e4
Merge pull request #39968 from BerriAI/litellm_remove_dead_model_hub_public_dialog
fix(ui): remove unreachable AI Hub dialog that put the session key in a URL
2026-09-05 16:10:15 -07:00