Skip to content

fix(ui): scope key models dropdown options to the key's team - #32382

Merged
mubashir1osmani merged 11 commits into
litellm_internal_stagingfrom
litellm_key_models_dropdown_team_gating
Jul 8, 2026
Merged

fix(ui): scope key models dropdown options to the key's team#32382
mubashir1osmani merged 11 commits into
litellm_internal_stagingfrom
litellm_key_models_dropdown_team_gating

Conversation

@mubashir1osmani

@mubashir1osmani mubashir1osmani commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Relevant issues

Linear ticket

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have added meaningful tests
  • My PR passes all CI/CD checks (e.g., lint, format, unit tests)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review (Greptile reviews automatically once the PR is opened; only comment @greptileai to re-request a review after pushing changes)

Delays in PR merge?

If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).

Screenshots / Proof of Fix

no team attached
Screenshot 2026-07-07 at 3 18 24 PM

team attached
Screenshot 2026-07-07 at 3 12 19 PM

Screenshots from a live proxy follow in the comments. To reproduce on a dashboard built from this branch, against a proxy on http://localhost:4000 with master key sk-1234 and a team whose models include all-proxy-models:

  1. Open the Virtual Keys page and the create key modal (or go straight to /ui/api-keys/?create=true)
  2. Leave Team unset and open the Models dropdown: All Proxy Models is offered, All Team Models is not
  3. Select the team and reopen the Models dropdown: All Team Models and the team's individual models are offered, All Proxy Models is not, even though the team's own model list carries it
  4. Open an existing teamless key, then Settings, then Edit Settings, then the Models dropdown: All Proxy Models is offered, All Team Models is not
  5. Open a team key the same way: All Team Models is offered, all-proxy-models is not

The new browser e2e tests walk the same steps headlessly against the proxy-served UI, submit the create modal with the offered sentinel for both the teamless and team paths, and read the created keys back through /key/info:

uv pip install playwright
uv run playwright install chromium
uv run pytest tests/e2e/management/test_key_models_dropdown_e2e.py -v

They read LITELLM_PROXY_URL (default http://localhost:4000) and need the proxy to serve a dashboard containing this change, so either a proxy whose bundled UI was rebuilt from this branch or the compose stack pointed at a locally built image (docker build -t litellm-local . then LITELLM_E2E_IMAGE=litellm-local docker compose up -d from tests/e2e/)

Type

🐛 Bug Fix

Changes

The key create and edit forms offered Models dropdown options that do not match the key's team context. A teamless key was offered all-team-models, which the backend expands to the full proxy model list when no team is attached, so picking it silently created an unrestricted key. A team key was offered all-proxy-models whenever the team's own model list carried that sentinel, because both forms merge team.models into the pickable list verbatim

The create modal (create_key_button.tsx, also mounted by the newer api-keys page) and the edit form (key_edit_view.tsx) now render All Team Models only when the key has a team, and offer All Proxy Models in its place when it does not, so a teamless key can still be granted every proxy model explicitly. A shared excludeProxyWideSentinel helper filters all-proxy-models out of the merged team model list in both forms; the team's individual models stay selectable so a key can still be scoped to a subset. no-default-models is deliberately not filtered because the create form uses its presence to force team selection

Component tests in create_key_button.test.tsx and key_edit_view.test.tsx pin the option pair for both team contexts on both forms, with assertions scoped to the models select; each rule was verified to fail with the gate or the filter reverted

The tests/e2e/management/ suite gains browser coverage on the shared harness: playwright logs into the dashboard the proxy serves at /ui, asserts the dropdown options a user actually sees for teamless and team keys on both create and edit, and walks the create modal end to end for both paths, submitting the offered sentinel and asserting through /key/info that the key persisted with the right models and team_id. The suite's conftest gains browser and logged-in page fixtures; playwright stays out of the project dependencies as an optional install behind importorskip (same pattern as pipecat in the realtime suite), so the suite's API tests collect and run without it. tests/e2e/docker-compose.yml gains an overridable proxy image (LITELLM_E2E_IMAGE) plus pinned UI credentials, the coverage registry gains a mgmt.key.update.happy_path UI row, and the install steps are documented in tests/e2e/CONTRIBUTING.md


Note

Medium Risk
Changes how API key model scope is chosen in the dashboard, which affects authorization breadth; backend rules are unchanged but mis-selection previously could grant wider access than intended.

Overview
Fixes the virtual-key Models dropdown on create and edit so the “all models” sentinel matches whether the key has a team.

Teamless keys now offer All Proxy Models (all-proxy-models) and no longer show All Team Models, which could expand to the full proxy list without a team. Team keys offer All Team Models plus the team’s models, while all-proxy-models is stripped from the merged list via excludeProxyWideSentinel even when the team’s model list includes that sentinel. Picking a sentinel collapses the selection to that value alone and disables individual model options while it is selected.

Coverage adds component tests, a Playwright management e2e suite (optional dependency, logged-in /ui fixtures), compose UI credentials, and an updated dashboard e2e spec for teamless create.

Reviewed by Cursor Bugbot for commit ed0e718. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • New Features

    • Improved API key “Models” selection so users see the correct special options (“All Proxy Models” vs “All Team Models”) based on whether a team is selected.
    • Added Playwright e2e coverage for dashboard key model-scoping behavior.
  • Bug Fixes

    • Fixed sentinel handling so the wrong “all models” option no longer appears.
    • Disabled individual model choices when an “all models” sentinel is selected and ensured consistent dropdown option scoping for create/edit flows.
  • Documentation

    • Updated e2e suite docs to explain dashboard/UI testing via /ui.
  • Tests

    • Added a new key models dropdown scoping e2e test and enhanced existing Playwright specs.

@mubashir1osmani
mubashir1osmani requested a review from a team July 7, 2026 21:32
@greptile-apps

greptile-apps Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a UI bug where the key create and edit forms offered the wrong "all models" sentinel option based on team context — teamless keys were offered All Team Models (which the backend expands to full proxy access when no team is attached) and team keys were exposed All Proxy Models even when the team's own model list contained that sentinel.

  • excludeProxyWideSentinel and hasAllModelsSentinel helpers are extracted into fetch_available_models_team_key.tsx and applied in both create_key_button.tsx and key_edit_view.tsx, so the merged team model list never surfaces the all-proxy-models sentinel as a raw option.
  • The sentinel option pair is now team-context-aware: "All Proxy Models" when no team is set, "All Team Models" (guarded behind team != null) when a team is resolved, and individual model options are disabled once either sentinel is selected.
  • Coverage is added at three layers: component tests (mock-Select with native <select> for create_key_button, real Ant Design Select with fireEvent.mouseDown for key_edit_view), an updated Playwright spec for the existing proxy-admin key test, and new Playwright e2e tests that log into the running proxy UI, assert dropdown options, and verify persisted models/team_id via /key/info.

Confidence Score: 5/5

Safe to merge — the changes are UI-only, narrowly scoped to the key create/edit model dropdown, and every sentinel-routing path is covered by component tests and e2e tests.

The two previously flagged blockers are resolved: excludeProxyWideSentinel is now applied in the teamless modelAvailableCall path in key_edit_view.tsx, preventing a duplicate all-proxy-models option; and "All Team Models" is gated behind team != null rather than keyData.team_id != null, so the option is suppressed while team data is still loading. No new access-control or data-corruption paths were introduced.

No files require special attention. The e2e test file (test_key_models_dropdown_e2e.py) requires a proxy configured with a gpt-5.5 deployment, but this is documented in the test file itself.

Important Files Changed

Filename Overview
ui/litellm-dashboard/src/components/key_team_helpers/fetch_available_models_team_key.tsx Adds excludeProxyWideSentinel (strips all-proxy-models from a model list) and hasAllModelsSentinel (detects either sentinel) as shared helpers used by both form components.
ui/litellm-dashboard/src/components/organisms/create_key_button.tsx Applies excludeProxyWideSentinel to merged team models, adds hardcoded "All Proxy Models" option for teamless keys (hidden when a team is selected), and disables individual model options once a sentinel is chosen via Form.useWatch.
ui/litellm-dashboard/src/components/templates/key_edit_view.tsx Applies excludeProxyWideSentinel in both teamless and team model-fetch paths, guards "All Team Models" option behind team != null (fixing the loading-state regression), and collapses sentinel selections to a single value in the onChange handler.
ui/litellm-dashboard/src/components/organisms/create_key_button.test.tsx Adds "models dropdown team gating" describe block with two new tests; updates team-dropdown mock to pass full team objects via onTeamSelect; switches fetch_available_models_team_key mock to importActual so real helper functions are exercised.
ui/litellm-dashboard/src/components/templates/key_edit_view.test.tsx Adds six new tests covering all four team-context sentinel rules (teamless/team, show/hide), a deduplication guard, sentinel collapsing, and a regression test for the loading-state guard (teams=[] yields no sentinel).
tests/e2e/management/test_key_models_dropdown_e2e.py New Playwright-based e2e suite covering all four dropdown scenarios end-to-end; sentinel-specific assertions and model creation/verification flow are well-structured, but correctness relies on the test proxy serving the gpt-5.5 model.
tests/e2e/management/conftest.py Adds optional browser (session-scoped) and ui_page (function-scoped) fixtures using importorskip so API tests continue to run without Playwright installed.
tests/e2e/docker-compose.yml Adds UI_USERNAME / UI_PASSWORD env vars to the proxy service so browser tests can log in; supports an overridable LITELLM_E2E_IMAGE for testing locally-built UI images.
tests/e2e/e2e_config.py Exports UI_USERNAME / UI_PASSWORD driven by E2E_UI_USERNAME / E2E_UI_PASSWORD env vars, defaulting to the same credentials as the compose stack.

Reviews (4): Last reviewed commit: "fix(e2e): inline PROXY_BASE_URL/ui after..." | Re-trigger Greptile

Comment thread ui/litellm-dashboard/src/components/templates/key_edit_view.tsx Outdated
@codecov

codecov Bot commented Jul 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

A teamless key no longer offers the all-team-models option in the create and
edit forms; the backend expands that sentinel to the full proxy model list when
no team is attached, which is rarely what the user intended. A team key no
longer surfaces the all-proxy-models sentinel that leaks in verbatim when the
team's own model list carries it; the dropdown keeps All Team Models plus the
team's individual models.

Adds browser coverage to the management e2e suite: playwright (an optional
dependency behind importorskip) drives the proxy-served dashboard at /ui,
asserts the dropdown options a real user sees for teamless and team keys on
both create and edit, and walks the create modal end to end, reading the
persisted key back through /key/info.
@mubashir1osmani
mubashir1osmani force-pushed the litellm_key_models_dropdown_team_gating branch from bba46a0 to cebf39d Compare July 7, 2026 21:59
@codspeed-hq

codspeed-hq Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will improve performance by 13.27%

⚡ 2 improved benchmarks
❌ 1 regressed benchmark
✅ 27 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
test_completion_multi_turn 3.1 ms 4.2 ms -25.25%
test_completion_simple_message 4.8 ms 3.2 ms +47.76%
test_completion_with_tools 4.2 ms 3.2 ms +31.59%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing litellm_key_models_dropdown_team_gating (ed0e718) with litellm_internal_staging (db24027)

Open in CodSpeed

A teamless key has no team allowlist to inherit, so the dropdown now offers All
Proxy Models in place of All Team Models on both the create and edit forms, with
the same exclusive-selection handling. Component and browser e2e tests updated to
pin the swapped option pair; the teamless create case now also walks the modal end
to end and reads the persisted key back through /key/info.
The create modal no longer offers All Team Models without a team; the teamless
path now offers All Proxy Models, which is what this spec exercises
@mubashir1osmani

Copy link
Copy Markdown
Contributor Author

@greptile-apps

When a key has a team_id but the teams prop does not yet include the matching team, availableModels stays empty and the models dropdown rendered All Team Models on its own with nothing to compare against. Gate the option on the team object being present so it only appears once team models are known, and add a regression test for the loading state

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

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ mubashir1osmani
❌ Mubashir Osmani


Mubashir Osmani seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@devin-ai-integration

Copy link
Copy Markdown
Contributor

On the confidence-score note about create_key_button.test.tsx not opening the Models dropdown: those tests aren't trivially passing. The suite mocks antd and renders Select.Option as a native <option> element, so every option is in the DOM whether or not the dropdown is open, and the assertions are scoped with within(modelsSelect). I mutation-checked this by reverting the create-form gate (!selectedProjectId && selectedCreateKeyTeam back to !selectedProjectId) and the teamless test fails: getByText("All Team Models") ... found <option>All Team Models</option> instead. The edit-form tests use real antd and do open the dropdown via mouseDown on the selector.

Pushed 57ba070 to address the P2 on key_edit_view.tsx (gating All Team Models on the resolved team object for the loading state). @greptileai

@greptile-apps

greptile-apps Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Thanks for the clarification on the mock strategy — the antd shim rendering Select.Option as native <option> elements makes the DOM-without-open approach legitimate, and the mutation check (reverting the gate causes the teamless assertion to fail on the visible node) is the right way to verify these aren't vacuous. That concern is resolved.

57ba070 also looks correct: gating on the resolved team object rather than keyData.team_id means the "All Team Models" option stays suppressed during the loading window, and the regression test (team key with empty teams prop → neither sentinel offered) will catch any future regression. This is exactly the guard I had in mind. P2 addressed.

Tip: You can customize Greptile's behavior for this repo with .greptile/rules.md and .greptile/config.json.

@mubashir1osmani

Copy link
Copy Markdown
Contributor Author

@greptile-apps

…t form

The teamless fetch path stored modelAvailableCall results without excludeProxyWideSentinel, so an all-proxy-models entry in the response rendered a second option colliding with the hardcoded All Proxy Models sentinel. Apply the same filter used on the team path and add a regression test asserting the sentinel option is not duplicated

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

Copy link
Copy Markdown
Contributor

Addressed the remaining item from the 4/5 summary in 46e2f2c. The teamless fetch path in key_edit_view.tsx now runs modelAvailableCall's result through excludeProxyWideSentinel before setAvailableModels, matching the team path, so an all-proxy-models entry in the response no longer renders a second option colliding with the hardcoded All Proxy Models sentinel. Added a regression test that stubs modelAvailableCall to return all-proxy-models for a teamless key and asserts the dropdown carries exactly one All Proxy Models option and no raw all-proxy-models duplicate; reverting the filter breaks that dropdown (two options share the same value) and the test fails. @greptileai

@greptile-apps

greptile-apps Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

The fix is solid. Looking at the key_edit_view.tsx changes in this commit:

  1. Teamless path deduplication: excludeProxyWideSentinel is now applied before setAvailableModels on both the teamless (modelAvailableCall) and team paths — so even if the API returns all-proxy-models in the model list, it won't render a second raw option colliding with the hardcoded "All Proxy Models" sentinel.

  2. Loading-state guard: The sentinel rendering is now keyData.team_id != null ? (team != null && <All Team Models>) : (<All Proxy Models>) — a key with team_id set but teams prop not yet resolved shows neither sentinel (gated on team != null), and the regression test for that case (teams={[]}) is included.

  3. Regression test: The new "should not duplicate the all-proxy-models option" test correctly stubs modelAvailableCall to return all-proxy-models in the response and asserts exactly one "All Proxy Models" option with no raw all-proxy-models duplicate — this will fail if either the filter or the static sentinel is removed.

All three points from the original feedback are addressed. Looks good to me.

@mubashir1osmani
mubashir1osmani enabled auto-merge (squash) July 8, 2026 00:13

@mateo-berri mateo-berri left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the edit form's onChange is a plain pass-through, so a user can submit a mixed list like ["all-proxy-models", "gpt-4"]. The PR's own design intent (visible in the create-form handler it adds) is exclusive selection, making this an oversight rather than a deliberate trade-off

Is this a valid concern?

@mateo-berri

Copy link
Copy Markdown
Contributor

bugbot run

@mateo-berri

Copy link
Copy Markdown
Contributor

@coderabbitai review (just using coderabbit to compare with bugbot. Don't treat its comments as blocking)

…dit form

The edit form models Select had a pass-through onChange, so a user could submit a mixed list like ["all-proxy-models", "gpt-4"] even though the sentinels are meant to be exclusive. Mirror the create form and collapse the selection to the sentinel when all-proxy-models or all-team-models is picked; add a regression test that selects a model plus the proxy sentinel and asserts the submitted models list is just ["all-proxy-models"]

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

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
gh pr view 32382 --repo BerriAI/litellm --json files,additions,deletions,changedFiles -q '.files[].path'
echo "---DIFF---"
gh pr diff 32382 --repo BerriAI/litellm > /tmp/pr.diff
wc -l /tmp/pr.diff

Length of output: 1041


🏁 Script executed:

#!/bin/bash
set -euo pipefail
sed -n '1,800p' /tmp/pr.diff

Length of output: 36067


The PR description image (3:18:24 PM) shows a "Key Ownership" modal with no team selected (Team field is blank, placeholder "Search or select a team"). The Models dropdown is open showing: "All Proxy Models", "gpt-5.5", "claude-haiku-4-5", "gemini-2.5-flash", "openai-text-embedding-3-small", "e2e-vs-chat-590f68c6195b", "e2e-vs-chat-8ec751388f40" — notably no "All Team Models" option.

The PR description image (3:12:19 PM) shows the same modal with Team set to "toes (d68bf164-e893-4bb8-ac6b-1b27472c0cac)". The Models dropdown now shows "All Team Models" (highlighted), "gemini-2.5-flash", "gpt-5.5", "openai-text-embedding-3-small" — notably no "All Proxy Models" option, and a "Create Key" button is visible.

@mateo-berri Reviewed the diff. Overall the fix looks correct and well-tested. Summary of what I checked:

Core logic (fetch_available_models_team_key.tsx, create_key_button.tsx, key_edit_view.tsx)

  • excludeProxyWideSentinel correctly strips only all-proxy-models from the merged team model list, leaving no-default-models untouched as documented — intentional since the create form uses its presence to force team selection.
  • In create_key_button.tsx, the all-team-models/all-proxy-models Options are now mutually exclusive based on selectedCreateKeyTeam, and the onChange handler pins the selection to whichever sentinel is picked (mirroring the existing all-team-models behavior for the new all-proxy-models case). No duplicate rendering since the sentinel is excluded from modelsToPick before the static Option is added.
  • In key_edit_view.tsx, the previous availableModels.length > 0 gate for "All Team Models" was replaced by a team != null check keyed off keyData.team_id. This is a behavior change: previously a team key with an empty resolved model list wouldn't show "All Team Models" at all; now it will as long as team has loaded, regardless of whether team.models is empty. This looks intentional per the PR description, but worth double-checking it's the desired behavior for teams with zero assigned models — could confirm with a quick manual test if not already covered.
  • The "team not yet loaded" case (team == null while keyData.team_id is set) correctly renders neither sentinel option, avoiding a flash of the wrong option — nice, and it's covered by a dedicated test.

Tests

  • Component tests in both *.test.tsx files pin the exact option pairs per team-context, and the new e2e Playwright suite (test_key_models_dropdown_e2e.py) walks the full create/edit flow end-to-end and verifies persistence via /key/info. The existing keys.spec.ts was updated consistently with the new "All Proxy Models" default for teamless keys.
  • Good touch keeping playwright optional via importorskip so the suite's API tests aren't gated on it.

Minor observations (non-blocking, per your note)

  • Same "team's own model list can leak all-proxy-models" pattern might exist in other places that merge team.models (e.g., team/user edit views) — worth a quick grep if you want to close out any sibling instances, though that may be intentionally out of scope for this isolated fix.
  • The e2e docs/scripts changes (docker-compose.yml, CONTRIBUTING.md, e2e_config.py) are clear and self-contained.

No blocking issues found from my side.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@devin-ai-integration

Copy link
Copy Markdown
Contributor

@mateo-berri re "Is this a valid concern?" on the exclusive-selection point: yes, it's valid. The edit form's models onChange was a plain pass-through (setFieldValue("models", value)), so a user could submit ["all-proxy-models", "gpt-4"], which is inconsistent with the create form that collapses to the sentinel. Fixed in 807aa56: the edit form now collapses the selection to ["all-proxy-models"] (or ["all-team-models"]) when a sentinel is picked. Added a regression test that selects gpt-4 then All Proxy Models and asserts the submitted models is exactly ["all-proxy-models"]; it fails if the handler reverts to a pass-through.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 46e2f2c. Configure here.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR updates key create/edit model dropdown handling to distinguish proxy-wide and team-wide sentinel options, adds management Playwright fixtures and docs, and adds browser coverage for team-scoped key model selection.

Changes

Models dropdown team gating

Layer / File(s) Summary
Create key UI and unit tests
ui/litellm-dashboard/src/components/key_team_helpers/fetch_available_models_team_key.tsx, ui/litellm-dashboard/src/components/organisms/create_key_button.tsx, ui/litellm-dashboard/src/components/organisms/create_key_button.test.tsx
Adds sentinel filtering helpers, filters proxy-wide models from create-key options, changes Models dropdown selection and disabling behavior, and updates test mocks and coverage for team-dependent options.
Edit key UI and unit tests
ui/litellm-dashboard/src/components/templates/key_edit_view.tsx, ui/litellm-dashboard/src/components/templates/key_edit_view.test.tsx
Filters edit-view model lists, updates Models dropdown sentinel handling and option gating, and adds edit-flow tests for sentinel deduplication and disabled options.
Management E2E fixtures and docs
tests/e2e/e2e_config.py, tests/e2e/management/conftest.py, tests/e2e/docker-compose.yml, tests/e2e/CLAUDE.md, tests/e2e/CONTRIBUTING.md, tests/e2e/coverage_registry/mgmt.yaml
Adds UI auth config, Playwright browser/page fixtures with login, docker-compose UI credentials, and documentation plus coverage registry updates for the management suite.
Management browser coverage
tests/e2e/management/test_key_models_dropdown_e2e.py, ui/litellm-dashboard/e2e_tests/tests/proxy-admin/keys.spec.ts
Adds Playwright coverage for teamless vs team key Models dropdown behavior and updates the existing dashboard spec to select All Proxy Models for the no-team create flow.

Estimated code review effort: 3 (Moderate) | ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly describes the main fix: scoping key model dropdown options by team context.
Description check ✅ Passed The PR description follows the template well and includes the required sections, checklist, screenshots, type, and change summary.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch litellm_key_models_dropdown_team_gating

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/e2e/management/conftest.py`:
- Around line 45-55: The ui_page fixture can leak a browser context if any setup
step before yield fails, because context.close() is only reached on the happy
path. Update ui_page to ensure the context is always closed even when page.goto,
page.fill, page.click, or page.wait_for_url raises by wrapping the setup/yield
flow in a try/finally or equivalent cleanup pattern. Keep the fix localized to
ui_page and preserve the existing browser.new_context, new_page, and post-yield
cleanup behavior.

In `@tests/e2e/management/test_key_models_dropdown_e2e.py`:
- Around line 22-24: The E402 suppression on the import in the Playwright test
needs an explicit reason comment. Update the `from playwright.sync_api import
Locator, Page, expect` line in `test_key_models_dropdown_e2e.py` so the `noqa`
includes a short justification for the deferred import, and keep the
`pytest.importorskip` guard in place to preserve the current test setup.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 16a9cf62-0ffd-4edc-ab02-110d855b6efb

📥 Commits

Reviewing files that changed from the base of the PR and between 46d9742 and 807aa56.

📒 Files selected for processing (13)
  • tests/e2e/CLAUDE.md
  • tests/e2e/CONTRIBUTING.md
  • tests/e2e/coverage_registry/mgmt.yaml
  • tests/e2e/docker-compose.yml
  • tests/e2e/e2e_config.py
  • tests/e2e/management/conftest.py
  • tests/e2e/management/test_key_models_dropdown_e2e.py
  • ui/litellm-dashboard/e2e_tests/tests/proxy-admin/keys.spec.ts
  • ui/litellm-dashboard/src/components/key_team_helpers/fetch_available_models_team_key.tsx
  • ui/litellm-dashboard/src/components/organisms/create_key_button.test.tsx
  • ui/litellm-dashboard/src/components/organisms/create_key_button.tsx
  • ui/litellm-dashboard/src/components/templates/key_edit_view.test.tsx
  • ui/litellm-dashboard/src/components/templates/key_edit_view.tsx

Comment thread tests/e2e/management/conftest.py Outdated
Comment thread tests/e2e/management/test_key_models_dropdown_e2e.py Outdated
…t noqa

Wrap the ui_page fixture setup in try/finally so the Playwright context is closed even if login (goto/fill/click/wait_for_url) raises before yield, and add a reason to the E402 suppression on the deferred playwright import per repo lint conventions

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

Copy link
Copy Markdown
Contributor Author

shouldnt the subsets be disabled if either "all-proxy-models" or "all-team-models" are selected?

…el is selected

Both key create and edit forms let a user pick individual models even after choosing All Proxy Models / All Team Models; the onChange collapse then silently dropped those picks. Add a shared hasAllModelsSentinel helper and disable the individual model options in both forms whenever a sentinel is selected, so the mutual exclusivity is visible rather than corrected after the fact. Adds an edit-form regression test asserting the individual options become disabled once the proxy sentinel is picked

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

Copy link
Copy Markdown
Contributor

@mubashir1osmani re "shouldnt the subsets be disabled if either all-proxy-models or all-team-models are selected?" — good call, done in fcc37ee. Both the create and edit forms now disable the individual model options whenever all-proxy-models or all-team-models is selected, so the mutual exclusivity is visible up front instead of being silently corrected by the onChange collapse after the fact. Added a shared hasAllModelsSentinel helper and an edit-form regression test that selects All Proxy Models and asserts the individual options become disabled (it fails if the guard is dropped).

mubashir1osmani and others added 3 commits July 7, 2026 21:15
Commit 3827afa removed the UI_BASE_URL definition from e2e_config.py but left it imported and used in the management e2e conftest and key-models dropdown test, so those modules raised ImportError on collection. Inline f"{PROXY_BASE_URL}/ui..." at the call sites, keeping the UI_BASE_URL symbol removed as intended.

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

Copy link
Copy Markdown
Contributor

@greptileai

@mateo-berri

Copy link
Copy Markdown
Contributor

bugbot run

@mateo-berri

Copy link
Copy Markdown
Contributor

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@mateo-berri mateo-berri left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM; thanks!

@mubashir1osmani
mubashir1osmani merged commit a05a1ee into litellm_internal_staging Jul 8, 2026
127 of 128 checks passed
@mubashir1osmani
mubashir1osmani deleted the litellm_key_models_dropdown_team_gating branch July 8, 2026 01:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants