Add core modules (prompt, template)
This commit is contained in:
59
src/promptforge/core/template.py
Normal file
59
src/promptforge/core/template.py
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
from typing import Any, Dict, List, Optional
|
||||||
|
from jinja2 import Environment, BaseLoader, TemplateSyntaxError, StrictUndefined, UndefinedError
|
||||||
|
from jinja2.exceptions import TemplateError
|
||||||
|
|
||||||
|
from .prompt import PromptVariable
|
||||||
|
from .exceptions import MissingVariableError, InvalidPromptError
|
||||||
|
|
||||||
|
|
||||||
|
class TemplateEngine:
|
||||||
|
def __init__(self):
|
||||||
|
self.env = Environment(
|
||||||
|
loader=BaseLoader(),
|
||||||
|
autoescape=True,
|
||||||
|
trim_blocks=True,
|
||||||
|
lstrip_blocks=True,
|
||||||
|
undefined=StrictUndefined,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_variables(self, content: str) -> List[str]:
|
||||||
|
from jinja2 import meta
|
||||||
|
ast = self.env.parse(content)
|
||||||
|
return sorted(meta.find_undeclared_variables(ast))
|
||||||
|
|
||||||
|
def render(
|
||||||
|
self,
|
||||||
|
content: str,
|
||||||
|
variables: Optional[Dict[str, Any]] = None,
|
||||||
|
required_variables: Optional[List[PromptVariable]] = None,
|
||||||
|
) -> str:
|
||||||
|
variables = variables.copy() if variables else {}
|
||||||
|
required_variables = required_variables or []
|
||||||
|
|
||||||
|
for var in required_variables:
|
||||||
|
if var.name not in variables and var.default is not None:
|
||||||
|
variables[var.name] = var.default
|
||||||
|
|
||||||
|
missing = []
|
||||||
|
for var in required_variables:
|
||||||
|
if var.required and var.name not in variables:
|
||||||
|
missing.append(var.name)
|
||||||
|
|
||||||
|
if missing:
|
||||||
|
raise MissingVariableError(
|
||||||
|
f"Missing required variables: {', '.join(missing)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
for var in required_variables:
|
||||||
|
if var.name in variables and var.type.value == "boolean":
|
||||||
|
val = variables[var.name]
|
||||||
|
if isinstance(val, str):
|
||||||
|
variables[var.name] = val.lower() in ("true", "1", "yes")
|
||||||
|
|
||||||
|
try:
|
||||||
|
template = self.env.from_string(content)
|
||||||
|
return template.render(**variables)
|
||||||
|
except TemplateSyntaxError as e:
|
||||||
|
raise InvalidPromptError(f"Template syntax error: {e.message}")
|
||||||
|
except (UndefinedError, TemplateError) as e:
|
||||||
|
raise InvalidPromptError(f"Template rendering error: {e}")
|
||||||
Reference in New Issue
Block a user