diff --git a/ui/litellm-dashboard/src/components/common_components/check_openapi_schema.tsx b/ui/litellm-dashboard/src/components/common_components/check_openapi_schema.tsx index 9697ebad788..0af004e7bd3 100644 --- a/ui/litellm-dashboard/src/components/common_components/check_openapi_schema.tsx +++ b/ui/litellm-dashboard/src/components/common_components/check_openapi_schema.tsx @@ -1,8 +1,15 @@ import React, { useState, useEffect } from "react"; -import { Form, Input, InputNumber, Select } from "antd"; -import { TextInput } from "@tremor/react"; -import { InfoCircleOutlined } from "@ant-design/icons"; -import { Tooltip } from "antd"; +import { Form, Select } from "antd"; +import { Input } from "@/components/ui/input"; +import { Textarea } from "@/components/ui/textarea"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip"; +import { Info } from "lucide-react"; +import NumericalInput from "@/components/shared/numerical_input"; import { getOpenAPISchema } from "../networking"; import { formatLabel } from "@/utils/textUtils"; @@ -25,24 +32,25 @@ interface OpenAPISchema { interface SchemaFormFieldsProps { schemaComponent: string; excludedFields?: string[]; + // eslint-disable-next-line @typescript-eslint/no-explicit-any form: any; overrideLabels?: { [key: string]: string }; overrideTooltips?: { [key: string]: string }; customValidation?: { + // eslint-disable-next-line @typescript-eslint/no-explicit-any [key: string]: (rule: any, value: any) => Promise; }; + // eslint-disable-next-line @typescript-eslint/no-explicit-any defaultValues?: { [key: string]: any }; } // Define which fields should be parsed as JSON export const jsonFields = ["metadata", "config", "enforced_params", "aliases"]; -// Helper function to determine if a field should be treated as JSON const isJSONField = (key: string, property: SchemaProperty): boolean => { return jsonFields.includes(key) || property.format === "json"; }; -// Helper function to validate JSON input const validateJSON = (value: string): boolean => { if (!value) return true; try { @@ -53,8 +61,11 @@ const validateJSON = (value: string): boolean => { } }; -const getFieldHelp = (key: string, property: SchemaProperty, type: string): string => { - // Default help text based on type +const getFieldHelp = ( + key: string, + property: SchemaProperty, + type: string, +): string => { const defaultHelp = { string: "Text input", @@ -63,28 +74,28 @@ const getFieldHelp = (key: string, property: SchemaProperty, type: string): stri boolean: "True/False value", }[type] || "Text input"; - // Specific field help text const specificHelp: { [key: string]: string } = { max_budget: "Enter maximum budget in USD (e.g., 100.50)", budget_duration: "Select a time period for budget reset", tpm_limit: "Enter maximum tokens per minute (whole number)", rpm_limit: "Enter maximum requests per minute (whole number)", duration: "Enter duration (e.g., 30s, 24h, 7d)", - metadata: 'Enter JSON object with key-value pairs\nExample: {"team": "research", "project": "nlp"}', + metadata: + 'Enter JSON object with key-value pairs\nExample: {"team": "research", "project": "nlp"}', config: 'Enter configuration as JSON object\nExample: {"setting": "value"}', permissions: "Enter comma-separated permission strings", - enforced_params: 'Enter parameters as JSON object\nExample: {"param": "value"}', + enforced_params: + 'Enter parameters as JSON object\nExample: {"param": "value"}', blocked: "Enter true/false or specific block conditions", - aliases: 'Enter aliases as JSON object\nExample: {"alias1": "value1", "alias2": "value2"}', + aliases: + 'Enter aliases as JSON object\nExample: {"alias1": "value1", "alias2": "value2"}', models: "Select one or more model names", key_alias: "Enter a unique identifier for this key", tags: "Enter comma-separated tag strings", }; - // Get specific help text or use default based on type const helpText = specificHelp[key] || defaultHelp; - // Add format requirements for special cases if (isJSONField(key, property)) { return `${helpText}\nMust be valid JSON format`; } @@ -105,7 +116,8 @@ const SchemaFormFields: React.FC = ({ customValidation = {}, defaultValues = {}, }) => { - const [schemaProperties, setSchemaProperties] = useState(null); + const [schemaProperties, setSchemaProperties] = + useState(null); const [error, setError] = useState(null); useEffect(() => { @@ -120,9 +132,13 @@ const SchemaFormFields: React.FC = ({ setSchemaProperties(componentSchema); + // eslint-disable-next-line @typescript-eslint/no-explicit-any const defaultFormValues: { [key: string]: any } = {}; Object.keys(componentSchema.properties) - .filter((key) => !excludedFields.includes(key) && defaultValues[key] !== undefined) + .filter( + (key) => + !excludedFields.includes(key) && defaultValues[key] !== undefined, + ) .forEach((key) => { defaultFormValues[key] = defaultValues[key]; }); @@ -130,11 +146,15 @@ const SchemaFormFields: React.FC = ({ form.setFieldsValue(defaultFormValues); } catch (error) { console.error("Schema fetch error:", error); - setError(error instanceof Error ? error.message : "Failed to fetch schema"); + setError( + error instanceof Error ? error.message : "Failed to fetch schema", + ); } + // eslint-disable-next-line react-hooks/exhaustive-deps }; fetchOpenAPISchema(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [schemaComponent, form, excludedFields]); const getPropertyType = (property: SchemaProperty): string => { @@ -156,7 +176,8 @@ const SchemaFormFields: React.FC = ({ const label = overrideLabels[key] || property.title || formatLabel(key); const tooltip = overrideTooltips[key] || property.description; - const rules = []; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const rules: any[] = []; if (isRequired) { rules.push({ required: true, message: `${label} is required` }); } @@ -165,6 +186,7 @@ const SchemaFormFields: React.FC = ({ } if (isJSONField(key, property)) { rules.push({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any validator: async (_: any, value: string) => { if (value && !validateJSON(value)) { throw new Error("Please enter valid JSON"); @@ -176,9 +198,14 @@ const SchemaFormFields: React.FC = ({ const formLabel = tooltip ? ( {label}{" "} - - - + + + + + + {tooltip} + + ) : ( label @@ -186,7 +213,9 @@ const SchemaFormFields: React.FC = ({ let inputComponent; if (isJSONField(key, property)) { - inputComponent = ; + inputComponent = ( +