""" Template utilities for Jinja2 template rendering with LangChain """ import logging from typing import Dict, Any from jinja2 import Environment, BaseLoader, TemplateError logger = logging.getLogger(__name__) class TemplateRenderer: """Jinja2 template renderer for LLM prompts""" def __init__(self): self.env = Environment( loader=BaseLoader(), # Enable safe variable substitution autoescape=False, # Custom delimiters to avoid conflicts with common markdown syntax variable_start_string='{{', variable_end_string='}}', block_start_string='{%', block_end_string='%}', comment_start_string='{#', comment_end_string='#}', # Keep linebreaks keep_trailing_newline=True, # Remove unnecessary whitespace trim_blocks=True, lstrip_blocks=True ) def render_template(self, template_string: str, variables: Dict[str, Any]) -> str: """ Render a Jinja2 template string with provided variables Args: template_string: The template string with Jinja2 syntax variables: Dictionary of variables to substitute Returns: Rendered template string Raises: TemplateError: If template rendering fails """ try: template = self.env.from_string(template_string) rendered = template.render(**variables) logger.debug(f"Template rendered successfully with variables: {list(variables.keys())}") return rendered except TemplateError as e: logger.error(f"Template rendering failed: {e}") logger.error(f"Template: {template_string[:200]}...") logger.error(f"Variables: {variables}") raise except Exception as e: logger.error(f"Unexpected error during template rendering: {e}") raise TemplateError(f"Template rendering failed: {e}") def render_system_prompt(self, template_string: str, variables: Dict[str, Any]) -> str: """ Render system prompt template Args: template_string: System prompt template variables: Variables for substitution Returns: Rendered system prompt """ return self.render_template(template_string, variables) def render_user_prompt(self, template_string: str, variables: Dict[str, Any]) -> str: """ Render user prompt template Args: template_string: User prompt template variables: Variables for substitution Returns: Rendered user prompt """ return self.render_template(template_string, variables) # Global template renderer instance template_renderer = TemplateRenderer() def render_prompt_template(template_string: str, variables: Dict[str, Any]) -> str: """ Convenience function to render prompt templates Args: template_string: Template string with Jinja2 syntax variables: Dictionary of variables to substitute Returns: Rendered template string """ return template_renderer.render_template(template_string, variables)