Commit graph

46489 commits

Author SHA1 Message Date
mateo-berri
2a1c21b72d fix(router): keep acreate_file fallbacks inside the requested model group
A file uploaded through Router.acreate_file lands in the account of the
deployment that stored it, so a cross-group fallback silently stores the
file with the wrong provider and every later batch or fine-tuning call
against the returned id permanently fails. Extend the provider-scoped
fallback pin that already covers input_file_id and training_file to file
creation, so the original provider error surfaces instead.
2026-08-18 19:46:45 -07:00
mateo-berri
138c77023a fix: accept bool thinking param instead of crashing with AttributeError
litellm.completion(thinking=True) crashed pre-network in is_thinking_enabled
with a retryable APIConnectionError ('bool' object has no attribute 'get'),
so the router burned retries on a deterministic failure and proxy clients got
a traceback instead of a usable response.

validate_and_fix_thinking_param now coerces thinking=True to the enabled dict
with the default medium budget and drops thinking=False, and the remaining
dict-assuming thinking accessors (base config, bedrock converse, deepseek)
guard with isinstance so raw bools can never crash a transform.
2026-08-18 19:44:31 -07:00
yuneng-jiang
f27d88bd13
test(ui): repoint the e2e locators at the post-antd form controls (#37421)
* test(ui): repoint the e2e locators at the post-antd form controls

Nine Playwright specs went red after the tremor and antd removals, none of
them because the product broke. The specs selected on markup those libraries
owned: tremor's TextInput stamped data-testid="base-input", the antd toast
facade rendered .ant-notification, and the team member modal's email field was
an .ant-select. Removing the libraries deleted those hooks silently.

Repoint each onto a user-facing locator that survives the next migration:
getByLabel for the key name, the MCP tool argument and the two cache pricing
fields, getByRole("combobox") for the team member email search, and the toast
container for the add-model success message.

The pricing fields needed a source change to be reachable at all. antd's
Form.Item used to assign the field name as the input id and tie the label to
it; the react-hook-form rewrite renders FieldLabel with no htmlFor and lets
FormField generate an opaque control id, so both cache inputs lost their
accessible name and could only be told apart by placeholder, which they share.
Pin the id back to the field name and point the label at it.

* fix(ui): let FormField own the pricing field label instead of hand-rendering one

The previous commit gave the cache cost inputs an accessible name by rendering
a FieldLabel with htmlFor next to the FormField. FieldLabel forwards Label's
props, and Label only accepts children, so next build failed type checking.

FormField already renders a label wired to the control id it generates, and
FormField.test.tsx covers that association, so passing label through is both
type-safe and less markup. The read-only branch keeps its plain FieldLabel,
which has no control to point at.
2026-08-19 02:41:05 +00:00
yuneng-jiang
1bc1a5ed81
refactor(ui): migrate the key edit form off Ant Design onto react-hook-form (#37398)
* refactor(ui): migrate the key edit form off Ant Design onto react-hook-form

The key editor was the last antd Form in the key flow. antd's store decided
the saved payload implicitly: onFinish reported whatever mounted Form.Items
happened to be registered, so a control could stop feeding the request
without anything failing.

The form now runs on react-hook-form with the dashboard's own field
primitives, and the payload is projected explicitly in keyEditFormValues so
every saved key is written out by name. That reproduces the old payload
exactly, including the keys antd sent holding undefined and the two
role-gated keys it dropped entirely when the field was not mounted.

The existing suite is kept as the contract and passes unedited apart from
the selects, whose queries moved from Ant Design class selectors to roles
and labels. MultiSelect now forwards a per-option disabled flag, which the
Models select needs to keep greying out individual models once the
all-proxy-models sentinel is picked.

* fix(ui): keep the key edit prompts control gated behind premium

The antd control carried disabled={!premiumUser} and a tooltip saying
prompts by key are premium. The port kept the premium placeholder but
dropped the gate, so a non-premium admin could type a prompt and have the
whole save rejected by the endpoint.

TagsInput had no disabled prop at all, which is why the gate could not
survive the port; it now takes one and passes it to the combobox. An audit
of every disabled expression against the antd original shows this was the
only gate lost.

Also pins the two payload keys that are assembled in the submit handler
from React state rather than bound fields, budget_fallbacks and
tag_rpm_limit. A field-driven suite cannot see them, and tag_rpm_limit's
only previous appearance was an empty map that reads the same whether the
assignment works or is deleted. The cases were written against the antd
implementation by another lane and are added unchanged.
2026-08-18 19:40:37 -07:00
yuneng-jiang
cb5f158023
test(ui): characterize the create key form payload contract (#37405)
The create key suite mocked antd wholesale and swapped in a fake form
store whose onFinish spread every value it had ever seen, which is the
inverse of what rc-field-form does: real antd reports only the mounted
registered fields, so anything inside a closed collapsible is absent
from the body rather than present and null. Fourteen children were
stubbed to () => null on top of that, so the suite passed no matter
what the form would actually submit and could not protect a port off
antd.

The integration test now renders the real tree and stubs only the
network boundary, and a submit payload contract block pins the exact
body with toStrictEqual so null, undefined and absent stay distinct.
It covers all sections closed, Optional Settings alone, all open, and
each nested section opened by itself, plus the collapse and re-expand
path that antd's store survives and a shouldUnregister port would not.

The genuinely unit-level logic, fetchTeamModels and fetchUserModels,
moves to a plain unit test that mocks modelAvailableCall alone.

getOpenAPISchema stays reachable through a stubbed global fetch rather
than the networking module mock, because networking imports jsonFields
from check_openapi_schema and that module imports getOpenAPISchema back,
so importOriginal binds the real export through the cycle.
2026-08-18 19:40:23 -07:00
yuneng-jiang
63f740f511
test(ui): pin the MCP server edit save payload before the form migration (#37404)
`mcp_server_edit` builds its update payload from `validateFields()`, so the
request body is whatever antd had mounted at the moment Save was pressed.
Nothing asserted that body, and the existing suite has no `toStrictEqual`
anywhere, so a key appearing, disappearing, or arriving as null instead of
undefined was invisible.

This adds a characterization net that drives the real component tree and
captures the exact object handed to `updateMCPServer`. Every case is pinned
with `toStrictEqual`, which is the only matcher that separates the three
states a key can be in: absent, present-as-undefined, and present-with-value.
That distinction is the whole point here, since a gated-off field and a
mounted-but-empty field currently differ, and `entra_obo` versus plain
`token_exchange` is exactly that difference in the wild.

19 cases cover the transports, all ten auth types, the credential subsets each
one contributes, and the tool allowlist gate. Values were captured from the
component as it behaves today rather than written from reading the source, so
the file records current behaviour instead of intended behaviour

A six-mutant battery run against the payload builder kills 6/6, each run
executing all 19 tests: leaking an audit field, deleting a binding, removing a
gate, turning a flat key into a lodash path, swapping undefined for null, and
swapping an empty-array default for null

Two explicit assignments in the payload turn out to be dead. `alias` and
`mcp_access_groups` are both already supplied by the `...restValues` spread
above them, so removing either line changes nothing. Left in place here and
noted for the payload extraction that follows
2026-08-18 19:40:02 -07:00
yuneng-jiang
6ecad76dec
test: allow protocol-constrained pass-through routes to declare fewer methods (#37415)
The pass-through method contract asserted that every route accepts GET, POST,
PUT, DELETE and PATCH. That holds for routes fronting a REST API, where
narrowing the set turns a request the upstream would have served into a 405,
but it does not hold for Amazon Comprehend Medical: it speaks AWS JSON 1.1,
which is POST-only, and its handler signs a POST upstream and requires a JSON
object body. Registering the other four verbs there would only produce routes
that always fail body parsing, so the route is POST-only on purpose and the
blanket assertion is the part that is wrong.

Carry a narrow exemption list instead of dropping the check. Exempted routes
are still pinned to an exact method set, so widening or narrowing one fails,
and a companion test asserts every exempted path is still registered so the
list cannot outlive the routes it covers.
2026-08-18 19:38:05 -07:00
yuneng-jiang
153b205d3e
test: build redaction and batch limiter fixtures the way production does (#37416)
Two suites broke because they stood in for production objects with stand-ins
that no longer answer the same way.

The redaction test faked a ResponsesAPIResponse and then reassigned
builtins.isinstance so the fake would pass the type check. Redaction now gates
on a tuple of accepted types, and the patched isinstance only recognised the
bare class, so the fake fell through to the generic branch and the assertions
ran against a plain dict. Building a real ResponsesAPIResponse drops the
builtins patch entirely and exercises the same type gate production takes.

The batch rate limiter tests constructed _PROXY_BatchRateLimiter with
parallel_request_limiter=None even though the parameter is not optional. That
stayed harmless until the output-token estimate started reading the limiter,
which turned it into an AttributeError. Inject the limiter the proxy injects,
sharing one InternalUsageCache the way _add_proxy_hooks does.
2026-08-18 19:37:50 -07:00
yuneng-jiang
7ac764970b
fix(proxy): return no rows when the aggregated activity entity filter is empty (#37414)
The aggregated daily-activity queries build their WHERE clause as raw SQL, and
an empty entity list rendered as `"team_id" IN ()`, which Postgres rejects with
`syntax error at or near ")"`. Callers reach that state normally: a caller
without admin view and no explicit team_ids has its scope resolved to the teams
it belongs to, so anyone belonging to no teams, an org admin for instance, sent
an empty list and got a 500 back from /team/daily/activity/aggregated.

The paginated endpoint hands the same empty list to Prisma, which renders
`in: []` and matches nothing, so it kept returning 200 with an empty result set.
Emit FALSE for the empty case so the raw-SQL path lands on the same answer,
mirroring what the api_key filter a few lines below already does.

The fix covers both aggregated queries at once because they share one WHERE
clause builder.
2026-08-18 19:37:32 -07:00
Mateo Wang
5f6a14dbb7
Merge pull request #37419 from BerriAI/litellm_fix_ocr_tests_req_format
test(ocr): update Azure DI supported-params assertion for req_format
2026-08-18 19:37:20 -07:00
mateo-berri
818886cfa1 fix(bedrock): raise non-retryable BadRequestError on unconvertible tool calls 2026-08-18 19:24:18 -07:00
mateo-berri
05e32e9fee test(ocr): update Azure DI supported-params assertion for req_format 2026-08-18 19:21:46 -07:00
mateo-berri
fe8c353435 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_fix_bedrock_malformed_toolcall_18667 2026-08-18 19:16:41 -07:00
ryan-crabbe-berri
ec6f1c1a56
refactor(ui): codemod the antd Tooltips outside form files onto the shadcn atom (#37402)
* refactor(ui): codemod the antd Tooltips outside form files onto the shadcn atom

The atoms/Tooltip wrapper gains an optional side and renders its children without a popup when there is no content, which covers antd's placement prop and its title={undefined} escape hatch. A TypeScript-AST codemod then rewrites every antd Tooltip that does not sit in a file still using antd Form, since those files get their primitives swapped as part of the react-hook-form migration.

* refactor(ui): fold the atoms Tooltip into the ui tooltip primitive as SimpleTooltip
2026-08-19 02:14:37 +00:00
mateo-berri
89fcdc30d9 chore(typing): ratchet lint budgets down by the errors this branch fixed
basedpyright -1283 across 48 rules, ruff-strict -115, type-discipline -99
2026-08-19 02:13:49 +00:00
mateo-berri
86e7bcaf54 fix(websearch): keep _inject_native_blocks untyped rather than dodge the write
Threading a TypeVar through the helper makes the fallback attribute write
unprovable, and routing it through setattr to quiet that only trades one
diagnostic for a bugbear violation. Leave the seam as it was
2026-08-19 02:00:51 +00:00
Mateo Wang
807e1da4af
Merge pull request #32448 from ChenluJi/feat/tinyfish-search-headers-and-extras
feat(tinyfish): surface response headers + top-level response extras
2026-08-18 18:53:02 -07:00
yuneng-jiang
5012d11a18
refactor(ui): style the logging settings from semantic tokens (#37385)
team/LoggingSettings.tsx carried 34 hardcoded palette classes and
common_components/PremiumLoggingSettings.tsx another 9, so both render
light-only regardless of theme. Map the neutrals onto foreground,
muted-foreground, muted and border, the red affordances onto destructive,
and swap the hand-rolled chips for the shadcn Badge primitive.

The three event-type options carried decorative green, red and blue dots.
The design system has no success or info token, so the dots are dropped
and the option labels, which already say "Success Only", "Failure Only"
and "Success & Failure", carry the meaning on their own.

This is groundwork, not a visible change: nothing in the dashboard ever
applies the .dark class today, so the dark palette is unreachable. The
files no longer hardcode colour and will follow the theme once one exists.
2026-08-18 18:52:41 -07:00
mateo-berri
7602c5ea72 fix(responses): keep websocket response.create pass-through semantics
Typing the managed-responses call kwargs as dict[str, object] forced an
isinstance filter on the popped model and previous_response_id, which turned a
malformed client value from a loud downstream failure into a silent fallback to
the connection's model. Keep those two seams and the metadata mapping as they
were so the frame still fails the way it always did
2026-08-19 01:45:42 +00:00
Srivatsa03
cd7cdb3e3a fix(cost): stop double-billing cached tokens that overlap a modality
Providers report cached_tokens and image_tokens as overlapping subsets of
prompt_tokens rather than a disjoint partition, so a request whose images
were served from cache paid for them twice, once at the cache-read rate and
again at the image or input rate. The synthetic case in the issue came out
at 109e-6 against a correct 39e-6. Clamp each modality to the part of the
request the cache did not already cover, so the billed components still sum
to prompt_tokens

Fixes #37281
2026-08-18 20:44:45 -05:00
Mateo Wang
41de13aa0c
Merge pull request #28501 from epistoteles/add-databricks-model-pricing
fix(databricks): add cost map entries for 14 newer Databricks models
2026-08-18 18:40:35 -07:00
mateo-berri
490079e7df test: cover nested cache_creation_input_tokens in responses bridge and spend logs 2026-08-18 18:38:30 -07:00
tin-berri
f6eaca9069
fix(mcp): serve token-forwarding servers when oauth discovery fails (#37399)
true_passthrough and oauth_delegate forward the caller's own bearer and mint
nothing, so their sessions consume no discovered OAuth endpoint. The discovery
completeness gate still failed them closed with a 503 raised before the upstream
was ever contacted, which the tools/list fan-out swallowed into HTTP 200 with an
empty tool list. Any upstream that publishes no RFC 9728 metadata, including
every OpenAPI-backed internal API, was permanently unusable.

A failed discovery is now fatal only to servers whose OAuth flow the gateway
runs itself. Discovery still runs for the forwarding modes, so /authorize,
/token and /register keep resolving their endpoints, and each keeps its own 400
when they are missing.

MCPServer.is_client_forwarded_token now owns the mode pair that five call sites
spelled inline, one of which had already named it is_client_forwarded_mode.
2026-08-19 01:32:41 +00:00
Mateo Wang
704cc41f28
Merge pull request #37388 from BerriAI/litellm_lit_5718_mcp_tool_bound_to_server
fix(mcp): bind tool existence check to the selected server
2026-08-18 18:22:00 -07:00
yuneng-jiang
2ed354f62b
bump: litellm-enterprise 0.1.56 -> 0.1.57, litellm-proxy-extras 0.4.86 -> 0.4.87, litellm 1.98.0 -> 1.99.0 (#37395)
enterprise/ and litellm-proxy-extras/ both changed between main and staging, so each gets a PATCH bump. The 1.98.0 line already graduated with v1.98.0-rc.1, so this promotion opens the 1.99.0 line and litellm takes its MINOR bump.

uv.lock re-resolved against the three new versions; the exclude-newer timestamp moves because the lock uses a rolling P3D window
2026-08-18 18:14:31 -07:00
mateo-berri
9187105c21 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_decrease_anys_fable_round3 2026-08-19 01:12:45 +00:00
mateo-berri
11552dbafc chore(typing): drop 1.3k basedpyright errors across 42 Any hotspot files
Replace implicit and explicit Any with real types across the highest-density
reportAny/reportExplicitAny files: module-private TypedDicts for dict payloads,
Protocols for duck-typed collaborators, and existing litellm/types models where
they already describe the shape

No new cast(), no # type: ignore, no # pyright: ignore, no # noqa, and no
new suppressions. Diagnostics that could not be resolved without one were left in
place rather than hidden
2026-08-19 01:12:41 +00:00
ryan-crabbe-berri
4493c826e7
fix(logging): close three secret-leak paths in verbose logging (#37391)
* fix(logging): close three secret-leak paths in verbose logging

The AWS credential pattern was the only key-name matcher in secret_redaction
that skipped optional quotes, so quoted dict-repr values leaked. Fold the three
AWS key names into the shared key-name alternation instead.

SecretRedactionFilter only scrubs str record attributes, so a dict/list/set
passed through extra={...} reached the formatter unredacted. Redact at the
formatter boundary so no value shape can bypass it.

log_raw_request_response wrote the request curl command to metadata["raw_request"]
unredacted, returned an unmasked raw_request_api_base, and fell back to dumping
model_call_details whenever api_base was empty.

* Update litellm/_logging.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix(logging): redact JSON log values without breaking the document

JsonFormatter redacted the serialized JSON, so a secret-named member
collapsed from '"api_key": "sk-..."' to a bare REDACTED token and the
line stopped parsing as JSON.

Redact before serialization instead: safe_dumps takes an optional
value_transform hook (default None, so all other callers are unchanged)
and redact_structured_value collapses only the value, leaving the key
and surrounding structure intact.

JsonFormatter now emits "api_key": "REDACTED" where the formatter unit
test expected the already-masked "sk**********". That test bypasses
SecretRedactionFilter, which in production collapses the pair before any
formatter runs, so the assertion is updated to match real behavior.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-08-19 01:03:34 +00:00
mateo-berri
24fc3f721c fix(databricks): match the claude 4.6 context limits to Anthropic's published values 2026-08-18 17:55:45 -07:00
ryan-crabbe-berri
869a8cd984
fix(vector_stores): stop leaking stored credentials in direct search debug logs (#37373)
* fix(vector_stores): stop leaking stored credentials in direct search debug logs

Direct vector store providers (RESP datastores like Valkey) have no HTTP
request to echo, so both search handlers called `logging_obj.pre_call` with
no `api_base`. The logging helper treats an empty `api_base` as "nothing to
render" and falls back to `str(self.model_call_details)`, which carries the
resolved `litellm_params`: the stored `valkey_password` and the embedding
config's `api_key` among them.

The stdout logger's regex redaction hid this, but `pre_call` also writes the
same string to `litellm_params["metadata"]["raw_request"]`, which ships
unredacted to every logging callback (Langfuse, OTel, etc.).

Pass a synthetic `<provider>://<vector_store_id>` endpoint plus an explicit
`request_str` so the debug output describes the call instead of dumping call
details, and fold the duplicated sync/async blocks into one helper so the
sanitized descriptor cannot drift between them.

* fix(vector_stores): type direct search query as Sequence[str]

The new helper's list[str] annotation pushed LIT001 over its
type-discipline ceiling. Sequence is the read-only shape the helper
actually needs, and list[str] still satisfies it at both call sites.
2026-08-18 17:46:59 -07:00
yuneng-jiang
b19d59be09
refactor(ui): move the model info edit form off antd Form (#37392)
* test(ui): characterize the model info and cache control submit payloads

Pins the antd behaviour these forms have today, ahead of moving them onto
react-hook-form: the full model info PATCH body, the sticky touched-field
semantics that decide which pricing keys ship, the mounted-only cache control
keys, and the string-typed injection point index.

* refactor(ui): move the model info edit form off antd Form

The deployment edit form on the model info view now runs on react-hook-form
with a zod resolver and shadcn controls, extracted into ModelInfoEditForm so
the view keeps the payload builder and the form keeps the fields.

Cache control injection points become a presentational value/onChange child,
which lets the model info view host it through react-hook-form while the add
model form keeps hosting it through antd. That child never wrote to a real
store on either side: it registered under cache_control_points while both
parents read cache_control_injection_points, so its form prop was inert.

antd marks a field touched on change and never clears it, and neither
touchedFields nor dirtyFields reproduces that, so the four pricing keys that
gate on it track first change explicitly.

The PTU rules move from antd validator wrappers to pure predicates that both
surfaces share, since the add model form still feeds the wrappers to its own
antd form.

* refactor(ui): trim comments and type the model record prop on the edit form

Cuts the explanatory comments that the house rules do not allow, keeping
only the three that record non-obvious library behaviour plus the eslint
directive, and narrows the modelData prop to the two fields the form reads.

Corrects the claim in 5b7ecede4e that the cache control child registered
the wrong key. At the staging tip the Form.List registration is on
cache_control_injection_points and is live, which is why this PR rehosts
it into advanced_settings. The dead part is the three
getFieldValue("cache_control_points") readers, whose key nothing
registers, so updateCacheControlPoints dereferences undefined and the
caught error reaches the console on every role, index or remove change.
2026-08-18 17:40:49 -07:00
ryan-crabbe-berri
bb8324c119
refactor(ui): drop @tremor/react and the theming scaffolding it needed (#37394)
The last tremor component import left the dashboard when the primitive
sweep merged, so the package, its v3 compatibility shim, its @theme token
block and the palette safelist it needed at runtime all have no consumer.

Removing the safelist is what shrinks the shipped stylesheet: tremor built
class names at runtime, so Tailwind had to emit every bg/text/border/ring/
stroke/fill utility across 22 palettes and 11 shades in case one was used.
Nothing in the app constructs a class name that way any more, so the
scanner finds every utility on its own.

The date-fns overrides pin also goes. It only existed because tremor and
react-day-picker@8 peered on date-fns 3 while Base UI wanted 4, and the
lockfile still resolves a single hoisted 4.4.0 without it.
2026-08-18 17:38:12 -07:00
yuneng-jiang
564ea1cf73
feat(ui): add success, warning and info status tokens (#37393)
The dashboard had no shared tokens for non-destructive status colours, so
components reached for raw Tailwind shades instead. Add --success, --warning
and --info alongside the existing --destructive, in both :root and .dark, and
register them in @theme inline so the usual utilities resolve.

Light values are picked for legibility as foreground text rather than by
copying a fixed shade number. Tailwind's ramps are not perceptually aligned
across hues, so amber-600 and green-600 sit at 66.6% and 62.7% lightness and
fail WCAG AA on white (3.19:1 and 3.22:1). green-700, amber-700 and blue-600
land at 52.7%, 55.5% and 54.6%, the same band as --destructive at 57.7%, and
clear AA. Dark mode uses the -400 shades, matching --destructive.

The .dark values are populated even though nothing can apply that class yet.
They are the artifact the later theme switch work will turn on.

Alert moves its info and warning variants onto the tokens. The tint is /5
rather than /10 because /10 drops both below AA. The error variant keeps its
existing shades: it involves no new token, and its current 9.21:1 is better
than anything the token form would give it.
2026-08-18 17:36:10 -07:00
mateo-berri
9018a95037 test(mcp): build fixture mapping state without in-place mutation 2026-08-18 17:35:40 -07:00
mubashir1osmani
d989f172e9 fix(batches): revert invalid Final on a loop-scoped local
Some checks failed
Terraform Modules / fmt, validate, test (aws) (push) Has been cancelled
basedpyright rejects a Final variable assigned inside a loop body
(reportGeneralTypeIssues); the type-discipline checker doesn't flag
this line without Final either, so the annotation only bought a
basedpyright budget regression.
2026-08-18 20:32:11 -04:00
devin-ai-integration[bot]
3f15dc3287
fix(mcp): attach per-user BYOK credential when listing tools for non-oauth2 auth types (#34787)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-18 17:10:00 -07:00
mateo-berri
4285ffd82b fix(databricks): drop the minimal reasoning effort flag from the claude-opus-4-6 entry 2026-08-18 17:09:17 -07:00
yuneng-jiang
c33b3a32a6
feat(bedrock): add a config toggle to disable agent-runtime pass-through (#37386)
* feat(bedrock): add a config toggle to disable agent-runtime pass-through

The /bedrock pass-through dispatches agents, knowledge bases, flows, rerank,
retrieveAndGenerate, generateQuery and optimize-prompt to bedrock-agent-runtime,
so an operator who only wants to expose model invoke and converse has no way to
narrow that surface

Adds general_settings.disable_bedrock_agent_runtime_passthrough. When set, those
routes are rejected with a 403 before credentials are fetched or the request is
signed. Plain bedrock-runtime model pass-through is unaffected, and the setting
defaults to off, so existing deployments behave exactly as before

The branch is inverted to an early return for the non-agent-runtime case so the
toggle can reject outright instead of falling through to model extraction, which
would surface a confusing 400 about an unparseable model

* style(bedrock): drop redundant docstrings from the agent-runtime toggle
2026-08-18 17:05:40 -07:00
mateo-berri
75a569b3e2 fix(databricks): sync the packaged cost map backup with the new Databricks entries 2026-08-18 17:04:25 -07:00
mubashir1osmani
98447e0043 fix(batches): reconcile merge with upstream batch pricing changes
- Resolved merge conflicts in _handle_completed_batch and
  CheckBatchCost._track_completed_batch_cost, keeping BatchCostUsageResult
  while adopting upstream's model_info threading and improved
  deployment-pricing lookup
- Fixed two upstream tests and one mock that still expected the old
  tuple(cost, usage, models) return shape
- Suppressed the one new LIT002 violation from the empty-output-file
  BatchCostUsageResult literal
2026-08-18 19:58:48 -04:00
Mateo Wang
f570af9fcf
Merge branch 'litellm_internal_staging' into add-databricks-model-pricing 2026-08-18 16:55:02 -07:00
Mateo Wang
55777d0e80
Merge pull request #35110 from shivijain2323/feature/bedrock-mantle-quota-project-itr1
feat(proxy): add project-level ITPM and OTPM quotas
2026-08-18 16:54:33 -07:00
mubashir1osmani
24a6d4de94 Merge remote-tracking branch 'berri/litellm_internal_staging' into litellm_managed_batches_observability
# Conflicts:
#	enterprise/litellm_enterprise/proxy/common_utils/check_batch_cost.py
#	litellm/batches/batch_utils.py
2026-08-18 19:48:44 -04:00
Mateo Wang
054aefce0d
Merge pull request #37387 from BerriAI/litellm_guardrail_usage_requeue
fix(guardrails): requeue usage rollup rows dropped after retry exhaustion
2026-08-18 16:42:06 -07:00
mateo-berri
a30e1f6e3d fix(mcp): bind tool existence check to the selected server 2026-08-18 16:41:40 -07:00
ryan-crabbe-berri
669c1334b4
refactor(ui): move the agent, guardrail, prompt, policy and skill forms off tremor (#37320)
* refactor(ui): move the agent, guardrail, prompt, policy and skill forms off tremor

The agent info Save Changes button used to rely on tremor's implicit
submit inside the antd Form, so it now carries an explicit type="submit".
Every converted TabsContent is keepMounted to keep tremor's always-mounted
panel semantics, pinned by a new guardrail info test. Prunes the tremor
no-restricted-imports suppressions these nine files no longer need.

* fix(ui): keep the line tab strip on the agent, guardrail and prompt info views

tremor's TabList defaulted to the line variant while shadcn's TabsList
defaults to the filled pill, so the bare conversion turned three underlined
tab strips into segmented pills. Restores the line variant plus the bottom
border and the tab padding the strips used to have.

* test(ui): pin the agent settings submit and the prompt raw json tab

Agent Settings only saves because Save Changes carries an explicit
type="submit" now that the button is a Base UI button, so a test drives the
edit and asserts the patch call fires. The prompt info tabs are keyed by slug
now, which also makes Raw JSON render for prompts with no template, so a
second test renders that case and asserts the serialized response is visible.
2026-08-18 23:40:44 +00:00
mubashir1osmani
3bfeaa78dd revert: undo accidental whole-file ruff-format of test_check_batch_cost.py
The prior commit ran ruff format on the whole file to type the
_batch_cost_result helper, reflowing hundreds of unrelated pre-existing
lines that were never ruff-format-clean to begin with (confirmed at the
PR's base commit, before any of these changes). CI's ruff-format gate
only checks litellm/**/*.py, not tests/, so this reformatting served no
CI purpose and only bloated the diff. Restores everything except the
intended TYPE_CHECKING import and _batch_cost_result annotations.
2026-08-18 19:39:28 -04:00
Mateo Wang
589f6859d8
Merge pull request #37356 from BerriAI/litellm_fix_v1_messages_double_content_block_stop
test(anthropic): pin one content_block_stop per tool_use block on the Responses adapter
2026-08-18 16:38:13 -07:00
mubashir1osmani
ff833a5872 fix(batches): address Greptile type-discipline feedback
Add Final to the reasoning_tokens local var and type the
_batch_cost_result test helper's parameters, per review feedback on
PR #37208.
2026-08-18 19:37:07 -04:00
mubashir1osmani
682032dd1b fix(batches): fix CI failures from lint format and merged upstream guard
- ruff format litellm/batches/batch_utils.py
- reconcile the upstream output_file_id=None guard (merged in from
  litellm_internal_staging) with BatchCostUsageResult, and count that
  batch's error_file_id failures instead of always reporting 0
- fix test_handle_completed_batch_no_output_file_is_zero's tuple
  unpacking, which predated the BatchCostUsageResult refactor
- commit the batch_successful_requests/batch_failed_requests fixture
  fix to test_spend_management_endpoints.py that was left uncommitted
2026-08-18 19:29:25 -04:00