simplified
This commit is contained in:
99
README.md
99
README.md
@@ -1,6 +1,6 @@
|
||||
# LLMUtils
|
||||
|
||||
A Python utility library for managing LLM prompts with Jinja2 template support and JSON schemas.
|
||||
A Python utility library for managing LLM prompts with Jinja2 templating and automatic schema loading.
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -19,12 +19,11 @@ pip install git+https://git.project-insanity.de/gmarth/LLMUtils.git
|
||||
## Features
|
||||
|
||||
- **Jinja2 Template Engine**: Full support for loops, conditionals, filters, and complex data structures
|
||||
- **Smart Prompt Management**: Load and manage prompt templates with variable substitution
|
||||
- **Smart Prompt Management**: Load and manage prompt templates with automatic schema detection
|
||||
- **On-demand Loading**: Prompts are loaded lazily at runtime for better performance
|
||||
- **Caching Support**: Optional caching to avoid repeated disk reads
|
||||
- **JSON Schema Support**: Associate structured output schemas with prompts
|
||||
- **Variable Validation**: Automatic validation of required template variables
|
||||
- **Flexible API**: Fill variables at retrieval or on-demand
|
||||
- **Automatic Schema Loading**: JSON schemas are automatically loaded when found next to prompt files
|
||||
- **Flexible Undefined Handling**: Configure how Jinja2 handles missing variables (strict, debug, silent)
|
||||
|
||||
## Quick Start
|
||||
|
||||
@@ -32,15 +31,18 @@ pip install git+https://git.project-insanity.de/gmarth/LLMUtils.git
|
||||
|
||||
```python
|
||||
from llmutils.prompt_manager import PromptManager
|
||||
from jinja2 import UndefinedError
|
||||
|
||||
# Get a prompt template
|
||||
result = PromptManager.get_prompt('greeting')
|
||||
print(result.variables) # See required variables: {'name', 'age'}
|
||||
print(result.template) # View the template: "Hello {{name}}, you are {{age}} years old"
|
||||
|
||||
# Fill the template
|
||||
filled = result.fill(name='Alice', age=30)
|
||||
print(filled) # "Hello Alice, you are 30 years old"
|
||||
# Fill the template - Jinja2 handles missing variables
|
||||
try:
|
||||
filled = result.fill(name='Alice', age=30)
|
||||
print(filled) # "Hello Alice, you are 30 years old"
|
||||
except UndefinedError as e:
|
||||
print(f"Missing variable: {e}")
|
||||
```
|
||||
|
||||
### Pre-filling Variables
|
||||
@@ -51,18 +53,18 @@ result = PromptManager.get_prompt('greeting', name='Alice', age=30)
|
||||
print(result.prompt) # Already filled: "Hello Alice, you are 30 years old"
|
||||
```
|
||||
|
||||
### Validation
|
||||
### Handling Optional Variables
|
||||
|
||||
Use Jinja2's built-in features for optional variables:
|
||||
|
||||
```python
|
||||
result = PromptManager.get_prompt('greeting')
|
||||
# Template with optional variables (greeting_flexible.md):
|
||||
# Hello {{ name | default('Guest') }}!
|
||||
# {% if age is defined %}You are {{ age }} years old.{% endif %}
|
||||
|
||||
# Check if variables are valid
|
||||
if not result.validate(name='Alice'):
|
||||
missing = result.get_missing_variables(name='Alice')
|
||||
print(f"Missing variables: {missing}") # {'age'}
|
||||
|
||||
# Fill with all required variables
|
||||
filled = result.fill(name='Alice', age=30)
|
||||
result = PromptManager.get_prompt('greeting_flexible')
|
||||
filled = result.fill(name='Alice') # Works! Age is optional
|
||||
print(filled) # "Hello Alice!\n"
|
||||
```
|
||||
|
||||
### Advanced Jinja2 Features
|
||||
@@ -75,8 +77,9 @@ filled = result.fill(
|
||||
priority='high'
|
||||
)
|
||||
|
||||
# Using conditionals
|
||||
# Using conditionals for optional variables
|
||||
result = PromptManager.get_prompt('status_report')
|
||||
# Template can handle optional variables with {% if variable %}
|
||||
filled = result.fill(
|
||||
error='Connection timeout', # Will show error message
|
||||
items=[] # Will show "No items"
|
||||
@@ -96,14 +99,35 @@ filled = result.fill(
|
||||
)
|
||||
```
|
||||
|
||||
### JSON Schema Support
|
||||
### Configuring Undefined Behavior
|
||||
|
||||
```python
|
||||
# Get prompt with associated schema
|
||||
result = PromptManager.get_prompt('task_prompt')
|
||||
from jinja2 import DebugUndefined, Undefined
|
||||
|
||||
# Default: StrictUndefined (raises errors on missing variables)
|
||||
PromptManager.configure()
|
||||
|
||||
# Debug mode: shows undefined variable names in output
|
||||
PromptManager.configure(undefined=DebugUndefined)
|
||||
result = PromptManager.get_prompt('greeting')
|
||||
filled = result.fill(name='Alice') # Output: "Hello Alice, you are {{ age }} years old"
|
||||
|
||||
# Silent mode: undefined variables become empty strings
|
||||
PromptManager.configure(undefined=Undefined)
|
||||
result = PromptManager.get_prompt('greeting')
|
||||
filled = result.fill(name='Alice') # Output: "Hello Alice, you are years old"
|
||||
```
|
||||
|
||||
### Automatic Schema Loading
|
||||
|
||||
Schemas are automatically loaded when a `.json` file exists next to the prompt:
|
||||
|
||||
```python
|
||||
# If you have both greeting.md and greeting.json files:
|
||||
result = PromptManager.get_prompt('greeting')
|
||||
|
||||
if result.schema:
|
||||
print("This prompt has a structured output schema")
|
||||
print("Schema automatically loaded!")
|
||||
print(result.schema) # The JSON schema dictionary
|
||||
```
|
||||
|
||||
@@ -111,11 +135,15 @@ if result.schema:
|
||||
|
||||
```python
|
||||
from pathlib import Path
|
||||
from jinja2 import DebugUndefined
|
||||
from llmutils.prompt_manager import PromptManager
|
||||
|
||||
# Configure custom prompts directory (default: ./prompts)
|
||||
PromptManager.configure(path=Path('/custom/prompts/location'))
|
||||
|
||||
# Configure undefined variable handling
|
||||
PromptManager.configure(undefined=DebugUndefined)
|
||||
|
||||
# Disable caching for development
|
||||
PromptManager.configure(caching=False)
|
||||
|
||||
@@ -200,25 +228,28 @@ No items to process.
|
||||
|
||||
The `ManagedPrompt` dataclass returned by `get_prompt()`:
|
||||
|
||||
- `template: str` - The original Jinja2 template string
|
||||
- `template: str` - The Jinja2 template string (or filled result if pre-filled)
|
||||
- `name: str` - The prompt name
|
||||
- `variables: Set[str]` - Required template variables (auto-extracted from Jinja2)
|
||||
- `schema: Optional[Dict]` - Associated JSON schema
|
||||
- `prompt: str` - Property that returns filled prompt or template
|
||||
- `schema: Optional[Dict]` - Associated JSON schema (automatically loaded)
|
||||
- `prompt: str` - Property that returns the template (backward compatibility)
|
||||
- `fill(**kwargs) -> str` - Fill template with variables using Jinja2
|
||||
- `validate(**kwargs) -> bool` - Check if all variables provided
|
||||
- `get_missing_variables(**kwargs) -> Set[str]` - Get missing variables
|
||||
|
||||
### PromptManager Methods
|
||||
|
||||
- `get_prompt(prompt_name, **kwargs) -> ManagedPrompt` - Get a prompt template
|
||||
- `get_schema(prompt_name) -> Optional[Dict]` - Get just the schema
|
||||
- `has_schema(prompt_name) -> bool` - Check if prompt has schema
|
||||
- `list_prompts() -> Dict` - List all available prompts
|
||||
- `get_prompt_info(prompt_name) -> Dict` - Get detailed prompt information
|
||||
- `configure(path=None, caching=None)` - Configure settings
|
||||
- `list_prompts() -> Dict[str, Dict[str, Any]]` - List all available prompts with schema info
|
||||
- `configure(path=None, caching=None, undefined=None)` - Configure settings
|
||||
- `reload_prompts()` - Clear the cache
|
||||
|
||||
### Configuration Options
|
||||
|
||||
- `path: Path` - Custom prompts directory (default: `./prompts`)
|
||||
- `caching: bool` - Enable/disable prompt caching (default: `True`)
|
||||
- `undefined: type` - Jinja2 undefined behavior:
|
||||
- `StrictUndefined` (default): Raises error on undefined variables
|
||||
- `DebugUndefined`: Shows `{{ variable }}` for undefined variables
|
||||
- `Undefined`: Replaces undefined variables with empty string
|
||||
|
||||
### Jinja2 Template Features
|
||||
|
||||
The library supports all standard Jinja2 features:
|
||||
|
||||
Reference in New Issue
Block a user