diff --git a/litellm/__init__.py b/litellm/__init__.py
index fcf1faeeb3b..8cf7d3922a9 100644
--- a/litellm/__init__.py
+++ b/litellm/__init__.py
@@ -5,7 +5,17 @@ warnings.filterwarnings("ignore", message=".*conflict with protected namespace.*
### INIT VARIABLES ####################
import threading
import os
-from typing import Callable, List, Optional, Dict, Union, Any, Literal, get_args, TYPE_CHECKING
+from typing import (
+ Callable,
+ List,
+ Optional,
+ Dict,
+ Union,
+ Any,
+ Literal,
+ get_args,
+ TYPE_CHECKING,
+)
from litellm.types.integrations.datadog_llm_obs import DatadogLLMObsInitParams
from litellm.llms.custom_httpx.http_handler import AsyncHTTPHandler, HTTPHandler
from litellm.caching.caching import Cache, DualCache, RedisCache, InMemoryCache
@@ -259,6 +269,11 @@ blocked_user_list: Optional[Union[str, List]] = None
banned_keywords_list: Optional[Union[str, List]] = None
llm_guard_mode: Literal["all", "key-specific", "request-specific"] = "all"
guardrail_name_config_map: Dict[str, GuardrailItem] = {}
+### PROMPTS ###
+from litellm.types.prompts.init_prompts import PromptSpec
+
+prompt_name_config_map: Dict[str, PromptSpec] = {}
+
##################
### PREVIEW FEATURES ###
enable_preview_features: bool = False
diff --git a/litellm/integrations/dotprompt/README.md b/litellm/integrations/dotprompt/README.md
index 7eaeca9a332..c69c96824be 100644
--- a/litellm/integrations/dotprompt/README.md
+++ b/litellm/integrations/dotprompt/README.md
@@ -275,7 +275,7 @@ Represents a single prompt with metadata.
**Prompt not found**: Ensure the `.prompt` file exists and has correct extension
```python
# Check available prompts
-from litellm.prompts import get_dotprompt_manager
+from litellm.integrations.dotprompt import get_dotprompt_manager
manager = get_dotprompt_manager()
print(manager.prompt_manager.list_prompts())
```
diff --git a/litellm/integrations/dotprompt/__init__.py b/litellm/integrations/dotprompt/__init__.py
index bbd8be80256..a50e8f5e55e 100644
--- a/litellm/integrations/dotprompt/__init__.py
+++ b/litellm/integrations/dotprompt/__init__.py
@@ -2,6 +2,10 @@ from typing import TYPE_CHECKING, Optional
if TYPE_CHECKING:
from .prompt_manager import PromptManager, PromptTemplate
+ from litellm.types.prompts.init_prompts import PromptLiteLLMParams, PromptSpec
+ from litellm.integrations.custom_prompt_management import CustomPromptManagement
+
+from litellm.types.prompts.init_prompts import SupportedPromptIntegrations
from .dotprompt_manager import DotpromptManager
@@ -22,6 +26,23 @@ def set_global_prompt_directory(directory: str) -> None:
litellm.global_prompt_directory = directory # type: ignore
+def prompt_initializer(
+ litellm_params: "PromptLiteLLMParams", prompt_spec: "PromptSpec"
+) -> "CustomPromptManagement":
+ """
+ Initialize a prompt from a .prompt file.
+ """
+ prompt_directory = getattr(litellm_params, "prompt_directory", None)
+ if not prompt_directory:
+ raise ValueError("prompt_directory is required for dotprompt")
+
+ return DotpromptManager(prompt_directory)
+
+
+prompt_initializer_registry = {
+ SupportedPromptIntegrations.DOT_PROMPT.value: prompt_initializer,
+}
+
# Export public API
__all__ = [
"PromptManager",
diff --git a/litellm/integrations/dotprompt/dotprompt_manager.py b/litellm/integrations/dotprompt/dotprompt_manager.py
index 830e9508322..cf3cfa374b9 100644
--- a/litellm/integrations/dotprompt/dotprompt_manager.py
+++ b/litellm/integrations/dotprompt/dotprompt_manager.py
@@ -3,20 +3,17 @@ Dotprompt manager that integrates with LiteLLM's prompt management system.
Builds on top of PromptManagementBase to provide .prompt file support.
"""
-from typing import List, Optional
+from typing import List, Optional, Tuple
-from litellm.integrations.custom_logger import CustomLogger
-from litellm.integrations.prompt_management_base import (
- PromptManagementBase,
- PromptManagementClient,
-)
+from litellm.integrations.custom_prompt_management import CustomPromptManagement
+from litellm.integrations.prompt_management_base import PromptManagementClient
from litellm.types.llms.openai import AllMessageValues
from litellm.types.utils import StandardCallbackDynamicParams
from .prompt_manager import PromptManager, PromptTemplate
-class DotpromptManager(PromptManagementBase, CustomLogger):
+class DotpromptManager(CustomPromptManagement):
"""
Dotprompt manager that integrates with LiteLLM's prompt management system.
@@ -93,6 +90,7 @@ class DotpromptManager(PromptManagementBase, CustomLogger):
3. Converts the rendered text into chat messages
4. Extracts model and optional parameters from metadata
"""
+
try:
# Get the prompt template
template = self.prompt_manager.get_prompt(prompt_id)
@@ -122,6 +120,31 @@ class DotpromptManager(PromptManagementBase, CustomLogger):
except Exception as e:
raise ValueError(f"Error compiling prompt '{prompt_id}': {e}")
+ def get_chat_completion_prompt(
+ self,
+ model: str,
+ messages: List[AllMessageValues],
+ non_default_params: dict,
+ prompt_id: Optional[str],
+ prompt_variables: Optional[dict],
+ dynamic_callback_params: StandardCallbackDynamicParams,
+ prompt_label: Optional[str] = None,
+ prompt_version: Optional[int] = None,
+ ) -> Tuple[str, List[AllMessageValues], dict]:
+ from litellm.integrations.prompt_management_base import PromptManagementBase
+
+ return PromptManagementBase.get_chat_completion_prompt(
+ self,
+ model,
+ messages,
+ non_default_params,
+ prompt_id,
+ prompt_variables,
+ dynamic_callback_params,
+ prompt_label,
+ prompt_version,
+ )
+
def _convert_to_messages(self, rendered_content: str) -> List[AllMessageValues]:
"""
Convert rendered prompt content to chat messages.
diff --git a/litellm/litellm_core_utils/litellm_logging.py b/litellm/litellm_core_utils/litellm_logging.py
index eb5f62c4427..b19fd92e751 100644
--- a/litellm/litellm_core_utils/litellm_logging.py
+++ b/litellm/litellm_core_utils/litellm_logging.py
@@ -562,7 +562,9 @@ class Logging(LiteLLMLoggingBaseClass):
custom_logger = (
prompt_management_logger
or self.get_custom_logger_for_prompt_management(
- model=model, non_default_params=non_default_params
+ model=model,
+ non_default_params=non_default_params,
+ prompt_id=prompt_id,
)
)
@@ -581,6 +583,7 @@ class Logging(LiteLLMLoggingBaseClass):
prompt_label=prompt_label,
prompt_version=prompt_version,
)
+
self.messages = messages
return model, messages, non_default_params
@@ -599,7 +602,10 @@ class Logging(LiteLLMLoggingBaseClass):
custom_logger = (
prompt_management_logger
or self.get_custom_logger_for_prompt_management(
- model=model, tools=tools, non_default_params=non_default_params
+ model=model,
+ tools=tools,
+ non_default_params=non_default_params,
+ prompt_id=prompt_id,
)
)
@@ -624,7 +630,11 @@ class Logging(LiteLLMLoggingBaseClass):
return model, messages, non_default_params
def get_custom_logger_for_prompt_management(
- self, model: str, non_default_params: Dict, tools: Optional[List[Dict]] = None
+ self,
+ model: str,
+ non_default_params: Dict,
+ tools: Optional[List[Dict]] = None,
+ prompt_id: Optional[str] = None,
) -> Optional[CustomLogger]:
"""
Get a custom logger for prompt management based on model name or available callbacks.
@@ -635,7 +645,7 @@ class Logging(LiteLLMLoggingBaseClass):
Returns:
A CustomLogger instance if one is found, None otherwise
"""
- # First check if model starts with a known custom logger compatible callback
+
for callback_name in litellm._known_custom_logger_compatible_callbacks:
if model.startswith(callback_name):
custom_logger = _init_custom_logger_compatible_class(
diff --git a/litellm/proxy/_experimental/out/model_hub_table.html b/litellm/proxy/_experimental/out/model_hub_table/index.html
similarity index 100%
rename from litellm/proxy/_experimental/out/model_hub_table.html
rename to litellm/proxy/_experimental/out/model_hub_table/index.html
diff --git a/litellm/proxy/_experimental/out/onboarding.html b/litellm/proxy/_experimental/out/onboarding.html
deleted file mode 100644
index f89e911a421..00000000000
--- a/litellm/proxy/_experimental/out/onboarding.html
+++ /dev/null
@@ -1 +0,0 @@
-
LiteLLM Dashboard
\ No newline at end of file
diff --git a/litellm/proxy/_new_secret_config.yaml b/litellm/proxy/_new_secret_config.yaml
index 18017acb8e3..0301cc3186e 100644
--- a/litellm/proxy/_new_secret_config.yaml
+++ b/litellm/proxy/_new_secret_config.yaml
@@ -1,9 +1,20 @@
model_list:
- model_name: openai-test
litellm_params:
- model: dotprompt/gpt-3.5-turbo
- prompt_id: test_hello_world_prompt
+ model: gpt-3.5-turbo
api_key: os.environ/OPENAI_API_KEY
-litellm_settings:
- global_prompt_directory: /Users/krrishdholakia/Documents/litellm/litellm/proxy/test_prompts
+guardrails:
+ - guardrail_name: azure-text-moderation
+ litellm_params:
+ guardrail: azure/text_moderations
+ mode: "post_call"
+ api_key: os.environ/AZURE_GUARDRAIL_API_KEY
+ api_base: os.environ/AZURE_GUARDRAIL_API_BASE
+
+prompts:
+ - prompt_id: test_hello_world_prompt
+ litellm_params:
+ prompt_integration: dotprompt
+ prompt_id: test_hello_world_prompt
+ prompt_directory: /Users/krrishdholakia/Documents/litellm/litellm/proxy/test_prompts
\ No newline at end of file
diff --git a/litellm/proxy/common_request_processing.py b/litellm/proxy/common_request_processing.py
index 329393c8737..ce4d5a18201 100644
--- a/litellm/proxy/common_request_processing.py
+++ b/litellm/proxy/common_request_processing.py
@@ -328,10 +328,6 @@ class ProxyBaseLLMRequestProcessing:
)
### CALL HOOKS ### - modify/reject incoming data before calling the model
- self.data = await proxy_logging_obj.pre_call_hook( # type: ignore
- user_api_key_dict=user_api_key_dict, data=self.data, call_type=route_type # type: ignore
- )
-
## LOGGING OBJECT ## - initialize logging object for logging success/failure events for call
## IMPORTANT Note: - initialize this before running pre-call checks. Ensures we log rejected requests to langfuse.
logging_obj, self.data = litellm.utils.function_setup(
@@ -343,6 +339,10 @@ class ProxyBaseLLMRequestProcessing:
self.data["litellm_logging_obj"] = logging_obj
+ self.data = await proxy_logging_obj.pre_call_hook( # type: ignore
+ user_api_key_dict=user_api_key_dict, data=self.data, call_type=route_type # type: ignore
+ )
+
return self.data, logging_obj
async def base_process_llm_request(
diff --git a/litellm/proxy/guardrails/guardrail_registry.py b/litellm/proxy/guardrails/guardrail_registry.py
index a0b1c160510..21429f462d4 100644
--- a/litellm/proxy/guardrails/guardrail_registry.py
+++ b/litellm/proxy/guardrails/guardrail_registry.py
@@ -415,6 +415,7 @@ class InMemoryGuardrailHandler:
litellm_params.api_base = str(get_secret(litellm_params.api_base))
guardrail_type = litellm_params.guardrail
+
if guardrail_type is None:
raise ValueError("guardrail_type is required")
diff --git a/litellm/proxy/guardrails/init_guardrails.py b/litellm/proxy/guardrails/init_guardrails.py
index 0ed48d671d9..aeef7040c4b 100644
--- a/litellm/proxy/guardrails/init_guardrails.py
+++ b/litellm/proxy/guardrails/init_guardrails.py
@@ -9,7 +9,32 @@ from litellm.types.guardrails import Guardrail, GuardrailItem, GuardrailItemSpec
all_guardrails: List[GuardrailItem] = []
+"""
+Map guardrail_name: , , during_call
+"""
+
+
+def init_guardrails_v2(
+ all_guardrails: List[Dict],
+ config_file_path: Optional[str] = None,
+):
+ from litellm.proxy.guardrails.guardrail_registry import IN_MEMORY_GUARDRAIL_HANDLER
+
+ guardrail_list: List[Guardrail] = []
+
+ for guardrail in all_guardrails:
+ initialized_guardrail = IN_MEMORY_GUARDRAIL_HANDLER.initialize_guardrail(
+ guardrail=cast(Guardrail, guardrail),
+ config_file_path=config_file_path,
+ )
+ if initialized_guardrail:
+ guardrail_list.append(initialized_guardrail)
+
+ verbose_proxy_logger.debug(f"\nGuardrail List:{guardrail_list}\n")
+
+
+### LEGACY IMPLEMENTATION ###
def initialize_guardrails(
guardrails_config: List[Dict[str, GuardrailItemSpec]],
premium_user: bool,
@@ -65,28 +90,3 @@ def initialize_guardrails(
"error initializing guardrails {}".format(str(e))
)
raise e
-
-
-"""
-Map guardrail_name: , , during_call
-
-"""
-
-
-def init_guardrails_v2(
- all_guardrails: List[Dict],
- config_file_path: Optional[str] = None,
-):
- from litellm.proxy.guardrails.guardrail_registry import IN_MEMORY_GUARDRAIL_HANDLER
-
- guardrail_list: List[Guardrail] = []
-
- for guardrail in all_guardrails:
- initialized_guardrail = IN_MEMORY_GUARDRAIL_HANDLER.initialize_guardrail(
- guardrail=cast(Guardrail, guardrail),
- config_file_path=config_file_path,
- )
- if initialized_guardrail:
- guardrail_list.append(initialized_guardrail)
-
- verbose_proxy_logger.debug(f"\nGuardrail List:{guardrail_list}\n")
diff --git a/litellm/proxy/prompts/__init__.py b/litellm/proxy/prompts/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/litellm/proxy/prompts/init_prompts.py b/litellm/proxy/prompts/init_prompts.py
new file mode 100644
index 00000000000..b2b7ca0cc47
--- /dev/null
+++ b/litellm/proxy/prompts/init_prompts.py
@@ -0,0 +1,28 @@
+"""
+Similar to init_guardrails.py, but for prompts.
+"""
+
+from typing import Dict, List, Optional, cast
+
+from litellm._logging import verbose_proxy_logger
+
+
+def init_prompts(
+ all_prompts: List[Dict],
+ config_file_path: Optional[str] = None,
+):
+ from litellm.types.prompts.init_prompts import PromptSpec
+
+ from .prompt_registry import IN_MEMORY_PROMPT_REGISTRY
+
+ prompt_list: List[PromptSpec] = []
+
+ for prompt in all_prompts:
+ initialized_prompt = IN_MEMORY_PROMPT_REGISTRY.initialize_prompt(
+ prompt=cast(PromptSpec, prompt),
+ config_file_path=config_file_path,
+ )
+ if initialized_prompt:
+ prompt_list.append(initialized_prompt)
+
+ verbose_proxy_logger.debug(f"\nPrompt List:{prompt_list}\n")
diff --git a/litellm/proxy/prompts/prompt_registry.py b/litellm/proxy/prompts/prompt_registry.py
new file mode 100644
index 00000000000..29d029eb9ac
--- /dev/null
+++ b/litellm/proxy/prompts/prompt_registry.py
@@ -0,0 +1,173 @@
+import importlib
+import os
+import uuid
+from pathlib import Path
+from typing import Callable, Dict, Optional
+
+from litellm._logging import verbose_proxy_logger
+from litellm.integrations.custom_prompt_management import CustomPromptManagement
+from litellm.types.prompts.init_prompts import PromptLiteLLMParams, PromptSpec
+
+prompt_initializer_registry = {}
+
+
+def get_prompt_initializer_from_integrations():
+ """
+ Get prompt initializers by discovering them from the prompt_integrations directory structure.
+
+ Scans the integrations directory for subdirectories containing __init__.py files
+ with either prompt_initializer_registry or initialize_prompt functions.
+
+ Returns:
+ Dict[str, Callable]: A dictionary mapping guardrail types to their initializer functions
+ """
+ discovered_initializers: Dict[str, Callable] = {}
+
+ try:
+ # Get the path to the prompt_integrations directory
+ current_dir = Path(__file__).parent.parent.parent
+ integrations_dir = os.path.join(current_dir, "integrations")
+
+ if not os.path.exists(integrations_dir):
+ verbose_proxy_logger.debug("integrations directory not found")
+ return discovered_initializers
+
+ # Scan each subdirectory in prompt_integrations
+ for item in os.listdir(integrations_dir):
+ item_path = os.path.join(integrations_dir, item)
+
+ # Skip files and __pycache__ directories
+ if not os.path.isdir(item_path) or item.startswith("__"):
+ continue
+
+ # Check if the directory has an __init__.py file
+ init_file = os.path.join(item_path, "__init__.py")
+ if not os.path.exists(init_file):
+ continue
+
+ module_path = f"litellm.integrations.{item}"
+ try:
+ # Import the module
+ verbose_proxy_logger.debug(
+ f"Discovering prompt integrations in: {module_path}"
+ )
+
+ module = importlib.import_module(module_path)
+
+ # Check for prompt_initializer_registry dictionary
+ if hasattr(module, "prompt_initializer_registry"):
+ registry = getattr(module, "prompt_initializer_registry")
+ if isinstance(registry, dict):
+ discovered_initializers.update(registry)
+ verbose_proxy_logger.debug(
+ f"Found prompt_initializer_registry in {module_path}: {list(registry.keys())}"
+ )
+
+ except ImportError as e:
+ verbose_proxy_logger.error(f"Could not import {module_path}: {e}")
+ continue
+ except Exception as e:
+ verbose_proxy_logger.error(f"Error processing {module_path}: {e}")
+ continue
+
+ verbose_proxy_logger.debug(
+ f"Discovered {len(discovered_initializers)} prompt initializers: {list(discovered_initializers.keys())}"
+ )
+
+ except Exception as e:
+ verbose_proxy_logger.error(f"Error discovering prompt initializers: {e}")
+
+ return discovered_initializers
+
+
+prompt_initializer_registry = get_prompt_initializer_from_integrations()
+
+
+class InMemoryPromptRegistry:
+ """
+ Class that handles adding prompt callbacks to the CallbacksManager.
+ """
+
+ def __init__(self):
+ self.IN_MEMORY_PROMPTS: Dict[str, PromptSpec] = {}
+ """
+ Prompt id to Prompt object mapping
+ """
+
+ self.prompt_id_to_custom_prompt: Dict[str, Optional[CustomPromptManagement]] = (
+ {}
+ )
+ """
+ Guardrail id to CustomGuardrail object mapping
+ """
+
+ def initialize_prompt(
+ self,
+ prompt: PromptSpec,
+ config_file_path: Optional[str] = None,
+ ) -> Optional[PromptSpec]:
+ """
+ Initialize a guardrail from a dictionary and add it to the litellm callback manager
+
+ Returns a Guardrail object if the guardrail is initialized successfully
+ """
+ import litellm
+
+ prompt_id = prompt.get("prompt_id") or str(uuid.uuid4())
+ prompt["prompt_id"] = prompt_id
+ if prompt_id in self.IN_MEMORY_PROMPTS:
+ verbose_proxy_logger.debug("prompt_id already exists in IN_MEMORY_PROMPTS")
+ return self.IN_MEMORY_PROMPTS[prompt_id]
+
+ custom_prompt_callback: Optional[CustomPromptManagement] = None
+ litellm_params_data = prompt["litellm_params"]
+ verbose_proxy_logger.debug("litellm_params= %s", litellm_params_data)
+
+ if isinstance(litellm_params_data, dict):
+ litellm_params = PromptLiteLLMParams(**litellm_params_data)
+ else:
+ litellm_params = litellm_params_data
+
+ prompt_integration = litellm_params.prompt_integration
+ if prompt_integration is None:
+ raise ValueError("prompt_integration is required")
+
+ initializer = prompt_initializer_registry.get(prompt_integration)
+
+ if initializer:
+ custom_prompt_callback = initializer(litellm_params, prompt)
+ if not isinstance(custom_prompt_callback, CustomPromptManagement):
+ raise ValueError(
+ f"CustomPromptManagement is required, got {type(custom_prompt_callback)}"
+ )
+ litellm.logging_callback_manager.add_litellm_callback(custom_prompt_callback) # type: ignore
+ else:
+ raise ValueError(f"Unsupported prompt: {prompt_integration}")
+
+ parsed_prompt = PromptSpec(
+ prompt_id=prompt_id,
+ litellm_params=litellm_params,
+ )
+
+ # store references to the prompt in memory
+ self.IN_MEMORY_PROMPTS[prompt_id] = parsed_prompt
+ self.prompt_id_to_custom_prompt[prompt_id] = custom_prompt_callback
+
+ return parsed_prompt
+
+ def get_prompt_by_id(self, prompt_id: str) -> Optional[PromptSpec]:
+ """
+ Get a prompt by its ID from memory
+ """
+ return self.IN_MEMORY_PROMPTS.get(prompt_id)
+
+ def get_prompt_callback_by_id(
+ self, prompt_id: str
+ ) -> Optional[CustomPromptManagement]:
+ """
+ Get a prompt callback by its ID from memory
+ """
+ return self.prompt_id_to_custom_prompt.get(prompt_id)
+
+
+IN_MEMORY_PROMPT_REGISTRY = InMemoryPromptRegistry()
diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py
index c6ba2a99d52..949387fca82 100644
--- a/litellm/proxy/proxy_server.py
+++ b/litellm/proxy/proxy_server.py
@@ -1822,6 +1822,7 @@ class ProxyConfig:
)
litellm.guardrail_name_config_map = guardrail_name_config_map
+
elif key == "global_prompt_directory":
from litellm.integrations.dotprompt import (
set_global_prompt_directory,
@@ -2201,6 +2202,15 @@ class ProxyConfig:
all_guardrails=guardrails_v2, config_file_path=config_file_path
)
+ ## Prompt settings
+ prompts: Optional[List[Dict]] = None
+ if config is not None:
+ prompts = config.get("prompts", None)
+ if prompts:
+ from litellm.proxy.prompts.init_prompts import init_prompts
+
+ init_prompts(all_prompts=prompts, config_file_path=config_file_path)
+
## CREDENTIALS
credential_list_dict = self.load_credential_list(config=config)
litellm.credential_list = credential_list_dict
diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py
index 51c5014563b..9e05a90b940 100644
--- a/litellm/proxy/utils.py
+++ b/litellm/proxy/utils.py
@@ -98,6 +98,8 @@ from litellm.types.utils import CallTypes, LLMResponseTypes, LoggedLiteLLMParams
if TYPE_CHECKING:
from opentelemetry.trace import Span as _Span
+ from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj
+
Span = Union[_Span, Any]
else:
Span = Any
@@ -957,6 +959,8 @@ class ProxyLogging:
2. /embeddings
3. /image/generation
"""
+ from litellm.utils import get_non_default_completion_params
+
verbose_proxy_logger.debug("Inside Proxy Logging Pre-call hook!")
self._init_response_taking_too_long_task(data=data)
@@ -964,6 +968,42 @@ class ProxyLogging:
if data is None:
return None
+ litellm_logging_obj = cast(
+ Optional["LiteLLMLoggingObj"], data.get("litellm_logging_obj", None)
+ )
+ prompt_id = data.get("prompt_id", None)
+
+ ## PROMPT TEMPLATE CHECK ##
+ if (
+ litellm_logging_obj is not None
+ and prompt_id is not None
+ and (call_type == "completion" or call_type == "acompletion")
+ ):
+ from litellm.proxy.prompts.prompt_registry import IN_MEMORY_PROMPT_REGISTRY
+
+ custom_logger = IN_MEMORY_PROMPT_REGISTRY.get_prompt_callback_by_id(
+ prompt_id
+ )
+
+ if custom_logger:
+ (
+ model,
+ messages,
+ optional_params,
+ ) = litellm_logging_obj.get_chat_completion_prompt(
+ model=data.get("model", ""),
+ messages=data.get("messages", []),
+ non_default_params=get_non_default_completion_params(kwargs=data),
+ prompt_id=prompt_id,
+ prompt_management_logger=custom_logger,
+ prompt_variables=data.get("prompt_variables", None),
+ prompt_label=data.get("prompt_label", None),
+ prompt_version=data.get("prompt_version", None),
+ )
+ data["model"] = model
+ data["messages"] = messages
+ data.update(optional_params)
+
try:
for callback in litellm.callbacks:
_callback = None
@@ -3696,26 +3736,24 @@ def is_valid_api_key(key: str) -> bool:
def construct_database_url_from_env_vars() -> Optional[str]:
"""
Construct a DATABASE_URL from individual environment variables.
-
+
Returns:
Optional[str]: The constructed DATABASE_URL or None if required variables are missing
"""
import urllib.parse
-
+
# Check if all required variables are provided
database_host = os.getenv("DATABASE_HOST")
database_username = os.getenv("DATABASE_USERNAME")
database_password = os.getenv("DATABASE_PASSWORD")
database_name = os.getenv("DATABASE_NAME")
- if (
- database_host
- and database_username
- and database_name
- ):
+ if database_host and database_username and database_name:
# Handle the problem of special character escaping in the database URL
database_username_enc = urllib.parse.quote_plus(database_username)
- database_password_enc = urllib.parse.quote_plus(database_password) if database_password else ""
+ database_password_enc = (
+ urllib.parse.quote_plus(database_password) if database_password else ""
+ )
database_name_enc = urllib.parse.quote_plus(database_name)
# Construct DATABASE_URL from the provided variables
@@ -3725,5 +3763,5 @@ def construct_database_url_from_env_vars() -> Optional[str]:
database_url = f"postgresql://{database_username_enc}@{database_host}/{database_name_enc}"
return database_url
-
+
return None
diff --git a/litellm/types/prompts/init_prompts.py b/litellm/types/prompts/init_prompts.py
new file mode 100644
index 00000000000..2800be32a44
--- /dev/null
+++ b/litellm/types/prompts/init_prompts.py
@@ -0,0 +1,27 @@
+from datetime import datetime
+from enum import Enum
+from typing import Dict, Optional
+
+from pydantic import BaseModel, ConfigDict
+from typing_extensions import Required, TypedDict
+
+
+class SupportedPromptIntegrations(str, Enum):
+ DOT_PROMPT = "dotprompt"
+ LANGFUSE = "langfuse"
+ CUSTOM = "custom"
+
+
+class PromptLiteLLMParams(BaseModel):
+ prompt_id: str
+ prompt_integration: str
+
+ model_config = ConfigDict(extra="allow", protected_namespaces=())
+
+
+class PromptSpec(TypedDict, total=False):
+ prompt_id: Required[str]
+ litellm_params: Required[PromptLiteLLMParams]
+ prompt_info: Optional[Dict]
+ created_at: Optional[datetime]
+ updated_at: Optional[datetime]