diff --git a/tests/e2e/ui/fixtures/menuMappings.ts b/tests/e2e/ui/fixtures/menuMappings.ts index 4cf90c00cd0..56b4356bde7 100644 --- a/tests/e2e/ui/fixtures/menuMappings.ts +++ b/tests/e2e/ui/fixtures/menuMappings.ts @@ -14,7 +14,6 @@ export const menuLabelToPage: Record = { "Internal Users": Page.Users, "Internal User": Page.Users, // Legacy label support Organizations: Page.Organizations, - "API Reference": Page.ApiRef, "AI Hub": Page.ModelHubTable, "Model Hub": Page.ModelHubTable, Logs: Page.Logs, diff --git a/tests/e2e/ui/fixtures/migratedPages.ts b/tests/e2e/ui/fixtures/migratedPages.ts index e49168ebb4a..84e7ed760d6 100644 --- a/tests/e2e/ui/fixtures/migratedPages.ts +++ b/tests/e2e/ui/fixtures/migratedPages.ts @@ -13,11 +13,6 @@ export const MIGRATED_E2E_PAGES: Readonly> = { linkName: "Models + Endpoints", content: { role: "heading", name: "Model Management" }, }, - api_ref: { - segment: "api-reference", - linkName: "API Reference", - content: { role: "heading", name: "OpenAI Compatible Proxy: API Reference" }, - }, "llm-playground": { segment: "playground", linkName: "Playground", content: { role: "tab", name: "Chat" } }, projects: { segment: "projects", diff --git a/tests/e2e/ui/fixtures/pages.ts b/tests/e2e/ui/fixtures/pages.ts index a850dcb4755..909cc93f6f8 100644 --- a/tests/e2e/ui/fixtures/pages.ts +++ b/tests/e2e/ui/fixtures/pages.ts @@ -10,7 +10,6 @@ export enum Page { Teams = "teams", Organizations = "organizations", AdminPanel = "admin-panel", - ApiRef = "api_ref", LoggingAndAlerts = "logging-and-alerts", Budgets = "budgets", Guardrails = "guardrails", diff --git a/tests/e2e/ui/tests/internal-viewer/internalViewer.spec.ts b/tests/e2e/ui/tests/internal-viewer/internalViewer.spec.ts index dd40976341d..4c2a80b5f2d 100644 --- a/tests/e2e/ui/tests/internal-viewer/internalViewer.spec.ts +++ b/tests/e2e/ui/tests/internal-viewer/internalViewer.spec.ts @@ -32,7 +32,6 @@ test.describe("Internal Viewer", () => { "Usage", "Logs", "Teams", - "API Reference", "AI Hub", ]; for (const label of expectedVisible) { diff --git a/tests/unit/proxy/test_ui_path_detection.py b/tests/unit/proxy/test_ui_path_detection.py index 5b5d43f647e..6ecdd037304 100644 --- a/tests/unit/proxy/test_ui_path_detection.py +++ b/tests/unit/proxy/test_ui_path_detection.py @@ -121,7 +121,7 @@ class TestUIDetectionLogic: # Verify routes exist found_routes = 0 - expected_routes = ["login", "guardrails", "logs", "api-reference"] + expected_routes = ["login", "guardrails", "logs"] for route in expected_routes: route_index = os.path.join(self.temp_dir, route, "index.html") if os.path.exists(route_index): diff --git a/ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/APIReferenceView.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/APIReferenceView.test.tsx deleted file mode 100644 index dae19032e20..00000000000 --- a/ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/APIReferenceView.test.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import { render, screen } from "@testing-library/react"; -import userEvent from "@testing-library/user-event"; -import { describe, expect, it, vi } from "vitest"; -import APIReferenceView from "./APIReferenceView"; - -vi.mock("@/components/CodeBlock", () => ({ - __esModule: true, - default: ({ code }: { code: string }) =>
{code}
, -})); - -describe("APIReferenceView", () => { - const codeBlockTestId = "api-reference-code-block"; - - it("uses the API doc base url when provided", () => { - const apiDocUrl = "https://docs.litellm.test"; - render(); - - const codeBlocks = screen.getAllByTestId(codeBlockTestId); - expect(codeBlocks[0]).toHaveTextContent(new RegExp(apiDocUrl)); - }); - - it("falls back to the proxy base url when the docs url is missing", () => { - const proxyUrl = "https://proxy.litellm.test"; - render(); - - const codeBlocks = screen.getAllByTestId(codeBlockTestId); - expect(codeBlocks[0]).toHaveTextContent(new RegExp(proxyUrl)); - }); - - it("prefers the docs url when both urls are provided", () => { - const apiDocUrl = "https://docs-preferred.litellm.test"; - const proxyUrl = "https://proxy-backup.litellm.test"; - - render( - , - ); - - const codeBlocks = screen.getAllByTestId(codeBlockTestId); - const renderedCode = codeBlocks[0].textContent ?? ""; - expect(renderedCode).toContain(apiDocUrl); - expect(renderedCode).not.toContain(proxyUrl); - }); - - it("renders the page title, blurb and docs link", () => { - render(); - - expect(screen.getByText("OpenAI Compatible Proxy: API Reference")).toBeInTheDocument(); - expect(screen.getByText(/LiteLLM is OpenAI Compatible/)).toBeInTheDocument(); - - const docsLink = screen.getByRole("link", { name: /API Reference Docs/ }); - expect(docsLink).toHaveAttribute("href", "https://docs.litellm.ai/docs/proxy/user_keys"); - expect(docsLink).toHaveAttribute("target", "_blank"); - }); - - it("exposes the three SDK tabs with the first selected by default", () => { - render(); - - expect(screen.getAllByRole("tab").map((tab) => tab.textContent)).toEqual([ - "OpenAI Python SDK", - "LlamaIndex", - "Langchain Py", - ]); - expect(screen.getAllByRole("tab").map((tab) => tab.getAttribute("aria-selected"))).toEqual([ - "true", - "false", - "false", - ]); - }); - - it.each([ - ["OpenAI Python SDK", "import openai"], - ["LlamaIndex", "from llama_index.llms import AzureOpenAI"], - ["Langchain Py", "from langchain.chat_models import ChatOpenAI"], - ])("selecting %s shows its snippet wired to the base url", async (tabName, marker) => { - const proxyUrl = "https://proxy.litellm.test"; - const user = userEvent.setup(); - render(); - - await user.click(screen.getByRole("tab", { name: tabName })); - - expect(screen.getByRole("tab", { name: tabName })).toHaveAttribute("aria-selected", "true"); - - const selectedPanel = screen.getByRole("tabpanel"); - expect(selectedPanel).toHaveTextContent(new RegExp(marker)); - expect(selectedPanel).toHaveTextContent(new RegExp(proxyUrl)); - }); -}); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/APIReferenceView.tsx b/ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/APIReferenceView.tsx deleted file mode 100644 index f55dc2e4c82..00000000000 --- a/ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/APIReferenceView.tsx +++ /dev/null @@ -1,142 +0,0 @@ -"use client"; -import React from "react"; -import { useTranslation } from "react-i18next"; -import CodeBlock from "@/components/CodeBlock"; -import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; -import DocLink from "./DocLink"; -import { productNames } from "@/i18n/untranslated/productNames"; - -interface ApiRefProps { - proxySettings: { - PROXY_BASE_URL?: string; - LITELLM_UI_API_DOC_BASE_URL?: string | null; - }; -} - -const APIReferenceView: React.FC = ({ proxySettings }) => { - const { t } = useTranslation(); - let base_url = ""; - const customDocBaseUrl = proxySettings?.LITELLM_UI_API_DOC_BASE_URL; - if (customDocBaseUrl && customDocBaseUrl.trim()) { - base_url = customDocBaseUrl; - } else if (proxySettings?.PROXY_BASE_URL) { - base_url = proxySettings.PROXY_BASE_URL; - } - - return ( -
-
- {/* Header row with Docs link on the right */} -
-

{t("apiReference.view.title")}

- -
- -

{t("apiReference.view.description")}

- - - - - {productNames.openAIPythonSdk} - - - {productNames.llamaIndex} - - - {productNames.langchainPython} - - - - - - - - - - - - - - -
-
- ); -}; - -export default APIReferenceView; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/DocLink.tsx b/ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/DocLink.tsx deleted file mode 100644 index cee174d7fdb..00000000000 --- a/ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/DocLink.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import React from "react"; -import { ExternalLink } from "lucide-react"; -import { useTranslation } from "react-i18next"; - -import { cn } from "@/lib/cva.config"; - -export type DocLinkProps = { - href?: string; - className?: string; -}; - -const DocLink = ({ href, className }: DocLinkProps) => { - const { t } = useTranslation(); - return ( - - {t("apiReference.docLink.label")} - - {t("apiReference.docLink.newTab")} - - ); -}; - -export default DocLink; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/api-reference/page.tsx b/ui/litellm-dashboard/src/app/(dashboard)/api-reference/page.tsx deleted file mode 100644 index 4d8498a1be4..00000000000 --- a/ui/litellm-dashboard/src/app/(dashboard)/api-reference/page.tsx +++ /dev/null @@ -1,22 +0,0 @@ -"use client"; - -import { useTranslation } from "react-i18next"; -import APIReferenceView from "./_components/APIReferenceView"; -import { DeprecationBanner } from "@/components/DeprecationBanner"; -import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized"; -import useProxySettings from "@/app/(dashboard)/hooks/proxySettings/useProxySettings"; - -const APIReferencePage = () => { - const { t } = useTranslation(); - const { accessToken } = useAuthorized(); - const proxySettings = useProxySettings(accessToken); - - return ( - <> - - - - ); -}; - -export default APIReferencePage; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/legacyPageRoutes.test.ts b/ui/litellm-dashboard/src/app/(dashboard)/legacyPageRoutes.test.ts index 315d988db54..70b2f9b0ab7 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/legacyPageRoutes.test.ts +++ b/ui/litellm-dashboard/src/app/(dashboard)/legacyPageRoutes.test.ts @@ -14,8 +14,6 @@ describe("legacyPageRedirectHref", () => { }); it("keeps the older aliases for renamed pages", () => { - expect(redirect("page=api_ref")).toBe("/ui/api-reference"); - expect(redirect("page=api-reference")).toBe("/ui/api-reference"); expect(redirect("page=claude-code-plugins")).toBe("/ui/skills"); }); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/legacyPageRoutes.ts b/ui/litellm-dashboard/src/app/(dashboard)/legacyPageRoutes.ts index 90b49e56c5a..98cdd1e79bb 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/legacyPageRoutes.ts +++ b/ui/litellm-dashboard/src/app/(dashboard)/legacyPageRoutes.ts @@ -5,8 +5,6 @@ const LEGACY_PAGE_ROUTES: ReadonlyMap = new Map( home: "home", "api-keys": "api-keys", models: "models-and-endpoints", - api_ref: "api-reference", - "api-reference": "api-reference", "llm-playground": "playground", projects: "projects", chat: "chat", diff --git a/ui/litellm-dashboard/src/components/leftnav.test.tsx b/ui/litellm-dashboard/src/components/leftnav.test.tsx index f3e02d13e56..e57a17c7136 100644 --- a/ui/litellm-dashboard/src/components/leftnav.test.tsx +++ b/ui/litellm-dashboard/src/components/leftnav.test.tsx @@ -282,7 +282,6 @@ describe("Sidebar (leftnav)", () => { "Organizations", "Access Groups", "Budgets", - "API Reference", "AI Hub", "Experimental", "Settings", @@ -701,7 +700,6 @@ describe("Sidebar (leftnav)", () => { expectHref("Models + Endpoints", "/ui/models-and-endpoints"); expectHref("Usage", "/ui/usage"); expectHref("Alerts", "/ui/alerts"); - expectHref("API Reference", "/ui/api-reference"); }); it("never links a leaf to the legacy ?page= switch", () => { diff --git a/ui/litellm-dashboard/src/components/leftnav.tsx b/ui/litellm-dashboard/src/components/leftnav.tsx index 652a3596980..4a968fa39ec 100644 --- a/ui/litellm-dashboard/src/components/leftnav.tsx +++ b/ui/litellm-dashboard/src/components/leftnav.tsx @@ -28,7 +28,6 @@ import { Building2, Boxes, ChevronRight, - Code2, Database, ExternalLink, FileText, @@ -420,13 +419,6 @@ const menuGroups: MenuGroup[] = [ { groupLabel: "DEVELOPER TOOLS", items: [ - { - key: "api_ref", - page: "api_ref", - route: "api-reference", - label: "shell.nav.items.apiReference", - icon: , - }, { key: "model-hub-table", page: "model-hub-table", diff --git a/ui/litellm-dashboard/src/components/networking.test.ts b/ui/litellm-dashboard/src/components/networking.test.ts index 47a1aef87c0..bc614f1a53a 100644 --- a/ui/litellm-dashboard/src/components/networking.test.ts +++ b/ui/litellm-dashboard/src/components/networking.test.ts @@ -388,7 +388,7 @@ describe("UI config and public endpoints", () => { await Networking.getUiConfig(); expect(Networking.serverRootPath).toBe("/litellm"); - expect(uiHref("api-reference")).toBe("/litellm/ui/api-reference"); + expect(uiHref("logs")).toBe("/litellm/ui/logs"); }); it("sends model group connection probes to the configured gateway", async () => { diff --git a/ui/litellm-dashboard/src/components/page_metadata.ts b/ui/litellm-dashboard/src/components/page_metadata.ts index b2d86dbe7b8..d818f33c4d9 100644 --- a/ui/litellm-dashboard/src/components/page_metadata.ts +++ b/ui/litellm-dashboard/src/components/page_metadata.ts @@ -34,7 +34,6 @@ export const pageDescriptions: Record = { projects: "shell.pageDescriptions.projects", "access-groups": "shell.pageDescriptions.accessGroups", budgets: "shell.pageDescriptions.budgets", - api_ref: "shell.pageDescriptions.apiRef", "model-hub-table": "shell.pageDescriptions.modelHubTable", caching: "shell.pageDescriptions.caching", "transform-request": "shell.pageDescriptions.transformRequest", diff --git a/ui/litellm-dashboard/src/i18n/locales/en.json b/ui/litellm-dashboard/src/i18n/locales/en.json index ebf8b5dc134..854a49fd546 100644 --- a/ui/litellm-dashboard/src/i18n/locales/en.json +++ b/ui/litellm-dashboard/src/i18n/locales/en.json @@ -8035,7 +8035,6 @@ "organizations": "Organizations", "accessGroups": "Access Groups", "budgets": "Budgets", - "apiReference": "API Reference", "aiHub": "AI Hub", "responseCache": "Response Cache", "experimental": "Experimental", @@ -8082,7 +8081,6 @@ "projects": "Manage projects within teams", "accessGroups": "Manage access groups for role-based permissions", "budgets": "Set and monitor spending budgets", - "apiRef": "Browse API documentation and endpoints", "modelHubTable": "Explore available AI models and providers", "caching": "Configure response caching and coordination Redis settings", "transformRequest": "Set up request transformation rules", @@ -8554,20 +8552,6 @@ "empty": "No posts yet" } }, - "apiReference": { - "page": { - "featureName": "The API Reference tab" - }, - "view": { - "title": "OpenAI Compatible Proxy: API Reference", - "description": "LiteLLM is OpenAI Compatible. This means your API Key works with the OpenAI SDK. Just replace the base_url to point to your litellm proxy. Example Below" - }, - "docLink": { - "title": "Open documentation in a new tab", - "label": "API Reference Docs", - "newTab": "(opens in a new tab)" - } - }, "uiTheme": { "settings": { "toasts": { diff --git a/ui/litellm-dashboard/src/utils/uiHref.test.ts b/ui/litellm-dashboard/src/utils/uiHref.test.ts index dae2594929c..53cfd4f7971 100644 --- a/ui/litellm-dashboard/src/utils/uiHref.test.ts +++ b/ui/litellm-dashboard/src/utils/uiHref.test.ts @@ -9,16 +9,16 @@ afterEach(() => { describe("uiHref", () => { it("builds a /ui-rooted path when serverRootPath is /", () => { - expect(uiHref("api-reference")).toBe("/ui/api-reference"); + expect(uiHref("logs")).toBe("/ui/logs"); }); it("prefixes a non-root serverRootPath without duplicating slashes", () => { setServerRootPath("/team-x/"); - expect(uiHref("api-reference")).toBe("/team-x/ui/api-reference"); + expect(uiHref("logs")).toBe("/team-x/ui/logs"); }); it("tolerates a leading slash in the route segment", () => { - expect(uiHref("/api-reference")).toBe("/ui/api-reference"); + expect(uiHref("/logs")).toBe("/ui/logs"); }); it("stays root-relative under next dev, which serves the app at /", () => { @@ -29,8 +29,8 @@ describe("uiHref", () => { describe("routeSegmentForPathname", () => { it("strips the /ui base and any trailing slash", () => { - expect(routeSegmentForPathname("/ui/api-reference")).toBe("api-reference"); - expect(routeSegmentForPathname("/ui/api-reference/")).toBe("api-reference"); + expect(routeSegmentForPathname("/ui/logs")).toBe("logs"); + expect(routeSegmentForPathname("/ui/logs/")).toBe("logs"); }); it("returns an empty segment for the dashboard root", () => { diff --git a/ui/litellm-dashboard/src/utils/uiHref.ts b/ui/litellm-dashboard/src/utils/uiHref.ts index 83e65b4d5a3..dcb75ca43b2 100644 --- a/ui/litellm-dashboard/src/utils/uiHref.ts +++ b/ui/litellm-dashboard/src/utils/uiHref.ts @@ -10,12 +10,12 @@ function uiBase(): string { return `${root}/ui`; } -/** Absolute (same-origin) href for a dashboard route segment, e.g. "api-reference" -> "/ui/api-reference". */ +/** Absolute (same-origin) href for a dashboard route segment, e.g. "logs" -> "/ui/logs". */ export function uiHref(routeSegment: string): string { return `${uiBase()}/${routeSegment.replace(/^\/+/, "")}`; } -/** First route segment under the UI base, e.g. "/ui/api-reference/" -> "api-reference" and "/ui/" -> "". */ +/** First route segment under the UI base, e.g. "/ui/logs/" -> "logs" and "/ui/" -> "". */ export function routeSegmentForPathname(pathname: string): string { const base = uiBase(); const relative = pathname.startsWith(base) ? pathname.slice(base.length) : pathname;