From e27b700345c08fed7d40a1a2f07a3d303a4d7b3d Mon Sep 17 00:00:00 2001 From: milan Date: Tue, 4 Aug 2026 17:36:55 +0000 Subject: [PATCH] fix(ui): let team admins pick All Proxy Models for teams outside an organization Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../ModelSelect/ModelSelect.test.tsx | 30 +++++++++++++++++++ .../components/ModelSelect/ModelSelect.tsx | 4 ++- ui/litellm-dashboard/src/components/Teams.tsx | 1 - .../src/components/team/TeamInfo.tsx | 3 -- 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.test.tsx b/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.test.tsx index e253bc4c0ef..a4d20372cd0 100644 --- a/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.test.tsx +++ b/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.test.tsx @@ -423,6 +423,36 @@ describe("ModelSelect", () => { }, shouldShow: false, }, + { + name: "when a team has no organization and the caller is not a proxy admin", + context: "team" as const, + options: { includeSpecialOptions: true }, + props: { teamID: "team-1" }, + setup: () => { + mockUseTeam.mockReturnValue({ + data: { team_id: "team-1", team_alias: "Test Team", models: ["gpt-4"] }, + isLoading: false, + } as any); + }, + shouldShow: true, + }, + { + name: "when a team belongs to an organization scoped to specific models", + context: "team" as const, + options: { includeSpecialOptions: true }, + props: { teamID: "team-1", organizationID: "org-1" }, + setup: () => { + mockUseTeam.mockReturnValue({ + data: { team_id: "team-1", team_alias: "Test Team", models: ["gpt-4"] }, + isLoading: false, + } as any); + mockUseOrganization.mockReturnValue({ + data: createMockOrganization(["gpt-4"]), + isLoading: false, + } as any); + }, + shouldShow: false, + }, ]; for (const testCase of testCases) { diff --git a/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.tsx b/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.tsx index 0965683c241..b4932a9f847 100644 --- a/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.tsx +++ b/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.tsx @@ -106,8 +106,10 @@ export const ModelSelect = (props: ModelSelectProps) => { const organizationHasAllProxyModels = organization?.models.includes(MODEL_SELECT_ALL_PROXY_MODELS_SPECIAL_VALUE.value) || organization?.models.length === 0; + const teamIsUnscopedByOrganization = context === "team" && !organizationID; + const scopeAllowsAllProxyModels = organizationHasAllProxyModels || teamIsUnscopedByOrganization; const shouldShowAllProxyModels = - showAllProxyModelsOverride || (organizationHasAllProxyModels && includeSpecialOptions) || context === "global"; + showAllProxyModelsOverride || (scopeAllowsAllProxyModels && includeSpecialOptions) || context === "global"; if (isLoading) { return ; diff --git a/ui/litellm-dashboard/src/components/Teams.tsx b/ui/litellm-dashboard/src/components/Teams.tsx index fc89751db6a..87fbd4b1e5d 100644 --- a/ui/litellm-dashboard/src/components/Teams.tsx +++ b/ui/litellm-dashboard/src/components/Teams.tsx @@ -715,7 +715,6 @@ const Teams: React.FC = ({ accessToken, userID, userRole, premiumUser organizationID={form.getFieldValue("organization_id")} options={{ includeSpecialOptions: true, - showAllProxyModelsOverride: !form.getFieldValue("organization_id"), }} context="team" dataTestId="create-team-models-select" diff --git a/ui/litellm-dashboard/src/components/team/TeamInfo.tsx b/ui/litellm-dashboard/src/components/team/TeamInfo.tsx index bbe5dc05a88..88c2338351c 100644 --- a/ui/litellm-dashboard/src/components/team/TeamInfo.tsx +++ b/ui/litellm-dashboard/src/components/team/TeamInfo.tsx @@ -18,7 +18,6 @@ import { useGuardrails, GuardrailListItem } from "@/app/(dashboard)/hooks/guardr import { formatNumberWithCommas } from "@/utils/dataUtils"; import { mapEmptyStringToNull } from "@/utils/keyUpdateUtils"; import type { ObjectPermission } from "@/components/object_permission_types"; -import { isProxyAdminRole } from "@/utils/roles"; import { EditOutlined, GlobalOutlined, @@ -1035,8 +1034,6 @@ const TeamInfoView: React.FC = ({ options={{ includeSpecialOptions: true, includeUserModels: !teamData?.team_info?.organization_id, - showAllProxyModelsOverride: - isProxyAdminRole(userRole) && !teamData?.team_info?.organization_id, }} context="team" dataTestId="models-select"