From f0bd33486ead7ed2ac025ab3675a92969920e649 Mon Sep 17 00:00:00 2001 From: Ryan Crabbe Date: Thu, 2 Apr 2026 16:14:34 -0700 Subject: [PATCH] fix: lazy import get_access_object to break cyclic import + short-circuit all-proxy-models display - Remove get_access_object from module-level import in team_endpoints.py and use a lazy _get_access_object wrapper to avoid cyclic dependency - Add _prisma_client is None early-exit guard in _resolve_access_group_resources - Short-circuit UI to show "All Proxy Models" when team.models is empty or contains "all-proxy-models", skipping access group model resolution --- .../proxy/management_endpoints/team_endpoints.py | 16 ++++++++++++++-- .../teams/components/TeamsTable/ModelsCell.tsx | 7 +++++-- .../src/components/team/TeamInfo.tsx | 4 ++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/litellm/proxy/management_endpoints/team_endpoints.py b/litellm/proxy/management_endpoints/team_endpoints.py index 125efb03d8c..c66177aafcf 100644 --- a/litellm/proxy/management_endpoints/team_endpoints.py +++ b/litellm/proxy/management_endpoints/team_endpoints.py @@ -64,7 +64,6 @@ from litellm.proxy._types import ( from litellm.proxy.auth.auth_checks import ( allowed_route_check_inside_route, can_org_access_model, - get_access_object, get_org_object, get_team_object, get_user_object, @@ -111,6 +110,16 @@ from litellm.types.proxy.management_endpoints.team_endpoints import ( router = APIRouter() +def _get_access_object(*args, **kwargs): + """ + Lazily import and delegate to `get_access_object` from + `litellm.proxy.auth.auth_checks` to avoid module-level cyclic imports. + """ + from litellm.proxy.auth.auth_checks import get_access_object as _inner_get_access_object + + return _inner_get_access_object(*args, **kwargs) + + class TeamMemberBudgetHandler: """Helper class to handle team member budget, RPM, and TPM limit operations""" @@ -3368,13 +3377,16 @@ async def _resolve_access_group_resources( if _user_api_key_cache is None: return empty + if _prisma_client is None: + return empty + models: List[str] = [] mcp_ids: List[str] = [] agent_ids: List[str] = [] for ag_id in access_group_ids: try: - ag = await get_access_object( + ag = await _get_access_object( access_group_id=ag_id, prisma_client=_prisma_client, user_api_key_cache=_user_api_key_cache, diff --git a/ui/litellm-dashboard/src/app/(dashboard)/teams/components/TeamsTable/ModelsCell.tsx b/ui/litellm-dashboard/src/app/(dashboard)/teams/components/TeamsTable/ModelsCell.tsx index 03a0a80bc71..62a7fdb783f 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/teams/components/TeamsTable/ModelsCell.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/teams/components/TeamsTable/ModelsCell.tsx @@ -16,8 +16,11 @@ interface ModelEntry { const ModelsCell = ({ team }: ModelsCellProps) => { const [expandedAccordion, setExpandedAccordion] = useState(false); + const isAllModels = !team.models || team.models.length === 0 || team.models.includes("all-proxy-models"); + const modelEntries: ModelEntry[] = useMemo(() => { - const entries: ModelEntry[] = (team.models || []).map((m) => ({ + if (isAllModels) return []; + const entries: ModelEntry[] = team.models.map((m) => ({ name: m, source: "direct" as const, })); @@ -25,7 +28,7 @@ const ModelsCell = ({ team }: ModelsCellProps) => { entries.push({ name: m, source: "access_group" }); } return entries; - }, [team.models, team.access_group_models]); + }, [team.models, team.access_group_models, isAllModels]); const renderBadge = (entry: ModelEntry, index: number) => { if (entry.name === "all-proxy-models") { diff --git a/ui/litellm-dashboard/src/components/team/TeamInfo.tsx b/ui/litellm-dashboard/src/components/team/TeamInfo.tsx index 79a55cf30fd..576f0a5f99c 100644 --- a/ui/litellm-dashboard/src/components/team/TeamInfo.tsx +++ b/ui/litellm-dashboard/src/components/team/TeamInfo.tsx @@ -655,7 +655,7 @@ const TeamInfoView: React.FC = ({ Models
- {info.models.length === 0 && !(info.access_group_models?.length) ? ( + {info.models.length === 0 || info.models.includes("all-proxy-models") ? ( All proxy models ) : ( <> @@ -672,7 +672,7 @@ const TeamInfoView: React.FC = ({ )}
- {info.access_group_models && info.access_group_models.length > 0 && ( + {info.models.length > 0 && !info.models.includes("all-proxy-models") && info.access_group_models && info.access_group_models.length > 0 && (
Direct