Commit graph

46489 commits

Author SHA1 Message Date
mateo-berri
528d358c05 fix: leave a bounded insert, a bounded writable CTE and an uncalled routine alone
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
A parenthesised VALUES list ended the search for an insert's row source
only when no group followed it, so a RETURNING or an ON CONFLICT DO
UPDATE carrying a subquery was read as the rows the insert copies. A
writable CTE bounded by its own VALUES list was handed the query the
statement ends with for the same reason: the WITH branch read the whole
statement rather than the part holding the insert.

A CREATE FUNCTION or CREATE PROCEDURE body was scanned as if it ran at
boot, but defining a routine only stores it. The body is now read when
the same migration names the routine somewhere else, so a migration that
defines a backfill and then runs it is still caught, and one whose name
needed quoting is read either way since quoting is blanked at the call
sites too.

main() had no test, so neither its exit codes nor the branch the CI gate
reads were pinned; a mutant returning 0 on a violation passed the whole
suite. Its four outcomes now have tests, along with both directions of
each fix above.
2026-08-22 17:30:37 -07:00
mateo-berri
112224a7fe fix(databricks): enable vision on fable-5 and pin every cache rate to published DBU
databricks-claude-fable-5 was the only fable-5 entry in the registry
declaring supports_vision false, and the only one of the five new
entries to do so.

Only the five new models were pinned against the published DBU table,
so the 26 cache literals added to pre-existing entries were checked by
nothing independent. Extend the table to all 33 entries carrying cache
rates and assert both cache fields against it for the 31 that take the
published rates, leaving the two older-vintage gemini-2-5 entries to
their existing guard.

Also widen the cache-declaration guard to both cache fields, and
replace the single-model equals-input assertion with one that covers
all 14 entries publishing no cache rates.
2026-08-22 17:30:10 -07:00
Devin AI
418e8ca5e8 fix(bedrock): build response field paths as an immutable sequence to satisfy the type discipline gate
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-23 00:00:21 +00:00
mateo-berri
0a869b7226 fix(databricks): derive cache rates from published cache DBU
Cache rates were derived as ratios of the dollar input rate (1.25x write,
0.1x read) while input and output derive from the published DBU table
times $0.070. Databricks publishes cache write and cache read DBU per
model, and those are not exact multiples of the input DBU, so the two
rules disagreed by up to 0.1 percent.

Rewrites 43 cache literals across 31 entries to published_cache_DBU x
$0.070. Skips databricks-gemini-2-5-pro and databricks-gemini-2-5-flash,
whose input and output rates predate the current table by a 1.25x
increase; their cache rates stay tied to their own input rate so each
entry remains internally consistent.

Replaces the ratio assertions with a test pinning the absolute published
DBU figures for the five new models, and adds a test pinning the
older-vintage exception. Corrects the metadata note on the five new
entries, which claimed the reference-only *_dbu_cost_per_token fields
drive cost calculation.
2026-08-22 16:42:52 -07:00
mateo-berri
e02f34b2c5 Merge remote-tracking branch 'origin/litellm_fix_24985_thinking_roundtrip' into litellm_fix_24985_thinking_roundtrip
# Conflicts:
#	litellm/llms/anthropic/experimental_pass_through/responses_adapters/transformation.py
2026-08-22 16:32:43 -07:00
mateo-berri
8a1fe281fd fix(responses-adapter): skip null reasoning summary text and keep thinking-only assistant turns 2026-08-22 16:29:35 -07:00
mateo-berri
521dc973c3 fix(interactions): keep alerting when an interaction that produced output has no usage
Silencing the cost-tracking alert for every usage-less interaction response
went one status too far. An interaction that stopped at failed, cancelled,
incomplete or budget_exceeded genuinely has nothing to charge for, so alerting
on it is noise. completed and requires_action are different: both mean the
model produced output, so a usage block is always expected, and one arriving
without it means the charge for real work was lost. That is precisely the case
failed_tracking_alert exists to surface, and swallowing it would let an
operator's interactions bill nothing with no signal that anything was wrong.

The status knowledge lives next to the other status predicates rather than in
the proxy callback. The reservation is still released on both paths, since
suppressing the alert was never what freed it.
2026-08-22 16:15:14 -07:00
Mateo Wang
aae36f4bd4
Merge pull request #37956 from BerriAI/litellm_fix_26167_bridged_session_lookup
fix(responses): keep the conversation when chaining previous_response_id on the bridge
2026-08-22 16:11:08 -07:00
Devin AI
20e92d1e68 fix(anthropic/bedrock): request summarized adaptive thinking for reasoning_effort and use provider thinking token counts
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-22 23:10:42 +00:00
mateo-berri
d8bcdd803d Merge branch 'litellm_google_interactions_cost' of https://github.com/BerriAI/litellm into litellm_google_interactions_cost 2026-08-22 16:07:42 -07:00
mateo-berri
b460254428 fix(interactions): price the settled background body against its own deployment
The poll fetches the terminal interaction through its own client call, which
stamps a response cost computed by a throwaway logging object holding none of
the original request's deployment context: no model_info, no router model_id,
no deployment litellm_params. Carrying that cost into the settlement event
billed custom-priced deployments at the wrong rate, and it also satisfied the
"already calculated" shortcut in _response_cost_calculator's caller, so the
settlement never repriced and never built a cost breakdown. The zeros stamped
by the usage-less create survived into the spend log row and the OTEL span.

Dropping the imported cost before re-emitting makes the settlement price the
settled body itself, against the deployment that served the create.
2026-08-22 16:06:52 -07:00
mateo-berri
444a023272 chore(databricks): write pricing at the derivation's precision
The figures came out of a float product of the DBU rate and the dollar
rate, so the map carried representation tails such as
2.9999900000000006e-07 where the derivation only means 2.99999e-07.

Trim the 44 values this change adds or edits to the shortest literal that
round-trips to the same figure, leaving every pre-existing value alone.
The largest move is under 1e-15 relative, so no billed amount changes.
2026-08-22 16:02:08 -07:00
Cursor Agent
d46b0bddd7
fix: drop null summary text and emit reasoning-only assistant turns 2026-08-22 22:58:04 +00:00
Cursor Agent
0ab8ef60bf
fix(interactions): stop the unpollable-create path from firing a false cost-tracking alert
The tightened gate correctly stopped deferring the reservation release for
InteractionsAPIResponses the scheduler will not poll (terminal status, or
in_progress without an id), but the response then fell through into the
generic 'Cost tracking failed' raise and the failed_tracking_alert path.
A create returning failed, cancelled, requires_action, incomplete,
budget_exceeded, or an id-less in_progress without usage therefore released
its reservation as intended and, in the same breath, alerted operators for a
legitimate no-usage response, both creating noise and masking real
cost-tracking failures.

The two gates are now nested under a single 'unbilled interaction response'
outer check, so any InteractionsAPIResponse with no usage takes either the
defer path (pollable, polling on) or the release-and-return path, and none
of them fall through to the generic failure raise. The two regression tests
also now assert failed_tracking_alert is not called, closing the observation
gap the report flagged.
2026-08-22 22:54:08 +00:00
mateo-berri
68bda94995 chore: mark the new API payload literals for the type-discipline budget 2026-08-22 15:53:12 -07:00
mateo-berri
e487e470c7 test(databricks): pin the cache-control test to the in-repo cost map
The new supports_prompt_caching assertion reads a capability this branch
adds to the registry, so it only holds against the bundled map. CI leaves
LITELLM_LOCAL_MODEL_COST_MAP unset and fetches main's copy, which lags the
branch until merge, so the test failed there while passing locally.

Use the local_model_cost_map fixture the repo already provides, matching
what the other two test files in this change do.
2026-08-22 15:51:17 -07:00
mateo-berri
da3dcb139d fix(databricks): charge the input rate for cache tokens on models with no cache pricing
The shared cost calculator treats a missing cache rate as free, so routing
Databricks through it billed cached tokens at zero on the 14 entries that
publish no cache pricing. On a 10,000 token prompt with 8,000 cache reads
that is $0.0010000 against the correct $0.0050001, a fivefold undercharge.

Those entries now declare cache rates equal to their input rate, which is
what a model with no caching discount should charge, and a test pins every
priced Databricks entry to declaring cache rates so no future entry can
regress into it.

Also repoints the provider-neutral generalization test off an id the new
Opus 5 entry now shadows, adds backup-to-main parity tests for the five new
entries, pins that Databricks Claude is never auto-injected with cache
control despite reporting caching support, and trims the Sonnet 5 pricing
note, which is served on an unauthenticated route.
2026-08-22 15:37:37 -07:00
mateo-berri
8b566a7f0a fix(interactions): stop two settlement paths from pinning the budget reservation
Both leave a background interaction's pre-call reservation open, so the
serving process keeps refusing traffic on the key at the estimated cost
while its recorded spend stays near zero.

A raise from the completion event propagated out with the settlement gate
already claimed, and nothing retries a claim that is set, so the reservation
was never released. Billing now releases it on the way out.

`requires_action` was missing from the terminal set. It is terminal for the
interaction it names: the API has no operation that resumes one, and a caller
answers a tool request by creating a new interaction whose
`previous_interaction_id` points at it. A function-calling background create
that stopped there was polled until the 3600s timeout, losing the tokens it
had already spent producing the tool request and holding its reservation open
for that whole window.
2026-08-22 15:28:12 -07:00
mateo-berri
23e64c8b3d chore(responses): keep the session lookup inside the type-discipline budget 2026-08-22 15:25:59 -07:00
yuneng-jiang
947dbbf029
Merge pull request #37913 from BerriAI/litellm_internal_staging
Some checks failed
Helm unit test / unit-test (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
Code Quality Checks / code-quality (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
Unit Tests: Documentation Validation / documentation (push) Has been cancelled
Unit Tests: Proxy DB Operations / assert-shard-coverage (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-endpoints (push) Has been cancelled
Unit Tests / proxy-infra (push) Has been cancelled
Unit Tests / proxy-server (push) Has been cancelled
Unit Tests / responses-caching-types (push) Has been cancelled
Unit Tests: Proxy DB Operations / custom-logging (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-runtime (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 / 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-server-core (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-utils (push) Has been cancelled
chore(ci): promote internal staging to main
2026-08-22 15:24:27 -07:00
Mateo Wang
75613bf22f
test: add regression coverage for twelve closed issues (#37974)
* test: add regression coverage for twelve closed issues

Adds targeted regression tests for behavior that was fixed but left ungated,
so the fixes cannot silently regress:

- #33772 openai cache_write_tokens cost
- #34309 Responses API cache cost_breakdown
- #35363 /v1/responses batch spend
- #36619 auto-router api_base/api_key leak on a shared model name
- #35359 batch fallbacks within the owning model group
- #36523 passthrough streamed Responses spend log
- #36646 passthrough embeddings spend log
- #37147 non-object metadata on create_batch is a 400
- #35362 unscoped list files reads the managed-file store
- #33221 gpt-5.6 bridges to Responses on function tools alone
- #34487 LLM complexity classifier runs for every caller metadata shape
- #35124 streamed /v1/messages emits success logging on both bridges

Cost assertions read rates from litellm.model_cost rather than hardcoding
dollar amounts, so they do not drift on repricing.

* fix: stop the new regression tests polluting and tripping over shared global state

Two shard failures, both from global state the new tests share with their
neighbours rather than from the behaviour under test.

test_main.py's local_cost_map pinned litellm.model_cost but left the
get_model_info lru_cache warm, so completion_cost billed at whatever prices
were cached earlier in the process while the assertions read the pinned map.
Clear the cache on both sides of the fixture, matching the local_model_cost_map
fixture in tests/test_litellm/conftest.py.

The anthropic messages streaming tests called GLOBAL_LOGGING_WORKER.flush()
on whatever queue happened to be around. A queue left non-empty by an earlier
test is still bound to that test's loop, so join() either hangs or raises
"bound to a different event loop". Rebind to the running loop before the call
and wait for the captured payload instead of a fixed sleep.
2026-08-22 22:24:05 +00:00
yuneng-jiang
ba07340964
chore: update Next.js build artifacts (2026-08-22 22:11 UTC, node v24.19.0) (#37976) 2026-08-22 15:20:50 -07:00
mateo-berri
7e59f8c209 fix: read every parenthesised group for the row source, not the last
Taking the last group at the statement's outermost level assumed the row
source was written there, and an insert is allowed to carry more after it:
`(SELECT ...) ON CONFLICT ("id") DO NOTHING` ends on the conflict target
and `... RETURNING ("id")` on the returning list, so the query supplying
the rows was never reached and a full table copy passed the gate.

Each group is now read on its own terms and the first to name a row source
is the answer, since the others are the column list and the clauses an
insert may carry, none of which names one.
2026-08-22 15:20:24 -07:00
mateo-berri
71d6f5f0be Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_fix_24985_thinking_roundtrip 2026-08-22 15:14:16 -07:00
mateo-berri
6c23f5ffba fix(databricks): price Sonnet 5 at standard rates past the introductory window
The introductory DBU rates run through 2026-08-31 and pricing carries no
expiry date, so a static introductory entry would undercharge by a third
from September 1 and let spend outrun enforced budgets. Ship the standard
rates, which match Sonnet 4.5 and 4.6, and keep the introductory numbers
in the entry notes.

Also give the new cost calculator tests full type annotations.
2026-08-22 15:12:02 -07:00
mateo-berri
d6d25ed310 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_fix_26167_bridged_session_lookup 2026-08-22 15:10:26 -07:00
Mateo Wang
11cbe472ac
Merge pull request #36355 from harryzhou2000/fix/responses-bridge-preserve-reasoning-input-items
fix(responses-bridge): preserve reasoning input items and signed thinking blocks
2026-08-22 15:07:02 -07:00
mateo-berri
a46f919e8d fix: read a set-operated insert's row source term by term
An `INSERT` whose `VALUES` list holds a scalar subquery was reported as a
rewrite whenever that list was not the plain top-level one: joined to
another term by `UNION`, `INTERSECT` or `EXCEPT`, or written inside
parentheses, which Postgres accepts. Both shapes insert a fixed handful of
rows, so the gate was rejecting migrations that do nothing wrong.

A set operation is now split into its terms and each is read on its own,
since the insert is a rewrite when any one term is a query. A row source
kept in parentheses is read on its own terms too. The operators are found
outside every parenthesis, so a set operation written inside a `VALUES`
list does not cut the list in half.
2026-08-22 15:05:10 -07:00
mateo-berri
c55b400f41 fix(databricks): bill cached tokens at cache rates and add missing Claude pricing
Databricks cost calculation multiplied every prompt token by the input rate, so
a cache read cost the same as an uncached token. Route it through
generic_cost_per_token, which already understands cache reads and cache writes,
and add the cache rates the registry was missing.

Adds Claude Opus 4.7, Opus 4.8, Opus 5, Sonnet 5 and Fable 5 on Databricks.
2026-08-22 14:55:30 -07:00
mateo-berri
5317a5ab50 test: cover the reverse bridge on an assistant message that precedes its function_call 2026-08-22 14:53:18 -07:00
mateo-berri
19a3fe1b66 fix(responses-bridge): fall back to summary text when content carries none
An empty content list, or one holding only opaque blocks, still lets the
provider-bound branch replay the summary text. The inspection path treated
any non-None content as final, so that replayed text stayed invisible to
guardrails and token counting.
2026-08-22 14:51:38 -07:00
yucheng-berri
8a7c873a01
fix(proxy): omit litellm_batch_guardrail when no guardrail acted (#37964)
The field is declared optional on OpenAIFileObject and its own docstring says it
is absent on every upload guardrails did not touch, but the /v1/files routes have
no response_model, so FastAPI falls through to jsonable_encoder with exclude_none
off and serialises the unset default as an explicit null. Every create and
retrieve response on a proxy with no guardrails configured at all picked up a
litellm_batch_guardrail: null it never had before, and so did every row of a file
list, since those rows are the same object.

A wrap serializer drops the key only when nothing set it, so the populated report
still reaches the wire intact, including a record whose guardrail is null. The
managed-files list route spreads a stored file_object blob rather than the model,
so rows persisted before this lands keep their null until it is dropped there too.
2026-08-22 14:51:11 -07:00
mateo-berri
6befeb8a17 fix(interactions): stop the cost poll loop instead of spinning on a non-positive interval 2026-08-22 14:48:32 -07:00
yuneng-jiang
7aef79b774
test(e2e): harden the suite against response-cache cross-talk, slow providers and single upstream blips (#37957)
* test(e2e): send no-cache on every cacheable request body, opt in only where a hit is the assertion

The e2e proxy runs with the response cache on, so any test that re-sends an
identical chat, messages, responses, completions, embeddings or rerank body
reads back a redis copy of an earlier call instead of reaching the provider.
Five tests in the last week failed that way. Default cache: {"no-cache": true}
on those request models and pass cache=None only in the two tests whose
assertion is the cache hit itself.

* test(e2e): give image edits and OCR a 180s client timeout

Both routes wait on providers that can legitimately take longer than the
60s transport-wide request timeout (gpt-image edits, Azure Document
Intelligence), and a client-side read timeout there fails a green request.
post/upload now accept a per-call timeout like get already does; only those
two call sites use it.

* test(e2e): rerun once on network errors and upstream 5xx only

Assertion failures still fail on the first attempt; only an outcome whose
error string carries the e2e_http network kind or a 5xx status gets one
more try. Test Engine records every attempt, so the flake rate stays
visible while a single provider blip no longer reds the rc run.

* test(e2e): let the reseed burst survive one upstream failure and print why

The burst is the precondition, not the property: one 5xx among six
concurrent calls still leaves five workers racing the cold counter, which
is what the reseed assertion measures. Two or more failures still abort,
and the failing bodies are now in the message instead of only the status
codes.

* test(e2e): keep polling Jaeger through a transient query failure

poll_traces_for_call already waits up to POLL_TIMEOUT for spans to land,
but a single refused connection to the query API failed the test on the
spot. Jaeger restarted twice during today's gate runs (19:05 and 19:41
UTC, each under a minute) and took ten and three otel tests with it while
the same tests passed on the rc build minutes later. A network failure
now counts as not-yet inside the same deadline; if Jaeger is still
unreachable when the deadline passes the test fails with that error, and
any non-network failure still fails immediately.
2026-08-22 14:47:03 -07:00
Mateo Wang
98dfb789cb
Merge pull request #37946 from BerriAI/litellm_fix_27333_bridge_item_ids
fix(responses): mint Responses API item IDs in the completion bridge
2026-08-22 14:46:54 -07:00
mateo-berri
12c4652fc4 fix: read bind values from the USING the command expression has closed
A `JOIN ... USING` inside a subquery that helps build an EXECUTE's command
was taken for the start of its bind values, so anything written after it
went unscanned and a rewrite there was never reported. Only a `USING` with
the parentheses closed can be the bind-values clause.
2026-08-22 14:43:51 -07:00
mateo-berri
d2b5034fea test(responses): fold the bridged streaming regressions into the mapped test file 2026-08-22 14:33:23 -07:00
mateo-berri
3d69ec3603 fix(responses-bridge): keep summary-only reasoning text scannable
A reasoning input item that carries only summary text is replayed to the
provider as reasoning_content, so inspection-only callers must see that
text too. They used to fall through to the generic content branch, which
reads content and drops a summary-only item, leaving guardrails and token
counters blind to text the model still receives.
2026-08-22 14:30:52 -07:00
mateo-berri
32bf1aba29 fix(anthropic): stop signing replayed thinking blocks and strip reasoning_content
A reasoning item id is not an Anthropic signature. Passing it off as one got the
block replayed to Anthropic and Bedrock as if it were real, and every backend that
verifies signatures rejected the turn. Thinking blocks now come back unsigned, and
the streaming path no longer emits a signature_delta for them.

Azure AI Foundry, Fireworks, and vLLM reject unknown message fields, so they now
strip reasoning_content alongside thinking_blocks the way Mistral already did.

The thinking-block helpers take ChatCompletionThinkingBlock and
ChatCompletionRedactedThinkingBlock instead of loose mappings.
2026-08-22 14:27:20 -07:00
Yassin Kortam
a44bb47563
fix(prometheus): fold auth/pre-call time into litellm_request_total_latency_metric (#37958)
litellm_request_total_latency_metric's start_time is set inside
common_processing_pre_call_logic, which only runs after user_api_key_auth
has already succeeded, so the metric silently excluded authentication and
pre-call setup time despite being documented as total request latency. The
sibling litellm_request_queue_time_seconds metric had the same problem:
its arrival_time was captured after auth too, despite its own comment
claiming to track when the request arrived at the proxy.

request.state.litellm_received_at is now stamped unconditionally at the
very first line of user_api_key_auth (previously only when OTEL was
configured), giving a timestamp that precedes all auth work. Both metrics
now derive from it: queue_time_seconds genuinely spans arrival through the
start of pre-call processing, and the total-latency metric adds that
queue time on top of its existing start/end window so it becomes true
end-to-end latency.

queue_time_seconds ends exactly at start_time rather than a separately
captured timestamp, so its window and the total-latency window share a
boundary instead of overlapping and double-counting a few lines of setup
work on every request.
2026-08-22 14:25:55 -07:00
Yassin Kortam
ba876c98e6
fix(auth): stop the team fallback from widening model access (#37962)
When get_team_object fails, the centralized auth gate rebuilds the team
from the token's own fields. A token whose team row was missing when the
key was read carries team_models=[] and team_blocked=False, and the
model-access check reads an empty model list as every model, so the
rebuilt team grants more than the real team ever did.

get_team_object reported a deleted team and a database that would not
answer as the same 404, so the fallback could not tell a definitive
answer from a degraded read. Raise a TeamNotFoundError subclass, still a
404 with the same detail so every other caller is unaffected, only when
the database answers and the row is absent.

A team that is provably gone now refuses, and no setting overrides that.
Otherwise the grant is merely unknown: a token carrying one may vouch,
since replaying a recorded grant cannot widen it, and a token carrying
none may not. allow_requests_on_db_unavailable still opts back out there,
and is only consulted once the failure is known to be a degraded read.

The Admin UI mints every session key against the UI_TEAM_ID sentinel,
which by design never has a team row, so every UI request hit the new
refusal with no override. Exempt UI_TEAM_ID explicitly so it keeps
reconstructing from the token unconditionally, matching how the MCP
handler and agent_permission_handler already special-case it.

Resolves LIT-5522
2026-08-22 14:25:29 -07:00
Yassin Kortam
15510f0b8b
fix(auth): resolve team object_permission independently in the unresolvable-team fallback (#37960)
* fix(auth): resolve team object_permission independently in the unresolvable-team fallback

When get_team_object fails for a token's team_id, _user_api_key_auth_builder
reconstructs a LiteLLM_TeamTableCachedObj from the token's own cached fields,
carrying team_object_permission_id but leaving object_permission unset. That
silently dropped any vector-store or MCP restriction the team carried,
granting more access than the token's own object_permission_id vouches for.

Resolve the object permission by its id directly via get_object_permission,
independent of the unreadable team row, matching how every other consumer of
a team's object_permission (vector store access checks, MCP tool/server
resolvers) already treats an unresolvable team as "no restriction at this
level" and re-resolves on its own.

* fix(auth): trim ticket references and narrative docstrings per Greptile review

Drop the LIT-5539 ticket id from test names and fixture strings, and shorten
both the new helper's docstring and the regression test docstrings to their
contracts rather than restating the fix's history.
2026-08-22 14:25:11 -07:00
Yassin Kortam
7ed91df836
fix(proxy): make /team/member_delete's four cleanups atomic (#37959)
The team roster update, the user.teams update, the team membership
delete, and the team-scoped verification token delete ran as four
sequential writes with no transaction around them, so a failure
between any two left the removal half applied. Thread a single
prisma transaction through all four writes, following the same
tx.<table> pattern /team/member_add and /team/member_update already
use, so either all four land or none do.
2026-08-22 14:24:57 -07:00
mateo-berri
9d22acab11 fix(responses): skip the session lookup retry when spend logs are off 2026-08-22 14:22:10 -07:00
mateo-berri
6a55683cd0 refactor: drop the unused response argument from the image item extractor
The image generation item ID no longer comes from the chat completion
response, so the extractor does not need it.
2026-08-22 14:22:08 -07:00
Yassin Kortam
9349b22c64
fix(guardrails): stop PII/PCI masking gaps in SpendLogs, debug logs, and logging_only response (#37965)
The Presidio guardrail masks messages in place inside pre_call_hook, but three
paths independently persisted or emitted the raw pre-guardrail data: the
SpendLogs proxy_server_request body snapshot (taken before the hook runs),
a verbose_proxy_logger.debug dump of the raw request, and logging_only mode's
async_logging_hook, which never masked the model's response before it reached
external logging callbacks.

Resolves LIT-6015
2026-08-22 14:15:55 -07:00
Mateo Wang
0fca861935
Merge pull request #37715 from syahra712/fix/batch-processed-guard
fix: don't retire a completed batch from cost recovery while output_file_id is lagging
2026-08-22 14:07:01 -07:00
mateo-berri
af18f77db6 fix(check_batch_cost): leave a lagging-output completed batch for the next poll cycle 2026-08-22 12:48:39 -07:00
mateo-berri
9cd6240387 Merge remote-tracking branch 'origin/litellm_internal_staging' into HEAD 2026-08-22 12:48:38 -07:00
tin
d4608af27b fix(proxy): skip health checks for strategy routers
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-22 19:30:54 +00:00