diff --git a/ui/litellm-dashboard/eslint-suppressions.json b/ui/litellm-dashboard/eslint-suppressions.json index 50b652ff57e..39df9e99339 100644 --- a/ui/litellm-dashboard/eslint-suppressions.json +++ b/ui/litellm-dashboard/eslint-suppressions.json @@ -42,9 +42,6 @@ }, "react-hooks/set-state-in-effect": { "count": 2 - }, - "unused-imports/no-unused-imports": { - "count": 1 } }, "src/app/(dashboard)/agents/_components/agent_card_discovery.tsx": { @@ -255,11 +252,6 @@ "count": 1 } }, - "src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_cost_results.test.tsx": { - "unused-imports/no-unused-imports": { - "count": 1 - } - }, "src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_cost_results.tsx": { "local/filename-pascal-case": { "count": 1 @@ -268,11 +260,6 @@ "count": 2 } }, - "src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_export_dropdown.test.tsx": { - "unused-imports/no-unused-imports": { - "count": 1 - } - }, "src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_export_dropdown.tsx": { "local/filename-pascal-case": { "count": 1 @@ -286,11 +273,6 @@ "count": 1 } }, - "src/app/(dashboard)/cost-tracking/_components/provider_discount_table.test.tsx": { - "unused-imports/no-unused-imports": { - "count": 1 - } - }, "src/app/(dashboard)/cost-tracking/_components/provider_discount_table.tsx": { "local/filename-pascal-case": { "count": 1 @@ -366,7 +348,7 @@ }, "src/app/(dashboard)/guardrails/_components/GuardrailTestResults.tsx": { "no-restricted-imports": { - "count": 2 + "count": 1 } }, "src/app/(dashboard)/guardrails/_components/GuardrailsPanel.tsx": { @@ -813,11 +795,6 @@ "count": 1 } }, - "src/app/(dashboard)/mcp-servers/_components/MCPLogoSelector.test.tsx": { - "unused-imports/no-unused-imports": { - "count": 1 - } - }, "src/app/(dashboard)/mcp-servers/_components/MCPNetworkSettings.tsx": { "react-hooks/immutability": { "count": 2 @@ -1146,9 +1123,6 @@ }, "react-hooks/set-state-in-effect": { "count": 4 - }, - "unused-imports/no-unused-imports": { - "count": 13 } }, "src/app/(dashboard)/playground/components/chat_ui/CodeInterpreterOutput.tsx": { @@ -2179,11 +2153,6 @@ "count": 1 } }, - "src/components/HelpLink.test.tsx": { - "unused-imports/no-unused-imports": { - "count": 1 - } - }, "src/components/LicenseExpiryBanner.tsx": { "no-restricted-imports": { "count": 1 @@ -2448,11 +2417,6 @@ "count": 1 } }, - "src/components/ToolDetail.tsx": { - "unused-imports/no-unused-imports": { - "count": 1 - } - }, "src/components/UIAccessControlForm.tsx": { "no-restricted-imports": { "count": 2 @@ -2678,9 +2642,6 @@ "src/components/agent_management/AgentSelector.test.tsx": { "react/display-name": { "count": 1 - }, - "unused-imports/no-unused-imports": { - "count": 1 } }, "src/components/agent_management/AgentSelector.tsx": { @@ -3272,7 +3233,7 @@ "count": 2 }, "prefer-const": { - "count": 5 + "count": 4 }, "react-hooks/set-state-in-effect": { "count": 1 @@ -3307,9 +3268,6 @@ "src/components/navbar.test.tsx": { "prefer-const": { "count": 1 - }, - "unused-imports/no-unused-imports": { - "count": 1 } }, "src/components/navbar.tsx": { @@ -3383,7 +3341,7 @@ "count": 2 }, "prefer-const": { - "count": 4 + "count": 2 }, "react-hooks/set-state-in-effect": { "count": 4 @@ -3570,7 +3528,7 @@ "count": 3 }, "prefer-const": { - "count": 7 + "count": 4 } }, "src/components/shared/CreatedKeyDisplay.tsx": { @@ -3793,11 +3751,6 @@ "count": 2 } }, - "src/components/templates/key_info_view.test.tsx": { - "unused-imports/no-unused-imports": { - "count": 2 - } - }, "src/components/templates/key_info_view.tsx": { "local/filename-pascal-case": { "count": 1 @@ -4117,11 +4070,6 @@ "count": 1 } }, - "src/components/view_logs/LogDetailsDrawer/RealtimePrettyView.test.tsx": { - "unused-imports/no-unused-imports": { - "count": 2 - } - }, "src/components/view_logs/LogDetailsDrawer/RealtimePrettyView.tsx": { "no-restricted-imports": { "count": 1 diff --git a/ui/litellm-dashboard/eslint.config.mjs b/ui/litellm-dashboard/eslint.config.mjs index b5e876bfbba..6216967356a 100644 --- a/ui/litellm-dashboard/eslint.config.mjs +++ b/ui/litellm-dashboard/eslint.config.mjs @@ -22,7 +22,10 @@ const eslintConfig = [ "local/no-complex-jsx-arrow": ["error", { maxStatements: 2 }], "@typescript-eslint/no-explicit-any": "warn", "no-console": ["warn", { allow: ["warn", "error"] }], - "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": [ + "error", + { args: "none", caughtErrors: "none", ignoreRestSiblings: true, varsIgnorePattern: "^_" }, + ], "@typescript-eslint/no-unused-expressions": "off", "@typescript-eslint/ban-ts-comment": "off", "prefer-const": "error", diff --git a/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/add_agent_form.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/add_agent_form.tsx index e35388b78da..2716e6f06c0 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/add_agent_form.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/add_agent_form.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect } from "react"; -import { Modal, Form, Select, Input, Steps, Radio, Tag, Divider, Switch, InputNumber, Collapse } from "antd"; +import { Modal, Form, Select, Input, Steps, Radio, Tag, Divider, Switch, InputNumber } from "antd"; import MessageManager from "@/components/molecules/message_manager"; import { Logo } from "@/components/molecules/logo/Logo"; import { Button } from "@tremor/react"; @@ -47,7 +47,7 @@ const AddAgentForm: React.FC = ({ visible, onClose, accessTok const [isSubmitting, setIsSubmitting] = useState(false); const [agentType, setAgentType] = useState("a2a"); const [agentTypeMetadata, setAgentTypeMetadata] = useState([]); - const [loadingMetadata, setLoadingMetadata] = useState(false); + const [, setLoadingMetadata] = useState(false); // Step 3: key assignment state const [keyAssignOption, setKeyAssignOption] = useState<"create_new" | "existing_key" | "skip">("create_new"); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_dashboard.tsx b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_dashboard.tsx index 47c266ceac0..5167ac16542 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_dashboard.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_dashboard.tsx @@ -65,32 +65,7 @@ interface CachePageProps { premiumUser: boolean; } -interface CacheHealthResponse { - status?: string; - cache_type?: string; - ping_response?: boolean; - set_cache_response?: string; - litellm_cache_params?: string; - error?: { - message: string; - type: string; - param: string; - code: string; - }; -} - // Helper function to deep-parse a JSON string if possible -const deepParse = (input: any) => { - let parsed = input; - if (typeof parsed === "string") { - try { - parsed = JSON.parse(parsed); - } catch { - return parsed; - } - } - return parsed; -}; const CacheDashboard: React.FC = ({ accessToken, token, userRole, userID, premiumUser }) => { const [selectedApiKeys, setSelectedApiKeys] = useState([]); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_health.tsx b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_health.tsx index 85649c1cf26..79ee312ecbb 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_health.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_health.tsx @@ -20,7 +20,7 @@ const deepParse = (input: any) => { // TableClickableErrorField component with copy-to-clipboard functionality const TableClickableErrorField: React.FC<{ label: string; value: string | null | undefined }> = ({ label, value }) => { const [isExpanded, setIsExpanded] = React.useState(false); - const [copied, setCopied] = React.useState(false); + const [, setCopied] = React.useState(false); const safeValue = value?.toString() || "N/A"; const truncated = safeValue.length > 50 ? safeValue.substring(0, 50) + "..." : safeValue; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_cost_results.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_cost_results.test.tsx index 6dc9309b5e3..04ef60469f0 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_cost_results.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_cost_results.test.tsx @@ -1,6 +1,6 @@ import React from "react"; import { describe, it, expect, vi, beforeEach } from "vitest"; -import { screen, within } from "@testing-library/react"; +import { screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { renderWithProviders } from "../../../../../../tests/test-utils"; import MultiCostResults from "./multi_cost_results"; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_export_dropdown.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_export_dropdown.test.tsx index 02940dd1325..e40fe7dbbca 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_export_dropdown.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_export_dropdown.test.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; +import { describe, it, expect, vi, beforeEach } from "vitest"; import { screen, fireEvent } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { renderWithProviders } from "../../../../../../tests/test-utils"; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/provider_discount_table.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/provider_discount_table.test.tsx index 2e8dbb429f0..f9a0a40f07d 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/provider_discount_table.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/provider_discount_table.test.tsx @@ -1,6 +1,6 @@ import React from "react"; import { describe, it, expect, vi, beforeEach } from "vitest"; -import { screen, within } from "@testing-library/react"; +import { screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { renderWithProviders } from "../../../../../tests/test-utils"; import ProviderDiscountTable from "./provider_discount_table"; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/provider_margin_table.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/provider_margin_table.tsx index 9d11e13fb52..75939a23751 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/provider_margin_table.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/provider_margin_table.tsx @@ -69,14 +69,6 @@ const ProviderMarginTable: React.FC = ({ setEditFixedAmount(""); }; - const handleKeyDown = (e: React.KeyboardEvent, provider: string) => { - if (e.key === "Enter") { - handleSaveEdit(provider); - } else if (e.key === "Escape") { - handleCancelEdit(); - } - }; - const formatMargin = (margin: number | { percentage?: number; fixed_amount?: number }): string => { if (typeof margin === "number") { return `${(margin * 100).toFixed(1)}%`; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.tsx index 1d959ccca95..2e007c06744 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.tsx @@ -25,7 +25,7 @@ const statusColors: Record = export function GuardrailDetail({ guardrailId, onBack, accessToken = null, startDate, endDate }: GuardrailDetailProps) { const [activeTab, setActiveTab] = useState("overview"); const [evaluationModalOpen, setEvaluationModalOpen] = useState(false); - const [logsPage, setLogsPage] = useState(1); + const [logsPage] = useState(1); const logsPageSize = 50; const { diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/GuardrailTestResults.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/GuardrailTestResults.tsx index 3c974de3632..10ce709244b 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/GuardrailTestResults.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/GuardrailTestResults.tsx @@ -1,11 +1,8 @@ import React, { useState } from "react"; import { Button, Card } from "@tremor/react"; -import { Typography } from "antd"; import { CopyOutlined, CheckCircleOutlined, ClockCircleOutlined, DownOutlined, RightOutlined } from "@ant-design/icons"; import NotificationsManager from "@/components/molecules/notifications_manager"; -const { Text } = Typography; - interface TestResult { guardrailName: string; response_text: string; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/add_guardrail_form.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/add_guardrail_form.tsx index 251ce631beb..436e038bd89 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/add_guardrail_form.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/add_guardrail_form.tsx @@ -1,4 +1,4 @@ -import { Form, Input, Modal, Select, Tag, Typography, Button } from "antd"; +import { Form, Input, Modal, Select, Tag, Button } from "antd"; import React, { useEffect, useMemo, useState } from "react"; import NotificationsManager from "@/components/molecules/notifications_manager"; import { @@ -30,7 +30,6 @@ import LLMJudgeFields from "./llm_judge/LLMJudgeFields"; import PiiConfiguration from "./pii_configuration"; import ToolPermissionRulesEditor, { ToolPermissionConfig } from "./tool_permission/ToolPermissionRulesEditor"; -const { Title, Text, Link } = Typography; const { Option } = Select; // Define human-friendly descriptions for each mode @@ -164,9 +163,9 @@ const AddGuardrailForm: React.FC = ({ visible, onClose, a const [providerParams, setProviderParams] = useState(null); // Azure Text Moderation state - const [selectedCategories, setSelectedCategories] = useState([]); - const [globalSeverityThreshold, setGlobalSeverityThreshold] = useState(2); - const [categorySpecificThresholds, setCategorySpecificThresholds] = useState<{ [key: string]: number }>({}); + const [, setSelectedCategories] = useState([]); + const [, setGlobalSeverityThreshold] = useState(2); + const [, setCategorySpecificThresholds] = useState<{ [key: string]: number }>({}); // Content Filter state const [selectedPatterns, setSelectedPatterns] = useState([]); @@ -336,22 +335,6 @@ const AddGuardrailForm: React.FC = ({ visible, onClose, a }; // Azure Text Moderation handlers - const handleCategorySelect = (category: string) => { - setSelectedCategories((prev) => - prev.includes(category) ? prev.filter((c) => c !== category) : [...prev, category], - ); - }; - - const handleGlobalSeverityChange = (threshold: number) => { - setGlobalSeverityThreshold(threshold); - }; - - const handleCategorySeverityChange = (category: string, threshold: number) => { - setCategorySpecificThresholds((prev) => ({ - ...prev, - [category]: threshold, - })); - }; const nextStep = async () => { try { @@ -388,45 +371,6 @@ const AddGuardrailForm: React.FC = ({ visible, onClose, a setCurrentStep(currentStep - 1); }; - const handleAddAndContinue = (competitorIntentOnly?: boolean) => { - // Competitor intent only: just advance to next step (no category to add) - if (competitorIntentOnly) { - setCurrentStep(currentStep + 1); - return; - } - - if (!pendingCategorySelection || !guardrailSettings) return; - - const contentFilterSettings = guardrailSettings.content_filter_settings; - if (!contentFilterSettings) return; - - const category = contentFilterSettings.content_categories?.find((c) => c.name === pendingCategorySelection); - if (!category) return; - - // Check if already added - if (selectedContentCategories.some((c) => c.category === pendingCategorySelection)) { - setPendingCategorySelection(""); - setCurrentStep(currentStep + 1); - return; - } - - // Add the category - setSelectedContentCategories([ - ...selectedContentCategories, - { - id: `category-${Date.now()}`, - category: category.name, - display_name: category.display_name, - action: category.default_action as "BLOCK" | "MASK", - severity_threshold: "medium", - }, - ]); - - // Clear pending selection and advance to next step - setPendingCategorySelection(""); - setCurrentStep(currentStep + 1); - }; - const resetForm = () => { form.resetFields(); setSelectedProvider(null); @@ -965,48 +909,6 @@ const AddGuardrailForm: React.FC = ({ visible, onClose, a } }; - const renderStepButtons = () => { - const totalSteps = shouldRenderContentFilterConfigSettings(selectedProvider) ? 5 : 2; - const isLastStep = currentStep === totalSteps - 1; - const isCategoriesStep = shouldRenderContentFilterConfigSettings(selectedProvider) && currentStep === 1; - const hasPendingCategory = pendingCategorySelection !== ""; - const hasCompetitorIntentConfigured = - competitorIntentEnabled && (competitorIntentConfig?.brand_self?.length ?? 0) > 0; - const canContinueFromCategoriesStep = hasPendingCategory || hasCompetitorIntentConfigured; - - return ( -
- {currentStep > 0 && } - {isCategoriesStep ? ( - <> - - - - ) : ( - <> - {!isLastStep && ( - - )} - {isLastStep && ( - - )} - - )} - -
- ); - }; - const renderEndpointSettings = () => { return (
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/KeywordTable.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/KeywordTable.tsx index 57e59423aa5..eed2c8a5129 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/KeywordTable.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/KeywordTable.tsx @@ -1,8 +1,7 @@ import { DeleteOutlined } from "@ant-design/icons"; -import { Button, Select, Table, Typography } from "antd"; +import { Button, Select, Table } from "antd"; import React from "react"; -const { Text } = Typography; const { Option } = Select; interface BlockedWord { diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_info.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_info.test.tsx index 7bb7737e152..5fcf07d3f8b 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_info.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_info.test.tsx @@ -229,7 +229,7 @@ describe("Guardrail Info", () => { vi.mocked(networking.getGuardrailProviderSpecificParams).mockResolvedValue({}); vi.mocked(networking.updateGuardrailCall).mockResolvedValue({ status: "success" }); - const { getByText, getByRole, getAllByRole, getByLabelText } = render( + const { getByText, getByLabelText } = render( {}} accessToken="123" isAdmin={true} />, ); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_info.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_info.tsx index 07df6ff15d9..54cac4bbe5c 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_info.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_info.tsx @@ -35,22 +35,6 @@ export interface GuardrailInfoProps { isAdmin: boolean; } -interface ProviderParam { - param: string; - description: string; - required: boolean; - default_value?: string; - options?: string[]; - type?: string; - fields?: { [key: string]: ProviderParam }; - dict_key_options?: string[]; - dict_value_type?: string; -} - -interface ProviderParamsResponse { - [provider: string]: { [key: string]: ProviderParam }; -} - const GuardrailInfoView: React.FC = ({ guardrailId, onClose, accessToken, isAdmin }) => { const [guardrailData, setGuardrailData] = useState(null); const [guardrailProviderSpecificParams, setGuardrailProviderSpecificParams] = useState(null); @@ -244,11 +228,6 @@ const GuardrailInfoView: React.FC = ({ guardrailId, onClose, resetToolPermissionEditor(); }, [resetToolPermissionEditor]); - const handleToolPermissionConfigChange = (config: ToolPermissionConfig) => { - setToolPermissionConfig(config); - setToolPermissionDirty(true); - }; - const handlePiiEntitySelect = (entity: string) => { setSelectedPiiEntities((prev) => { if (prev.includes(entity)) { diff --git a/ui/litellm-dashboard/src/app/(dashboard)/hooks/teams/useTeams.test.ts b/ui/litellm-dashboard/src/app/(dashboard)/hooks/teams/useTeams.test.ts index 28320b76597..fbab40c0b23 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/hooks/teams/useTeams.test.ts +++ b/ui/litellm-dashboard/src/app/(dashboard)/hooks/teams/useTeams.test.ts @@ -437,7 +437,7 @@ describe("useTeam", () => { }); // Import useQueryClient to get access to query client - const { useQueryClient } = await import("@tanstack/react-query"); + await import("@tanstack/react-query"); // Manually test the queryFn logic by calling it directly // This simulates what would happen if enabled check was bypassed diff --git a/ui/litellm-dashboard/src/app/(dashboard)/hooks/useAuthorized.test.ts b/ui/litellm-dashboard/src/app/(dashboard)/hooks/useAuthorized.test.ts index 567ca911458..f3ec7b3713b 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/hooks/useAuthorized.test.ts +++ b/ui/litellm-dashboard/src/app/(dashboard)/hooks/useAuthorized.test.ts @@ -265,7 +265,7 @@ describe("useAuthorized", () => { const token = createJwt(decodedPayload); document.cookie = `token=${token}; path=/;`; - const { result } = renderHook(() => useAuthorized(), { wrapper }); + renderHook(() => useAuthorized(), { wrapper }); await waitFor(() => { expect(clearTokenCookiesMock).toHaveBeenCalled(); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/CreateMCPServer.tsx b/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/CreateMCPServer.tsx index 0785dd142ff..d567c318743 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/CreateMCPServer.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/CreateMCPServer.tsx @@ -333,7 +333,6 @@ const CreateMCPServer: React.FC = ({ if (!pendingRestoredValues) { return; } - const transportReady = transportType || pendingRestoredValues.transport || ""; if (pendingRestoredValues.transport && !transportType) { // wait until transportType state catches up so the URL field is mounted return; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/MCPLogoSelector.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/MCPLogoSelector.test.tsx index 67b5d6bfe92..f126a030b9f 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/MCPLogoSelector.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/MCPLogoSelector.test.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { render, screen, fireEvent } from "@testing-library/react"; +import { render, screen } from "@testing-library/react"; import { describe, it, expect, vi, beforeEach } from "vitest"; import userEvent from "@testing-library/user-event"; import MCPLogoSelector from "./MCPLogoSelector"; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/mcp_connect.tsx b/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/mcp_connect.tsx index 7bdfd9c6b8f..74b77735377 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/mcp_connect.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/mcp_connect.tsx @@ -1,14 +1,13 @@ /* eslint-disable react/no-unescaped-entities */ import React, { useState } from "react"; -import { Card, Typography, Space, Alert, Button, Switch, Form, Collapse } from "antd"; +import { Card, Typography, Space, Alert, Button, Switch, Form } from "antd"; import { TabPanel, TabPanels, TabGroup, TabList, Tab, Title as TremorTitle, Text as TremorText } from "@tremor/react"; import { CopyIcon, Code, Terminal, Globe, CheckIcon, ExternalLinkIcon, KeyIcon, ServerIcon, Zap } from "lucide-react"; import { getProxyBaseUrl } from "@/components/networking"; import { copyToClipboard as utilCopyToClipboard } from "@/utils/dataUtils"; const { Title, Text } = Typography; -const { Panel } = Collapse; interface CodeBlockProps { code: string; @@ -117,12 +116,6 @@ interface MCPConnectProps { const MCPConnect: React.FC = ({ currentServerAccessGroups = [] }) => { const proxyBaseUrl = getProxyBaseUrl(); const [copiedStates, setCopiedStates] = useState>({}); - const [serverHeaders, setServerHeaders] = useState>({ - openai: [], - litellm: [], - cursor: [], - http: [], - }); const [currentServer] = useState("Zapier_MCP"); // This should match the current server being viewed const copyToClipboard = async (text: string, key: string) => { @@ -135,22 +128,6 @@ const MCPConnect: React.FC = ({ currentServerAccessGroups = [] } }; - const getHeadersConfig = (type: string) => { - const headers: Record = { - "x-litellm-api-key": "Bearer YOUR_LITELLM_API_KEY", - }; - - if (serverHeaders[type]?.length > 0) { - // Format server names (replace spaces with underscores) - const formattedServers = serverHeaders[type].map((s) => s.replace(/\s+/g, "_")); - - // Use comma-separated string (can include both servers and access groups) - headers["x-mcp-servers"] = formattedServers.join(","); - } - - return headers; - }; - const CodeBlock: React.FC<{ code: string; copyKey: string; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/ChatUI.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/ChatUI.test.tsx index b5f2bf7b10c..3c94977f0dc 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/ChatUI.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/ChatUI.test.tsx @@ -60,7 +60,7 @@ describe("ChatUI", () => { }); it("should show the voice selector when the endpoint type is audio_speech", async () => { - const { getByText, container } = render( + const { getByText } = render( { }); it("should allow the user to select a model", async () => { - const { getByText, container } = render( + const { getByText } = render( { { model_group: "ResponsesModel", mode: "responses" }, ]); - const { getByText, baseElement } = render( + const { getByText } = render( = ({ chatHistory, setChatHistory, mcpEvents, - setMCPEvents, messageTraceId, setMessageTraceId, responsesSessionId, - setResponsesSessionId, useApiSessionManagement, - setUseApiSessionManagement, updateTextUI, updateReasoningContent, updateTimingData, @@ -604,7 +590,7 @@ const ChatUI: React.FC = ({ return; } // Resolve the real server ID (toolsets use toolset: prefix) - const mcpServerId = rawSelected.startsWith("toolset:") ? rawSelected : rawSelected; + rawSelected.startsWith("toolset:") ? rawSelected : rawSelected; if (!selectedMCPDirectTool) { NotificationsManager.fromBackend("Please select an MCP tool to call"); return; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/RealtimePlayground.tsx b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/RealtimePlayground.tsx index 68a150be8c0..2bf645fced2 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/RealtimePlayground.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/RealtimePlayground.tsx @@ -37,8 +37,6 @@ const RealtimePlayground: React.FC = ({ const audioContextRef = useRef(null); const mediaStreamRef = useRef(null); const processorRef = useRef(null); - const playbackQueueRef = useRef([]); - const isPlayingRef = useRef(false); const messagesEndRef = useRef(null); const nextPlayTimeRef = useRef(0); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/add_policy_form.tsx b/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/add_policy_form.tsx index 8da2d3af36f..3f7b4385757 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/add_policy_form.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/add_policy_form.tsx @@ -8,7 +8,6 @@ import NotificationsManager from "@/components/molecules/notifications_manager"; import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized"; const { Text } = Typography; -const { Option } = Select; interface AddPolicyFormProps { visible: boolean; @@ -162,7 +161,7 @@ const AddPolicyForm: React.FC = ({ const [form] = Form.useForm(); const [isSubmitting, setIsSubmitting] = useState(false); const [resolvedGuardrails, setResolvedGuardrails] = useState([]); - const [isLoadingResolved, setIsLoadingResolved] = useState(false); + const [, setIsLoadingResolved] = useState(false); const [modelConditionType, setModelConditionType] = useState<"model" | "regex">("model"); const [availableModels, setAvailableModels] = useState([]); const [step, setStep] = useState<"pick_mode" | "simple_form">("pick_mode"); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/ai_suggestion_modal.tsx b/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/ai_suggestion_modal.tsx index cbf24b425f4..c13ee470449 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/ai_suggestion_modal.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/ai_suggestion_modal.tsx @@ -76,7 +76,7 @@ const AiSuggestionModal: React.FC = ({ const [testInputText, setTestInputText] = useState(""); const [isTestLoading, setIsTestLoading] = useState(false); const [testResults, setTestResults] = useState(null); - const [testOverallAction, setTestOverallAction] = useState(null); + const [, setTestOverallAction] = useState(null); const [collapsedResults, setCollapsedResults] = useState>(new Set()); // Enrichment state for competitor templates const [enrichedDefs, setEnrichedDefs] = useState>({}); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/policy_info.tsx b/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/policy_info.tsx index c49093f3238..fda6972f747 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/policy_info.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/policy_info.tsx @@ -53,7 +53,7 @@ const PolicyInfoView: React.FC = ({ const [policy, setPolicy] = useState(null); const [isLoading, setIsLoading] = useState(true); const [resolvedGuardrails, setResolvedGuardrails] = useState([]); - const [isLoadingResolved, setIsLoadingResolved] = useState(false); + const [, setIsLoadingResolved] = useState(false); const fetchPolicy = useCallback(async () => { if (!accessToken || !policyId) return; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/prompts/_components/add_prompt_form.tsx b/ui/litellm-dashboard/src/app/(dashboard)/prompts/_components/add_prompt_form.tsx index 1bd831ca49d..c02efa82499 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/prompts/_components/add_prompt_form.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/prompts/_components/add_prompt_form.tsx @@ -15,12 +15,6 @@ interface AddPromptFormProps { onSuccess: () => void; } -interface PromptFormData { - prompt_id: string; - prompt_integration: string; - prompt_file?: File; -} - const AddPromptForm: React.FC = ({ visible, onClose, accessToken, onSuccess }) => { const [form] = Form.useForm(); const [loading, setLoading] = useState(false); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/prompts/_components/index.tsx b/ui/litellm-dashboard/src/app/(dashboard)/prompts/_components/index.tsx index 9bebabb8cf2..c885fdcbf35 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/prompts/_components/index.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/prompts/_components/index.tsx @@ -47,7 +47,7 @@ const PromptsPanel: React.FC = ({ accessToken, userRole }) => { const [isDeleting, setIsDeleting] = useState(false); const [promptToDelete, setPromptToDelete] = useState<{ id: string; name: string } | null>(null); - const isAdmin = userRole ? isAdminRole(userRole) : false; + userRole ? isAdminRole(userRole) : false; // Admin Viewer follows the read-parity rule: see prompts, no writes. const canModify = userRole ? isProxyAdminRole(userRole) : false; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/prompts/_components/prompt_editor_view/VersionHistorySidePanel.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/prompts/_components/prompt_editor_view/VersionHistorySidePanel.test.tsx index c76c64b89a6..97f671b1b71 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/prompts/_components/prompt_editor_view/VersionHistorySidePanel.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/prompts/_components/prompt_editor_view/VersionHistorySidePanel.test.tsx @@ -182,7 +182,7 @@ describe("VersionHistorySidePanel", () => { render(); await waitFor(() => { - const versionItems = screen.getAllByTestId("tag"); + screen.getAllByTestId("tag"); // Should have Active tag for the selected version expect(screen.getByText("Active")).toBeInTheDocument(); }); @@ -464,7 +464,7 @@ describe("VersionHistorySidePanel", () => { render(); await waitFor(() => { - const versionElements = screen.getAllByTestId("tag"); + screen.getAllByTestId("tag"); // Verify versions are displayed as they come from the API expect(screen.getByText("v2")).toBeInTheDocument(); }); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/prompts/_components/prompt_editor_view/index.tsx b/ui/litellm-dashboard/src/app/(dashboard)/prompts/_components/prompt_editor_view/index.tsx index fa69a520145..e09ca787a69 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/prompts/_components/prompt_editor_view/index.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/prompts/_components/prompt_editor_view/index.tsx @@ -44,7 +44,7 @@ const PromptEditorView: React.FC = ({ onClose, onSuccess, }; const [prompt, setPrompt] = useState(getInitialPrompt()); - const [editMode, setEditMode] = useState(!!initialPromptData); + const [editMode] = useState(!!initialPromptData); const [showHistoryModal, setShowHistoryModal] = useState(false); // Construct versioned ID from prompt_id and version field diff --git a/ui/litellm-dashboard/src/app/(dashboard)/transform-request/TransformRequestPanel.tsx b/ui/litellm-dashboard/src/app/(dashboard)/transform-request/TransformRequestPanel.tsx index 0c41547b9b7..0c7f10eab0e 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/transform-request/TransformRequestPanel.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/transform-request/TransformRequestPanel.tsx @@ -11,12 +11,6 @@ interface TransformRequestPanelProps { accessToken: string | null; } -interface TransformResponse { - raw_request_api_base: string; - raw_request_body: Record; - raw_request_headers: Record; -} - const TransformRequestPanel: React.FC = ({ accessToken }) => { const [originalRequestJSON, setOriginalRequestJSON] = useState(`{ "model": "openai/gpt-4o", diff --git a/ui/litellm-dashboard/src/app/(dashboard)/ui-theme/UIThemeSettings.tsx b/ui/litellm-dashboard/src/app/(dashboard)/ui-theme/UIThemeSettings.tsx index 035d87c4e9b..4da93d8e0b9 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/ui-theme/UIThemeSettings.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/ui-theme/UIThemeSettings.tsx @@ -15,7 +15,7 @@ interface UIThemeSettingsProps { } const UIThemeSettings: React.FC = ({ userID, userRole, accessToken }) => { - const { logoUrl, setLogoUrl, faviconUrl, setFaviconUrl } = useTheme(); + const { setLogoUrl, setFaviconUrl } = useTheme(); const [logoUrlInput, setLogoUrlInput] = useState(""); const [faviconUrlInput, setFaviconUrlInput] = useState(""); const [loading, setLoading] = useState(false); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/UsagePageView.tsx b/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/UsagePageView.tsx index 46a17017d39..19f650386a6 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/UsagePageView.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/UsagePageView.tsx @@ -985,40 +985,5 @@ const UsagePage: React.FC = ({ teams, organizations }) => { }; // Add this helper function to process model-specific activity data -const getModelActivityData = (userSpendData: { results: DailyData[]; metadata: any }) => { - const modelData: { - [key: string]: { - total_requests: number; - total_tokens: number; - daily_data: Array<{ - date: string; - api_requests: number; - total_tokens: number; - }>; - }; - } = {}; - - userSpendData.results.forEach((day: DailyData) => { - Object.entries(day.breakdown.models || {}).forEach(([model, metrics]) => { - if (!modelData[model]) { - modelData[model] = { - total_requests: 0, - total_tokens: 0, - daily_data: [], - }; - } - - modelData[model].total_requests += metrics.metrics.api_requests; - modelData[model].total_tokens += metrics.metrics.total_tokens; - modelData[model].daily_data.push({ - date: day.date, - api_requests: metrics.metrics.api_requests, - total_tokens: metrics.metrics.total_tokens, - }); - }); - }); - - return modelData; -}; export default UsagePage; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/UsageViewSelect/UsageViewSelect.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/UsageViewSelect/UsageViewSelect.test.tsx index b33129fcdb4..d72fc7bca0c 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/UsageViewSelect/UsageViewSelect.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/UsageViewSelect/UsageViewSelect.test.tsx @@ -8,10 +8,10 @@ vi.mock("antd", async () => { function Select(props: any) { const { value, onChange, options, optionRender, labelRender, ...rest } = props; const selectedOption = options?.find((opt: any) => opt.value === value); - const renderedLabel = labelRender ? labelRender({ value, label: selectedOption?.label }) : selectedOption?.label; + labelRender ? labelRender({ value, label: selectedOption?.label }) : selectedOption?.label; const optionElements = options?.map((opt: any) => { - const rendered = optionRender ? optionRender({ value: opt.value, label: opt.label }) : opt.label; + optionRender ? optionRender({ value: opt.value, label: opt.label }) : opt.label; return React.createElement("option", { key: opt.value, value: opt.value }, opt.label); }); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/users/_components/edit_user.tsx b/ui/litellm-dashboard/src/app/(dashboard)/users/_components/edit_user.tsx index de031984846..0f3e0dedb52 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/users/_components/edit_user.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/users/_components/edit_user.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { useEffect } from "react"; import { TextInput, SelectItem } from "@tremor/react"; import { Button as Button2, Modal, Form, Select as Select2, InputNumber } from "antd"; @@ -15,7 +15,6 @@ interface EditUserModalProps { } const EditUserModal: React.FC = ({ visible, possibleUIRoles, onCancel, user, onSubmit }) => { - const [editedUser, setEditedUser] = useState(user); const [form] = Form.useForm(); useEffect(() => { diff --git a/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/vector_store_info.tsx b/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/vector_store_info.tsx index ec20a3fd318..e5646037d14 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/vector_store_info.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/vector_store_info.tsx @@ -36,7 +36,6 @@ const VectorStoreInfoView: React.FC = ({ const [isEditing, setIsEditing] = useState(editVectorStore); const [metadataString, setMetadataString] = useState("{}"); const [credentials, setCredentials] = useState([]); - const [activeTab, setActiveTab] = useState(editVectorStore ? "details" : "details"); const fetchVectorStoreDetails = async () => { if (!accessToken) return; diff --git a/ui/litellm-dashboard/src/app/chat/page.tsx b/ui/litellm-dashboard/src/app/chat/page.tsx index b6dccef47c6..7b6b26c6436 100644 --- a/ui/litellm-dashboard/src/app/chat/page.tsx +++ b/ui/litellm-dashboard/src/app/chat/page.tsx @@ -65,7 +65,6 @@ export default function ChatConversationPage() { updateLastAssistantMessage, truncateFromMessage, } = useChatShell(); - const hadActiveConversationOnMountRef = useRef(activeConversationId !== null); const [selectedModel, setSelectedModel] = useState(null); const [models, setModels] = useState([]); diff --git a/ui/litellm-dashboard/src/components/AIHub/UsefulLinksManagement.tsx b/ui/litellm-dashboard/src/components/AIHub/UsefulLinksManagement.tsx index 42acfd94185..d8730888c84 100644 --- a/ui/litellm-dashboard/src/components/AIHub/UsefulLinksManagement.tsx +++ b/ui/litellm-dashboard/src/components/AIHub/UsefulLinksManagement.tsx @@ -23,7 +23,7 @@ const UsefulLinksManagement: React.FC = ({ accessTok const [links, setLinks] = useState([]); const [newLink, setNewLink] = useState({ url: "", displayName: "" }); const [editingLink, setEditingLink] = useState(null); - const [loading, setLoading] = useState(false); + const [, setLoading] = useState(false); const [isExpanded, setIsExpanded] = useState(true); const [isRearranging, setIsRearranging] = useState(false); const [originalLinksOrder, setOriginalLinksOrder] = useState([]); diff --git a/ui/litellm-dashboard/src/components/CreateUserButton.tsx b/ui/litellm-dashboard/src/components/CreateUserButton.tsx index 2b0c801f0bd..8de9f010fa3 100644 --- a/ui/litellm-dashboard/src/components/CreateUserButton.tsx +++ b/ui/litellm-dashboard/src/components/CreateUserButton.tsx @@ -15,7 +15,7 @@ import { Tooltip, Typography, } from "antd"; -import React, { useEffect, useMemo, useState } from "react"; +import React, { useEffect, useState } from "react"; import BulkCreateUsers from "./bulk_create_users_button"; import TeamDropdown from "./common_components/team_dropdown"; import { getModelDisplayName } from "./key_team_helpers/fetch_available_models_team_key"; @@ -29,7 +29,7 @@ import { } from "./networking"; import OnboardingModal, { InvitationLink } from "./onboarding_link"; const { Option } = Select; -const { Text, Link, Title } = Typography; +const { Text, Link } = Typography; // Helper function to generate UUID compatible across all environments const generateUUID = (): string => { if (typeof crypto !== "undefined" && crypto.randomUUID) { @@ -80,11 +80,6 @@ export const CreateUserButton: React.FC = ({ const { data: organizations = [] } = useOrganizations(); // Derive teams from the user's organizations, falling back to the teams prop - const availableTeams = useMemo(() => { - const orgTeams = organizations.flatMap((org) => org.teams || []); - if (orgTeams.length > 0) return orgTeams; - return teams || []; - }, [organizations, teams]); useEffect(() => { const fetchData = async () => { diff --git a/ui/litellm-dashboard/src/components/EntityUsageExport/utils.test.ts b/ui/litellm-dashboard/src/components/EntityUsageExport/utils.test.ts index dfeecdc4fa6..e91b7b73a1e 100644 --- a/ui/litellm-dashboard/src/components/EntityUsageExport/utils.test.ts +++ b/ui/litellm-dashboard/src/components/EntityUsageExport/utils.test.ts @@ -1876,7 +1876,7 @@ describe("EntityUsageExport utils", () => { it("should create CSV file and trigger download", () => { const createObjectURLSpy = vi.spyOn(window.URL, "createObjectURL").mockReturnValue("blob:mock-url"); - const revokeObjectURLSpy = vi.spyOn(window.URL, "revokeObjectURL"); + vi.spyOn(window.URL, "revokeObjectURL"); const createElementSpy = vi.spyOn(document, "createElement"); const appendChildSpy = vi.spyOn(document.body, "appendChild"); const removeChildSpy = vi.spyOn(document.body, "removeChild"); @@ -1892,7 +1892,7 @@ describe("EntityUsageExport utils", () => { it("should generate correct filename", () => { const anchorElement = document.createElement("a"); - const createElementSpy = vi.spyOn(document, "createElement").mockReturnValue(anchorElement); + vi.spyOn(document, "createElement").mockReturnValue(anchorElement); const today = new Date().toISOString().split("T")[0]; @@ -1935,7 +1935,7 @@ describe("EntityUsageExport utils", () => { it("should create JSON file and trigger download", () => { const createObjectURLSpy = vi.spyOn(window.URL, "createObjectURL").mockReturnValue("blob:mock-url"); - const revokeObjectURLSpy = vi.spyOn(window.URL, "revokeObjectURL"); + vi.spyOn(window.URL, "revokeObjectURL"); const createElementSpy = vi.spyOn(document, "createElement"); const appendChildSpy = vi.spyOn(document.body, "appendChild"); const removeChildSpy = vi.spyOn(document.body, "removeChild"); @@ -1955,7 +1955,7 @@ describe("EntityUsageExport utils", () => { it("should generate correct filename", () => { const anchorElement = document.createElement("a"); - const createElementSpy = vi.spyOn(document, "createElement").mockReturnValue(anchorElement); + vi.spyOn(document, "createElement").mockReturnValue(anchorElement); const today = new Date().toISOString().split("T")[0]; const mockDateRange: DateRangePickerValue = { diff --git a/ui/litellm-dashboard/src/components/HelpLink.test.tsx b/ui/litellm-dashboard/src/components/HelpLink.test.tsx index b1709436c72..e502126477a 100644 --- a/ui/litellm-dashboard/src/components/HelpLink.test.tsx +++ b/ui/litellm-dashboard/src/components/HelpLink.test.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { describe, it, expect, vi } from "vitest"; +import { describe, it, expect } from "vitest"; import { screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { renderWithProviders } from "../../tests/test-utils"; diff --git a/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.tsx b/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.tsx index 0965683c241..e993fed2408 100644 --- a/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.tsx +++ b/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.tsx @@ -2,7 +2,7 @@ import { ProxyModel, useAllProxyModels } from "@/app/(dashboard)/hooks/models/us import { useOrganization } from "@/app/(dashboard)/hooks/organizations/useOrganizations"; import { useTeam } from "@/app/(dashboard)/hooks/teams/useTeams"; import { useCurrentUser } from "@/app/(dashboard)/hooks/users/useCurrentUser"; -import { Select, Skeleton, Tooltip, type SelectProps } from "antd"; +import { Select, Skeleton, Tooltip } from "antd"; import { Organization, Team } from "../networking"; import { splitWildcardModels } from "./modelUtils"; @@ -93,8 +93,7 @@ const filterModels = ( export const ModelSelect = (props: ModelSelectProps) => { const { teamID, organizationID, options, context, dataTestId, value = [], onChange, style } = props; - const { includeUserModels, showAllTeamModelsOption, showAllProxyModelsOverride, includeSpecialOptions } = - options || {}; + const { showAllProxyModelsOverride, includeSpecialOptions } = options || {}; const { data: allProxyModels, isLoading: isLoadingAllProxyModels } = useAllProxyModels(); const { data: team, isLoading: isLoadingTeam } = useTeam(teamID); const { data: organization, isLoading: isLoadingOrganization } = useOrganization(organizationID); @@ -113,10 +112,6 @@ export const ModelSelect = (props: ModelSelectProps) => { return ; } - const optionRender: NonNullable = (option) => { - return {option.label}; - }; - const handleChange = (values: string[]) => { const specialValues = values.filter(isSpecialOption); diff --git a/ui/litellm-dashboard/src/components/Settings/AdminSettings/SSOSettings/Modals/EditSSOSettingsModal.test.tsx b/ui/litellm-dashboard/src/components/Settings/AdminSettings/SSOSettings/Modals/EditSSOSettingsModal.test.tsx index 7415683af83..7536286b404 100644 --- a/ui/litellm-dashboard/src/components/Settings/AdminSettings/SSOSettings/Modals/EditSSOSettingsModal.test.tsx +++ b/ui/litellm-dashboard/src/components/Settings/AdminSettings/SSOSettings/Modals/EditSSOSettingsModal.test.tsx @@ -320,7 +320,7 @@ describe("EditSSOSettingsModal", () => { useEditSSOSettings: { mutateAsync: mockMutateAsync, isPending: false }, }); - const { mockOnSuccess } = renderComponent(); + renderComponent(); fireEvent.click(screen.getByTestId(TEST_IDS.TRIGGER_FORM_SUBMIT)); diff --git a/ui/litellm-dashboard/src/components/Teams.tsx b/ui/litellm-dashboard/src/components/Teams.tsx index fc89751db6a..d3cb7712193 100644 --- a/ui/litellm-dashboard/src/components/Teams.tsx +++ b/ui/litellm-dashboard/src/components/Teams.tsx @@ -43,13 +43,6 @@ interface TeamProps { premiumUser?: boolean; } -interface EditTeamModalProps { - visible: boolean; - onCancel: () => void; - team: any; // Assuming TeamType is a type representing your team object - onSubmit: (data: FormData) => void; // Assuming FormData is the type of data to be submitted -} - import DeleteResourceModal from "./common_components/DeleteResourceModal"; import { teamCreateCall } from "./networking"; import { ModelSelect } from "./ModelSelect/ModelSelect"; @@ -112,18 +105,6 @@ const getAdminOrganizations = ( return []; }; -const getOrganizationAlias = ( - organizationId: string | null | undefined, - organizations: Organization[] | null | undefined, -): string => { - if (!organizationId || !organizations) { - return organizationId || "N/A"; - } - - const organization = organizations.find((org) => org.organization_id === organizationId); - return organization?.organization_alias || organizationId; -}; - // @deprecated const Teams: React.FC = ({ accessToken, userID, userRole, premiumUser = false }) => { const { data: organizationsData } = useOrganizations(); @@ -135,27 +116,22 @@ const Teams: React.FC = ({ accessToken, userID, userRole, premiumUser const [currentOrgForCreateTeam, setCurrentOrgForCreateTeam] = useState(null); const [form] = Form.useForm(); - const [memberForm] = Form.useForm(); - const [value, setValue] = useState(""); - const [editModalVisible, setEditModalVisible] = useState(false); const [selectedTeam, setSelectedTeam] = useState(null); const { teamId: selectedTeamId, openTeam, close: closeTeamDetail } = useTeamDetailRouting(); const [editTeam, setEditTeam] = useState(false); const [isTeamModalVisible, setIsTeamModalVisible] = useState(false); - const [isAddMemberModalVisible, setIsAddMemberModalVisible] = useState(false); - const [isEditMemberModalVisible, setIsEditMemberModalVisible] = useState(false); const [userModels, setUserModels] = useState([]); const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [teamToDelete, setTeamToDelete] = useState(null); - const [modelsToPick, setModelsToPick] = useState([]); + const [, setModelsToPick] = useState([]); const [isTeamDeleting, setIsTeamDeleting] = useState(false); // Add this state near the other useState declarations const [guardrailsList, setGuardrailsList] = useState([]); const [policiesList, setPoliciesList] = useState([]); const [loggingSettings, setLoggingSettings] = useState([]); - const [mcpAccessGroups, setMcpAccessGroups] = useState([]); + const [, setMcpAccessGroups] = useState([]); const [mcpAccessGroupsLoaded, setMcpAccessGroupsLoaded] = useState(false); const [modelAliases, setModelAliases] = useState<{ [key: string]: string }>({}); const [routerSettings, setRouterSettings] = useState(null); @@ -245,12 +221,6 @@ const Teams: React.FC = ({ accessToken, userID, userRole, premiumUser setRouterSettingsKey((prev) => prev + 1); }; - const handleMemberOk = () => { - setIsAddMemberModalVisible(false); - setIsEditMemberModalVisible(false); - memberForm.resetFields(); - }; - const handleCancel = () => { setIsTeamModalVisible(false); form.resetFields(); @@ -260,12 +230,6 @@ const Teams: React.FC = ({ accessToken, userID, userRole, premiumUser setRouterSettingsKey((prev) => prev + 1); }; - const handleMemberCancel = () => { - setIsAddMemberModalVisible(false); - setIsEditMemberModalVisible(false); - memberForm.resetFields(); - }; - const handleDelete = async (team: Team) => { // Set the team to delete and open the confirmation modal setTeamToDelete(team); diff --git a/ui/litellm-dashboard/src/components/ToolDetail.tsx b/ui/litellm-dashboard/src/components/ToolDetail.tsx index 06f14638141..309b95b2d3d 100644 --- a/ui/litellm-dashboard/src/components/ToolDetail.tsx +++ b/ui/litellm-dashboard/src/components/ToolDetail.tsx @@ -26,10 +26,8 @@ import { keyListCall, teamListCall, updateToolPolicy, - type ToolPolicyOption, type ToolPolicyOverrideRow, } from "@/components/networking"; -import type { Team } from "@/components/key_team_helpers/key_list"; interface ToolDetailProps { toolName: string; @@ -87,7 +85,7 @@ export function ToolDetail({ toolName, onBack, accessToken }: ToolDetailProps) { staleTime: 60_000, }); - const { data: teamsData } = useQuery({ + useQuery({ queryKey: ["teams-list-tool-detail"], queryFn: () => teamListCall(accessToken!, null, null), enabled: !!accessToken, @@ -122,24 +120,6 @@ export function ToolDetail({ toolName, onBack, accessToken }: ToolDetailProps) { })); }, [logsData?.logs]); - const teams: Team[] = useMemo(() => { - const arr = Array.isArray(teamsData) ? teamsData : teamsData?.data ?? []; - return arr.map((t: { team_id?: string; id?: string; team_alias?: string }) => ({ - team_id: t.team_id ?? t.id ?? "", - team_alias: t.team_alias ?? t.team_id ?? "", - models: [], - max_budget: null, - budget_duration: null, - tpm_limit: null, - rpm_limit: null, - organization_id: "", - created_at: "", - keys: [], - members_with_roles: [], - spend: 0, - })); - }, [teamsData]); - const keys: KeyOption[] = useMemo(() => { const keysRes = keysData?.keys ?? keysData?.data ?? []; return keysRes.map((k: { token?: string; api_key?: string; key_hash?: string; key_alias?: string }) => ({ diff --git a/ui/litellm-dashboard/src/components/UsagePage/components/EntityUsage/TopKeyView.tsx b/ui/litellm-dashboard/src/components/UsagePage/components/EntityUsage/TopKeyView.tsx index 60f25837589..1542b313334 100644 --- a/ui/litellm-dashboard/src/components/UsagePage/components/EntityUsage/TopKeyView.tsx +++ b/ui/litellm-dashboard/src/components/UsagePage/components/EntityUsage/TopKeyView.tsx @@ -20,7 +20,7 @@ interface TopKeyViewProps { } const TopKeyView: React.FC = ({ topKeys, teams, showTags = false, topKeysLimit, setTopKeysLimit }) => { - const { accessToken, userRole, userId: userID, premiumUser } = useAuthorized(); + const { accessToken } = useAuthorized(); const [isModalOpen, setIsModalOpen] = useState(false); const [selectedKey, setSelectedKey] = useState(null); const [keyData, setKeyData] = useState(undefined); diff --git a/ui/litellm-dashboard/src/components/add_model/AddModelForm.tsx b/ui/litellm-dashboard/src/components/add_model/AddModelForm.tsx index 03be04b9919..307f3665e83 100644 --- a/ui/litellm-dashboard/src/components/add_model/AddModelForm.tsx +++ b/ui/litellm-dashboard/src/components/add_model/AddModelForm.tsx @@ -66,7 +66,7 @@ const AddModelForm: React.FC = ({ } = useProviderFields(); const { data: guardrailsData } = useGuardrails(); const guardrailsList = guardrailsData?.guardrails.map((g) => g.guardrail_name); - const { data: tagsList, isLoading: isTagsLoading, error: tagsError } = useTags(); + const { data: tagsList } = useTags(); const handleTestConnection = async () => { setIsTestingConnection(true); diff --git a/ui/litellm-dashboard/src/components/add_model/RouterConfigBuilder.tsx b/ui/litellm-dashboard/src/components/add_model/RouterConfigBuilder.tsx index 08acf993e2c..b28d402f116 100644 --- a/ui/litellm-dashboard/src/components/add_model/RouterConfigBuilder.tsx +++ b/ui/litellm-dashboard/src/components/add_model/RouterConfigBuilder.tsx @@ -126,13 +126,6 @@ const RouterConfigBuilder: React.FC = ({ modelInfo, va }; // Handle utterances change (convert textarea string to array) - const handleUtterancesChange = (routeId: string, utterancesText: string) => { - const utterancesArray = utterancesText - .split("\n") - .map((line) => line.trim()) // Only trims leading/trailing whitespace, preserves internal spaces - .filter((line) => line.length > 0); - updateRoute(routeId, "utterances", utterancesArray); - }; // Prepare model options for dropdowns const modelOptions = modelInfo.map((model) => ({ diff --git a/ui/litellm-dashboard/src/components/add_model/add_auto_router_tab.tsx b/ui/litellm-dashboard/src/components/add_model/add_auto_router_tab.tsx index ae90d42ba8a..b20ff629a4c 100644 --- a/ui/litellm-dashboard/src/components/add_model/add_auto_router_tab.tsx +++ b/ui/litellm-dashboard/src/components/add_model/add_auto_router_tab.tsx @@ -38,8 +38,6 @@ interface AddAutoRouterTabProps { createScope?: ModelWriteScope; } -const { Title } = Typography; - const AddAutoRouterTab: React.FC = ({ handleOk, accessToken, @@ -91,7 +89,7 @@ const AddAutoRouterTab: React.FC = ({ const isAdmin = all_admin_roles.includes(userRole); - const modelGroupOptions = Array.from(new Set(modelInfo.map((option) => option.model_group))).map((model_group) => ({ + Array.from(new Set(modelInfo.map((option) => option.model_group))).map((model_group) => ({ value: model_group, label: model_group, })); diff --git a/ui/litellm-dashboard/src/components/add_model/handle_add_model_submit.tsx b/ui/litellm-dashboard/src/components/add_model/handle_add_model_submit.tsx index 71590660765..908a4c498dc 100644 --- a/ui/litellm-dashboard/src/components/add_model/handle_add_model_submit.tsx +++ b/ui/litellm-dashboard/src/components/add_model/handle_add_model_submit.tsx @@ -197,7 +197,7 @@ export const handleAddModelSubmit = async (values: any, accessToken: string, for model_info: modelInfoObj, }; - const response: any = await modelCreateCall(accessToken, new_model); + await modelCreateCall(accessToken, new_model); } callback && callback(); diff --git a/ui/litellm-dashboard/src/components/add_model/model_connection_test.tsx b/ui/litellm-dashboard/src/components/add_model/model_connection_test.tsx index 5b284fd26f5..bee92152842 100644 --- a/ui/litellm-dashboard/src/components/add_model/model_connection_test.tsx +++ b/ui/litellm-dashboard/src/components/add_model/model_connection_test.tsx @@ -24,7 +24,7 @@ const ModelConnectionTest: React.FC = ({ onTestComplete, }) => { const [error, setError] = React.useState(null); - const [rawRequest, setRawRequest] = React.useState(null); + const [, setRawRequest] = React.useState(null); const [rawResponse, setRawResponse] = React.useState(null); const [isLoading, setIsLoading] = React.useState(true); const [isSuccess, setIsSuccess] = React.useState(false); @@ -51,7 +51,7 @@ const ModelConnectionTest: React.FC = ({ return; } - const { litellmParamsObj, modelInfoObj, modelName: returnedModelName } = result[0]; + const { litellmParamsObj, modelInfoObj } = result[0]; const response = await testConnectionRequest(accessToken, litellmParamsObj, modelInfoObj, modelInfoObj?.mode); if (response.status === "success") { diff --git a/ui/litellm-dashboard/src/components/add_pass_through.tsx b/ui/litellm-dashboard/src/components/add_pass_through.tsx index c0343e268a1..0c9fbfb0347 100644 --- a/ui/litellm-dashboard/src/components/add_pass_through.tsx +++ b/ui/litellm-dashboard/src/components/add_pass_through.tsx @@ -37,7 +37,6 @@ const AddPassThroughEndpoint: React.FC = ({ const [form] = Form.useForm(); const [isModalVisible, setIsModalVisible] = useState(false); const [isLoading, setIsLoading] = useState(false); - const [selectedModel, setSelectedModel] = useState(""); const [pathValue, setPathValue] = useState(""); const [targetValue, setTargetValue] = useState(""); const [includeSubpath, setIncludeSubpath] = useState(true); @@ -107,11 +106,6 @@ const AddPassThroughEndpoint: React.FC = ({ } }; - const copyToClipboard = (text: string) => { - navigator.clipboard.writeText(text); - NotificationsManager.success("Copied to clipboard!"); - }; - return (