mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-07 08:26:10 +00:00
feat(ui): team passthrough routes create parity + edit load fix (#28098)
* feat(ui): team allowed_passthrough_routes create parity + edit load fix Add the Allowed Pass Through Routes selector to the create-team modal (previously only on the edit form), and fix the edit form silently dropping the field: it lives under team metadata, so initialValues must read info.metadata.allowed_passthrough_routes — otherwise the selector renders empty and saving wipes admin-set routes. Both selectors are gated to premium proxy admins, mirroring the server-side gate. Resolves LIT-3019 * fix(ui): persist team allowed_passthrough_routes edits on save The edit form loaded the selector but the save path never wrote it back: allowed_passthrough_routes stayed in the raw metadata JSON textarea and parsedMetadata (from that textarea) always won, so selector edits were silently discarded. Strip it from the textarea initialValues and overlay values.allowed_passthrough_routes into updateData.metadata, mirroring how guardrails is handled. Resolves LIT-3019 * fix(ui): preserve team passthrough routes for non-proxy-admins on save Only proxy admins may set allowed_passthrough_routes (server-side gate). For non-proxy-admins, write the team's stored value back into metadata instead of the form value, so saving an unrelated setting can't silently wipe routes; omit the key entirely when the team never had any. Resolves LIT-3019
This commit is contained in:
parent
5a00cb1592
commit
fb73995c40
2 changed files with 54 additions and 7 deletions
|
|
@ -45,6 +45,7 @@ import OrganizationDropdown from "./common_components/OrganizationDropdown";
|
|||
import TableIconActionButton from "./common_components/IconActionButton/TableIconActionButtons/TableIconActionButton";
|
||||
import { teamListCall as v2TeamListCall, type TeamsResponse } from "@/app/(dashboard)/hooks/teams/useTeams";
|
||||
import AccessGroupSelector from "./common_components/AccessGroupSelector";
|
||||
import PassThroughRoutesSelector from "./common_components/PassThroughRoutesSelector";
|
||||
import AgentSelector from "./agent_management/AgentSelector";
|
||||
import ModelAliasManager from "./common_components/ModelAliasManager";
|
||||
import PremiumLoggingSettings from "./common_components/PremiumLoggingSettings";
|
||||
|
|
@ -1446,6 +1447,30 @@ const Teams: React.FC<TeamProps> = ({
|
|||
placeholder="Select vector stores (optional)"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="Allowed Pass Through Routes"
|
||||
name="allowed_passthrough_routes"
|
||||
className="mt-8"
|
||||
>
|
||||
<Tooltip
|
||||
title={
|
||||
!premiumUser
|
||||
? "Premium feature - Upgrade to set allowed pass through routes"
|
||||
: !isProxyAdminRole(userRole || "")
|
||||
? "Only proxy admins can set allowed pass through routes"
|
||||
: ""
|
||||
}
|
||||
placement="top"
|
||||
>
|
||||
<PassThroughRoutesSelector
|
||||
onChange={(values: string[]) => form.setFieldValue("allowed_passthrough_routes", values)}
|
||||
value={form.getFieldValue("allowed_passthrough_routes")}
|
||||
accessToken={accessToken || ""}
|
||||
placeholder="Select pass through routes (optional)"
|
||||
disabled={!premiumUser || !isProxyAdminRole(userRole || "")}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Form.Item>
|
||||
</AccordionBody>
|
||||
</Accordion>
|
||||
|
||||
|
|
|
|||
|
|
@ -502,6 +502,14 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
|
|||
(n) => !(values.guardrails || []).includes(n),
|
||||
);
|
||||
|
||||
// Non-proxy-admins can't set allowed_passthrough_routes; preserve the
|
||||
// stored value so an unrelated save can't wipe it.
|
||||
const passthroughRoutesMetadata = is_proxy_admin
|
||||
? { allowed_passthrough_routes: values.allowed_passthrough_routes || [] }
|
||||
: info.metadata?.allowed_passthrough_routes
|
||||
? { allowed_passthrough_routes: info.metadata.allowed_passthrough_routes }
|
||||
: {};
|
||||
|
||||
const updateData: any = {
|
||||
team_id: teamId,
|
||||
team_alias: values.team_alias,
|
||||
|
|
@ -515,6 +523,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
|
|||
budget_duration: values.budget_duration,
|
||||
metadata: {
|
||||
...parsedMetadata,
|
||||
...passthroughRoutesMetadata,
|
||||
guardrails: (values.guardrails || []).filter((n: string) => !globalGuardrailNames.has(n)),
|
||||
opted_out_global_guardrails: optedOutGlobalGuardrails,
|
||||
...(values.logging_settings?.length > 0 ? { logging: values.logging_settings } : {}),
|
||||
|
|
@ -961,7 +970,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
|
|||
: "",
|
||||
metadata: info.metadata
|
||||
? JSON.stringify(
|
||||
(({ logging, secret_manager_settings, soft_budget_alerting_emails, model_tpm_limit, model_rpm_limit, ...rest }) => rest)(info.metadata),
|
||||
(({ logging, secret_manager_settings, soft_budget_alerting_emails, model_tpm_limit, model_rpm_limit, allowed_passthrough_routes, ...rest }) => rest)(info.metadata),
|
||||
null,
|
||||
2,
|
||||
)
|
||||
|
|
@ -986,6 +995,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
|
|||
},
|
||||
access_group_ids: info.access_group_ids || [],
|
||||
default_team_member_models: info.default_team_member_models || [],
|
||||
allowed_passthrough_routes: info.metadata?.allowed_passthrough_routes || [],
|
||||
}}
|
||||
layout="vertical"
|
||||
>
|
||||
|
|
@ -1338,12 +1348,24 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
|
|||
</Form.Item>
|
||||
|
||||
<Form.Item label="Allowed Pass Through Routes" name="allowed_passthrough_routes">
|
||||
<PassThroughRoutesSelector
|
||||
onChange={(values: string[]) => form.setFieldValue("allowed_passthrough_routes", values)}
|
||||
value={form.getFieldValue("allowed_passthrough_routes")}
|
||||
accessToken={accessToken || ""}
|
||||
placeholder="Select pass through routes"
|
||||
/>
|
||||
<Tooltip
|
||||
title={
|
||||
!premiumUser
|
||||
? "Premium feature - Upgrade to set allowed pass through routes"
|
||||
: !is_proxy_admin
|
||||
? "Only proxy admins can set allowed pass through routes"
|
||||
: ""
|
||||
}
|
||||
placement="top"
|
||||
>
|
||||
<PassThroughRoutesSelector
|
||||
onChange={(values: string[]) => form.setFieldValue("allowed_passthrough_routes", values)}
|
||||
value={form.getFieldValue("allowed_passthrough_routes")}
|
||||
accessToken={accessToken || ""}
|
||||
placeholder="Select pass through routes"
|
||||
disabled={!premiumUser || !is_proxy_admin}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="MCP Servers / Access Groups" name="mcp_servers_and_groups">
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue