Commit graph

50132 commits

Author SHA1 Message Date
mateo-berri
04eae31769 fix(logging): keep secret-free log extras as their original objects
A non-string extra was scrubbed by a safe_dumps round trip, which handed
every user-attached handler a JSON-shaped copy even when nothing in it
was redacted. The record now keeps the original object whenever the plain
and the scrubbed renderings compare equal, so only an extra that carried
a secret comes back as its scrubbed shape
2026-09-16 14:17:48 -07:00
ryan-crabbe-berri
17844cf14b Merge remote-tracking branch 'origin/main' into pr41379 2026-09-16 14:17:23 -07:00
ryan-crabbe-berri
cfe65f7b55 fix(proxy)!: enforce fallback budget by default
A budget bypass that ships off by default stays open for every deployment
that does not know to look for the flag, so `enforce_fallback_budget` now
defaults to true and `general_settings.enforce_fallback_budget: false` is
the opt-out for anyone who wants the old unguarded behaviour back.

BREAKING CHANGE: a paid fallback target is now refused for callers who are
over their key or user `max_budget`. Deployments relying on fallbacks to
keep serving over-budget callers must set enforce_fallback_budget: false.
2026-09-16 14:15:27 -07:00
kerry-berri
930ec9643a
Merge pull request #41446 from BerriAI/litellm_fix_anthropic_stream_served_model
fix(anthropic): carry the served model from message_start onto stream chunks
2026-09-16 14:14:54 -07:00
mateo-berri
b2e0611c3f Merge remote-tracking branch 'origin/main' into HEAD 2026-09-16 14:13:00 -07:00
Yujong Lee
c621435ef7 refactor(ocr): move file preparation from the python bridge into litellm-core
Delete litellm/ocr/input.py and the native _ocr_file_document, _ocr_upload_document
and _ocr_mime_type helpers. File documents now project to a typed OcrDocumentInput
and the core lifecycle reads local paths, encodes bytes and asks the host to read
file-like objects through a ReadDocument operation before the provider request

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 21:02:30 +00:00
Yuneng Jiang
f10d95fb95
test(together_ai): drop the prefix-strip assertion, e2e covers it live
tests/e2e/llm_translation/test_together_ai_e2e.py registers its model with the
full registry key, so a slashed together_ai/<vendor>/<model> goes through the
prefix strip on every e2e run and an over-strip would fail against the real
API. The unit assertion was a second copy of that. The roles check stays, since
nothing in e2e exercises it.
2026-09-16 13:58:38 -07:00
Mateo Wang
b3898dfd85
Merge pull request #36815 from BerriAI/litellm_otel_gen_ai_system_none
fix(otel): drop None metric and event attributes before OTLP export
2026-09-16 13:56:05 -07:00
yucheng
b96a804004 fix(proxy): seed litellm_call_id into request data before parsing can fail
The failure hook received data without the resolved id when body parsing or
add_litellm_data_to_request raised, so proxy-only spend logging minted a fresh id
that did not match the error log or the x-litellm-call-id header. The id is now
part of the request data from the start and merged over the parsed body, which
also removes the post-hoc in-place assignment

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 20:55:32 +00:00
Yuneng Jiang
baca62df13
test(logging): pick this test's own records out of the shared log batch
The generic API logger batches whatever is queued when it flushes, so records
from tests in other files in the same job land in the same request. Two tests
assumed otherwise: one read actual_request[0], the other counted NDJSON lines,
and both broke whenever another file logged first. Select by the messages each
test sent instead, which keeps the format assertions and stops the order from
deciding the outcome.
2026-09-16 13:53:28 -07:00
Yuneng Jiang
9421b26bf6
fix(e2e): stage the seeded device id per thread, not per process
Build 232 took two compat cells red with a FileNotFoundError renaming
`.claude.json.197` onto `.claude.json`. `run_claude_models_parallel`
drives several models from one process, so a pid-suffixed staged name is
shared between threads: one thread renamed the file the other was still
writing, and the loser died on a path that no longer existed.

mkstemp in the same directory gives a name that is unique per thread as
well as per process, and the rename stays atomic.
2026-09-16 13:47:07 -07:00
Yassin Kortam
4bf04b22b0
Merge pull request #41472 from BerriAI/litellm_customer_budget_prometheus_metrics
feat(prometheus): add customer (end_user) budget gauges
2026-09-16 13:46:57 -07:00
Yassin Kortam
8cdb275ec0
Merge pull request #41460 from BerriAI/litellm_pg10_migration_default_guard
ci(migrations): flag defaulted ADD COLUMN on request-log tables
2026-09-16 13:45:48 -07:00
Mateo Wang
8e524370e1
Merge pull request #41343 from BerriAI/litellm_lit5030_bedrock_invoke_nova_prompt_caching
fix(bedrock): make prompt caching work on the Nova InvokeModel route
2026-09-16 13:42:21 -07:00
Yuneng Jiang
27020c6d37
Merge remote-tracking branch 'origin/main' into litellm_unpin_together_ai_serverless_model 2026-09-16 13:41:03 -07:00
Yassin Kortam
c4a9341ef6
Merge pull request #34829 from max-sixty/bugfix/http-handler-del-closes-streaming-client
fix(http_handler): keep a handler alive while a response it issued is still reading
2026-09-16 13:39:04 -07:00
mateo-berri
4c79abfa0c Merge commit '79fc5153d3' into litellm_otel_gen_ai_system_none
# Conflicts:
#	litellm/integrations/opentelemetry.py
2026-09-16 13:38:40 -07:00
yassin
857301444e Merge remote-tracking branch 'origin/main' into litellm_streaming_buffer_release_on_scan 2026-09-16 20:34:36 +00:00
yassin
8acd2477a6 fix(guardrails): hold legacy function_call stream windows until the end-of-stream scan
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 20:34:20 +00:00
Yassin Kortam
c2cf6e191e
Merge pull request #41458 from BerriAI/litellm_regenerate_no_body_secret_sync
fix(proxy): sync AWS Secrets Manager on body-less key regenerate
2026-09-16 13:31:01 -07:00
yucheng
df9a87f44a fix(otel): keep caller tracestate on the legacy request span
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 20:28:03 +00:00
yassin
81d57cbad7 fix(prometheus): skip customer budget cache read when end_user tracking is off
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 20:23:59 +00:00
Yassin Kortam
79fc5153d3
Merge pull request #41462 from BerriAI/litellm_otel_promote_nested_request_metadata_keys
feat(otel): promote nested request metadata keys to litellm.metadata.* span attributes
2026-09-16 13:23:05 -07:00
Yassin Kortam
dbecd11d99
Merge pull request #41468 from BerriAI/litellm_key_alias_update_secret_sync
fix(proxy): rename AWS Secrets Manager secret when key alias changes
2026-09-16 13:20:53 -07:00
mateo-berri
6015437d67 test(bedrock): assert the Nova cache-read rate as a discount instead of pinning the vendor ratio 2026-09-16 13:19:58 -07:00
Yuneng Jiang
c00f1b4a5c
test: add extension and browser integration contracts
Some checks failed
Terraform Provider / gofmt, vet, build, test (push) Has been cancelled
Terraform Provider / Provider endpoints vs proxy OpenAPI schema (push) Has been cancelled
LiteLLM Rust / rust-lint (push) Has been cancelled
LiteLLM Rust / rust-test (push) Has been cancelled
Adds integration contracts for MCP lifecycle, protocol errors and OAuth
configuration, A2A wire versions, the OpenAI consumer path, persisted
toolsets, callback delivery, guardrail effects, configured prices, the
filtered spend ledger, and a CircleCI-owned browser flow for project
detachment, with the ASGI, browser-state, client and MCP helpers they use.
Consolidates the eleven commits previously stacked on
litellm_integration_providers onto its rebased tip
2026-09-16 13:15:53 -07:00
Yuneng Jiang
fa5d31a837
test(integration): send OpenAI-shaped error types from the fake upstream
Some checks failed
LiteLLM Rust / rust-lint (push) Has been cancelled
LiteLLM Rust / rust-test (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
Since #40994 the proxy relays the upstream error body on a 400, so the
public error type is now whatever the upstream sent instead of the
status-derived name. The fake upstream answered every scripted failure
with type api_error, which made the public-error contract in
test_retry_counts_and_public_errors_match_actual_provider_attempts fail
on main. The fake now sends the type a real OpenAI-compatible upstream
sends for the status, so the assertion holds whether the proxy relays
or maps the type
2026-09-16 13:14:47 -07:00
yassin
e7d537442d fix(prometheus): read the cached customer row for request-time budget gauges
The request path used get_end_user_object, which falls back to a database
lookup on a cache miss. Read the LiteLLM_EndUserTable row auth already cached
instead, with the default budget already attached, and leave misses to the
periodic refresh

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 20:13:52 +00:00
Mateo Wang
365c6de875
Merge pull request #41340 from BerriAI/litellm_anthropic_passthrough_strip_virtual_key
fix(proxy): never forward the LiteLLM virtual key to Anthropic on the /anthropic passthrough
2026-09-16 13:12:42 -07:00
Mateo Wang
737929f338
Merge pull request #41335 from BerriAI/litellm_fireworks_dict_reasoning_effort
fix(fireworks_ai): flatten dict-form reasoning_effort to its effort string
2026-09-16 13:12:37 -07:00
yassin
1979533901 test(router): force the callback to observe the usage stamp before the pre-header increment fails
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 20:10:22 +00:00
yujonglee
560065df16
Merge pull request #41480 from BerriAI/litellm_rust_ci_nextest_rust_cache
ci(rust): split rust jobs, use nextest and Swatinem/rust-cache
2026-09-16 13:08:20 -07:00
Mateo Wang
2b33201a09
Merge pull request #41475 from BerriAI/litellm_bedrock_kb_user_context
fix(bedrock): forward userContext in Knowledge Base Retrieve requests
2026-09-16 13:07:03 -07:00
Devin AI
a229f99ac8 test(models): drive Grok prompt caching coverage through litellm APIs
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 19:59:07 +00:00
yassin
9ebd55e53e test(router): cover success callback recovering the count when the pre-header increment fails
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 19:57:55 +00:00
mateo-berri
884087f01c test(bedrock): type the vector store search test helper 2026-09-16 12:55:29 -07:00
Yujong Lee
48df3d5a48 ci(rust): install nextest via pinned taiki-e/install-action
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 19:54:46 +00:00
mateo-berri
043c954aa9 fix(proxy): keep a caller's own Anthropic key when the proxy has no master key
Without a master key the auth layer echoes whatever key the caller presented as the authenticated key, so the passthrough's strip-by-value matched the caller's own Anthropic key and dropped it: a bring-your-own-key request that returned 200 on main answered 401 telling the caller to send the key they had just sent. Only the auth module's own no-auth dev-mode definition, shared through is_no_auth_dev_mode, decides that nothing was authenticated, and only when no custom auth is installed; JWTs, OAuth2 tokens, and custom-auth credentials are still stripped there. The sk- prefix heuristic goes with it.

The Vertex credential-less test now sets a master key, since a virtual key can only authenticate under one: the auth layer returns before any key lookup when the master key is unset.
2026-09-16 12:52:37 -07:00
mateo-berri
a2724e7f15 fix(otel): drop None attributes before they reach the OTLP encoder
The metric attribute filter now removes every attribute whose value is
None, and the content and inference-details events pass their attributes
through drop_none before emitting, so a call with no provider label or no
model name never hands the OTLP exporter a NoneType attribute. This closes
the gen_ai.request.model report on #36759 the same way the gen_ai.system
one was closed, and the regression tests cover both keys.
2026-09-16 12:52:14 -07:00
Devin AI
ba03f60f71 fix(models): add batch and flex tier prices on Azure dated and Gemini latest alias rows
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 19:50:28 +00:00
Yuneng Jiang
7679e42736
test: cover provider wire contracts, streaming and recovery
Adds owned local TCP peers, a Redis process helper and SigV4 helpers to
tests/integration, and integration contracts for Anthropic and Bedrock wire
shapes, Bedrock role configuration, S3 wire, observed routing, Redis
recovery and stream contracts. Consolidates the four commits previously
stacked on litellm_integration_accounting onto its main-merged tip
2026-09-16 12:48:30 -07:00
Yujong Lee
3f15dcd96b ci(rust): fold fmt into the clippy job
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 19:47:48 +00:00
Yuneng Jiang
5d38240ada
Merge remote-tracking branch 'origin/main' into HEAD
Some checks failed
LiteLLM Rust / rust-lint (push) Has been cancelled
LiteLLM Rust / rust-test (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-16 12:46:42 -07:00
yassin
7ff8945da4 fix(router): sync both usage keys from Redis even when one increment is zero
A stream counted before its usage is known increments TPM by zero, so the
worker that served it never refreshed its local TPM value from Redis and
the first byte headers reported the token count another worker had already
consumed. Both pipeline operations now always run, matching the pre-change
callback, so the returned values refresh both worker local keys

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 19:45:48 +00:00
Yuneng Jiang
2481146727
docs(e2e): say why the CLI-driving cells needed a driver fix, not a rule 2026-09-16 12:44:53 -07:00
Yujong Lee
e850232f02 test(rust): assert merge cost scales linearly instead of a wall-clock bound
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 19:43:42 +00:00
yassin
0d605b7b45 Merge remote-tracking branch 'origin/main' into litellm_streaming_buffer_release_on_scan 2026-09-16 19:42:36 +00:00
mateo-berri
0dff64ce1a fix(bedrock): move a Nova invoke cache point behind an image or tool result to the last text block 2026-09-16 12:42:15 -07:00
Yuneng Jiang
39acea0754
feat(e2e): make Claude Code send the same bytes every build
The compat cells drove the CLI with a fresh HOME per invocation and the
pytest process's own working directory, and both reach the request body.
The system prompt names a memory directory built from
$CLAUDE_CONFIG_DIR/projects/<cwd slug>, so a per-invocation config
directory rewrote every body, and the CLI adds a git block for its
working directory, so inheriting the checkout rewrote every body once
per candidate. The device id churned for the same reason: the CLI mints
it once and persists it in .claude.json, which we threw away each call.

Nothing here was load-bearing. All three ride in metadata.user_id, whose
job is abuse detection, not quota, caching or continuity. So pin the
config directory and the working directory at fixed paths, seed the
device id, and pin the session id.

HOME stays fresh and empty per invocation, so the isolation is no weaker
than before, and the CLI's own state no longer outlives the pod either.
The working directory is deliberately not the checkout, so a
model-directed Read now sees an empty directory rather than the
repository.

A pinned session id needs --no-session-persistence beside it: the CLI
refuses a session id another live process holds, and the matrix runs its
cells across xdist workers. Without the flag, six of eight concurrent
invocations die on "Session ID is already in use".
2026-09-16 12:42:15 -07:00
kerry-berri
b6143b3711
Merge pull request #41457 from BerriAI/litellm-providers/price-sync
chore(prices): sync Google Gemini prices: 22 models
2026-09-16 12:37:16 -07:00