Commit graph

4746 commits

Author SHA1 Message Date
Yuneng Jiang
9a0487553d
Merge remote-tracking branch 'origin' into litellm_oss_staging_04_09_2026 2026-04-10 16:41:27 -07:00
Yuneng Jiang
a771e1939c
Fix unhandled "window is not defined" error in user_edit_view tests
Tremor's internal Tooltip component sets a setTimeout that fires after
the jsdom test environment tears down, causing a ReferenceError. Add
afterEach that flushes pending timers before cleanup.
2026-04-10 00:10:40 -07:00
Yuneng Jiang
c42594ab3e
address greptile review feedback (greploop iteration 1)
Remove leftover 10000ms per-test timeout in add_model_tab.test.tsx that was
missed in the initial sweep. The test now inherits the 30000ms global.
2026-04-09 23:58:35 -07:00
Yuneng Jiang
92cf642c2f
[Test] UI - Unit tests: raise global vitest timeout and remove per-test overrides
Raise vitest testTimeout from 10s to 30s and drop per-test timeout overrides
across UI unit tests. Group CreateUserButton and TeamInfo tests under nested
describe blocks to make the most flaky suites easier to scan.
2026-04-09 23:58:35 -07:00
Yuneng Jiang
3ac0d7c88c
[Fix] Let setSecureItem propagate storage errors to callers
Remove the silent try/catch from setSecureItem so OAuth hooks can
surface actionable "enable storage" guidance instead of a cryptic
"state lost" error after the round-trip. Add a local try/catch in
ChatUI where the storage write is non-critical.
2026-04-09 23:58:35 -07:00
Yuneng Jiang
a29e2eea62
[Fix] Address review feedback on storage utility and Dockerfiles
- Dockerfile.health_check: HEALTHCHECK now verifies the script is intact
  instead of unconditionally exiting 0
- secureStorage.ts: replace deprecated escape/unescape with
  encodeURIComponent/decodeURIComponent; don't delete legacy values on
  decode failure so in-flight flows can time out naturally
- OAuth callback: add same-origin check before redirecting to stored
  return URL
2026-04-09 23:58:35 -07:00
Yuneng Jiang
9baf586791
[Fix] UI: resolve CodeQL security alerts and Dockerfile.health_check hardening
Port security fixes from litellm_v1.82.3.dev.6:
- Use secureStorage (sessionStorage wrapper) instead of raw storage for tokens
- Add URL validation for stored worker URLs to prevent open redirects
- Add same-origin checks before redirecting to stored return URLs
- Harden Dockerfile.health_check with non-root user and exec-form HEALTHCHECK
2026-04-09 23:58:35 -07:00
Chetan Soni
422b7b3357
feat(mcp): add per-user OAuth token storage for interactive MCP flows 2026-04-09 23:58:35 -07:00
Yuneng Jiang
2e0af3795a
fix(e2e): broaden Copy Key button regex to match both modal versions
Some checks failed
Unit Tests: Proxy DB Operations / proxy-db (auth-checks, tests/proxy_unit_tests/test_auth_checks.py tests/proxy_unit_tests/test_user_api_key_auth.py, 20, 8) (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-db (key-generation, tests/proxy_unit_tests/test_key_generate_prisma.py, 30, 0) (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-db (remaining, tests/proxy_unit_tests --ignore=tests/proxy_unit_tests/test_key_generate_prisma.py --ignore=tests/proxy_unit_tests/test_auth_checks.py --ignore=tests/proxy_unit_tests/test_user_api_key_auth.py, 20, 8) (push) Has been cancelled
Unit Tests: Security / security (push) Has been cancelled
On case-sensitive Linux CI, the old regenerate_key_modal.tsx from main
can coexist with the new RegenerateKeyModal.tsx after merge. The old
modal renders "Copy Virtual Key" while the new one renders "Copy Key".
Use /Copy.*Key/ to match both.
2026-04-09 23:36:35 -07:00
Yuneng Jiang
89320a955c
fix(e2e): remove flaky banner check and increase regenerate key timeout 2026-04-09 23:21:01 -07:00
Yuneng Jiang
9071dbba12
fix(ui): remove leftover setIsOwnKey call after state removal 2026-04-09 21:24:22 -07:00
yuneng-jiang
cc43d09d79
Potential fix for pull request finding 'CodeQL / Unused variable, import, function or class'
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-09 21:19:02 -07:00
Yuneng Jiang
71640f062c
Merge remote-tracking branch 'origin/main' into litellm_regen_key_modal_antd 2026-04-09 21:14:57 -07:00
Yuneng Jiang
92dbd2c491
address greptile review feedback (greploop iteration 1)
Remove leftover 10000ms per-test timeout in add_model_tab.test.tsx that was
missed in the initial sweep. The test now inherits the 30000ms global.
2026-04-09 20:54:36 -07:00
Yuneng Jiang
3a316b9131
[Test] UI - Unit tests: raise global vitest timeout and remove per-test overrides
Raise vitest testTimeout from 10s to 30s and drop per-test timeout overrides
across UI unit tests. Group CreateUserButton and TeamInfo tests under nested
describe blocks to make the most flaky suites easier to scan.
2026-04-09 20:42:30 -07:00
Yuneng Jiang
1d50f774e2
fix(ui): support all duration suffixes in regenerate expiry preview
calculateNewExpiryTime only handled s/h/d, but the grace-period
validation and backend accept m, w, and mo as well. Entering any of
those in the Expire Key field caused the function to return null,
which then propagated as expires: null in the onKeyUpdate payload —
the parent UI would then render the expiry as "Never" even though
the backend had correctly applied the new expiry.

Extend the suffix check to cover s/m/h/d/w/mo, matching "mo" before
"m" so "1mo" isn't misread as minutes. Also nullish-coalesce the
call site so an unparseable duration falls back to the previous
expiry instead of null. Add parametric tests for each supported
suffix plus a regression test for the null fallback.
2026-04-09 20:31:35 -07:00
Yuneng Jiang
f95ef935ef
fix(ui): prefer form values over API echo in regenerate update payload
The regenerate endpoint returns a GenerateKeyResponse that inherits
max_budget/tpm_limit/rpm_limit from KeyRequestBase, so the API echoes
the existing values back. The previous updatedKeyData layout spread
...response *after* the explicit formValues assignments, which meant
the user's just-submitted edits were silently overwritten by the API
echo before being propagated to the parent via onKeyUpdate.

Reorder so the response spread comes first and the formValues-derived
fields override it, and add a regression test that mocks a response
with stale limits to lock the behavior in. Also drop the two leftover
debug console.log statements.
2026-04-09 20:25:10 -07:00
Yuneng Jiang
839d9bd5f3
refactor(ui): polish regenerate key success view
- Label the key block with a small "Virtual Key" caption so the gray
  box is clearly the key container.
- Move the Copy Key action to the modal footer as a primary button
  with icon; inline copy icon next to the key is removed.
- Swap the button to "Copied" with a check icon on success instead of
  firing a notification — less noisy and keeps feedback in place.
- Disable clicking outside the modal to close (maskClosable=false) so
  users must explicitly dismiss via Close or X.
- Enlarge the key text and let its container span the full modal
  width.
- Tests updated accordingly, including a new test for the copied-state
  swap and the "Virtual Key" label.
2026-04-09 20:14:01 -07:00
yuneng-jiang
ce75598f97
Merge pull request #25384 from BerriAI/litellm_/bold-pare
[Fix] UI: improve storage handling and Dockerfile consistency
2026-04-09 19:55:24 -07:00
Yuneng Jiang
15f7cc9134
refactor(ui): replace success-view divs in regenerate key modal with antd
Use Flex, Typography.Paragraph (with copyable), and Typography.Text
instead of raw divs + code block + CopyToClipboard wrapper. Drops the
direct react-copy-to-clipboard dependency in this component in favor
of antd's native copyable support.

Also fixes two test issues surfaced when running the e2e locally:
- RegenerateKeyModal.test.tsx no longer mocks react-copy-to-clipboard
  (the component no longer imports it), removing the CJS require()
  inside an ESM mock factory flagged by Greptile.
- keys.spec.ts scopes the Regenerate and Copy lookups to the modal.
  The Regenerate button has an icon whose aria-label ("sync") is
  concatenated into the button's accessible name, so an exact-match
  lookup on "Regenerate" failed; and the new Paragraph copyable
  renders a generic "Copy" button that collided with the other
  copyable fields on the key info view.
2026-04-09 18:43:28 -07:00
shivam
31f750146b
added option to allow team user to see logs of team 2026-04-09 17:43:20 -07:00
Chetan Soni
ce2add3b16 feat(mcp): add per-user OAuth token storage for interactive MCP flows 2026-04-09 12:42:42 -07:00
user
8d1493ed08
fix(security): bump vulnerable dependencies
pip:
- cryptography 43.0.3 → 46.0.7 (5 CVEs including CVSS 8.2 ECDH key leak)

npm:
- hono 4.1.4/4.12.7 → 4.12.12 (prototype pollution, cookie injection,
  path traversal, middleware bypass, IP matching bypass)
- @hono/node-server 1.19.6 → 1.19.13 (serveStatic middleware bypass)
- vite 7.3.1 → 7.3.2 (file read via WebSocket, path traversal, fs.deny bypass)
- lodash override 4.17.23 → 4.18.1 (code injection via _.template,
  prototype pollution via _.unset/_.omit)

mlflow left at 3.9.0 — 2 of 3 alerts have no upstream fix, and
3.11.1 is blocked by exclude-newer (transitive dep chain).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 19:35:19 +00:00
Abhijoy Sarkar
c688d9d6bc
Add PromptGuard guardrail integration (#24268)
* Add PromptGuard guardrail integration

Add PromptGuard as a first-class guardrail vendor in LiteLLM's proxy,
supporting prompt injection detection, PII redaction, topic filtering,
entity blocklists, and hallucination detection via PromptGuard's
/api/v1/guard API endpoint.

Backend:
- Add PROMPTGUARD to SupportedGuardrailIntegrations enum
- Implement PromptGuardGuardrail (CustomGuardrail subclass) with
  apply_guardrail handling allow/block/redact decisions
- Add Pydantic config model with api_key, api_base, ui_friendly_name
- Auto-discovered via guardrail_hooks/promptguard/__init__.py registries

Frontend:
- Add PromptGuard partner card to Guardrail Garden with eval scores
- Add preset configuration for quick setup
- Add logo to guardrailLogoMap

Tests:
- 30 unit tests covering configuration, allow/block/redact actions,
  request payload construction, error handling, config model, and
  registry wiring

* Fix redact path and init ordering per review feedback

- P1: Update structured_messages (not just texts) when PromptGuard
  returns a redact decision, so PII redaction is effective for the
  primary LLM message path
- P2: Validate credentials before allocating the HTTPX client so
  resources aren't acquired if PromptGuardMissingCredentials is raised
- Add tests for structured_messages redaction and texts-only redaction

* Harden PromptGuard integration: fail-open, event hooks, images, docs

- Add block_on_error config (default fail-closed, configurable fail-open)
- Declare supported_event_hooks (pre_call, post_call) like other vendors
- Forward images from GenericGuardrailAPIInputs to PromptGuard API
- Wrap API call in try/except for resilient error handling
- Add comprehensive documentation page with config examples
- Register docs page in sidebar alongside other guardrail providers
- Expand test suite from 32 to 40 tests covering new functionality

* Fix dict[str, Any] -> Dict[str, Any] for Python 3.8 compat

* Address remaining Greptile feedback: timeout, redact guard

- Add explicit 10s timeout to async_handler.post() to prevent
  indefinite hangs when PromptGuard API is unresponsive
- Guard redact path: only update inputs["texts"] when the key
  was originally present, avoiding phantom key injection
- Add test: redact with structured_messages only does not create
  texts key (41 tests total)

* Fix CI lint: black formatting, add PromptGuardConfigModel to LitellmParams

- Reformat promptguard.py to match CI black version (parenthesization)
- Add PromptGuardConfigModel as base class of LitellmParams for proper
  Pydantic schema validation, consistent with all other guardrail vendors
- Use litellm_params.block_on_error directly (now a typed field)

* Address Greptile review: redact path, null decision, error context

- P1: Filter _extract_texts_from_messages to user-role messages only,
  preventing system/assistant content from being injected into texts
- P1: Strengthen test_redact_updates_structured_messages assertion from
  weak `in` check to strict equality, catching the injection bug
- P2: Use `result.get("decision") or "allow"` to handle explicit null
  decision values (not just absent keys)
- P2: Wrap bare exception re-raise in GuardrailRaisedException so the
  caller knows which guardrail failed (block_on_error=True path)
- P2: Add static Promptguard entry in guardrail_provider_map so the
  preset works before populateGuardrailProviderMap is called
- Add test for explicit null decision treated as allow

* Fix black formatting: collapse f-string in error message
2026-04-09 08:12:24 -07:00
Lucas Song
0ba8adffed fix(ui): use mutation for attachment delete
Adopt a React Query mutation for policy attachment deletion and add a pending-state test on the policies index panel. This removes local delete-loading state and keeps modal loading tied to mutation status.

Made-with: Cursor
2026-04-09 01:20:34 -07:00
Yuneng Jiang
e42baeb5ab
[Refactor] UI - Virtual Keys: migrate regenerate key modal to AntD
Replace Tremor components in the regenerate key modal with Ant Design
equivalents and move the component to a new PascalCase file. The form
layout now uses Row/Col to place Max Budget, TPM Limit, and RPM Limit
on one row and Expire Key with Grace Period on another, reducing the
vertical footprint. The success view shows an Alert banner, the key
alias as secondary context, and the regenerated key in a monospace
block with an inline primary Copy button.

Also adds unit tests for the new component and updates the existing
Playwright spec to match the new banner and button text.
2026-04-08 23:52:25 -07:00
Yuneng Jiang
e8c51ecd7c
fix: address PR review - allow clearing router settings, remove unused modelData prop
- Send router_settings when clearing existing settings (so backend
  updates instead of silently retaining old values)
- Remove unused modelData prop from RouterSettingsAccordion (it fetches
  models internally via fetchAvailableModels)
2026-04-08 22:24:21 -07:00
Yuneng Jiang
4ba9219e1d
fix: exclude defaults from hasValues check to avoid overwriting router settings
enable_tag_filtering: false (the default) passed the hasValues guard,
causing every team save to send router_settings even for teams that
never had them configured. This could silently overwrite backend-set
values. Now exclude false and empty arrays from the check.
2026-04-08 22:15:38 -07:00
Yuneng Jiang
20ed120d1a
[Fix] Let setSecureItem propagate storage errors to callers
Remove the silent try/catch from setSecureItem so OAuth hooks can
surface actionable "enable storage" guidance instead of a cryptic
"state lost" error after the round-trip. Add a local try/catch in
ChatUI where the storage write is non-critical.
2026-04-08 22:13:55 -07:00
Yuneng Jiang
ce6973109a
fix: add getRouterSettingsCall mock to TeamInfo tests 2026-04-08 21:47:34 -07:00
Yuneng Jiang
f6d5d70903
refactor: simplify router settings integration - use ref-only, no onChange loop
Remove the onChange/value feedback loop between TeamInfo and
RouterSettingsAccordion. The parent passes initial value once and reads
current values at save time via ref.getValue(). This eliminates the
circular data flow that caused stale state and fallback tab resets.
2026-04-08 21:47:34 -07:00
Yuneng Jiang
7d3c0b1cac
fix: prevent internal onChange from re-initializing fallback groups
When a fallback model was selected, the onChange effect fired, parent
re-rendered with new value prop, and the useEffect re-initialized the
groups with new IDs from fallbacksToGroups. This caused the active
fallback group tab to reset to Group 1. Now internal updates always
skip re-initialization regardless of value key changes.
2026-04-08 21:47:34 -07:00
Yuneng Jiang
aa9319128e
Revert "fix: make RouterSettingsAccordion tabs controlled to prevent tab reset"
This reverts commit 9ff4bf66b03912f2c1ab893d2bdb31fba0ea9488.
2026-04-08 21:47:34 -07:00
Yuneng Jiang
25dd4f3e7a
fix: make RouterSettingsAccordion tabs controlled to prevent tab reset
The uncontrolled TabGroup reset to the first tab whenever the component
re-rendered due to onChange state updates. Using controlled index/onIndexChange
keeps the user on the current tab during fallback selection.
2026-04-08 21:47:34 -07:00
Yuneng Jiang
f93db822fd
fix: treat empty router settings inputs as null instead of preserving old values
When a user clears a numeric field in the RouterSettingsAccordion, the empty
input should result in null, not fall through to the previous value from state.
2026-04-08 21:47:34 -07:00
Yuneng Jiang
7654234f20
fix: use ref to read router settings at save time instead of stale state
The RouterSettingsAccordion uses uncontrolled DOM inputs for numeric fields.
The onChange effect only fires when formValue or fallbacks change, not when
the user types into uncontrolled inputs. Using the ref's getValue() method
at save time ensures we read fresh values from the DOM.
2026-04-08 21:47:34 -07:00
Yuneng Jiang
a449cf801f
fix: reset router settings state on cancel to prevent stale data 2026-04-08 21:47:34 -07:00
Yuneng Jiang
6fd7a3ec76
[Feature] UI - Teams: Add router settings to team Settings tab
Add RouterSettingsAccordion to the team edit form and a read-only
display of router settings (routing strategy, retries, fallbacks,
cooldown, timeout, tag filtering) in the Settings tab.
2026-04-08 21:47:34 -07:00
Yuneng Jiang
70a5c27cbd
[Fix] Address review feedback on storage utility and Dockerfiles
- Dockerfile.health_check: HEALTHCHECK now verifies the script is intact
  instead of unconditionally exiting 0
- secureStorage.ts: replace deprecated escape/unescape with
  encodeURIComponent/decodeURIComponent; don't delete legacy values on
  decode failure so in-flight flows can time out naturally
- OAuth callback: add same-origin check before redirecting to stored
  return URL
2026-04-08 17:51:34 -07:00
Yuneng Jiang
a881ac5133
[Fix] UI: resolve CodeQL security alerts and Dockerfile.health_check hardening
Port security fixes from litellm_v1.82.3.dev.6:
- Use secureStorage (sessionStorage wrapper) instead of raw storage for tokens
- Add URL validation for stored worker URLs to prevent open redirects
- Add same-origin checks before redirecting to stored return URLs
- Harden Dockerfile.health_check with non-root user and exec-form HEALTHCHECK
2026-04-08 17:21:25 -07:00
Yuneng Jiang
467dbc4a3c
[Fix] Remove old broken key tests superseded by proxy-admin/keys.spec.ts 2026-04-08 13:32:37 -07:00
Yuneng Jiang
4ee7d42981
[Fix] Restructure HTML files after UI build so extensionless routes work in CI 2026-04-08 13:24:52 -07:00
Yuneng Jiang
a8f4f464ce
[Fix] Add missing test fixtures and address review feedback
- Add constants.ts with all required exports (key aliases, team IDs)
- Add fixtures/users.ts with all role definitions and storage paths
- Add fixtures/seed.sql for deterministic test database seeding
- Remove Firefox project from playwright config (only Chromium installed)
- Remove unused variable in teams.spec.ts
- Rename CircleCI job to e2e_ui_testing
2026-04-08 12:40:41 -07:00
Yuneng Jiang
d09d98a70a
[Feature] E2E UI tests: proxy-admin team and key management with CI integration
Add Playwright E2E tests covering proxy admin team and key management
workflows, with a self-contained test runner and CircleCI integration.

Tests cover: create team, invite user, edit/delete team members, create
key in team, regenerate key, update TPM/RPM limits, delete key, and
verify internal user keys are visible.

Infrastructure: run_e2e.sh builds the UI from source before starting
the proxy, ensuring tests always run against the latest UI changes.
Added data-testid attributes to key UI components for reliable selectors.
2026-04-08 11:51:15 -07:00
Lucas Song
727a6f21b8
Update ui/litellm-dashboard/src/components/policies/index.tsx
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-04-08 01:03:19 -07:00
Lucas Song
a02ec3bfa0 fix(ui): delete policy attachments via controlled modal
Replace static Modal.confirm with DeleteResourceModal so attachment delete reliably triggers the API call. Add a regression test covering the confirm->delete flow.

Made-with: Cursor
2026-04-07 23:06:13 -07:00
ishaan-berri
e3c8867a37
Potential fix for pull request finding 'CodeQL / Unused variable, import, function or class'
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-07 09:33:12 -07:00
ishaan-berri
0a1ded5d54
Potential fix for pull request finding 'CodeQL / Unused variable, import, function or class'
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-07 09:32:49 -07:00
ishaan-berri
67e491cca5
Potential fix for pull request finding 'CodeQL / Syntax error'
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-07 09:32:40 -07:00
Yuneng Jiang
54f4be6ab6
Merge remote-tracking branch 'origin/main' into litellm_ui_e2e_psql_pr 2026-04-06 23:18:35 -07:00