mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-30 01:52:18 +00:00
fix(ui): rename All Models tab to Deployed Models and model filters to All Proxy Models (#43638)
* fix(ui): rename All Models tab to Deployed Models and view filter to All Proxy Models Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(ui): use All Proxy Models label for the public model name filter Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(e2e): rename ALL_MODELS_VIEW constant to ALL_PROXY_MODELS_VIEW Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: kerry <kerry@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
98c710c411
commit
f4a217d005
7 changed files with 37 additions and 25 deletions
|
|
@ -17,7 +17,7 @@ import { CHAT_MODEL_A, CHAT_MODEL_B, masterKey } from "../../helpers/traffic";
|
|||
|
||||
const MOCK_LLM_BASE = `http://127.0.0.1:${process.env.MOCK_LLM_PORT ?? "8090"}/v1`;
|
||||
const CURRENT_TEAM_VIEW = "Current Team Models";
|
||||
const ALL_MODELS_VIEW = "All Available Models";
|
||||
const ALL_PROXY_MODELS_VIEW = "All Proxy Models";
|
||||
const PERSONAL_TEAM = "Personal";
|
||||
|
||||
const teamSelector = (page: PlaywrightPage): Locator =>
|
||||
|
|
@ -174,10 +174,10 @@ test.describe("Models and Endpoints for an internal user", () => {
|
|||
`${ungrantedModelName} is granted to no team and must not leak into ${E2E_TEAM_ORG_ALIAS}`,
|
||||
).toHaveCount(0);
|
||||
|
||||
await chooseOption(page, viewSelector(page), ALL_MODELS_VIEW);
|
||||
await chooseOption(page, viewSelector(page), ALL_PROXY_MODELS_VIEW);
|
||||
await expect(
|
||||
modelRow(page, CHAT_MODEL_A),
|
||||
`switching to ${ALL_MODELS_VIEW} leaves the table populated rather than blanking it`,
|
||||
`switching to ${ALL_PROXY_MODELS_VIEW} leaves the table populated rather than blanking it`,
|
||||
).toHaveCount(1, { timeout: 15_000 });
|
||||
|
||||
await expect(page).toHaveURL((url) =>
|
||||
|
|
@ -192,7 +192,7 @@ test.describe("Models and Endpoints for an internal user", () => {
|
|||
await expect(
|
||||
viewSelector(page),
|
||||
"the selected view is restored from the URL after a reload",
|
||||
).toContainText(ALL_MODELS_VIEW, { timeout: 15_000 });
|
||||
).toContainText(ALL_PROXY_MODELS_VIEW, { timeout: 15_000 });
|
||||
await expect(modelRow(page, CHAT_MODEL_A)).toHaveCount(1, { timeout: 15_000 });
|
||||
await expect(page.getByTestId("pagination-range")).toHaveText("Showing 1-1 of 1");
|
||||
await expect(modelRow(page, CHAT_MODEL_B)).toHaveCount(0);
|
||||
|
|
|
|||
|
|
@ -362,7 +362,7 @@ test.describe("Add Model", () => {
|
|||
await expect(page.getByText(/Connection to .* failed/)).toBeVisible({ timeout: 30_000 });
|
||||
});
|
||||
|
||||
test("Add specific model and verify it appears in All Models", async ({ page }) => {
|
||||
test("Add specific model and verify it appears in Deployed Models", async ({ page }) => {
|
||||
await navigateToPage(page, Page.Models);
|
||||
await page.getByRole("tab", { name: "Add Model" }).click();
|
||||
|
||||
|
|
@ -389,8 +389,8 @@ test.describe("Add Model", () => {
|
|||
// Wait for success notification
|
||||
await expect(page.getByText("created successfully")).toBeVisible({ timeout: 15_000 });
|
||||
|
||||
// Navigate to All Models tab
|
||||
await page.getByRole("tab", { name: "All Models" }).click();
|
||||
// Navigate to Deployed Models tab
|
||||
await page.getByRole("tab", { name: "Deployed Models" }).click();
|
||||
await page.waitForLoadState("networkidle");
|
||||
|
||||
// Search for the model we just added
|
||||
|
|
@ -469,7 +469,7 @@ test.describe("Add Model", () => {
|
|||
});
|
||||
|
||||
// The Models table renders team-scoped models with the team id in the row.
|
||||
await page.getByRole("tab", { name: "All Models" }).click();
|
||||
await page.getByRole("tab", { name: "Deployed Models" }).click();
|
||||
await page.waitForLoadState("networkidle");
|
||||
|
||||
await page.getByPlaceholder("Search model names").fill("cohere");
|
||||
|
|
@ -488,7 +488,7 @@ test.describe("Add Model", () => {
|
|||
}
|
||||
});
|
||||
|
||||
test("Add wildcard route and verify it appears in All Models", async ({ page }) => {
|
||||
test("Add wildcard route and verify it appears in Deployed Models", async ({ page }) => {
|
||||
await navigateToPage(page, Page.Models);
|
||||
await page.getByRole("tab", { name: "Add Model" }).click();
|
||||
|
||||
|
|
@ -513,8 +513,8 @@ test.describe("Add Model", () => {
|
|||
// Wait for success notification
|
||||
await expect(page.getByText("created successfully")).toBeVisible({ timeout: 15_000 });
|
||||
|
||||
// Navigate to All Models tab
|
||||
await page.getByRole("tab", { name: "All Models" }).click();
|
||||
// Navigate to Deployed Models tab
|
||||
await page.getByRole("tab", { name: "Deployed Models" }).click();
|
||||
await page.waitForLoadState("networkidle");
|
||||
|
||||
// Search for the wildcard model
|
||||
|
|
|
|||
|
|
@ -403,6 +403,17 @@ describe("AllModelsTab", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("uses All Proxy Models as the public model name filter default", async () => {
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(<AllModelsTab {...defaultProps} />);
|
||||
|
||||
await user.click(screen.getByTestId("datatable-filters-trigger"));
|
||||
await user.click(await screen.findByPlaceholderText("Filter by Public Model Name"));
|
||||
|
||||
expect(await screen.findByRole("option", { name: "All Proxy Models" })).toBeInTheDocument();
|
||||
expect(screen.queryByRole("option", { name: "All Models" })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders every row the server returned for the selected model group so rows match the footer total", () => {
|
||||
setModelsInfo([makeRow(), { ...makeRow({ model_info: { id: "model-2" } }), model_name: "claude-opus" }], 2);
|
||||
renderWithProviders(<AllModelsTab {...defaultProps} selectedModelGroup="claude-opus" />);
|
||||
|
|
@ -567,7 +578,7 @@ describe("AllModelsTab", () => {
|
|||
renderWithProviders(<AllModelsTab {...defaultProps} />);
|
||||
|
||||
await user.click(screen.getByTestId("models-view-select"));
|
||||
await user.click(await screen.findByRole("option", { name: "All Available Models" }));
|
||||
await user.click(await screen.findByRole("option", { name: "All Proxy Models" }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText(/create a Virtual Key/i)).not.toBeInTheDocument();
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ export const ALL_MODEL_GROUPS_VALUE = "all";
|
|||
export const WILDCARD_MODEL_GROUP_VALUE = "wildcard";
|
||||
|
||||
const MODEL_TABLE_BODY_HEIGHT = 600;
|
||||
const ALL_PROXY_MODELS_LABEL = "All Proxy Models";
|
||||
|
||||
const FILTER_LABELS: Record<string, string> = {
|
||||
[MODEL_NAME_COLUMN_ID]: "Public Model Name",
|
||||
|
|
@ -39,7 +40,7 @@ const FILTER_LABELS: Record<string, string> = {
|
|||
|
||||
const VIEW_MODE_LABELS: Record<ModelViewMode, string> = {
|
||||
current_team: "Current Team Models",
|
||||
all: "All Available Models",
|
||||
all: ALL_PROXY_MODELS_LABEL,
|
||||
};
|
||||
|
||||
export interface ModelsTableTeamOption {
|
||||
|
|
@ -146,7 +147,7 @@ export function AllModelsTable({
|
|||
|
||||
const modelGroupOptions = useMemo(
|
||||
() => [
|
||||
{ label: "All Models", value: ALL_MODEL_GROUPS_VALUE },
|
||||
{ label: ALL_PROXY_MODELS_LABEL, value: ALL_MODEL_GROUPS_VALUE },
|
||||
{ label: "Wildcard Models (*)", value: WILDCARD_MODEL_GROUP_VALUE },
|
||||
...availableModelGroups.map((group) => ({ label: group, value: group })),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export function AutoRoutersPanel({
|
|||
const canCreate = createScope !== "forbidden";
|
||||
const { data: deployments, isLoading } = useAutoRouters();
|
||||
const invalidateAutoRouters = useInvalidateAutoRouters();
|
||||
// Clicking a router opens the same ?model= drill-in the All Models table uses, so an auto
|
||||
// Clicking a router opens the same ?model= drill-in the Deployed Models table uses, so an auto
|
||||
// router gets the full ModelInfoView: Model Settings, Edit Settings, Edit Auto Router and
|
||||
// Delete. A separate detail view here would be a worse copy of it.
|
||||
const { openModel } = useModelDetailRouting();
|
||||
|
|
|
|||
|
|
@ -81,9 +81,9 @@ describe("ModelsAndEndpointsPage", () => {
|
|||
};
|
||||
});
|
||||
|
||||
it("renders the admin tab bar and the All Models panel by default", () => {
|
||||
it("renders the admin tab bar and the Deployed Models panel by default", () => {
|
||||
renderPage();
|
||||
expect(screen.getByRole("tab", { name: "All Models" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("tab", { name: "Deployed Models" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("tab", { name: "LLM Credentials" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("tab", { name: "Health Status" })).toBeInTheDocument();
|
||||
expect(screen.getByTestId("panel-all-models")).toBeInTheDocument();
|
||||
|
|
@ -101,7 +101,7 @@ describe("ModelsAndEndpointsPage", () => {
|
|||
detailState.modelId = "abc-123";
|
||||
renderPage();
|
||||
expect(screen.getByTestId("model-info")).toHaveTextContent("model:abc-123");
|
||||
expect(screen.queryByRole("tab", { name: "All Models" })).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole("tab", { name: "Deployed Models" })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders the team detail overlay from the ?team drill-in with admin edit rights", () => {
|
||||
|
|
@ -138,7 +138,7 @@ describe("ModelsAndEndpointsPage", () => {
|
|||
it("keeps the full admin tab order for a real admin", () => {
|
||||
renderPage();
|
||||
expect(screen.getAllByRole("tab").map((tab) => tab.textContent)).toEqual([
|
||||
"All Models",
|
||||
"Deployed Models",
|
||||
"Add Model",
|
||||
"Auto-Routers Beta",
|
||||
"LLM Credentials",
|
||||
|
|
@ -154,7 +154,7 @@ describe("ModelsAndEndpointsPage", () => {
|
|||
it("hides the admin write-form tabs from a view-only admin, keeping the read views", () => {
|
||||
mockUseAuthorized.mockReturnValue(VIEW_ONLY_ADMIN);
|
||||
renderPage();
|
||||
expect(screen.getByRole("tab", { name: "All Models" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("tab", { name: "Deployed Models" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("tab", { name: "Health Status" })).toBeInTheDocument();
|
||||
expect(screen.queryByRole("tab", { name: "LLM Credentials" })).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole("tab", { name: "Pass-Through Endpoints" })).not.toBeInTheDocument();
|
||||
|
|
@ -169,7 +169,7 @@ describe("ModelsAndEndpointsPage", () => {
|
|||
mockUseAuthorized.mockReturnValue(VIEW_ONLY_ADMIN);
|
||||
renderPage();
|
||||
expect(screen.queryByRole("tab", { name: "Add Model" })).not.toBeInTheDocument();
|
||||
expect(screen.getByRole("tab", { name: "All Models" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("tab", { name: "Deployed Models" })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Read parity: the Auto-Routers list stays reachable for a view-only admin; only the
|
||||
|
|
@ -180,14 +180,14 @@ describe("ModelsAndEndpointsPage", () => {
|
|||
expect(screen.getByRole("tab", { name: /Auto-Routers/ })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Auto-routers are excluded from the All Models table, so this tab is their home: the only
|
||||
// Auto-routers are excluded from the Deployed Models table, so this tab is their home: the only
|
||||
// place in the product to list, create, edit or delete one.
|
||||
describe("Auto-Routers tab", () => {
|
||||
it("sits third, after All Models and Add Model", () => {
|
||||
it("sits third, after Deployed Models and Add Model", () => {
|
||||
renderPage();
|
||||
|
||||
const tabs = screen.getAllByRole("tab").map((tab) => tab.textContent);
|
||||
expect(tabs[0]).toContain("All Models");
|
||||
expect(tabs[0]).toContain("Deployed Models");
|
||||
expect(tabs[1]).toBe("Add Model");
|
||||
expect(tabs[2]).toContain("Auto-Routers");
|
||||
// Badged Beta while the tab settles; BetaBadge renders the label text.
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ export default function ModelsAndEndpointsPage() {
|
|||
[canCreate, canViewAutoRouters, isAdmin, isViewOnly],
|
||||
);
|
||||
|
||||
const allModelsLabel = isAdmin ? "All Models" : "Your Models";
|
||||
const allModelsLabel = isAdmin ? "Deployed Models" : "Your Models";
|
||||
const tabLabel = (slug: "" | ModelTabSlug): React.ReactNode => {
|
||||
if (!slug) return allModelsLabel;
|
||||
if (slug === "auto-routers" || slug === "access-group-budgets") {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue