Skip to content

fix(ui): show team BYOK models in team fallback settings - #36241

Merged
ryan-crabbe-berri merged 3 commits into
litellm_internal_stagingfrom
litellm_fallback_ui_team_byok_models
Aug 8, 2026
Merged

fix(ui): show team BYOK models in team fallback settings#36241
ryan-crabbe-berri merged 3 commits into
litellm_internal_stagingfrom
litellm_fallback_ui_team_byok_models

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

TLDR

Problem this solves:

  • Team fallback UI hid the team's own BYOK models
  • Team settings loaded the proxy wide model listing

How it solves it:

  • Team settings now passes its team id down
  • Fallback options come from /models?team_id=...

Relevant issues

Linear ticket

Resolves LIT-5299

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

Repro and verification against a live proxy on localhost:4000 with the Admin UI dev server on localhost:3000, using a team that owns a BYOK wildcard deployment (model_name: openai/* with model_info.team_id set)

Before, at commit ca2ed49e2a:

  1. Go to http://localhost:3000/teams/?team=<TEAM_ID>, Settings, Edit Settings, Router Settings, Fallbacks
  2. Open the Primary Model dropdown. Only gpt-5-mini is listed, none of the team's openai/* models appear

The backend already exposes both listings, which is what the dropdown difference comes down to:

curl -s http://localhost:4000/models -H "Authorization: Bearer $LITELLM_MASTER_KEY" | jq '.data | length'
1
curl -s "http://localhost:4000/models?team_id=<TEAM_ID>" -H "Authorization: Bearer $LITELLM_MASTER_KEY" | jq '.data | length'
213
curl -s "http://localhost:4000/models?team_id=<TEAM_ID>" -H "Authorization: Bearer $LITELLM_MASTER_KEY" | jq -r '.data[].id' | grep -E '^openai/(\*|gpt-5\.2)$'
openai/*
openai/gpt-5.2

After, at commit 4166054, same steps:

  1. Typing openai in Primary Model now lists openai/* and every expansion; pick openai/gpt-5.2
  2. In Fallback Chain, type openai/* and select it
  3. Click Save Changes. The UI shows "Team settings updated successfully" and the saved router settings persist on reload

Re-verified the same flow at commit 49efcfb after the react-query refactor, this time picking openai/gpt-5.6 with an openai/* fallback chain: the dropdown lists the team's openai/* expansions, the save succeeds, and /team/info returns the persisted fallbacks. Screenshots are in the PR comments

Type

🐛 Bug Fix
🧹 Refactoring

Changes

RouterSettingsAccordion is shared by the global Router Settings page and the per team settings form, and it always built its fallback options from fetchAvailableModels, which hits /model_group/info. That listing resolves with no team id, so Router.get_model_names drops team scoped rows and a team's own BYOK models never showed up, even while you were editing that exact team.

The accordion now takes an optional teamId and, when present, loads options from the team aware /models?team_id=... route through a new fetchAvailableModelsForTeam helper. TeamInfo passes the team id it already has. Global Router Settings passes nothing, so its behavior is unchanged.

The model fetch now goes through react-query instead of a hand-rolled effect: useQuery keyed on the access token and team id replaces the local state plus manual stale-response guard, since the dashboard already ships @tanstack/react-query with a provider at the app root. Out of order responses are handled by query keying, and the component tests render under a QueryClientProvider

Final Attestation

  • The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR

Link to Devin session: https://app.devin.ai/sessions/c2770b07352e4073b24895ec26693f2b

Team router settings loaded fallback options from /model_group/info, which resolves models without a team, so a team's own BYOK deployments were never selectable in its own fallback config. Load the team-scoped listing when a team id is present.

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

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@CLAassistant

CLAassistant commented Aug 8, 2026

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.

✅ ryan-crabbe-berri
❌ devin-ai-integration[bot]
You have signed the CLA already but the status is still pending? Let us recheck it.

@greptile-apps

greptile-apps Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR fixes team fallback settings by loading team-scoped models through a team-aware query while preserving the proxy-wide behavior for global router settings

  • Passes the current team ID into RouterSettingsAccordion
  • Adds a helper that converts /models?team_id=... results into fallback model groups
  • Uses a team-specific TanStack Query key so late responses from previously selected teams cannot replace the current options
  • Adds coverage for team-scoped models, global fallback behavior, and overlapping team requests

Confidence Score: 5/5

The PR appears safe to merge

No blocking failure remains

Important Files Changed

Filename Overview
ui/litellm-dashboard/src/components/common_components/RouterSettingsAccordion.tsx Replaces manually managed model-fetch state with a query keyed by access token and team ID, resolving the previously reported stale-response race
ui/litellm-dashboard/src/components/llm_calls/fetch_models.tsx Adds a team-aware model-list helper that deduplicates, filters, sorts, and maps model IDs for fallback selection
ui/litellm-dashboard/src/components/team/TeamInfo.tsx Passes the active team ID into the shared router settings accordion
ui/litellm-dashboard/src/components/common_components/RouterSettingsAccordion.test.tsx Covers team and global model sources and verifies that a late response for an old team does not replace the current team's options
ui/litellm-dashboard/src/components/llm_calls/fetch_models.test.tsx Verifies team-scoped endpoint arguments, sentinel filtering, deduplication, sorting, and empty responses

Reviews (3): Last reviewed commit: "refactor(ui): use react-query for fallba..." | Re-trigger Greptile

Comment thread ui/litellm-dashboard/src/components/common_components/RouterSettingsAccordion.tsx Outdated
@devin-ai-integration

devin-ai-integration Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

Tested end to end against a local proxy with a team that owns a BYOK wildcard deployment openai/* registered with model_info.team_id, hitting the real OpenAI API.

Setup: a proxy-level model demo-proxy-model (openai/gpt-4.1-mini with a deliberately broken key) assigned to that team, plus the team's own BYOK wildcard with a working key. All requests use a team-scoped virtual key.

Before configuring anything, the failing model has nothing to fall back to:

$ curl -sS -i -X POST http://localhost:4000/v1/chat/completions \
    -H "Authorization: Bearer $TK" -H "Content-Type: application/json" \
    -d '{"model":"demo-proxy-model","messages":[{"role":"user","content":"Say hello in 3 words."}]}'

HTTP/1.1 401 Unauthorized
{"error":{"message":"litellm.AuthenticationError: ... Received Model Group=demo-proxy-model\nAvailable Model Group Fallbacks=None","code":"401"}}

openai/gpt-4.1-mini is only offered in the Fallback Chain because of this PR. The old team-agnostic listing does not have it:

$ curl -s -H "Authorization: Bearer $KEY" localhost:4000/model_group/info | jq -c '[.data[].model_group]'
["gpt-5-mini","demo-proxy-model"]

In Team Settings > Edit Settings > Router Settings > Fallbacks, the team's BYOK model shows up and is selectable:

Fallback Chain offers the team BYOK openai/gpt-4.1-mini

Configured fallback demo-proxy-model to openai/gpt-4.1-mini

Same request now succeeds, and the headers prove it landed on the team's BYOK deployment at real OpenAI

Successful fallback with LiteLLM headers

HTTP/1.1 200 OK
x-litellm-model-id: 225329bb-bb05-4697-8d40-faf416f2bb92
x-litellm-model-api-base: https://api.openai.com
x-litellm-model-group: openai/gpt-4.1-mini
x-litellm-attempted-fallbacks: 1
{"model":"gpt-4.1-mini-2025-04-14","choices":[{"message":{"content":"Hello there, friend!","role":"assistant"}}],...}

x-litellm-model-id is the team-owned BYOK wildcard deployment, so the fallback configured in the UI is what served the request

Persistence

Fallbacks: 1 configured after reload

Re-opened form round-trip

$ curl -s -H "Authorization: Bearer $KEY" "localhost:4000/team/info?team_id=$TEAM" | jq -c .team_info.router_settings.fallbacks
[{"demo-proxy-model":["openai/gpt-4.1-mini"]}]
Regression: global admin Router Settings unchanged

Global router settings fallbacks

Still loads the proxy-wide listing only (demo-proxy-model, gpt-5-mini), searching openai returns "No data", no console errors

Dashboard unit tests: 7 passed, including the new stale-response case

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

Copy link
Copy Markdown
Contributor

@greptileai re review

@ryan-crabbe-berri

Copy link
Copy Markdown
Contributor

Re-QA at 49efcfb after the react-query refactor: the dropdown lists the team's openai/* expansions, the fallback saves and persists after reload

primary model dropdown listing the team openai wildcard models

fallback chain configured with openai/gpt-5.6 and openai wildcard

team settings showing one configured fallback after reload

@ryan-crabbe-berri

Copy link
Copy Markdown
Contributor

@greptileai

@ryan-crabbe-berri
ryan-crabbe-berri enabled auto-merge (squash) August 8, 2026 19:21
@codecov

codecov Bot commented Aug 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@ryan-crabbe-berri
ryan-crabbe-berri merged commit cfd64d4 into litellm_internal_staging Aug 8, 2026
77 checks passed
@ryan-crabbe-berri
ryan-crabbe-berri deleted the litellm_fallback_ui_team_byok_models branch August 8, 2026 19:28
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.

2 participants