Commit graph

5900 commits

Author SHA1 Message Date
joshua-berri
25af172b85
fix(mcp): keep config-defined servers read-only (#42299)
* fix(mcp): persist config server edits in the database

* test(mcp): cover config loading and failed promotion responses

* test(mcp): preserve auth policy during config server promotion

* fix(mcp): preserve existing YAML metadata during config loading

* fix(mcp): reuse bounded traversal for config secret checks

* fix(mcp): honor database access groups after config promotion

* fix(mcp): keep config-defined servers read-only

* fix(ui): clear frontend warnings and require warning-free green checks

* fix(ui): preserve legacy MCP access group labels

* ci: remove remaining frontend action runtime warnings

* fix(mcp): limit read-only fix to ticket scope

* fix(mcp): preserve API stability and remove unrelated guidance

---------

Co-authored-by: Joshua Valluru <326636767+joshua-berri@users.noreply.github.com>
2026-09-21 22:56:21 -07:00
tin-berri
5a8c4f48e4
feat(router): native compact-to-fit across conversation APIs (#42074)
* feat(router): native compact-to-fit across conversation APIs

* fix(router): preserve compaction admission and shared client boundaries

* fix(router): honor compaction fit fallbacks and router-scoped access

* fix(router): charge compaction usage to caller token limits

* test(http): keep FastAPI inside proxy tests

* fix(router): check compactor capacity before skipping escalation
2026-09-21 22:52:29 -07:00
Zachary Lyon
19c13ac971
feat(proxy): add TinyFish Agent API passthrough with per-step billing (#41099)
* feat(proxy): add TinyFish Agent API passthrough with per-step billing

* chore(ui): regenerate dashboard API types for /tinyfish passthrough

* fix(proxy): satisfy strict lint budget for tinyfish passthrough

* style: ruff format tinyfish passthrough handler

* test(proxy): exercise tinyfish route through the app with a faked upstream

* refactor(proxy): make cross-module tinyfish billing hooks public

* fix(proxy): tolerate transient tinyfish poll failures instead of dropping the charge

* fix(proxy): defer billing for disconnected tinyfish SSE runs to the background poller

* Revert "fix(proxy): defer billing for disconnected tinyfish SSE runs to the background poller"

This reverts commit ef0bcfb4a0.

* fix(proxy): bill tinyfish SSE runs via detached poller and only COMPLETED runs

Disconnected run-sse clients previously left completed runs unbilled: the stream-end
handler saw a still-RUNNING run and logged $0. The poller now spawns from the streaming
path on the first run_id frame, outlives the disconnect, and writes the one spend row when
the run turns terminal; the stream-end path only logs the $0 fallback for run_id-less
streams. Costs now apply only to COMPLETED runs ($0 for FAILED/CANCELLED, matching the
upstream invoice), spend rows carry the request's litellm_call_id (previously NULL
request_ids collided and were silently dropped), and the GET /v1/runs listing is blocked
so callers behind the shared key cannot discover each other's runs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pxz11TQKYvCXvKawNUa2g4

* fix(proxy): drop GET /v1/runs from the tinyfish allowlist error message

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pxz11TQKYvCXvKawNUa2g4

* chore(proxy): sync openapi artifacts for tinyfish docstring, suppress LIT011 on flag write

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pxz11TQKYvCXvKawNUa2g4

* style(proxy): ruff-format the sse poller flag write

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pxz11TQKYvCXvKawNUa2g4

* style(proxy): keep the rebind-ok suppression on the flag write's own line

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pxz11TQKYvCXvKawNUa2g4

* fix(proxy): harden tinyfish billing paths from review findings

Skip failure dispatch when the SSE poller owns billing (a failure row collided with the
poller's billed row on request_id and dropped the charge), late-spawn the poller for
run_ids that arrive in unterminated frames instead of mispricing RUNNING runs at $0,
thread litellm_params into poller-billed standard logging objects so SLO consumers see
attribution, untype the run error field so upstream error-shape drift cannot void a
billable run, normalize a schemeless TINYFISH_AGENT_API_BASE, extend the poll budget to
cover queue wait (3600s) with ~60s outage tolerance, and log poller cancellation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pxz11TQKYvCXvKawNUa2g4

* chore(proxy): satisfy ratcheted BLE001/LIT002 budgets from main in tinyfish handler

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pxz11TQKYvCXvKawNUa2g4

* style(proxy): drop stray blank line from merge resolution

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pxz11TQKYvCXvKawNUa2g4

* fix(proxy): reject passthrough envelope controls on tinyfish route, raise blocking-run timeout

The generic passthrough unwraps a caller-supplied custom_body as the forwarded request and
honors a caller stream flag, so custom_body.use_vault bypassed the credentialed-run 403 and
stream: true flipped a blocking run into the streaming pipeline. The route now 400s the
envelope fields (custom_body, stream, query_params); streaming comes from the endpoint.
Blocking runs also get a 1500s default timeout covering the upstream 1200s run cap, unless
the operator configured pass_through_request_timeout.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pxz11TQKYvCXvKawNUa2g4

* style(proxy): resolve operator timeout without a dict-literal default

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pxz11TQKYvCXvKawNUa2g4

* test(passthrough): list the TinyFish route among protocol-constrained pass-through routes

* chore(proxy): regenerate the lazy OpenAPI snapshot after merging main

* chore(proxy): keep the lazy OpenAPI snapshot as CI's Python 3.12 renders it

* fix(proxy): reject TinyFish POST bodies that are not a JSON object

A form-encoded or text body carried stream and use_vault past both field
gates, because the gates only saw fields the body parsed to as JSON. The
route now checks the content type before reading the body and answers 400
for anything that is not a JSON object.

* fix(tinyfish): reject submit paths with extra slashes so run-async always bills

The allowlist dropped empty path segments, so POST /v1/automation/run-async/
was forwarded upstream while the billing dispatch only recognises the exact
path and would have logged the submit at $0 without starting the poller.
Any path with a trailing or doubled slash now returns 403 before forwarding.

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-09-21 21:21:43 -07:00
devin-ai-integration[bot]
0fd1c191ca
feat(fal_ai): add queue-only /fal_ai pass-through route with spend tracking (#42360) 2026-09-22 02:59:58 +00:00
devin-ai-integration[bot]
1106b16745
feat(openrouter): price typesafe/jev-1.13 and add an openrouter decisions pass-through (#42301) 2026-09-22 02:44:15 +00:00
devin-ai-integration[bot]
8b33da7bb3
feat(proxy): opt-in litellm_call_id in JSON error bodies (#42391)
* feat(proxy): opt-in litellm_call_id in JSON error bodies

Add general_settings.include_call_id_in_error_body. When true, the value
already on the x-litellm-call-id response header is copied into JSON error
bodies: as error.litellm_call_id on the OpenAI-shaped routes, /v1/messages,
and streaming first-chunk errors, and as a top-level litellm_call_id on
pass-through routes. Off by default, so error bodies stay byte-identical
unless an admin opts in

* chore(proxy): drop helper docstring and restore lazy OpenAPI snapshot

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-09-21 19:17:18 -07:00
jesus-berri
f6d5b28443
Merge pull request #39578 from Louis-Vauterin/jwt-key-mapping-token-id
feat(jwt-key-mapping): accept token_id as an alternative to the plaintext key
2026-09-21 18:22:54 -07:00
yuneng-jiang
a59ecfb7c5
Merge pull request #42367 from BerriAI/litellm_team_usage_export_per_user
feat(ui): add per-user breakdown to team usage export
2026-09-21 18:07:54 -07:00
tin-berri
275c0c4d96
Merge pull request #42057 from BerriAI/litellm_classifier_forecast_cards
feat(ui): show Capability and FUSE v2 routing forecasts
2026-09-21 17:55:25 -07:00
yuneng
49126d4434 test(ui): pin the clock in the per-user export filename test
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 00:34:59 +00:00
yuneng
86a019128e fix(ui): key per-user export buckets on a collision-free tuple
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 00:25:13 +00:00
yucheng-berri
12f79308cf
Merge pull request #42354 from BerriAI/litellm_fix_video_key_guardrails_lit_6685
* fix(guardrails): scan video prompts for key-attached guardrails on /v1/videos

/v1/videos dispatches call_type avideo_generation, which CallTypes did not
know and no guardrail translation handler covered, so the unified guardrail
hook returned the request unscanned. Add the video call types and an OpenAI
video guardrail translation package that scans the prompt for create, remix,
edit and extension requests

Resolves LIT-6685

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

* chore(ui): regenerate api types for video call types

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

* test: skip avideo_generation in azure sdk client exhaustive check

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

* test(e2e): retry a leaked video job until the guardrail sync deadline

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

* refactor(guardrails): satisfy the type-discipline gate in the video handler

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

* test(guardrails): gate the video e2e on a chat probe so a miss starts at most one paid job

Addresses Greptile review: typed RewritingGuardrail override, dropped routine docstrings, and the e2e waits for the key guardrail to sync via /chat/completions before its single /v1/videos call

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

---------

Co-authored-by: yucheng <yucheng@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 17:23:56 -07:00
Yassin Kortam
9cc5b78c33
Merge pull request #41634 from BerriAI/litellm_agent_access_groups
feat(agents): attach access groups to agents and enforce them for models, MCP servers and agent calls
2026-09-21 19:13:46 -05:00
tin-berri
094a60bb9c
Merge pull request #41872 from BerriAI/litellm_context_escalation_opt_in
fix(router): make context-window escalation opt-in
2026-09-21 17:03:33 -07:00
yuneng-jiang
1f4b595072
Merge pull request #41788 from BerriAI/litellm_config_read_source
feat(proxy): report the source of alerting, UI and router settings on read
2026-09-21 17:02:18 -07:00
yuneng-jiang
a158aa878f
Merge pull request #41773 from BerriAI/litellm_dashboard-form-happy-paths
test(ui): cover dashboard form journeys
2026-09-21 16:56:25 -07:00
Tin Chi Lo
9221109d18 chore(router): resolve merge conflict with main 2026-09-21 16:52:47 -07:00
Tin Chi Lo
21fb652586 chore: merge main to restore lint checker 2026-09-21 16:44:08 -07:00
yuneng-jiang
c21ab96741
Merge pull request #42293 from BerriAI/litellm_complexity_router_advanced_fields
feat(ui): expose remaining complexity router advanced settings
2026-09-21 16:43:50 -07:00
yuneng-jiang
6b254b6be2
Merge pull request #41769 from BerriAI/litellm_model-actor-edges
test(model_management): cover actor edges and wildcard models
2026-09-21 16:43:24 -07:00
yuneng
a2163a2831 style(ui): format entity usage export files with prettier
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 23:41:27 +00:00
tin-berri
c1c1ec4f84
Merge pull request #42026 from BerriAI/litellm_user_jwt_savings
feat(ui): add internal-user savings and auto-router usage
2026-09-21 16:41:16 -07:00
yuneng
b7d1423ad3 feat(ui): add per-user breakdown to team usage export
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 23:26:12 +00:00
yuneng
beceb1bedb test(ui): cover per-user team usage export
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 23:23:15 +00:00
joshua-berri
1baa26d36b
Merge pull request #41074 from BerriAI/litellm_mcp_server_list_stable_order
fix(mcp): keep server lists stable across refreshes
2026-09-21 23:06:09 +00:00
Yuneng Jiang
143725fc06
Merge remote-tracking branch 'origin/main' into litellm_config_read_source 2026-09-21 15:54:52 -07:00
yucheng
8ffca3bd19 chore(ui): regenerate api types for video call types
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 22:47:14 +00:00
ryan
8a1c6e49fb feat(auth): only allow password-login dashboard sessions to call /user/password/change
Password login now stamps login_method=username_password into the UI session key
metadata, and change_password rejects any caller that is not a litellm-dashboard
key carrying that marker with 403 before the user row is read. SSO sessions and
user-associated virtual keys can no longer use the endpoint as a current_password
guessing oracle. The forced-reset session is still minted by the password login
path, so it keeps access to the endpoint

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 22:22:12 +00:00
ryan
5da590a3c5 chore(ui): regenerate schema.d.ts for change_password docstring
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 22:05:44 +00:00
ryan
7c8aed072f chore: merge main into litellm_cherry_pick_password_breach_reset
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 21:54:35 +00:00
yucheng-berri
e0e5b7924a
Merge pull request #42312 from BerriAI/litellm_bedrock_batch_s3_creds_leak
Register s3_access_key_id, s3_secret_access_key and s3_encryption_key_id as
LiteLLM-owned batch params so they are no longer forwarded to Bedrock as
additionalModelRequestFields (which 400s ordinary chat on a batch-configured
deployment), keep them on CredentialLiteLLMParams so the batch/file paths
still receive them, and redact the S3 credential key names in debug logs.

Resolves LIT-8290

Co-authored-by: yucheng <yucheng@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 14:50:54 -07:00
Joshua Valluru
5ec61e7a0b chore: merge main into MCP ordering fix 2026-09-21 14:36:41 -07:00
Joshua Valluru
4c1a6309c2 test(mcp): type server fixtures and role queries 2026-09-21 14:31:28 -07:00
Joshua Valluru
64078689d3 refactor(mcp): clear server list lint warnings 2026-09-21 14:18:01 -07:00
Yassin Kortam
f6c69af427
Merge pull request #41101 from hMED22/litellm_add_edenai_provider
feat(edenai): add Eden AI provider across chat, Responses, Messages, embeddings, audio, images and video
2026-09-21 16:16:28 -05:00
yuneng-jiang
5e0512b611
Merge pull request #42291 from BerriAI/litellm_lit7597_detach_credential
fix(proxy): detach stored credential when model editor selects None
2026-09-21 14:05:28 -07:00
kerry-berri
f5f53a4cf4
Merge pull request #40429 from BerriAI/litellm_upgrade_banner_changelog_stats
feat(ui): add upgrade banner with latest release changelog stats
2026-09-21 13:56:05 -07:00
yucheng
b41edb57c1 fix(bedrock): keep batch S3 credentials out of chat requests and debug logs
Register s3_access_key_id, s3_secret_access_key and s3_encryption_key_id as
LiteLLM-owned batch params so they are no longer forwarded to Bedrock as
additionalModelRequestFields (which 400s ordinary chat on a batch-configured
deployment), keep them on CredentialLiteLLMParams so the batch/file paths
still receive them, and redact the S3 credential key names in debug logs.

Resolves LIT-8290

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 20:42:04 +00:00
Yuneng Jiang
ddf6565970
Merge remote-tracking branch 'origin/main' into litellm_config_read_source 2026-09-21 13:25:45 -07:00
Yuneng Jiang
be2f0d081b
fix(proxy): report sources only on the read endpoints main does not cover
/config/field/info and /config/list already report per-key source on main,
so this drops the branch's versions of those and keeps /alerting/settings,
/get/ui_settings and /router/settings.

Read endpoints no longer write the freshly read database row back into the
shared settings store; the reload path already keeps it current, and a GET
that mutates global state leaks across callers.

Regenerates the lazy OpenAPI snapshot on Python 3.12, matching CI, and the
dashboard API types for the two new response fields.
2026-09-21 13:25:39 -07:00
Mateo Wang
662e5b6e32
Merge pull request #42284 from BerriAI/litellm_qianwen_ai_platform_rename
fix: rename the mainland China brand to Qianwen AI Platform
2026-09-21 13:18:20 -07:00
kerry-berri
5216844c40
Merge pull request #42286 from BerriAI/litellm_fal_ai_minimax_h3
feat(fal_ai): add MiniMax H3 text-to-video and reference-to-video
2026-09-21 13:16:08 -07:00
kerry
9611af7817 Merge remote-tracking branch 'origin/main' into litellm_upgrade_banner_changelog_stats 2026-09-21 20:06:41 +00:00
yuneng
4117d9f786 style(ui): format complexity router files
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 20:01:08 +00:00
yucheng-berri
42519a7680
Merge pull request #42262 from BerriAI/litellm_bedrock_batch_s3_bucket_owner
* fix(bedrock): send s3BucketOwner on batch input and output data config

Resolve s3_bucket_owner from litellm_params, then optional_params, then
AWS_S3_BUCKET_OWNER and emit it on both S3 data configs so cross-account
batch buckets pass Bedrock ownership validation. Omitted when unset

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

* refactor(bedrock): build batch output config with explicit returns

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

---------

Co-authored-by: yucheng <yucheng@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 12:59:08 -07:00
Tin Chi Lo
7f997a420d chore(ui): resolve routing forecast merge conflict 2026-09-21 12:57:57 -07:00
yuneng
f70683ae92 fix(ui): satisfy complexity router CI lint budgets
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 19:56:30 +00:00
yucheng-berri
884407dad4
Merge pull request #42119 from BerriAI/litellm_default_policy_attachments
* feat(policy_engine): add default fallback policy attachments

A policy attachment with default: true applies only when no non-default
attachment matches the request, so an opt-in guardrail policy replaces the
fallback one instead of running alongside it. Supported in config.yaml,
/policies/attachments, the Admin UI Attachments tab and the resolver
(matched_via is prefixed with default:).

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

* fix(policy_engine): ignore inapplicable non-default attachments when selecting defaults

A non-default attachment whose policy is missing or whose condition does not match the request
no longer suppresses default attachments. The impact preview marks default counts as an upper bound

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

* refactor(policy_engine): accept any sequence of policy names in condition matching

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

* fix(policy_engine): resolve policies once and apply fallback semantics in get_matching_policies

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

---------

Co-authored-by: yucheng <yucheng@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 12:55:42 -07:00
ryan
baee50546f chore: merge main into litellm_cherry_pick_password_breach_reset
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 19:54:40 +00:00
tin-berri
457b01e96d
Merge pull request #42055 from BerriAI/litellm_prompt_caching_request_table
feat(ui): show prompt caching requests and net savings
2026-09-21 12:45:11 -07:00