diff --git a/litellm/proxy/proxy_config.yaml b/litellm/proxy/proxy_config.yaml index f1d27c35da..b2f47caac7 100644 --- a/litellm/proxy/proxy_config.yaml +++ b/litellm/proxy/proxy_config.yaml @@ -1,16 +1,4 @@ model_list: - - model_name: openai/* - litellm_params: - model: openai/* - api_key: os.environ/OPENAI_API_KEY - - model_name: bedrock/* - litellm_params: - model: bedrock/* - api_base: https://exampleopenaiendpoint-production.up.railway.app/ - - model_name: text-embedding-ada-002 - litellm_params: - model: openai/text-embedding-ada-002 - api_key: os.environ/OPENAI_API_KEY - model_name: fake-openai-endpoint litellm_params: model: openai/fake @@ -19,11 +7,6 @@ model_list: - -litellm_settings: - callbacks: ["langfuse"] - - litellm_settings: callbacks: ["prometheus"] prometheus_initialize_budget_metrics: true diff --git a/ui/litellm-dashboard/src/components/model_dashboard.tsx b/ui/litellm-dashboard/src/components/model_dashboard.tsx index 05ff85098e..240e159fba 100644 --- a/ui/litellm-dashboard/src/components/model_dashboard.tsx +++ b/ui/litellm-dashboard/src/components/model_dashboard.tsx @@ -83,6 +83,8 @@ import { CheckCircleIcon, XCircleIcon, FilterIcon, + ChevronUpIcon, + ChevronDownIcon, } from "@heroicons/react/outline"; import DeleteModelButton from "./delete_model_button"; const { Title: Title2, Link } = Typography; @@ -92,6 +94,7 @@ import { Upload } from "antd"; import TimeToFirstToken from "./model_metrics/time_to_first_token"; import DynamicFields from "./model_add/dynamic_form"; import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; +import { Providers, provider_map, providerLogoMap, getProviderLogoAndName, getPlaceholder } from "./provider_info_helpers"; interface ModelDashboardProps { accessToken: string | null; @@ -136,42 +139,6 @@ interface ProviderSettings { fields: ProviderFields[]; } -enum Providers { - OpenAI = "OpenAI", - Azure = "Azure", - Azure_AI_Studio = "Azure AI Studio", - Anthropic = "Anthropic", - Google_AI_Studio = "Google AI Studio", - Bedrock = "Amazon Bedrock", - Groq = "Groq", - MistralAI = "Mistral AI", - Deepseek = "Deepseek", - OpenAI_Compatible = "OpenAI-Compatible Endpoints (Together AI, etc.)", - Vertex_AI = "Vertex AI (Anthropic, Gemini, etc.)", - Cohere = "Cohere", - Databricks = "Databricks", - Ollama = "Ollama", - xAI = "xAI", -} - -const provider_map: Record = { - OpenAI: "openai", - Azure: "azure", - Azure_AI_Studio: "azure_ai", - Anthropic: "anthropic", - Google_AI_Studio: "gemini", - Bedrock: "bedrock", - Groq: "groq", - MistralAI: "mistral", - Cohere: "cohere_chat", - OpenAI_Compatible: "openai", - Vertex_AI: "vertex_ai", - Databricks: "databricks", - xAI: "xai", - Deepseek: "deepseek", - Ollama: "ollama", - -}; const retry_policy_map: Record = { "BadRequestError (400)": "BadRequestErrorRetries", @@ -182,12 +149,22 @@ const retry_policy_map: Record = { "InternalServerError (500)": "InternalServerErrorRetries", }; -const handleSubmit = async ( +export const handleSubmit = async ( formValues: Record, accessToken: string, form: any ) => { try { + // If model_name is not provided, use provider.toLowerCase() + "/*" + if (!formValues["model_name"]) { + formValues["model_name"] = formValues["custom_llm_provider"].toLowerCase() + "/*"; + } + + // If model is not provided, use provider.toLowerCase() + "/*" + if (!formValues["model"]) { + formValues["model"] = [formValues["custom_llm_provider"].toLowerCase() + "/*"]; + } + /** * For multiple litellm model names - create a separate deployment for each * - get the list @@ -362,6 +339,8 @@ const ModelDashboard: React.FC = ({ const [allEndUsers, setAllEndUsers] = useState([]); + // Add state for advanced settings visibility + const [showAdvancedSettings, setShowAdvancedSettings] = useState(false); const updateModelMetrics = async ( modelGroup: string | null, @@ -1332,23 +1311,6 @@ const ModelDashboard: React.FC = ({ ); }; - const getPlaceholder = (selectedProvider: string): string => { - if (selectedProvider === Providers.Vertex_AI) { - return "gemini-pro"; - } else if (selectedProvider == Providers.Anthropic) { - return "claude-3-opus"; - } else if (selectedProvider == Providers.Bedrock) { - return "claude-3-opus"; - } else if (selectedProvider == Providers.Google_AI_Studio) { - return "gemini-pro"; - } else if (selectedProvider == Providers.Azure_AI_Studio) { - return "azure_ai/command-r-plus"; - } else if (selectedProvider == Providers.Azure) { - return "azure/my-deployment"; - } else { - return "gpt-3.5-turbo"; - } - }; const handleOk = () => { form @@ -1587,14 +1549,35 @@ const ModelDashboard: React.FC = ({

{model.model_name || "-"}

-

{model.provider || "-"}

+ style={{ + maxWidth: "100px", + whiteSpace: "normal", + wordBreak: "break-word", + }} + > +
+ {model.provider && ( + {`${model.provider} { + // Create a div with provider initial as fallback + const target = e.target as HTMLImageElement; + const parent = target.parentElement; + if (parent) { + const fallbackDiv = document.createElement('div'); + fallbackDiv.className = 'w-4 h-4 rounded-full bg-gray-200 flex items-center justify-center text-xs'; + fallbackDiv.textContent = model.provider?.charAt(0) || '-'; + parent.replaceChild(fallbackDiv, target); + } + }} + /> + )} +

{model.provider || "-"}

+
+ = ({ labelAlign="left" > <> + = ({ setSelectedProvider(provider); }} > - {provider} +
+ {`${provider} { + // Create a div with provider initial as fallback + const target = e.target as HTMLImageElement; + const parent = target.parentElement; + if (parent) { + const fallbackDiv = document.createElement('div'); + fallbackDiv.className = 'w-5 h-5 rounded-full bg-gray-200 flex items-center justify-center text-xs'; + fallbackDiv.textContent = provider.charAt(0); + parent.replaceChild(fallbackDiv, target); + } + }} + /> + {provider} +
))}
- - - - - - - - - Model name your users will pass in. - - - - - - { (selectedProvider === Providers.Azure) || (selectedProvider === Providers.OpenAI_Compatible) || (selectedProvider === Providers.Ollama) ? ( - - ) : providerModels.length > 0 ? ( - - Custom Model Name (Enter below) - {providerModels.map((model, index) => ( - - {model} - - ))} - - ) : ( - - )} - - - prevValues.model !== currentValues.model} - > - {({ getFieldValue }) => { - const selectedModels = getFieldValue('model') || []; - return selectedModels.includes('custom') && ( - - - - ) - }} - - - - - - - Actual model name used for making{" "} - - litellm.completion() call - - . We'll{" "} - - loadbalance - {" "} - models with the same 'public name' - - - {dynamicProviderForm !== undefined && dynamicProviderForm.fields.length > 0 && ( = ({ rules={[{ required: true, message: "Required" }]} label="API Key" name="api_key" + tooltip="LLM API Credentials" > @@ -2044,7 +1961,111 @@ const ModelDashboard: React.FC = ({ )} - setShowAdvancedSettings(!showAdvancedSettings)} + style={{ cursor: 'pointer' }} + > +
+ Advanced Settings + +
+ + + {showAdvancedSettings && ( + <> + + + + + + + + Model name your users will pass in. + + + + + + + + {(selectedProvider === Providers.Azure) || (selectedProvider === Providers.OpenAI_Compatible) || (selectedProvider === Providers.Ollama) ? ( + + ) : providerModels.length > 0 ? ( + + Custom Model Name (Enter below) + {providerModels.map((model, index) => ( + + {model} + + ))} + + ) : ( + + )} + + + + prevValues.model !== currentValues.model} + > + {({ getFieldValue }) => { + const selectedModels = getFieldValue('model') || []; + return selectedModels.includes('custom') && ( + + + + ) + }} + + + + + + + + Actual model name used for making{" "} + + litellm.completion() call + + . We'll{" "} + + loadbalance + {" "} + models with the same 'public name' + + + + = ({ }' /> + + )} + + -
+ +
+ + + Need Help? + + Add Model
- - - Need Help? - - diff --git a/ui/litellm-dashboard/src/components/provider_info_helpers.tsx b/ui/litellm-dashboard/src/components/provider_info_helpers.tsx new file mode 100644 index 0000000000..1e7f29ddb1 --- /dev/null +++ b/ui/litellm-dashboard/src/components/provider_info_helpers.tsx @@ -0,0 +1,95 @@ +import React from "react"; +import { handleSubmit } from "./model_dashboard"; + +export enum Providers { + OpenAI = "OpenAI", + Azure = "Azure", + Azure_AI_Studio = "Azure AI Studio", + Anthropic = "Anthropic", + Google_AI_Studio = "Google AI Studio", + Bedrock = "Amazon Bedrock", + Groq = "Groq", + MistralAI = "Mistral AI", + Deepseek = "Deepseek", + OpenAI_Compatible = "OpenAI-Compatible Endpoints (Together AI, etc.)", + Vertex_AI = "Vertex AI (Anthropic, Gemini, etc.)", + Cohere = "Cohere", + Databricks = "Databricks", + Ollama = "Ollama", + xAI = "xAI", + } + +export const provider_map: Record = { + OpenAI: "openai", + Azure: "azure", + Azure_AI_Studio: "azure_ai", + Anthropic: "anthropic", + Google_AI_Studio: "gemini", + Bedrock: "bedrock", + Groq: "groq", + MistralAI: "mistral", + Cohere: "cohere_chat", + OpenAI_Compatible: "openai", + Vertex_AI: "vertex_ai", + Databricks: "databricks", + xAI: "xai", + Deepseek: "deepseek", + Ollama: "ollama", +}; + +export const providerLogoMap: Record = { + [Providers.OpenAI]: "https://artificialanalysis.ai/img/logos/openai_small.svg", + [Providers.Azure]: "https://upload.wikimedia.org/wikipedia/commons/a/a8/Microsoft_Azure_Logo.svg", + [Providers.Azure_AI_Studio]: "https://upload.wikimedia.org/wikipedia/commons/a/a8/Microsoft_Azure_Logo.svg", + [Providers.Anthropic]: "https://artificialanalysis.ai/img/logos/anthropic_small.svg", + [Providers.Google_AI_Studio]: "https://artificialanalysis.ai/img/logos/google_small.svg", + [Providers.Bedrock]: "https://artificialanalysis.ai/img/logos/aws_small.png", + [Providers.Groq]: "https://artificialanalysis.ai/img/logos/groq_small.png", + [Providers.MistralAI]: "https://artificialanalysis.ai/img/logos/mistral_small.png", + [Providers.Cohere]: "https://artificialanalysis.ai/img/logos/cohere_small.png", + [Providers.OpenAI_Compatible]: "https://upload.wikimedia.org/wikipedia/commons/4/4e/OpenAI_Logo.svg", + [Providers.Vertex_AI]: "https://artificialanalysis.ai/img/logos/google_small.svg", + [Providers.Databricks]: "https://artificialanalysis.ai/img/logos/databricks_small.png", + [Providers.Ollama]: "https://artificialanalysis.ai/img/logos/ollama_small.svg", + [Providers.xAI]: "https://artificialanalysis.ai/img/logos/xai_small.svg", + [Providers.Deepseek]: "https://artificialanalysis.ai/img/logos/deepseek_small.jpg", +}; + +export const getProviderLogoAndName = (providerValue: string): { logo: string, displayName: string } => { + if (!providerValue) { + return { logo: "", displayName: "-" }; + } + + // Find the enum key by matching provider_map values + const enumKey = Object.keys(provider_map).find( + key => provider_map[key].toLowerCase() === providerValue.toLowerCase() + ); + + if (!enumKey) { + return { logo: "", displayName: providerValue }; + } + + // Get the display name from Providers enum and logo from map + const displayName = Providers[enumKey as keyof typeof Providers]; + const logo = providerLogoMap[displayName as keyof typeof providerLogoMap]; + + return { logo, displayName }; +}; + +export const getPlaceholder = (selectedProvider: string): string => { + if (selectedProvider === Providers.Vertex_AI) { + return "gemini-pro"; + } else if (selectedProvider == Providers.Anthropic) { + return "claude-3-opus"; + } else if (selectedProvider == Providers.Bedrock) { + return "claude-3-opus"; + } else if (selectedProvider == Providers.Google_AI_Studio) { + return "gemini-pro"; + } else if (selectedProvider == Providers.Azure_AI_Studio) { + return "azure_ai/command-r-plus"; + } else if (selectedProvider == Providers.Azure) { + return "azure/my-deployment"; + } else { + return "gpt-3.5-turbo"; + } + };