# LiteLLM Dotprompt Manager A powerful prompt management system for LiteLLM that supports [Google's Dotprompt specification](https://google.github.io/dotprompt/getting-started/). This allows you to manage your AI prompts in organized `.prompt` files with YAML frontmatter, Handlebars templating, and full integration with LiteLLM's completion API. ## Features - **📁 File-based prompt management**: Organize prompts in `.prompt` files - **🎯 YAML frontmatter**: Define model, parameters, and schemas in file headers - **🔧 Handlebars templating**: Use `{{variable}}` syntax with Jinja2 backend - **✅ Input validation**: Automatic validation against defined schemas - **🔗 LiteLLM integration**: Works seamlessly with `litellm.completion()` - **💬 Smart message parsing**: Converts prompts to proper chat messages - **⚙️ Parameter extraction**: Automatically applies model settings from prompts ## Quick Start ### 1. Create a `.prompt` file Create a file called `chat_assistant.prompt`: ```yaml --- model: gpt-4 temperature: 0.7 max_tokens: 150 input: schema: user_message: string system_context?: string --- {% if system_context %}System: {{system_context}} {% endif %}User: {{user_message}} ``` ### 2. Use with LiteLLM ```python import litellm litellm.set_global_prompt_directory("path/to/your/prompts") # Use with completion - the model prefix 'dotprompt/' tells LiteLLM to use prompt management response = litellm.completion( model="dotprompt/gpt-4", # The actual model comes from the .prompt file prompt_id="chat_assistant", prompt_variables={ "user_message": "What is machine learning?", "system_context": "You are a helpful AI tutor." }, # Any additional messages will be appended after the prompt messages=[{"role": "user", "content": "Please explain it simply."}] ) print(response.choices[0].message.content) ``` ## Prompt File Format ### Basic Structure ```yaml --- # Model configuration model: gpt-4 temperature: 0.7 max_tokens: 500 # Input schema (optional) input: schema: name: string age: integer preferences?: array --- # Template content using Handlebars syntax Hello {{name}}! {% if age >= 18 %} You're an adult, so here are some mature recommendations: {% else %} Here are some age-appropriate suggestions: {% endif %} {% for pref in preferences %} - Based on your interest in {{pref}}, I recommend... {% endfor %} ``` ### Supported Frontmatter Fields - **`model`**: The LLM model to use (e.g., `gpt-4`, `claude-3-sonnet`) - **`input.schema`**: Define expected input variables and their types - **`output.format`**: Expected output format (`json`, `text`, etc.) - **`output.schema`**: Structure of expected output ### Additional Parameters - **`temperature`**: Model temperature (0.0 to 1.0) - **`max_tokens`**: Maximum tokens to generate - **`top_p`**: Nucleus sampling parameter (0.0 to 1.0) - **`frequency_penalty`**: Frequency penalty (0.0 to 1.0) - **`presence_penalty`**: Presence penalty (0.0 to 1.0) - any other parameters that are not model or schema-related will be treated as optional parameters to the model. ### Input Schema Types - `string` or `str`: Text values - `integer` or `int`: Whole numbers - `float`: Decimal numbers - `boolean` or `bool`: True/false values - `array` or `list`: Lists of values - `object` or `dict`: Key-value objects Use `?` suffix for optional fields: `name?: string` ## Message Format Conversion The dotprompt manager intelligently converts your rendered prompts into proper chat messages: ### Simple Text → User Message ```yaml --- model: gpt-4 --- Tell me about {{topic}}. ``` Becomes: `[{"role": "user", "content": "Tell me about AI."}]` ### Role-Based Format → Multiple Messages ```yaml --- model: gpt-4 --- System: You are a {{role}}. User: {{question}} ``` Becomes: ```python [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "What is AI?"} ] ``` ## Example Prompts ### Data Extraction ```yaml # extract_info.prompt --- model: gemini/gemini-1.5-pro input: schema: text: string output: format: json schema: title?: string summary: string tags: array --- Extract the requested information from the given text. Return JSON format. Text: {{text}} ``` ### Code Assistant ```yaml # code_helper.prompt --- model: claude-3-5-sonnet-20241022 temperature: 0.2 max_tokens: 2000 input: schema: language: string task: string code?: string --- You are an expert {{language}} programmer. Task: {{task}} {% if code %} Current code: ```{{language}} {{code}} ``` {% endif %} Please provide a complete, well-documented solution. ``` ### Multi-turn Conversation ```yaml # conversation.prompt --- model: gpt-4 temperature: 0.8 input: schema: personality: string context: string --- System: You are a {{personality}}. {{context}} User: Let's start our conversation. ``` ## API Reference ### PromptManager The core class for managing `.prompt` files. #### Methods - **`__init__(prompt_directory: str)`**: Initialize with directory path - **`render(prompt_id: str, variables: dict) -> str`**: Render prompt with variables - **`list_prompts() -> List[str]`**: Get all available prompt IDs - **`get_prompt(prompt_id: str) -> PromptTemplate`**: Get prompt template object - **`get_prompt_metadata(prompt_id: str) -> dict`**: Get prompt metadata - **`reload_prompts() -> None`**: Reload all prompts from directory - **`add_prompt(prompt_id: str, content: str, metadata: dict)`**: Add prompt programmatically ### DotpromptManager LiteLLM integration class extending `PromptManagementBase`. #### Methods - **`__init__(prompt_directory: str)`**: Initialize with directory path - **`should_run_prompt_management(prompt_id: str, params: dict) -> bool`**: Check if prompt exists - **`set_prompt_directory(directory: str)`**: Change prompt directory - **`reload_prompts()`**: Reload prompts from directory ### PromptTemplate Represents a single prompt with metadata. #### Properties - **`content: str`**: The prompt template content - **`metadata: dict`**: Full metadata from frontmatter - **`model: str`**: Specified model name - **`temperature: float`**: Model temperature - **`max_tokens: int`**: Token limit - **`input_schema: dict`**: Input validation schema - **`output_format: str`**: Expected output format - **`output_schema: dict`**: Output structure schema ## Best Practices 1. **Organize by purpose**: Group related prompts in subdirectories 2. **Use descriptive names**: `extract_user_info.prompt` vs `prompt1.prompt` 3. **Define schemas**: Always specify input schemas for validation 4. **Version control**: Store `.prompt` files in git for change tracking 5. **Test prompts**: Use the test framework to validate prompt behavior 6. **Keep templates focused**: One prompt should do one thing well 7. **Use includes**: Break complex prompts into reusable components ## Troubleshooting ### Common Issues **Prompt not found**: Ensure the `.prompt` file exists and has correct extension ```python # Check available prompts from litellm.integrations.dotprompt import get_dotprompt_manager manager = get_dotprompt_manager() print(manager.prompt_manager.list_prompts()) ``` **Template errors**: Verify Handlebars syntax and variable names ```python # Test rendering directly manager.prompt_manager.render("my_prompt", {"test": "value"}) ``` **Model not working**: Check that model name in frontmatter is correct ```python # Check prompt metadata metadata = manager.prompt_manager.get_prompt_metadata("my_prompt") print(metadata) ``` ### Validation Errors Input validation failures show helpful error messages: ``` ValueError: Invalid type for field 'age': expected int, got str ``` Make sure your variables match the defined schema types. ## Contributing The LiteLLM Dotprompt manager follows the [Dotprompt specification](https://google.github.io/dotprompt/) for maximum compatibility. When contributing: 1. Ensure compatibility with existing `.prompt` files 2. Add tests for new features 3. Update documentation 4. Follow the existing code style ## License This prompt management system is part of LiteLLM and follows the same license terms.