mirror of
https://github.com/tiennm99/litellm.git
synced 2026-08-10 20:22:26 +00:00
Migrate Add Model Fields to backend (#16620)
This commit is contained in:
@@ -0,0 +1,744 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from litellm.types.proxy.public_endpoints.public_endpoints import (
|
||||
ProviderCreateInfo,
|
||||
ProviderCredentialField,
|
||||
)
|
||||
|
||||
DEFAULT_MODEL_PLACEHOLDER = "gpt-3.5-turbo"
|
||||
|
||||
_FALLBACK_FIELDS: List[Dict[str, Any]] = [
|
||||
{
|
||||
"key": "api_base",
|
||||
"label": "API Base",
|
||||
"field_type": "text",
|
||||
"required": False,
|
||||
},
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": False,
|
||||
},
|
||||
]
|
||||
|
||||
PROVIDER_BASE_INFO: Dict[str, Dict[str, Any]] = {
|
||||
"AIML": {
|
||||
"provider_display_name": "AI/ML API",
|
||||
"litellm_provider": "aiml",
|
||||
"default_model_placeholder": "aiml/flux-pro/v1.1",
|
||||
},
|
||||
"Anthropic": {
|
||||
"provider_display_name": "Anthropic",
|
||||
"litellm_provider": "anthropic",
|
||||
"default_model_placeholder": "claude-3-opus",
|
||||
},
|
||||
"AssemblyAI": {
|
||||
"provider_display_name": "AssemblyAI",
|
||||
"litellm_provider": "assemblyai",
|
||||
},
|
||||
"Azure": {
|
||||
"provider_display_name": "Azure",
|
||||
"litellm_provider": "azure",
|
||||
"default_model_placeholder": "azure/my-deployment",
|
||||
},
|
||||
"Azure_AI_Studio": {
|
||||
"provider_display_name": "Azure AI Foundry (Studio)",
|
||||
"litellm_provider": "azure_ai",
|
||||
"default_model_placeholder": "azure_ai/command-r-plus",
|
||||
},
|
||||
"Bedrock": {
|
||||
"provider_display_name": "Amazon Bedrock",
|
||||
"litellm_provider": "bedrock",
|
||||
"default_model_placeholder": "claude-3-opus",
|
||||
},
|
||||
"Cerebras": {
|
||||
"provider_display_name": "Cerebras",
|
||||
"litellm_provider": "cerebras",
|
||||
},
|
||||
"Cohere": {
|
||||
"provider_display_name": "Cohere",
|
||||
"litellm_provider": "cohere",
|
||||
},
|
||||
"Dashscope": {
|
||||
"provider_display_name": "Dashscope",
|
||||
"litellm_provider": "dashscope",
|
||||
},
|
||||
"Databricks": {
|
||||
"provider_display_name": "Databricks (Qwen API)",
|
||||
"litellm_provider": "databricks",
|
||||
},
|
||||
"DeepInfra": {
|
||||
"provider_display_name": "DeepInfra",
|
||||
"litellm_provider": "deepinfra",
|
||||
"default_model_placeholder": "deepinfra/<any-model-on-deepinfra>",
|
||||
},
|
||||
"Deepgram": {
|
||||
"provider_display_name": "Deepgram",
|
||||
"litellm_provider": "deepgram",
|
||||
},
|
||||
"Deepseek": {
|
||||
"provider_display_name": "Deepseek",
|
||||
"litellm_provider": "deepseek",
|
||||
},
|
||||
"ElevenLabs": {
|
||||
"provider_display_name": "ElevenLabs",
|
||||
"litellm_provider": "elevenlabs",
|
||||
},
|
||||
"FalAI": {
|
||||
"provider_display_name": "Fal AI",
|
||||
"litellm_provider": "fal_ai",
|
||||
"default_model_placeholder": "fal_ai/fal-ai/flux-pro/v1.1-ultra",
|
||||
},
|
||||
"FireworksAI": {
|
||||
"provider_display_name": "Fireworks AI",
|
||||
"litellm_provider": "fireworks_ai",
|
||||
},
|
||||
"Google_AI_Studio": {
|
||||
"provider_display_name": "Google AI Studio",
|
||||
"litellm_provider": "gemini",
|
||||
"default_model_placeholder": "gemini-pro",
|
||||
},
|
||||
"GradientAI": {
|
||||
"provider_display_name": "GradientAI",
|
||||
"litellm_provider": "gradient_ai",
|
||||
},
|
||||
"Groq": {
|
||||
"provider_display_name": "Groq",
|
||||
"litellm_provider": "groq",
|
||||
},
|
||||
"Hosted_Vllm": {
|
||||
"provider_display_name": "vllm",
|
||||
"litellm_provider": "hosted_vllm",
|
||||
},
|
||||
"Infinity": {
|
||||
"provider_display_name": "Infinity",
|
||||
"litellm_provider": "infinity",
|
||||
},
|
||||
"JinaAI": {
|
||||
"provider_display_name": "Jina AI",
|
||||
"litellm_provider": "jina_ai",
|
||||
"default_model_placeholder": "jina_ai/",
|
||||
},
|
||||
"MistralAI": {
|
||||
"provider_display_name": "Mistral AI",
|
||||
"litellm_provider": "mistral",
|
||||
},
|
||||
"Ollama": {
|
||||
"provider_display_name": "Ollama",
|
||||
"litellm_provider": "ollama",
|
||||
},
|
||||
"OpenAI": {
|
||||
"provider_display_name": "OpenAI",
|
||||
"litellm_provider": "openai",
|
||||
},
|
||||
"OpenAI_Compatible": {
|
||||
"provider_display_name": "OpenAI-Compatible Endpoints (Together AI, etc.)",
|
||||
"litellm_provider": "openai",
|
||||
},
|
||||
"OpenAI_Text": {
|
||||
"provider_display_name": "OpenAI Text Completion",
|
||||
"litellm_provider": "text-completion-openai",
|
||||
},
|
||||
"OpenAI_Text_Compatible": {
|
||||
"provider_display_name": "OpenAI-Compatible Text Completion Models (Together AI, etc.)",
|
||||
"litellm_provider": "text-completion-openai",
|
||||
},
|
||||
"Openrouter": {
|
||||
"provider_display_name": "Openrouter",
|
||||
"litellm_provider": "openrouter",
|
||||
},
|
||||
"Oracle": {
|
||||
"provider_display_name": "Oracle Cloud Infrastructure (OCI)",
|
||||
"litellm_provider": "oci",
|
||||
"default_model_placeholder": "oci/xai.grok-4",
|
||||
},
|
||||
"Perplexity": {
|
||||
"provider_display_name": "Perplexity",
|
||||
"litellm_provider": "perplexity",
|
||||
},
|
||||
"SageMaker": {
|
||||
"provider_display_name": "AWS SageMaker",
|
||||
"litellm_provider": "sagemaker_chat",
|
||||
"default_model_placeholder": "sagemaker/jumpstart-dft-meta-textgeneration-llama-2-7b",
|
||||
},
|
||||
"Sambanova": {
|
||||
"provider_display_name": "Sambanova",
|
||||
"litellm_provider": "sambanova",
|
||||
},
|
||||
"Snowflake": {
|
||||
"provider_display_name": "Snowflake",
|
||||
"litellm_provider": "snowflake",
|
||||
"default_model_placeholder": "snowflake/mistral-7b",
|
||||
},
|
||||
"TogetherAI": {
|
||||
"provider_display_name": "TogetherAI",
|
||||
"litellm_provider": "together_ai",
|
||||
},
|
||||
"Triton": {
|
||||
"provider_display_name": "Triton",
|
||||
"litellm_provider": "triton",
|
||||
},
|
||||
"Vertex_AI": {
|
||||
"provider_display_name": "Vertex AI (Anthropic, Gemini, etc.)",
|
||||
"litellm_provider": "vertex_ai",
|
||||
"default_model_placeholder": "gemini-pro",
|
||||
},
|
||||
"VolcEngine": {
|
||||
"provider_display_name": "VolcEngine",
|
||||
"litellm_provider": "volcengine",
|
||||
"default_model_placeholder": "volcengine/<any-model-on-volcengine>",
|
||||
},
|
||||
"Voyage": {
|
||||
"provider_display_name": "Voyage AI",
|
||||
"litellm_provider": "voyage",
|
||||
"default_model_placeholder": "voyage/",
|
||||
},
|
||||
"xAI": {
|
||||
"provider_display_name": "xAI",
|
||||
"litellm_provider": "xai",
|
||||
},
|
||||
}
|
||||
|
||||
PROVIDER_CREDENTIAL_FIELDS: Dict[str, List[Dict[str, Any]]] = {
|
||||
"OpenAI": [
|
||||
{
|
||||
"key": "api_base",
|
||||
"label": "API Base",
|
||||
"field_type": "text",
|
||||
"placeholder": "https://api.openai.com/v1",
|
||||
"tooltip": "Common endpoints: https://api.openai.com/v1, https://eu.api.openai.com, https://us.api.openai.com",
|
||||
"default_value": "https://api.openai.com/v1",
|
||||
},
|
||||
{
|
||||
"key": "organization",
|
||||
"label": "OpenAI Organization ID",
|
||||
"placeholder": "[OPTIONAL] my-unique-org",
|
||||
},
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "OpenAI API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"OpenAI_Text": [
|
||||
{
|
||||
"key": "api_base",
|
||||
"label": "API Base",
|
||||
"field_type": "text",
|
||||
"placeholder": "https://api.openai.com/v1",
|
||||
"tooltip": "Common endpoints: https://api.openai.com/v1, https://eu.api.openai.com, https://us.api.openai.com",
|
||||
"default_value": "https://api.openai.com/v1",
|
||||
},
|
||||
{
|
||||
"key": "organization",
|
||||
"label": "OpenAI Organization ID",
|
||||
"placeholder": "[OPTIONAL] my-unique-org",
|
||||
},
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "OpenAI API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"Vertex_AI": [
|
||||
{
|
||||
"key": "vertex_project",
|
||||
"label": "Vertex Project",
|
||||
"placeholder": "adroit-cadet-1234..",
|
||||
"required": True,
|
||||
},
|
||||
{
|
||||
"key": "vertex_location",
|
||||
"label": "Vertex Location",
|
||||
"placeholder": "us-east-1",
|
||||
"required": True,
|
||||
},
|
||||
{
|
||||
"key": "vertex_credentials",
|
||||
"label": "Vertex Credentials",
|
||||
"field_type": "upload",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"AssemblyAI": [
|
||||
{
|
||||
"key": "api_base",
|
||||
"label": "API Base",
|
||||
"field_type": "select",
|
||||
"required": True,
|
||||
"options": [
|
||||
"https://api.assemblyai.com",
|
||||
"https://api.eu.assemblyai.com",
|
||||
],
|
||||
},
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "AssemblyAI API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"Azure": [
|
||||
{
|
||||
"key": "api_base",
|
||||
"label": "API Base",
|
||||
"placeholder": "https://...",
|
||||
"required": True,
|
||||
},
|
||||
{
|
||||
"key": "api_version",
|
||||
"label": "API Version",
|
||||
"placeholder": "2023-07-01-preview",
|
||||
"tooltip": "By default litellm will use the latest version. If you want to use a different version, you can specify it here",
|
||||
},
|
||||
{
|
||||
"key": "base_model",
|
||||
"label": "Base Model",
|
||||
"placeholder": "azure/gpt-3.5-turbo",
|
||||
},
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "Azure API Key",
|
||||
"field_type": "password",
|
||||
"placeholder": "Enter your Azure API Key",
|
||||
},
|
||||
{
|
||||
"key": "azure_ad_token",
|
||||
"label": "Azure AD Token",
|
||||
"field_type": "password",
|
||||
"placeholder": "Enter your Azure AD Token",
|
||||
},
|
||||
],
|
||||
"Azure_AI_Studio": [
|
||||
{
|
||||
"key": "api_base",
|
||||
"label": "API Base",
|
||||
"placeholder": "https://<test>.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-10-21",
|
||||
"tooltip": "Enter your full Target URI from Azure Foundry here. Example: https://litellm8397336933.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-10-21",
|
||||
"required": True,
|
||||
},
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "Azure API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"OpenAI_Compatible": [
|
||||
{
|
||||
"key": "api_base",
|
||||
"label": "API Base",
|
||||
"placeholder": "https://...",
|
||||
"required": True,
|
||||
},
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "OpenAI API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"Dashscope": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "Dashscope API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
{
|
||||
"key": "api_base",
|
||||
"label": "API Base",
|
||||
"placeholder": "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
|
||||
"default_value": "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
|
||||
"required": True,
|
||||
"tooltip": "The base URL for your Dashscope server. Defaults to https://dashscope-intl.aliyuncs.com/compatible-mode/v1 if not specified.",
|
||||
},
|
||||
],
|
||||
"OpenAI_Text_Compatible": [
|
||||
{
|
||||
"key": "api_base",
|
||||
"label": "API Base",
|
||||
"placeholder": "https://...",
|
||||
"required": True,
|
||||
},
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "OpenAI API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"Bedrock": [
|
||||
{
|
||||
"key": "aws_access_key_id",
|
||||
"label": "AWS Access Key ID",
|
||||
"field_type": "password",
|
||||
"tooltip": "You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",
|
||||
},
|
||||
{
|
||||
"key": "aws_secret_access_key",
|
||||
"label": "AWS Secret Access Key",
|
||||
"field_type": "password",
|
||||
"tooltip": "You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",
|
||||
},
|
||||
{
|
||||
"key": "aws_session_token",
|
||||
"label": "AWS Session Token",
|
||||
"field_type": "password",
|
||||
"tooltip": "Temporary credentials session token. You can provide the raw token or the environment variable (e.g. `os.environ/MY_SESSION_TOKEN`).",
|
||||
},
|
||||
{
|
||||
"key": "aws_region_name",
|
||||
"label": "AWS Region Name",
|
||||
"placeholder": "us-east-1",
|
||||
"tooltip": "You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",
|
||||
},
|
||||
{
|
||||
"key": "aws_session_name",
|
||||
"label": "AWS Session Name",
|
||||
"placeholder": "my-session",
|
||||
"tooltip": "Name for the AWS session. You can provide the raw value or the environment variable (e.g. `os.environ/MY_SESSION_NAME`).",
|
||||
},
|
||||
{
|
||||
"key": "aws_profile_name",
|
||||
"label": "AWS Profile Name",
|
||||
"placeholder": "default",
|
||||
"tooltip": "AWS profile name to use for authentication. You can provide the raw value or the environment variable (e.g. `os.environ/MY_PROFILE_NAME`).",
|
||||
},
|
||||
{
|
||||
"key": "aws_role_name",
|
||||
"label": "AWS Role Name",
|
||||
"placeholder": "MyRole",
|
||||
"tooltip": "AWS IAM role name to assume. You can provide the raw value or the environment variable (e.g. `os.environ/MY_ROLE_NAME`).",
|
||||
},
|
||||
{
|
||||
"key": "aws_web_identity_token",
|
||||
"label": "AWS Web Identity Token",
|
||||
"field_type": "password",
|
||||
"tooltip": "Web identity token for OIDC authentication. You can provide the raw token or the environment variable (e.g. `os.environ/MY_WEB_IDENTITY_TOKEN`).",
|
||||
},
|
||||
{
|
||||
"key": "aws_bedrock_runtime_endpoint",
|
||||
"label": "AWS Bedrock Runtime Endpoint",
|
||||
"placeholder": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
||||
"tooltip": "Custom Bedrock runtime endpoint URL. You can provide the raw value or the environment variable (e.g. `os.environ/MY_BEDROCK_ENDPOINT`).",
|
||||
},
|
||||
],
|
||||
"SageMaker": [
|
||||
{
|
||||
"key": "aws_access_key_id",
|
||||
"label": "AWS Access Key ID",
|
||||
"field_type": "password",
|
||||
"tooltip": "You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",
|
||||
},
|
||||
{
|
||||
"key": "aws_secret_access_key",
|
||||
"label": "AWS Secret Access Key",
|
||||
"field_type": "password",
|
||||
"tooltip": "You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",
|
||||
},
|
||||
{
|
||||
"key": "aws_region_name",
|
||||
"label": "AWS Region Name",
|
||||
"placeholder": "us-east-1",
|
||||
"tooltip": "You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",
|
||||
},
|
||||
],
|
||||
"Ollama": [
|
||||
{
|
||||
"key": "api_base",
|
||||
"label": "API Base",
|
||||
"placeholder": "http://localhost:11434",
|
||||
"default_value": "http://localhost:11434",
|
||||
"tooltip": "The base URL for your Ollama server. Defaults to http://localhost:11434 if not specified.",
|
||||
},
|
||||
],
|
||||
"Anthropic": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"placeholder": "sk-",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"Deepgram": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"ElevenLabs": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"Google_AI_Studio": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"placeholder": "aig-",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"Groq": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"MistralAI": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"Deepseek": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"Cohere": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"Databricks": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"xAI": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"AIML": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"Cerebras": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"Sambanova": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"Perplexity": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"TogetherAI": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"Openrouter": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"FireworksAI": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"GradientAI": [
|
||||
{
|
||||
"key": "api_base",
|
||||
"label": "GradientAI Endpoint",
|
||||
"placeholder": "https://...",
|
||||
},
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "GradientAI API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"Triton": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
},
|
||||
{
|
||||
"key": "api_base",
|
||||
"label": "API Base",
|
||||
"placeholder": "http://localhost:8000/generate",
|
||||
},
|
||||
],
|
||||
"Hosted_Vllm": [
|
||||
{
|
||||
"key": "api_base",
|
||||
"label": "API Base",
|
||||
"placeholder": "https://...",
|
||||
"required": True,
|
||||
},
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "vLLM API Key",
|
||||
"field_type": "password",
|
||||
},
|
||||
],
|
||||
"Voyage": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"JinaAI": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"VolcEngine": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"DeepInfra": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"Oracle": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"Snowflake": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "Snowflake API Key / JWT Key for Authentication",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
{
|
||||
"key": "api_base",
|
||||
"label": "Snowflake API Endpoint",
|
||||
"placeholder": "https://1234567890.snowflakecomputing.com/api/v2/cortex/inference:complete",
|
||||
"tooltip": "Enter the full endpoint with path here. Example: https://1234567890.snowflakecomputing.com/api/v2/cortex/inference:complete",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
"Infinity": [
|
||||
{
|
||||
"key": "api_base",
|
||||
"label": "API Base",
|
||||
"placeholder": "http://localhost:7997",
|
||||
},
|
||||
],
|
||||
"FalAI": [
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"field_type": "password",
|
||||
"required": True,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def _normalize_field(field: Dict[str, Any]) -> ProviderCredentialField:
|
||||
return ProviderCredentialField(
|
||||
key=field["key"],
|
||||
label=field["label"],
|
||||
placeholder=field.get("placeholder"),
|
||||
tooltip=field.get("tooltip"),
|
||||
required=field.get("required", False),
|
||||
field_type=field.get("field_type", "text"),
|
||||
options=field.get("options"),
|
||||
default_value=field.get("default_value"),
|
||||
)
|
||||
|
||||
|
||||
def get_provider_create_metadata() -> List[ProviderCreateInfo]:
|
||||
providers: List[ProviderCreateInfo] = []
|
||||
|
||||
for provider_key, base_info in PROVIDER_BASE_INFO.items():
|
||||
raw_fields = PROVIDER_CREDENTIAL_FIELDS.get(provider_key, _FALLBACK_FIELDS)
|
||||
normalized_fields = [_normalize_field(field) for field in raw_fields]
|
||||
|
||||
providers.append(
|
||||
ProviderCreateInfo(
|
||||
provider=provider_key,
|
||||
provider_display_name=base_info["provider_display_name"],
|
||||
litellm_provider=base_info["litellm_provider"],
|
||||
default_model_placeholder=base_info.get(
|
||||
"default_model_placeholder", DEFAULT_MODEL_PLACEHOLDER
|
||||
),
|
||||
credential_fields=normalized_fields,
|
||||
)
|
||||
)
|
||||
|
||||
providers.sort(key=lambda item: item.provider_display_name.lower())
|
||||
return providers
|
||||
|
||||
@@ -3,11 +3,17 @@ from typing import List
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
|
||||
from litellm.proxy._types import CommonProxyErrors
|
||||
from litellm.proxy.public_endpoints.provider_create_metadata import (
|
||||
get_provider_create_metadata,
|
||||
)
|
||||
from litellm.proxy.auth.user_api_key_auth import user_api_key_auth
|
||||
from litellm.types.proxy.management_endpoints.model_management_endpoints import (
|
||||
ModelGroupInfoProxy,
|
||||
)
|
||||
from litellm.types.proxy.public_endpoints.public_endpoints import PublicModelHubInfo
|
||||
from litellm.types.proxy.public_endpoints.public_endpoints import (
|
||||
PublicModelHubInfo,
|
||||
ProviderCreateInfo,
|
||||
)
|
||||
from litellm.types.utils import LlmProviders
|
||||
|
||||
router = APIRouter()
|
||||
@@ -74,3 +80,16 @@ async def get_supported_providers() -> List[str]:
|
||||
"""
|
||||
|
||||
return sorted(provider.value for provider in LlmProviders)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/public/providers/fields",
|
||||
tags=["public", "providers"],
|
||||
response_model=List[ProviderCreateInfo],
|
||||
)
|
||||
async def get_provider_fields() -> List[ProviderCreateInfo]:
|
||||
"""
|
||||
Return provider metadata required by the dashboard create-model flow.
|
||||
"""
|
||||
|
||||
return get_provider_create_metadata()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import Dict, Optional
|
||||
from typing import Dict, List, Literal, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
@@ -8,3 +8,22 @@ class PublicModelHubInfo(BaseModel):
|
||||
custom_docs_description: Optional[str]
|
||||
litellm_version: str
|
||||
useful_links: Optional[Dict[str, str]]
|
||||
|
||||
|
||||
class ProviderCredentialField(BaseModel):
|
||||
key: str
|
||||
label: str
|
||||
placeholder: Optional[str] = None
|
||||
tooltip: Optional[str] = None
|
||||
required: bool = False
|
||||
field_type: Literal["text", "password", "select", "upload"] = "text"
|
||||
options: Optional[List[str]] = None
|
||||
default_value: Optional[str] = None
|
||||
|
||||
|
||||
class ProviderCreateInfo(BaseModel):
|
||||
provider: str
|
||||
provider_display_name: str
|
||||
litellm_provider: str
|
||||
credential_fields: List[ProviderCredentialField]
|
||||
default_model_placeholder: Optional[str] = None
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
import os
|
||||
import sys
|
||||
from copy import deepcopy
|
||||
|
||||
import pytest
|
||||
|
||||
sys.path.insert(0, os.path.abspath("../../.."))
|
||||
|
||||
import litellm.proxy.public_endpoints.provider_create_metadata as pcm # noqa: E402
|
||||
from litellm.proxy.public_endpoints.provider_create_metadata import ( # noqa: E402
|
||||
_normalize_field,
|
||||
get_provider_create_metadata,
|
||||
)
|
||||
|
||||
|
||||
def test_get_provider_create_metadata_includes_openai_fields():
|
||||
metadata = get_provider_create_metadata()
|
||||
|
||||
openai_info = next(item for item in metadata if item.provider == "OpenAI")
|
||||
|
||||
assert openai_info.provider_display_name == "OpenAI"
|
||||
assert openai_info.litellm_provider == "openai"
|
||||
keys = {field.key for field in openai_info.credential_fields}
|
||||
assert {"api_base", "api_key"}.issubset(keys)
|
||||
|
||||
|
||||
def test_get_provider_create_metadata_returns_sorted_display_names():
|
||||
metadata = get_provider_create_metadata()
|
||||
display_names = [item.provider_display_name for item in metadata]
|
||||
|
||||
assert display_names == sorted(display_names, key=str.lower)
|
||||
|
||||
|
||||
def test_get_provider_create_metadata_uses_fallback_fields(monkeypatch):
|
||||
overridden_fields = deepcopy(pcm.PROVIDER_CREDENTIAL_FIELDS)
|
||||
overridden_fields.pop("Azure", None)
|
||||
monkeypatch.setattr(pcm, "PROVIDER_CREDENTIAL_FIELDS", overridden_fields)
|
||||
|
||||
metadata = get_provider_create_metadata()
|
||||
azure_info = next(item for item in metadata if item.provider == "Azure")
|
||||
|
||||
fallback_keys = [field.key for field in azure_info.credential_fields]
|
||||
assert fallback_keys == ["api_base", "api_key"]
|
||||
assert all(field.required is False for field in azure_info.credential_fields)
|
||||
|
||||
|
||||
def test_normalize_field_applies_defaults():
|
||||
normalized = _normalize_field({"key": "api_key", "label": "API Key"})
|
||||
|
||||
assert normalized.key == "api_key"
|
||||
assert normalized.label == "API Key"
|
||||
assert normalized.field_type == "text"
|
||||
assert normalized.required is False
|
||||
assert normalized.placeholder is None
|
||||
assert normalized.options is None
|
||||
@@ -23,3 +23,25 @@ def test_get_supported_providers_returns_enum_values():
|
||||
expected_providers = sorted(provider.value for provider in LlmProviders)
|
||||
assert response.json() == expected_providers
|
||||
|
||||
|
||||
def test_get_provider_fields_returns_metadata():
|
||||
app = FastAPI()
|
||||
app.include_router(router)
|
||||
client = TestClient(app)
|
||||
|
||||
response = client.get("/public/providers/fields")
|
||||
|
||||
assert response.status_code == 200
|
||||
payload = response.json()
|
||||
assert isinstance(payload, list)
|
||||
|
||||
provider_lookup = {item["provider"]: item for item in payload}
|
||||
assert "OpenAI" in provider_lookup
|
||||
|
||||
openai_fields = provider_lookup["OpenAI"]
|
||||
assert openai_fields["provider_display_name"] == "OpenAI"
|
||||
assert openai_fields["litellm_provider"] == "openai"
|
||||
|
||||
credential_keys = {field["key"] for field in openai_fields["credential_fields"]}
|
||||
assert {"api_base", "api_key"}.issubset(credential_keys)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user