AITOOL / prompts /prompt_templates.py
NandanData's picture
Upload 54 files
ab3b796 verified
"""
Prompt Templates Module
Manages prompt templates for different AI tools and providers
Includes system for storing, loading, and managing user-created prompts
"""
import os
import json
import uuid
import logging
from typing import Dict, Any, List, Optional
from datetime import datetime
# Setup logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("prompts")
class PromptTemplate:
"""Represents a prompt template that can be used with AI providers"""
def __init__(self,
id: str = None,
name: str = "",
description: str = "",
template: str = "",
system_message: str = "",
category: str = "",
is_public: bool = False,
created_by: str = "system",
created_at: str = None,
price: float = 0.0,
parameters: Dict[str, Any] = None,
provider_defaults: Dict[str, Any] = None):
"""Initialize a prompt template"""
self.id = id or str(uuid.uuid4())
self.name = name
self.description = description
self.template = template
self.system_message = system_message
self.category = category
self.is_public = is_public
self.created_by = created_by
self.created_at = created_at or datetime.now().isoformat()
self.price = price
self.parameters = parameters or {}
self.provider_defaults = provider_defaults or {}
def to_dict(self) -> Dict[str, Any]:
"""Convert template to dictionary"""
return {
"id": self.id,
"name": self.name,
"description": self.description,
"template": self.template,
"system_message": self.system_message,
"category": self.category,
"is_public": self.is_public,
"created_by": self.created_by,
"created_at": self.created_at,
"price": self.price,
"parameters": self.parameters,
"provider_defaults": self.provider_defaults
}
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'PromptTemplate':
"""Create template from dictionary"""
return cls(
id=data.get("id"),
name=data.get("name", ""),
description=data.get("description", ""),
template=data.get("template", ""),
system_message=data.get("system_message", ""),
category=data.get("category", ""),
is_public=data.get("is_public", False),
created_by=data.get("created_by", "system"),
created_at=data.get("created_at"),
price=data.get("price", 0.0),
parameters=data.get("parameters", {}),
provider_defaults=data.get("provider_defaults", {})
)
def render(self, variables: Dict[str, Any] = None) -> Dict[str, str]:
"""
Render the prompt template with the provided variables
Returns both the rendered prompt and system message
"""
variables = variables or {}
prompt = self.template
system = self.system_message
# Replace variables in the template
for key, value in variables.items():
placeholder = "{" + key + "}"
prompt = prompt.replace(placeholder, str(value))
system = system.replace(placeholder, str(value))
return {
"prompt": prompt,
"system_message": system
}
class PromptTemplateManager:
"""Manages prompt templates, including default and user-created ones"""
def __init__(self, templates_dir: str = None):
"""Initialize the prompt template manager"""
self.templates_dir = templates_dir or os.path.join(os.path.dirname(__file__), "templates")
self.user_templates_dir = os.path.join(self.templates_dir, "user")
# Create directories if they don't exist
os.makedirs(self.templates_dir, exist_ok=True)
os.makedirs(self.user_templates_dir, exist_ok=True)
# Load default templates
self.default_templates = self._load_default_templates()
# Load user templates
self.user_templates = self._load_user_templates()
def _load_default_templates(self) -> Dict[str, PromptTemplate]:
"""Load default templates from files"""
templates = {}
# Define default templates if no files exist yet
default_templates = {
"general_chat": PromptTemplate(
id="general_chat",
name="General Chat",
description="A general-purpose chat prompt",
template="Please answer the following question or respond to the message: {input}",
system_message="You are a helpful assistant that provides accurate and concise responses.",
category="general",
created_by="system"
),
"creative_writing": PromptTemplate(
id="creative_writing",
name="Creative Writing",
description="Generate creative writing based on a premise",
template="Write a {genre} {format} about {topic}.",
system_message="You are a creative writer with expertise in different genres and formats.",
category="creative",
created_by="system",
parameters={
"genre": {"type": "string", "description": "Genre of the writing", "default": "science fiction"},
"format": {"type": "string", "description": "Format of the writing", "default": "short story"},
"topic": {"type": "string", "description": "Topic or premise", "required": True}
}
),
"code_assistant": PromptTemplate(
id="code_assistant",
name="Code Assistant",
description="Generate or debug code in various languages",
template="I need help with the following code task in {language}:\n\n{task}\n\n{code}",
system_message="You are an expert programmer. Provide well-commented, efficient, and correct code solutions.",
category="development",
created_by="system",
parameters={
"language": {"type": "string", "description": "Programming language", "required": True},
"task": {"type": "string", "description": "Description of the coding task", "required": True},
"code": {"type": "string", "description": "Existing code (if any)", "default": ""}
},
provider_defaults={
"openai": {"model": "gpt-4-turbo"},
"deepseek": {"model": "deepseek-coder"}
}
),
"image_prompt": PromptTemplate(
id="image_prompt",
name="Image Generation",
description="Detailed prompt for image generation",
template="{subject} {style}, {details}, {quality}",
system_message="",
category="images",
created_by="system",
parameters={
"subject": {"type": "string", "description": "Main subject of the image", "required": True},
"style": {"type": "string", "description": "Art style", "default": "digital art"},
"details": {"type": "string", "description": "Additional details", "default": "detailed, vibrant colors"},
"quality": {"type": "string", "description": "Quality descriptors", "default": "high quality, 4k, trending on artstation"}
},
provider_defaults={
"openai": {"model": "dall-e-3"}
}
)
}
# Save default templates if they don't exist
for template_id, template in default_templates.items():
template_path = os.path.join(self.templates_dir, f"{template_id}.json")
if not os.path.exists(template_path):
with open(template_path, "w") as f:
json.dump(template.to_dict(), f, indent=2)
templates[template_id] = template
return templates
def _load_user_templates(self) -> Dict[str, PromptTemplate]:
"""Load user-created templates"""
templates = {}
try:
# List all JSON files in user_templates_dir
for filename in os.listdir(self.user_templates_dir):
if filename.endswith(".json"):
template_path = os.path.join(self.user_templates_dir, filename)
with open(template_path, "r") as f:
template_data = json.load(f)
template = PromptTemplate.from_dict(template_data)
templates[template.id] = template
except Exception as e:
logger.error(f"Error loading user templates: {e}")
return templates
def get_all_templates(self) -> List[PromptTemplate]:
"""Get all available templates (default + user)"""
all_templates = list(self.default_templates.values())
# Add public user templates and user's own templates
for template in self.user_templates.values():
if template.is_public:
all_templates.append(template)
return all_templates
def get_user_templates(self, user_id: str) -> List[PromptTemplate]:
"""Get templates created by a specific user"""
return [t for t in self.user_templates.values() if t.created_by == user_id]
def get_template(self, template_id: str) -> Optional[PromptTemplate]:
"""Get a specific template by ID"""
if template_id in self.default_templates:
return self.default_templates[template_id]
if template_id in self.user_templates:
return self.user_templates[template_id]
return None
def create_template(self, template: PromptTemplate) -> PromptTemplate:
"""Create a new user template"""
# Ensure unique ID
if template.id in self.default_templates or template.id in self.user_templates:
template.id = str(uuid.uuid4())
# Save template to file
template_path = os.path.join(self.user_templates_dir, f"{template.id}.json")
with open(template_path, "w") as f:
json.dump(template.to_dict(), f, indent=2)
# Add to user templates
self.user_templates[template.id] = template
return template
def update_template(self, template: PromptTemplate) -> Optional[PromptTemplate]:
"""Update an existing user template"""
if template.id not in self.user_templates:
logger.error(f"Template {template.id} not found or not a user template")
return None
# Save updated template
template_path = os.path.join(self.user_templates_dir, f"{template.id}.json")
with open(template_path, "w") as f:
json.dump(template.to_dict(), f, indent=2)
# Update in memory
self.user_templates[template.id] = template
return template
def delete_template(self, template_id: str, user_id: str) -> bool:
"""Delete a user template"""
if template_id not in self.user_templates:
logger.error(f"Template {template_id} not found or not a user template")
return False
# Check ownership
template = self.user_templates[template_id]
if template.created_by != user_id and user_id != "admin":
logger.error(f"User {user_id} does not own template {template_id}")
return False
# Delete template file
template_path = os.path.join(self.user_templates_dir, f"{template_id}.json")
try:
os.remove(template_path)
del self.user_templates[template_id]
return True
except Exception as e:
logger.error(f"Error deleting template {template_id}: {e}")
return False
def get_templates_by_category(self, category: str) -> List[PromptTemplate]:
"""Get templates by category"""
all_templates = self.get_all_templates()
return [t for t in all_templates if t.category.lower() == category.lower()]
def get_public_templates(self) -> List[PromptTemplate]:
"""Get all public templates created by users"""
return [t for t in self.user_templates.values() if t.is_public]
# Example usage
if __name__ == "__main__":
# Initialize manager
manager = PromptTemplateManager()
# Get all templates
all_templates = manager.get_all_templates()
print(f"Loaded {len(all_templates)} templates")
# Create a new template
new_template = PromptTemplate(
name="SEO Content",
description="Generate SEO-optimized content for websites",
template="Write SEO-optimized content about {topic} targeting the keyword {keyword}. {tone} tone, {length} words.",
system_message="You are an expert SEO content writer who creates engaging, well-researched content that ranks well in search engines.",
category="marketing",
created_by="user123",
is_public=True,
parameters={
"topic": {"type": "string", "description": "Main topic", "required": True},
"keyword": {"type": "string", "description": "Target keyword", "required": True},
"tone": {"type": "string", "description": "Content tone", "default": "professional"},
"length": {"type": "number", "description": "Content length in words", "default": 500}
}
)
created = manager.create_template(new_template)
print(f"Created new template: {created.id} - {created.name}")
# Test rendering a template
code_template = manager.get_template("code_assistant")
if code_template:
rendered = code_template.render({
"language": "Python",
"task": "Create a function to calculate Fibonacci numbers",
"code": "def fibonacci(n):\n # TODO: Implement"
})
print("\nRendered prompt:")
print(rendered["prompt"])
print("\nSystem message:")