Commit graph

50724 commits

Author SHA1 Message Date
ryan-crabbe-berri
df2dd9b7f2 feat(ui): keep projects search and project key table state in the URL
The projects list search lives in ?project_search= and its pagination now goes through useUrlTableState, keeping the page and page_size keys. The key table inside a project reads keys_search, keys_page and keys_page_size, resets to its first page on a new search, and no longer snaps a deep-linked page while the key fetch is failing. Closing a project drops its keys_ params so they do not leak into the next project
2026-09-16 16:12:47 -07:00
ryan-crabbe-berri
417cc5c4fb feat(ui): keep organizations list and detail tab state in the URL
The organizations list now reads its search (org_search), org ID filter (filter_org_id), sort (sort_by, sort_order) and pagination (page, page_size) from the URL through useUrlTableState. The detail view tabs are controlled by ?org_tab=, and the Edit row action opens ?org=<id>&org_tab=settings in one history entry instead of passing an editOrg flag
2026-09-16 16:12:47 -07:00
yuneng-jiang
765e6e498d
Merge pull request #41402 from BerriAI/litellm_/buildkite-litellm-e2e-setup-ff714d
feat(e2e): make the provider cache reusable across builds and mount Bedrock behind it
2026-09-16 16:12:29 -07:00
ryan-crabbe-berri
81ae5caa7e fix(proxy): pass only a team admin's changed fields on to the team update 2026-09-16 16:11:52 -07:00
yassin
acd4f0eb04 fix(spend_tracking): attribute router-rejected requests to the model group provider
A request for a configured model group that the router rejects before picking a deployment (all deployments in cooldown, no healthy deployment) never gets a custom_llm_provider in its logging kwargs. The spend log payload persisted an empty provider, the daily spend tables carried it through, and the Admin UI Usage page rendered those requests under unknown even though every model in the group has a provider

get_logging_payload now takes the proxy router and, when the logged provider is missing, infers it from the model group's deployments. It only attributes when every deployment in the group resolves to the same provider; mixed groups, unknown groups and a missing router leave the value empty as before. Explicitly logged providers keep precedence

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 23:10:47 +00:00
Yujong Lee
3de23e7f18 test(rust_bridge): drop generated OCR route assertions from bridge_route tests
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 23:10:10 +00:00
mateo-berri
610249c663 fix(bedrock): carry the tool_call_id into the rewritten tool call text 2026-09-16 16:08:46 -07:00
ryan-crabbe-berri
8bb4317c75
Merge pull request #41331 from BerriAI/litellm_ui_url_state_foundation
feat(ui): shared URL-state layer for tables and tabs
2026-09-16 16:07:45 -07:00
yuneng-jiang
030901211e
Merge pull request #41360 from BerriAI/litellm_unpin_together_ai_serverless_model
test(together_ai): move request-shape checks to the mapped file, drop the live ones
2026-09-16 16:07:33 -07:00
yuneng-jiang
fddf83a2ac
Merge pull request #41487 from BerriAI/litellm_isolate_generic_api_ndjson_test
test(logging): pick this test's own records out of the shared log batch
2026-09-16 16:06:47 -07:00
ryan-crabbe-berri
be6e7ef173
Merge pull request #41345 from BerriAI/litellm_remove_duplicate_user_budget_hook
fix(proxy): remove duplicate user budget hook that 429'd zero-cost models
2026-09-16 16:06:41 -07:00
Yujong Lee
23c059faba ci: assign chat_completions and messages test dirs to the misc shard
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 23:05:55 +00:00
Yujong Lee
c85acc8d28 test(rust_bridge): cover binding validation, async upstream errors, and OCR preparation failures
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 23:04:38 +00:00
yassin
e2e7f5f879 feat(vertex_ai): stream GCS batch output files from /v1/files/{id}/content
Vertex AI file content retrieval downloaded the whole GCS object into memory
before responding, which made large batch output files (hundreds of MB, image
generation JSONL past 4 GiB) impractical to fetch through the proxy.

Add BaseLLMHTTPHandler.async_retrieve_file_content_streaming, an httpx
stream=True path that hands the byte iterator to the provider config through
the new BaseFilesConfig.transform_file_content_stream hook and closes the
response on completion, early close, and HTTP error. VertexAIFilesConfig peeks
at the first JSONL row: Generate Content batch output is converted to OpenAI
batch format one row at a time (content-length dropped since it changes),
embeddings output stays buffered so fanned-out rows can be regrouped, and
anything else passes through with the upstream content-type and content-length.

vertex_ai joins FILE_CONTENT_STREAMING_PROVIDERS, so the proxy returns a
StreamingResponse for it while OpenAI-compatible providers and the buffered
Vertex path are unchanged.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 23:03:22 +00:00
yucheng-berri
659c4ce5a1
Merge pull request #40669 from BerriAI/litellm_otel_passthrough_trace_propagation
fix(otel): propagate W3C trace context on HTTP and WebSocket passthrough
2026-09-16 16:02:46 -07:00
Yuneng Jiang
939757ceff
Merge remote-tracking branch 'origin/litellm_/buildkite-litellm-e2e-setup-ff714d' into litellm_/buildkite-litellm-e2e-setup-ff714d 2026-09-16 16:02:09 -07:00
mateo-berri
02d9aae8c8 fix(proxy): stop forwarding LiteLLM credential headers on Bedrock agent-runtime passthrough
The agent-runtime branch of /bedrock/{endpoint} (agents, knowledgebases, flows,
retrieveAndGenerate, rerank, generateQuery, optimize-prompt) forwarded every
caller header to AWS next to the SigV4 signature, so a LiteLLM key presented in
x-api-key or x-litellm-api-key reached bedrock-agent-runtime verbatim. Build the
upstream header set explicitly: drop LiteLLM credential headers by name and any
authenticated secret by value, keep the remaining caller headers, and let the
signed headers win on collisions.
2026-09-16 16:01:52 -07:00
Yuneng Jiang
afb28540bb
fix(e2e): keep the CLI determinism test out of the in-cluster suite
It drives the real CLI for several seconds. The edge stamps every
upstream call with PYTEST_CURRENT_TEST, a process-global that names
whichever test the worker is in when the call arrives rather than the one
that made it, so a test that holds a worker that long collects other
tests' in-flight calls. Build 234's key report credits this test with 20
Bedrock and 7 Anthropic misses, and it makes no provider call at all.

Those misattributed calls take the wrong test id into the cache key and
write recordings under it, so the test was polluting the shared corpus it
exists to protect.

Deselected unless E2E_CLI_DETERMINISM is set, the same opt-in shape the
managed-files, prompt-caching and redis-chaos markers already use. The
attribution bug itself is older than this branch and is reported, not
fixed here.
2026-09-16 16:01:32 -07:00
yuneng-jiang
fa35300266
Merge branch 'main' into litellm_/buildkite-litellm-e2e-setup-ff714d 2026-09-16 16:00:45 -07:00
mateo-berri
8045794c37 Merge remote-tracking branch 'origin/main' into litellm_dashscope_reasoning_effort 2026-09-16 15:59:08 -07:00
yuneng-jiang
ceaa0adef8
Merge branch 'main' into litellm_unpin_together_ai_serverless_model 2026-09-16 15:57:17 -07:00
yuneng-jiang
7f83650a41
Merge branch 'main' into litellm_isolate_generic_api_ndjson_test 2026-09-16 15:56:53 -07:00
ryan-crabbe-berri
36eb9cdb35 test(proxy): drop the route-list membership test that the PATCH gate tests already cover 2026-09-16 15:56:27 -07:00
ryan
789b8285bc Merge remote-tracking branch 'origin/main' into litellm_remove_duplicate_user_budget_hook 2026-09-16 22:56:19 +00:00
yuneng-jiang
680233fa8b
Merge pull request #41496 from BerriAI/litellm_/litellm-ci-failure-be9267
fix(prices): dedupe Nova cache_read_input_token_cost keys left by a text merge
2026-09-16 15:56:07 -07:00
Yujong Lee
c635399f6e merge: origin/main into litellm_rust_bridge_declarative_route_catalog
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 22:54:51 +00:00
ryan-crabbe-berri
d29753c521 fix(ui): let another tab's column save replace a toggle this tab could not save
A column toggle that localStorage refused was kept in memory and read ahead of storage, so a later save from another tab stayed hidden until this tab saved again. A storage event now drops the in-memory copy for its key, or all of them when another tab clears storage
2026-09-16 15:51:45 -07:00
ryan-crabbe-berri
adc937c493 fix(ui): read persisted column visibility from storage instead of a mounted copy
usePersistedColumnVisibility kept a useState copy seeded once at mount, so a later tableId or defaults change showed the old table's columns and saved them under the new key. It now reads localStorage through useSyncExternalStore, keeping only writes that storage refused in memory, so the hook has no copy to go stale. Stored choices are layered over the defaults on every read, and changes saved in another tab show up.
2026-09-16 15:51:45 -07:00
ryan-crabbe-berri
4d30bbce45 fix(ui): keep controlled client-side table pages across data reloads
Controlled client-mode DataTables no longer let TanStack reset the page index when rows change, since the owner of the pagination state decides the page. Once rows settle, a page past the end snaps back to the last page, matching server mode
2026-09-16 15:51:45 -07:00
ryan-crabbe-berri
eda81fff59 feat(ui): shared URL-state layer for tables and tabs
Add useUrlTableState (search, sort, page, page size and filter_<column>
in the query string via one nuqs useQueryStates call, with keyPrefix and
urlKeys for routes that host two tables or need legacy key names) and
useUrlTab (validated ?tab= param with a role-aware fallback). Migrate
the Virtual Keys table onto useUrlTableState with a byte-identical URL
contract and bind the Playground tab strip to ?tab=.

DataTable gains controlled columnVisibility/onColumnVisibilityChange
plus usePersistedColumnVisibility (localStorage per table id), and an
isError prop that keeps the server page clamp from rewriting a
deep-linked ?page= after a failed fetch. Virtual Keys uses both.

The expired-session redirect in handleError now keeps the query string
and hash so the return URL captured on re-login restores the filtered
view instead of the bare list.

Delete useTabRouting and tabRoutes, the pathname tab router left over
from the reverted path-per-tab attempt (#34327, reverted in #34629);
tab persistence has to be a query param on the static export.
2026-09-16 15:51:45 -07:00
ryan-crabbe-berri
c37d0a2e66 fix(proxy): read general_settings without a cast and test the /team/update gate by behavior only 2026-09-16 15:51:04 -07:00
kerry
4b70696afa fix(streaming): estimate interrupted Anthropic stream usage from reasoning_content
Interrupted Anthropic streams that die before message_delta were billed at
the message_start placeholder (any value above 1 was trusted) or at 0 when
the partial response was reasoning-only, because the token_counter fallback
only looked at visible text. Reset the placeholder whenever no finish_reason
or second usage event arrived, fold the already-counted reasoning tokens into
the fallback estimate, and drop the stale completion_tokens_details so cost
is computed from the recovered count

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 22:49:25 +00:00
mateo-berri
ebae692a0d refactor(responses): drop the api_base cast and mark the header merge mutable-ok
Some checks failed
Terraform Modules / fmt, validate, test (aws) (push) Has been cancelled
Terraform Modules / fmt, validate, test (gcp) (push) Has been cancelled
LiteLLM Rust / rust-lint (push) Has been cancelled
LiteLLM Rust / rust-test (push) Has been cancelled
LiteLLM Rust / rust-wheel (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 15:45:50 -07:00
Yujong Lee
9617312ab2 add PublicDispatch 2026-09-16 15:44:46 -07:00
ryan
dae16264c1 test(auth): cover over-budget user on zero-cost vs paid model in common_checks
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 15:42:15 -07:00
ryan
287bbaa6c1 fix(proxy): remove duplicate user budget hook that 429'd zero-cost models
_PROXY_MaxBudgetLimiter re-checked spend:user:{id} against user_max_budget in
async_pre_call_hook without the zero-cost model exemption that
_user_max_budget_check applies in auth, so free models were rejected with
"Max budget limit reached." once a user was over budget. Auth already owns
this check, so the hook is deleted rather than taught the exemption again

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 15:42:15 -07:00
ryan-crabbe-berri
cac521246a style(ui): right-align the Save banner button 2026-09-16 15:38:30 -07:00
ryan-crabbe-berri
d9de2fc5f7 style(ui): right-align the team admin editable fields Save button 2026-09-16 15:38:30 -07:00
ryan-crabbe-berri
b92bd98df6 feat(ui): save team admin editable fields from their own card with a Save button
Ticking a field only changes the draft. The allow-list is written when the proxy admin clicks Save, and the card sits next to UI Settings instead of inside its auto-saving toggles.
2026-09-16 15:38:30 -07:00
ryan-crabbe-berri
6e2ae19670 fix(proxy): enforce org budget ceilings on /team/update
update_team loaded the org without its budget row, so the org max_budget,
tpm_limit and rpm_limit checks silently passed. It now loads the budget the
same way /team/new does
2026-09-16 15:38:30 -07:00
ryan-crabbe-berri
a44a58e91a feat(proxy): let team admins edit tpm_limit when a proxy admin enables it
tpm_limit is the first field in the team-admin allow-list registry. The team
settings tab gives a team admin a form with only the enabled fields and sends
only those on save, and UI Settings labels the checkbox the same way
2026-09-16 15:38:30 -07:00
ryan-crabbe-berri
d233043b05 test(proxy): expect team-admin budget changes to stop at the allow-list
max_budget is not a team-admin editable field yet, so the behavior suite now
pins the 403 in both directions instead of the old lower-is-allowed rule
2026-09-16 15:38:30 -07:00
ryan-crabbe-berri
66519da9b6 fix(proxy): report the caller's team edit access on /team/info
The dashboard gated the team settings form on a role it guessed from the
is_* props, the members list and the org list. The org list is premium
gated and empty while loading, so a team admin who is also an org admin
was told team admins cannot edit, although /team/update accepts them as
an org admin

/team/info now returns caller_edit_access, resolved by the same helper
/team/update uses, and TeamInfo keys the form and the toast off that
field. The org list is only read for the organization dropdown now, and
general_settings is read through one validated accessor in both handlers
2026-09-16 15:38:30 -07:00
ryan-crabbe-berri
50f890d02d fix(proxy): keep the team-admin field allow-list importable on python 3.10
assert_never landed in typing in 3.11, so importing it from typing broke the
3.10 import smoke job and the py310 typing gate. Take it from typing_extensions
like the rest of the proxy does.

Also drop /team/update from test_neighbouring_team_routes_stay_closed. The route
is self-managed now, so the coarse gate admits the caller and update_team decides,
which the sibling test in the same file already asserts.

Claude-Session: https://claude.ai/code/session_018PUCupsaarVLJy4iDFx256
2026-09-16 15:38:06 -07:00
ryan-crabbe-berri
af0312ba8f refactor(ui): name the admin checks behind the team-admin edit branch
The five-condition chain pushed local/no-long-condition-chain one over its
ceiling and failed the dashboard lint gate.

Claude-Session: https://claude.ai/code/session_018PUCupsaarVLJy4iDFx256
2026-09-16 15:38:06 -07:00
ryan-crabbe-berri
ac47c95db9 fix(proxy): re-read UI settings on every config reload
The persisted UI settings were read once at startup, so a proxy admin
flipping a runtime flag through PATCH /update/ui_settings only changed the
pod that served the request. Every other pod kept serving the old value
until it restarted.

add_deployment, the reload the scheduler runs every 30s, now re-reads the
row and applies the runtime flags before it takes the model reconcile lock,
so a change made through one pod reaches the rest within one reload
interval. The startup hook and the two settings endpoints share that helper
instead of each repeating the flag copy.

Claude-Session: https://claude.ai/code/session_018PUCupsaarVLJy4iDFx256
2026-09-16 15:38:06 -07:00
ryan-crabbe-berri
9b77b5c2cb feat(proxy): let proxy admins choose which team fields team admins may edit
Team admins could never reach POST /team/update: the route gate answered
401 before the handler's team-admin branch ran. This moves /team/update
into the self-managed routes, resolves proxy admin, org admin or team
admin inside the handler, and filters team admins through a new
proxy-wide UI setting, team_admin_editable_team_fields. The setting is
an allow-list of team fields. Empty means team admins cannot edit team
settings and get a 403 pointing at the proxy admin, and changing a field
outside the list fails 403 naming that field. Only values that differ
from what is stored count, since the dashboard resends the whole form.

The registry of fields the setting accepts ships empty on purpose. Each
field lands in its own follow-up PR with its value diff and dashboard
wiring. The Admin UI gains a "Team admin editable fields" section under
Settings > UI and a toast on the team page while editing is disabled.

Refs LIT-5722

Claude-Session: https://claude.ai/code/session_01A6SkwJdfZUmkzfUkrEkqX8
2026-09-16 15:38:06 -07:00
Yuneng Jiang
b9751a38ab
Revert "fix(prices): dedupe Nova cache_read_input_token_cost keys left by a text merge"
This reverts commit a9fc6d255b.
2026-09-16 15:36:54 -07:00
ryan-crabbe-berri
9357491f91
Merge pull request #35418 from BerriAI/litellm_skills_ssh_sources
feat(ui): accept ssh clone urls when registering a skill
2026-09-16 15:36:18 -07:00
yucheng
62b69294c1 test(utils): build the rewritten hook response without in-place mutation
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 22:34:52 +00:00