Commit graph

45043 commits

Author SHA1 Message Date
mateo-berri
ae2a5e1472 fix(ui): distinguish hosted and local vLLM in the provider dropdown 2026-08-14 13:39:37 -07:00
Scott Wilson
4c49d03732 fix(anthropic): preserve optional Responses tool properties
Translating Anthropic tools left the outbound function-tool `strict` unset,
which the Responses API does not read as non-strict. OpenAI's function-calling
docs say strict mode requires every field in `properties` to be marked
required, and with `strict` omitted the schema gets normalized to satisfy that
instead of being rejected. What users see is a tool whose `required` lists
every property, so models fill optional Anthropic tool arguments with empty
values. Send `strict` explicitly so an unset value stays non-strict and an
explicit `strict: true` still reaches the provider

On the Chat Completions adapter, `strict` was also missing from
`mapped_tool_params`, so a tool-level `strict` was merged into the OpenAI
function `parameters` schema (mutating the caller's `input_schema` along the
way) instead of being set on the function. Map it to `function.strict` and
leave it unset when the caller omits it, since Chat Completions already
defaults to non-strict
2026-08-14 16:19:45 -04:00
Shifat Islam Santo
4cd1c81a2d fix: add supports_mid_conversation_system to bare first-party Claude cost-map keys 2026-08-14 14:53:11 -05:00
Shifat Islam Santo
1b5e50727c fix: reuse block builder for lint budget, assert unflagged cache e2e 2026-08-14 14:40:10 -05:00
Shifat Islam Santo
658c67c152 fix: preserve prompt cache for mid-conversation system on unflagged Claude models 2026-08-14 14:19:48 -05:00
shivam
3838969527 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_fix_redis_spend_buffer_requeue_33872 2026-08-14 19:07:19 +00:00
yuneng-jiang
f03df1bb42
Merge pull request #36966 from BerriAI/litellm_shadcn_smallfiles_0814
refactor(ui): migrate ten small dashboard files off antd and tremor
2026-08-14 11:50:56 -07:00
yuneng-jiang
e659147aee
Merge pull request #36964 from BerriAI/litellm_/cranky-jepsen-f831e1
refactor(ui): move MCP permission panels onto shadcn primitives
2026-08-14 11:50:42 -07:00
Fahima Mokhtari
b9d2fd0ee9
fix(exception_mapping): bare 429 in an error body no longer outranks the status code (#36705)
is_error_str_rate_limit treats any standalone 429 in the stringified exception as
a rate limit, and for openai-compatible providers that check runs before the
status-code branch. Providers echo the request back in validation errors, so a
400 whose body happens to contain a 429 comes out as RateLimitError.

Tokenised prompts hit this routinely, since 429 is an ordinary token id (" that"
in several tokenisers) and an echoed prompt_token_ids array is enough:

  {"error":{"message":"`tools` must not be an empty array",
            "type":"invalid_request_error","code":400},
   "prompt_token_ids":[9906,429,1234]}

The mislabel is not cosmetic. RateLimitError tells callers and routers to retry,
so a request that cannot succeed gets replayed, and the failure is booked against
provider throttling rather than the caller. Against DeepInfra, one recurring 400
("`tools` must not be an empty array") came back as a rate limit in 77 of 198
occurrences, the split depending only on whether the echoed prompt contained 429.

16482 narrowed '"429" in error_str' to \b429\b after a false positive on
'asbjdad429addad'. Word boundaries cannot separate a real 429 from a token id, so
the same class of false positive survives.

is_error_str_rate_limit now takes an optional status_code, and the bare-number
branch fires only when no explicit status contradicts it. The status is read off
an arbitrary exception, so a non-integer is treated as unknown and left to the
existing behaviour. The repo has a single call site.

The phrase branches are untouched, so a provider reporting a real rate limit in
the message text under a non-429 status still maps to RateLimitError (11455).
This is not "status code wins".

Tests cover the matcher (suppressed under a 400; still detected with no status,
None, 429, or a non-integer status; phrase honoured under a 400) and
exception_type end to end (400 with 429 in the echoed body -> BadRequestError,
real 429 -> RateLimitError). Reverting the source change fails the latter.
2026-08-14 11:39:35 -07:00
Fahima Mokhtari
e1ef7775bd
fix(main): an explicit provider outranks a known OpenAI model name (#36800)
* fix(main): an explicit provider outranks a known OpenAI model name

completion() picks the OpenAI handler whenever `model in
litellm.open_ai_chat_completion_models`, and that clause is evaluated before the
gemini and vertex_ai branches. get_llm_provider() already resolves those names
to "openai", so the clause only adds anything when the provider is something
else, and then it silently overrides it: the config built for the requested
provider is handed to the OpenAI handler.

For gemini that is fatal. VertexGeminiConfig.transform_request raises
NotImplementedError by design, since Vertex builds its request in its own
handler, so `gemini/gpt-4o` dies in async_transform_request before anything is
sent. register_model() reaches the same state without an odd model id: an entry
claiming litellm_provider "openai" adds its name to
open_ai_chat_completion_models, so one mislabelled pricing entry reroutes every
later call to that model in the process.

The name clause now applies only when no other provider was resolved.

* test(main): move the routing regression into the mapped test file

CLAUDE.md asks bug fixes to extend the mapped test file, so these belong in
tests/test_litellm/test_main.py rather than a module of their own.

They also no longer swap out the provider handler objects. Both Gemini cases
inject an HTTPHandler whose post() answers like generativelanguage does, then
assert the URL the request went to and read the reply back; the OpenAI case
injects an OpenAI client and patches its own raw-response create. That asserts
the endpoint the call reaches instead of which attribute the test replaced, and
matches the neighbouring tests in the file.
2026-08-14 11:39:02 -07:00
Yuneng Jiang
c51c5f1821
refactor(ui): drop narration comments from the MCP permission panels 2026-08-14 11:24:47 -07:00
Yuneng Jiang
538f5b3e84
refactor(ui): drop explanatory comments from the migration tests 2026-08-14 11:21:01 -07:00
yuneng-jiang
2bc9bb4a9d
Merge pull request #36962 from BerriAI/litellm_shadcn_daterange_type_0814
refactor(ui): declare DateRangePickerValue locally instead of importing it from tremor
2026-08-14 11:16:08 -07:00
yuneng-jiang
387ad0bb4f
Merge pull request #36960 from BerriAI/litellm_cost_tracking_removal_pending_state
fix(ui): keep the cost tracking removal confirmation open until it settles
2026-08-14 11:15:53 -07:00
Yuneng Jiang
aa093980b1
refactor(ui): migrate ten small dashboard files off antd and tremor
Moves the onboarding views, router settings inputs, tag rate limit editor,
fallback buttons, created-key display and the shared numerical input onto the
in-repo shadcn layer. Each control has a direct equivalent, so this is a
like-for-like swap with no layout changes and no new styling.

Router settings saves by reading input values straight off the DOM with
document.querySelector('input[name="..."]'), a path no test covered. Adds a
regression test that types into a field and asserts the typed value reaches
the payload, so the name attribute contract stays enforced.

Also adds tests for TagRateLimitEditor, which had none and whose RPM cell
switched from antd InputNumber to a native number input.
2026-08-14 11:15:30 -07:00
abhinav
1241bd5ce1 feat(proxy): add per-component response cost headers
- Extract input_cost, output_cost, cache_read_cost, cache_creation_cost, reasoning_cost, and tool_usage_cost from logging object cost breakdown
- Populate x-litellm-response-cost-* component headers in ProxyBaseLLMRequestProcessing.get_custom_headers
- Ensure headers are omitted when cost breakdown is absent or values are None
- Add comprehensive test suite covering component headers, math invariants, caching, reasoning, and discounts/margins
2026-08-14 23:43:04 +05:30
Yuneng Jiang
caf305f732
refactor(ui): move MCP permission panels onto shadcn primitives
Replaces antd Radio, Checkbox and Tooltip, plus Tremor Text and Badge,
with the in-repo shadcn equivalents across the three MCP permission
panels, and drops the no-restricted-imports suppressions they no longer
need. Also removes the stale suppression on settings.test.tsx, which
imports neither library.

The tool rows keep their existing click-to-toggle behaviour: the row
owns the toggle and the checkbox no longer carries its own change
handler, since Base UI replays the click through a hidden input that
reaches the row on its own.

Adds payload-level tests for the risk-group view covering group clear,
mixed-state re-arm, single-tool toggles from both the box and the row,
and a controlled round trip proving each control re-renders from the
permissions it emitted.
2026-08-14 11:08:09 -07:00
Yuneng Jiang
fe61fa12e4
refactor(ui): declare DateRangePickerValue locally instead of importing it from tremor
DateRangePickerValue is a plain object shape, not a component, so the
twelve files that used it were each carrying a no-restricted-imports
suppression for a type that tremor declares as
{ from?: Date; to?: Date; selectValue?: string }.

Declare that shape in components/shared/date_picker_types.ts and point
every consumer at it, which drops ten suppressions from the baseline.
advanced_date_picker and usage_date_picker keep their tremor imports:
they still render tremor Button, Text and DateRangePicker, and moving
DateRangePicker itself needs react-day-picker.
2026-08-14 11:01:43 -07:00
Shivi Jain
2b23295f82 fix(proxy): reconcile project quota reservations 2026-08-14 23:31:18 +05:30
Yuneng Jiang
7da8a3bef5
test(ui): build the deferred removal with Promise.withResolvers
The pending-state test seeded its deferred promise by declaring the resolver
with let and reassigning it inside the executor. Promise.withResolvers is the
standard way to get the same handle without the reassignment, and the
assertions are unchanged.
2026-08-14 10:43:15 -07:00
Daniel Meismer
2fabfd7eef Merge upstream/litellm_internal_staging into litellm_searchable_usage_report_user_filter
Resolve the usage-filter conflicts by reusing upstream's PaginatedSearchSelect for User Usage while preserving server-side search, pagination, loading, and no-results behavior.

Generated with AI

Co-Authored-By: Codex
2026-08-14 13:43:02 -04:00
Yuneng Jiang
62b072dcf7
Merge branch 'litellm_internal_staging' into litellm_cost_tracking_removal_pending_state 2026-08-14 10:33:53 -07:00
Yuneng Jiang
4974290d3f
fix(ui): keep the cost tracking removal confirmation open until it settles
The discount and margin removal confirmation used AlertDialogAction, which
renders AlertDialogPrimitive.Close and dismisses the dialog on click. The
dialog therefore disappeared while the removal request was still in flight,
leaving the admin with no sign that anything happened and free to fire a
duplicate removal.

Swap the confirm control for a plain destructive Button, track an isRemoving
pending state that disables Cancel and relabels Remove to "Removing...", and
clear the pending removal in a finally block once the request settles.
2026-08-14 10:33:27 -07:00
yuneng-jiang
c9917cbf99
Merge pull request #36918 from BerriAI/litellm_shadcn_modelhub_0814
refactor(ui): move the model hub and model select onto shadcn primitives
2026-08-14 10:33:24 -07:00
yuneng-jiang
5156bf04b6
Merge pull request #36915 from BerriAI/litellm_shadcn_settings_0814
refactor(ui): migrate router settings and shared badges off antd and tremor
2026-08-14 10:28:02 -07:00
Armaan Sandhu
e1f3d6e158
feat(proxy): serve Anthropic-native /v1/models for Claude Code gateway discovery (#35455)
* feat(proxy): serve Anthropic-native /v1/models for Claude Code gateway discovery

* refactor(proxy): move Anthropic model-list formatter into llms/anthropic/common_utils

* fix(proxy): make model_list request param optional for direct callers

* style: apply ruff format to changed lines

* style: satisfy ruff strict-rule budget (UP006, I001)

* style: satisfy type-discipline budget (LIT002 mutable-ok, LIT009 pyright ignore)

* style: satisfy LIT001/LIT010 and drop explanatory comment per contributor rules

* fix(proxy): translate team model names in the Anthropic /v1/models response

* ci: trigger buildkite status report

* feat(proxy): carry token limits into the Anthropic-native /v1/models entries

* fix(proxy): cast the injected request so the anthropic-version guard is a real comparison

* fix(proxy): explain the model listing casts so the type-discipline gate passes

---------

Co-authored-by: yuneng-jiang <yuneng@berri.ai>
Co-authored-by: Yassin Kortam <yassin@berri.ai>
2026-08-14 10:22:58 -07:00
yuneng-jiang
3d35cff9f5
Merge pull request #36913 from BerriAI/litellm_shadcn_permissions_0814
refactor(ui): migrate key info and permissions views off antd and tremor
2026-08-14 10:15:28 -07:00
yuneng-jiang
10df18be66
Merge pull request #36910 from BerriAI/litellm_shadcn_common_0814
refactor(ui): migrate shared common_components off antd and tremor
2026-08-14 10:11:52 -07:00
yuneng-jiang
609ecf06c2
Merge pull request #36866 from BerriAI/litellm_/remove-test-migrate-gha-d1eae8
ci: drop the duplicate proxy_unit_tests letter-shard workflow
2026-08-14 10:11:08 -07:00
Yuneng Jiang
693683c013
Merge branch 'litellm_internal_staging' into litellm_shadcn_modelhub_0814 2026-08-14 09:59:57 -07:00
Yuneng Jiang
30c1b972d4
Merge branch 'litellm_internal_staging' into litellm_shadcn_settings_0814 2026-08-14 09:59:20 -07:00
Yuneng Jiang
e897e2b0aa
Merge branch 'litellm_internal_staging' into litellm_shadcn_permissions_0814 2026-08-14 09:59:12 -07:00
Yuneng Jiang
da339a7e8a
Merge branch 'litellm_internal_staging' into litellm_shadcn_common_0814 2026-08-14 09:57:34 -07:00
Yuneng Jiang
7e375ed6e8 chore: retrigger e2e gate 2026-08-14 09:48:49 -07:00
yuneng-jiang
b77923fc87
Merge pull request #36955 from BerriAI/litellm_shadcn_next_0814
refactor(ui): move the cost tracking components onto shadcn primitives
2026-08-14 09:46:30 -07:00
yuneng-jiang
48a3423aed
Merge pull request #36936 from BerriAI/litellm_shadcn_rootbig_0814
refactor(ui): move the settings page and bulk user invite onto shadcn primitives
2026-08-14 09:41:07 -07:00
yuneng-jiang
8c168177ec
Merge pull request #36927 from BerriAI/litellm_shadcn_rootcomponents_0814
refactor(ui): move the root-level dashboard components onto shadcn primitives
2026-08-14 09:40:54 -07:00
yuneng-jiang
cb33d204f4
Merge pull request #36924 from BerriAI/litellm_shadcn_dropdowns_0814
refactor(ui): move the shared dropdowns and selectors onto shadcn primitives
2026-08-14 09:40:49 -07:00
yuneng-jiang
de57ebbad9
Merge pull request #36908 from BerriAI/litellm_shadcn_aihub_0814
refactor(ui): migrate AI Hub off antd and tremor to shadcn
2026-08-14 09:39:00 -07:00
yuneng-jiang
5ab91b3f07
Merge pull request #36904 from BerriAI/litellm_shadcn_viewlogs_0814
refactor(ui): migrate log details drawer off antd to shadcn
2026-08-14 09:38:51 -07:00
yuneng-jiang
5374e0b0c7
Merge pull request #36902 from BerriAI/litellm_shadcn_navbar_0814
refactor(ui): migrate Navbar off antd to shadcn
2026-08-14 09:36:38 -07:00
Yuneng Jiang
035f8d5f8a
refactor(ui): move the cost tracking components onto shadcn primitives
Rebuilds the provider discount and margin tables, the pricing calculator and
its multi-cost results on the in-repo shadcn layer, and swaps the imperative
antd modal.confirm removals for AlertDialog. Row actions gained accessible
names, which replace the Tremor stub mocks the tests used to drive.
cost_tracking_settings keeps its two antd Modals and Forms, since they wrap
the two add forms that stay on antd for now.
2026-08-14 09:36:16 -07:00
Shivi Jain
312d12fe0c fix(proxy): enforce project ITPM/OTPM quota on every Responses WebSocket frame
The connection-level pre-call hook only ran once per WebSocket
connection, so a project caller could send unlimited high-token
response.create frames after a single minimal reservation. Adds
enforce_project_io_token_quota_for_frame to the v3 rate limiter and
wires it into both the native and managed WebSocket handlers via a
duck-typed litellm.callbacks lookup, so the SDK layer stays free of
proxy imports. A rejected frame gets an error event; the connection
stays open for the client to retry.

Also fixes the RET504 and BLE001 strict-lint-budget violations the
litellm_internal_staging merge introduced in
parallel_request_limiter_v3.py, which were failing the lint check.
2026-08-14 21:39:34 +05:30
pokepoke81
732e23a4f9
Remove comment about prompt-cache usage in test
Remove outdated comment regarding prompt-cache counts in chunk_parser.
2026-08-14 11:24:30 -04:00
Shivi Jain
a9227057a1 Resolving merge conflicts and verai comment for batch 2026-08-14 20:52:05 +05:30
Yuneng Jiang
3170fff768
refactor(ui): move the settings page and bulk user invite onto shadcn primitives
Rebuilds settings.tsx and bulk_create_users_button.tsx on the in-repo shadcn
layer. The settings callback form moves from antd Form to react-hook-form with
the shared Field primitives, and the CSV drop zone replaces antd Upload with a
native file input plus drag handlers. Both public prop signatures are
unchanged, so no caller moves.
2026-08-14 07:49:33 -07:00
pokepoke81
ce66cbce0e fix(databricks): surface prompt-cache token counts in streaming usage
chunk_parser built ModelResponseStream without passing usage, so the
cache_read_input_tokens and cache_creation_input_tokens that Databricks
returns for Anthropic models never reached the cost calculator. Every
streamed request was billed at the full input rate even when served
from cache.

ModelResponseStream already coerces a usage dict into Usage, which maps
those keys into prompt_tokens_details, so passing the chunk's usage
through is sufficient.
2026-08-14 10:45:21 -04:00
Yuneng Jiang
4544f7dbad
revert(ui): keep the onboarding link modal on antd
The invitation dialog opens over the still-antd Invite User modal. Lifting
only the shadcn dialog content above antd's mask leaves its own backdrop
underneath, so an outside click reaches the wrong modal. Adding a second
backdrop stops that but does not restore dismissal, and the same hazard
already ships in three guardrails modals, so the stacking needs one shared
fix rather than a fourth local workaround.
2026-08-14 07:10:13 -07:00
Yuneng Jiang
15a331f6df
refactor(ui): move the root-level dashboard components onto shadcn primitives
Rebuilds nine components under src/components on the in-repo shadcn layer:
both banners, the navbar chrome, the onboarding link dialog, the model
filters, the model group alias table, the object permissions and logging
settings views, and the user dashboard grid. Every public prop signature is
unchanged, so no caller moves.
2026-08-14 06:52:06 -07:00
Yuneng Jiang
362875a7e6
fix(ui): hold the delete dialog open mid-deletion and keep unmatched select values
DeleteResourceModal let escape, the backdrop and the close button dismiss it
while the delete request was still in flight. SearchSelect blanked its field
whenever the value was missing from options, which happens while they load;
it now falls back to the raw value the way PaginatedSearchSelect already did.
2026-08-14 06:29:49 -07:00