Commit graph

1855 commits

Author SHA1 Message Date
Devin AI
9529dff700 refactor(auth): move final budget lookup decisions into Rust 2026-11-09 01:14:37 +00:00
Devin AI
1b2d5a3f04 Preserve lazy configured-route classification in native auth 2026-11-09 00:54:39 +00:00
Devin AI
a7d198f673 Select model budget scope reads and wire enterprise route policy 2026-11-09 00:53:25 +00:00
Devin AI
ca42107a42 test(auth): freeze independent Phase 1 budget references 2026-11-09 00:39:23 +00:00
Devin AI
ceab6a0b6c Stage registry reads and optional route enablement in native auth 2026-11-09 00:38:20 +00:00
Devin AI
e4a9b7a877 Wire native managed model and route policy into shared auth flows 2026-11-09 00:36:44 +00:00
Devin AI
3e8b949238 feat(auth): move role and JWT route selection into native decisions 2026-11-09 00:26:52 +00:00
Devin AI
342848ec81 Stage managed model scopes and team alias resolution in native auth 2026-11-09 00:26:10 +00:00
Devin AI
7b076b140b refactor: move spend counter admission policy into Rust 2026-11-09 00:25:33 +00:00
Devin AI
9ab8927be2 refactor: stage personal model listings and agent ceilings in native policy 2026-11-09 00:03:19 +00:00
Devin AI
12dc0f3c69 fix(auth): preserve budget model and spend read projections 2026-11-09 00:02:37 +00:00
Devin AI
c65385eaf9 refactor(auth): integrate native end-user and lazy common policy reads 2026-11-09 00:02:37 +00:00
Devin AI
deb365d39f refactor(auth): move end-user defaults and identity stages into Rust 2026-11-08 23:45:20 +00:00
Devin AI
85d98f0adf feat(auth): stage resolved model scopes and member grant reads 2026-11-08 23:42:14 +00:00
Devin AI
749ab0aa04 refactor(auth): integrate native budget context and reservation member limits 2026-11-08 23:41:48 +00:00
Devin AI
e55f54b825 feat(auth): stage team overrides and personal owner model requests 2026-11-08 23:39:25 +00:00
Devin AI
edc45d1319 refactor(auth): move budget context selection into native stages 2026-11-08 23:32:24 +00:00
Devin AI
0c3aab84eb feat(auth): stage personal team budgets and model grants in native policy 2026-11-08 23:30:59 +00:00
Devin AI
d3cec75e42 refactor(auth): select common checks and reservation targets in Rust 2026-11-08 23:30:18 +00:00
Devin AI
d2598e5b1c feat(auth): stage native fallback candidate and attribution policy 2026-11-08 23:14:19 +00:00
Devin AI
8943507cc8 refactor(auth): move budget alert planning into native policy 2026-11-08 23:13:58 +00:00
Devin AI
93834233cf refactor: stage raw auth effects and managed grant decisions in Rust 2026-11-08 23:13:20 +00:00
Devin AI
a47c0a0c10 fix(auth): preserve user model precheck order 2026-11-08 22:53:13 +00:00
Devin AI
4b210e4b65 feat(auth): stage native model access and pricing reads 2026-11-08 22:53:13 +00:00
Devin AI
39a8729d50 refactor(auth): drive model limits and exemption reads through native facts 2026-11-08 22:41:46 +00:00
Devin AI
cad362a398 refactor(auth): port model and route policy to native decisions 2026-11-08 22:37:24 +00:00
Devin AI
b27761d08b feat(auth): add native common and model budget policy boundaries 2026-11-08 22:32:27 +00:00
Devin AI
298381a26d refactor(auth): move access and admission decisions into Rust 2026-11-08 22:32:05 +00:00
Devin AI
8bd7f5089a refactor(auth): run Phase 1 decisions in a pure Rust core 2026-11-08 22:08:24 +00:00
Yujong Lee
54122b4d89 refactor(auth): decide the team member per-model budget fallback in AuthCore
The core now decides when an over-budget team member may fall back and walks
the router's fallback targets in order, skipping the requested model, through
its own TeamMemberStep and driver. The proxy handler only reads the targets
and vets each one, so _try_team_member_model_budget_fallback and its
per-model helper are gone

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 15:10:10 +09:00
Yujong Lee
84851bc75f refactor(auth): decide key and user per-model budgets in AuthCore
The core now owns which models get checked, when an over-budget key may fall
back to its budget_fallbacks, and that the user check sees the rerouted model.
The virtual-key chain runs it inline, custom auth through check_model_budgets
and JWT through check_user_model_budgets, so the three paths share one walk.
A budget refusal is now a ModelBudgetExceeded denial that the proxy turns back
into the same BudgetExceededError

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 14:57:10 +09:00
Yujong Lee
87a1064e90 refactor(auth): finish the virtual-key decision chain in AuthCore
The core now decides the soft budget alert, when per-model budgets run, the
team and project context load, the proxy budget alert and the missing-token
denial, so the builder only projects the grant. One projection serves both
the request builder and internal jobs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 09:52:33 +09:00
Yujong Lee
08fbc4ac4c refactor(auth): decide key budget checks in AuthCore
The key checks that ran first in validate_resolved_virtual_key now run in
the Python core, in the same order: blocked key, model access, deactivated
owner, budget exemption, team member budget, expiry, budget alerts and the
key's own max budget or throttle. Lookups, counters and alerts are effects
the proxy answers, and internal jobs run the same checks through
start_resolved_key.

The soft budget, per-model budgets and the team, project and global spend
lookups stay in _finish_virtual_key_auth for a later pass. The source-shape
tests now read the functions that replaced validate_resolved_virtual_key

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 08:31:36 +09:00
Yujong Lee
8683d4a77e refactor(auth): resolve virtual keys through AuthCore effects
The Python core now decides the whole virtual key resolution path. It asks
the proxy to resolve the end user, the presented key (preresolved, cached or
UI login), evict an expired cached admin key and load an uncached key from
the DB, each as a typed effect with its own continuation. It decides the
admin key expiry, master-key-only routes, the no-DB case and the sk- prefix
check itself, so the builder no longer has a legacy fallback.

The budget and team checks in validate_resolved_virtual_key still run after
Allow(VirtualKey) and move into the core in later passes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 07:58:45 +09:00
Yujong Lee
4b5b3abfce refactor(auth): decide credential and master key auth through a pure AuthCore
Add the AuthCore interface in litellm._auth and a Python core that decides
the no-master-key, missing key, malformed key, /user/auth and master key
cases. Everything else defers to the legacy builder. The builder projects
the outcome into UserAPIKeyAuth or the existing error contract, and the
end-user resolution it shared with the master key path is extracted.

A master key request no longer inherits end-user limits from an earlier
master key request, since the master key is no longer read back from the
key cache

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 07:38:04 +09:00
Yujong Lee
6b3ee11810 refactor(auth): extract credential selection into litellm._auth
Move scheme stripping, key-source precedence, websocket key selection,
hash_token and is_master_key into litellm/_auth as the interface the Rust
auth port will mirror. Authorization schemes now match case-insensitively
like FastAPI's HTTPBearer. Pass-through endpoint keys join the precedence
table instead of a separate fallback, and the dead custom-header helper
plus the duplicated hash_token and is_master_key bodies are gone
2026-11-06 07:14:51 +09:00
yucheng-berri
ff2709f5c3
fix(zscaler_ai_guard)!: scan only the last user turn on requests (#50139)
* fix(zscaler_ai_guard): scan only the last user turn on requests

* fix(zscaler_ai_guard): keep scanning A2A requests and refuse scan_only_tool_results

* fix(zscaler_ai_guard): join the last user turn's text parts with spaces like before

* fix(zscaler_ai_guard): keep scanning tool results when scan_only_tool_results is set

* fix(zscaler_ai_guard): scan the latest user turn when assistant or tool messages follow it

* fix(zscaler_ai_guard): skip the scan when the latest user turn is only whitespace

A blank latest user turn was sent to Zscaler on its own, which answers
Content is empty, so the proxy returned 500 where main returned 200

---------

Co-authored-by: Arnav Maiti <amaiti@zscaler.com>
2026-11-05 13:00:21 -08:00
ryan-crabbe-berri
f069da8e0e
fix(anthropic): report temperature/top_p as supported only when the model keeps them (#50144)
* fix(anthropic): report temperature/top_p as supported only when the model keeps them

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

* test(vertex_ai): accept the generic unsupported-param message for Claude batch rows

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-11-05 12:38:58 -08:00
devin-ai-integration[bot]
89cc395a88
feat(gemini): add Omni 1.2 Flash pricing and update video model successors (#50229) 2026-11-05 18:42:29 +00:00
Nate Armstrong
067f93340f
refactor(router): delete the python router core, the rust core is the only core (#50178) 2026-11-05 10:40:46 -08:00
joshua-berri
85bc58085e
fix(accounting): keep spend commits working when prometheus_client is not installed (#50230)
* fix(accounting): keep spend commits working when prometheus_client is not installed

The delivery worker imported the ledger metrics module, which imported
prometheus_client at module level. update_database imports the worker
outside its try block, so installs without the proxy-runtime extra failed
every spend commit. The metrics now register only when prometheus_client
is importable and are skipped otherwise

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* style(accounting): note why prometheus_client can be missing

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Joshua Valluru <326636767+joshua-berri@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 10:35:26 -08:00
Kerry Lu
f25fff42a6
fix(openai): never send OPENAI_ADMIN_KEY as the bearer token for a deployment without an api_key (#50218)
* fix(openai): authenticate raw chat requests with the deployment api_key only, never OPENAI_ADMIN_KEY

openai 3.x request options default to bearer_auth plus admin_api_key_auth, so a deployment whose api_key is empty sent Authorization: Bearer <OPENAI_ADMIN_KEY> to its api_base. Pass security={"bearer_auth": True} when the installed SDK's make_request_options accepts it (openai 2.x has no admin key fallback and no security kwarg)

* test(openai): assert the admin key never reaches the wire whether the SDK sends unsigned or refuses

---------

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-11-05 09:58:42 -08:00
Mateo Wang
88ea40e69c
fix(github-copilot): send the GitHub token directly instead of exchanging it (#50126)
* fix(github-copilot): use GitHub token directly

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

* fix(github-copilot): expire API base cache

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

* test(github-copilot): restore authenticator coverage

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

* fix(github-copilot): update direct token auth tests

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

* fix(github-copilot): cover direct-token error paths

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

* fix(github-copilot): satisfy type-discipline gate

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-11-05 09:45:17 -08:00
tessellark
f357872c98
test(integration): stop the wire peer from dropping requests whose bytes arrive late (#49889)
* test(integration): stop the wire peer from dropping requests whose bytes arrive late

The scripted wire peer set a fixed 5 s socket timeout, so a request whose
bytes reached it late on a loaded rig was dropped with no reply and the
proxy answered 500 Server disconnected. Remove the timeout and, at
teardown, stop reading on every accepted connection so idle handlers exit
at once. A request still arriving when teardown starts never reaches the
test's respond callback.

* fix(tests): bound wire peer teardown on unread replies and answer complete requests

* fix(tests): poll wire peer reads so teardown keeps queued requests and only cuts stuck calls

* fix(tests): write wire peer replies in pieces so teardown never cuts a client still reading

* fix(tests): give a wire peer reply the whole teardown grace when its write blocked before teardown

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-11-05 09:24:05 -08:00
joshua-berri
a12a6cd154
feat(accounting)!: make the SpendLogs ledger the default accounting path (#49872)
* fix(accounting): keep one undecodable delivery from blocking the ledger

A request whose metadata carried a 401-digit tokens_saved stored that number in
its delivery payload. The query engine could not decode it when the worker
claimed the batch, so every later delivery on the proxy stayed pending

The worker now claims the payload as text and decodes each row in Python. A row
that still cannot be decoded is parked alone while the rest of the batch
applies. The payload builder also clamps integers to the JSON-safe range, so
caller-supplied counts can no longer reach the engine at that size

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(accounting): take spend locks in one order so the ledger cannot deadlock

A ledger delivery updates many spend tables in one transaction, so it can
deadlock with any writer that locks the same rows in another order. It took the
team advisory lock after the user and team rows, while team roster writers take
it first

The delivery now takes every team advisory lock before any row, then writes
tables in one canonical order with ids sorted. It also runs under the rollup
lock_timeout, applies 500 deliveries per batch by default, and spreads retries
with jitter

The writers that could still collide with it now follow the same order. The
budget reset cascade, model allowlist rename, global spend reset, bulk user
update, org delete and the delete-by-list paths lock their rows in key order
first, and access group endpoints update teams and keys in one sorted pass

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(accounting): prove a ledger delivery waits instead of deadlocking

Real Postgres tests hold the first lock of a team roster change, an access group
update and a budget reset cascade, start a delivery, and let the other writer
finish. The delivery must wait and then charge once. Before the lock order fix
each case ends in a Postgres deadlock

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(accounting)!: make the SpendLogs ledger the default accounting path

use_spend_logs_ledger now defaults to true, so every request is charged through
LiteLLM_SpendLogDelivery. Setting it to false rolls back to the in-memory and
Redis spend queues, which stay in place. Tests that cover those legacy writers
pin the setting off, and the rest check the queued charge the ledger stores

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(proxy): let the mocked client open a transaction for key and team deletes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(proxy): take team locks first when a model rename rewrites allowlists

A rename locked team rows before user rows while a roster change holds the team
advisory lock and a user row, so the two could deadlock. The rename now takes the
advisory lock for every team that lists the model, sorted, before any row lock.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(accounting): drain a backlog in one worker run, one batch per transaction

One run applied a single fresh batch, so at 500 per batch charges fell behind any
load above that rate. The worker now keeps claiming fresh batches while they come
back full, for up to five seconds, and each batch still commits on its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(accounting): queue only the charge when a request's spend log is suppressed

With logging off for a request, the ledger still queued the full row, so a failed
flush or a shutdown could leave its prompt and response in Redis. The queue now
holds only the fields the charge needs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* style(proxy): format the rename team listing query

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(accounting): remove expired delivery receipts as fast as the worker applies them

The worker now applies several batches per run but still removed one cleanup batch
of applied receipts, so the table could outgrow its retention window. Cleanup now
repeats while each pass removes a full batch, for up to five seconds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(proxy): retry a model rename when a team starts listing the model mid-lock

The team advisory locks come from a snapshot, so a team that gained the old name
before its row lock was locked without its advisory lock. That attempt now commits
without writing and the next one locks the fresh set of teams.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Joshua Valluru <326636767+joshua-berri@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 09:14:10 -08:00
tin-berri
aa7917a3d2
feat(skills): show download counts and downloader history (#50165) 2026-11-05 05:25:08 -08:00
tin-berri
79e63d3e06
feat(skills): add optional manual security scans (#50194) 2026-11-05 01:57:39 -08:00
ishaan-j-berri
639625d679
fix(usage): restore per-user spend breakdown on the user aggregated route (#49464)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-11-05 01:57:23 -08:00
tin-berri
7e4ad6eb33
feat(skills)!: add portable submissions and admin review (#50160) 2026-11-05 00:56:51 -08:00
tin-berri
0ad5d750d4
feat(skills)!: version published Skills Hub updates (#50152) 2026-11-05 00:19:38 -08:00