fix: resolve CI linting and type errors
Some checks failed
CI / test (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / type-check (push) Has been cancelled

This commit is contained in:
2026-02-04 12:58:13 +00:00
parent 925e44ceb4
commit 6d6f4a509f

View File

@@ -1,3 +1,5 @@
"""Jinja2-based template engine for prompt rendering."""
from typing import Any, Dict, List, Optional from typing import Any, Dict, List, Optional
from jinja2 import Environment, BaseLoader, TemplateSyntaxError, StrictUndefined, UndefinedError from jinja2 import Environment, BaseLoader, TemplateSyntaxError, StrictUndefined, UndefinedError
from jinja2.exceptions import TemplateError from jinja2.exceptions import TemplateError
@@ -7,6 +9,8 @@ from .exceptions import MissingVariableError, InvalidPromptError
class TemplateEngine: class TemplateEngine:
"""Jinja2 template engine for prompt rendering with variable substitution."""
def __init__(self): def __init__(self):
self.env = Environment( self.env = Environment(
loader=BaseLoader(), loader=BaseLoader(),
@@ -17,6 +21,14 @@ class TemplateEngine:
) )
def get_variables(self, content: str) -> List[str]: def get_variables(self, content: str) -> List[str]:
"""Extract variable names from template content.
Args:
content: Template content with {{variable}} syntax.
Returns:
List of variable names found.
"""
from jinja2 import meta from jinja2 import meta
ast = self.env.parse(content) ast = self.env.parse(content)
return sorted(meta.find_undeclared_variables(ast)) return sorted(meta.find_undeclared_variables(ast))
@@ -27,6 +39,20 @@ class TemplateEngine:
variables: Optional[Dict[str, Any]] = None, variables: Optional[Dict[str, Any]] = None,
required_variables: Optional[List[PromptVariable]] = None, required_variables: Optional[List[PromptVariable]] = None,
) -> str: ) -> str:
"""Render template with variable substitution.
Args:
content: Template content.
variables: Dictionary of variable values.
required_variables: List of variable definitions for validation.
Returns:
Rendered content.
Raises:
MissingVariableError: If a required variable is missing.
InvalidPromptError: If template has syntax errors.
"""
variables = variables.copy() if variables else {} variables = variables.copy() if variables else {}
required_variables = required_variables or [] required_variables = required_variables or []
@@ -56,4 +82,76 @@ class TemplateEngine:
except TemplateSyntaxError as e: except TemplateSyntaxError as e:
raise InvalidPromptError(f"Template syntax error: {e.message}") raise InvalidPromptError(f"Template syntax error: {e.message}")
except (UndefinedError, TemplateError) as e: except (UndefinedError, TemplateError) as e:
raise InvalidPromptError(f"Template rendering error: {e}") raise InvalidPromptError(f"Template rendering error: {e}")
def validate_variables(
self,
variables: Dict[str, Any],
required_variables: List[PromptVariable],
) -> List[str]:
"""Validate variable values against definitions.
Args:
variables: Provided variable values.
required_variables: Variable definitions.
Returns:
List of validation error messages (empty if valid).
"""
errors = []
for var in required_variables:
if var.name not in variables:
if var.required and var.default is None:
errors.append(f"Missing required variable: {var.name}")
continue
value = variables[var.name]
var_type = var.type.value
if var_type == "string":
if not isinstance(value, str):
errors.append(f"{var.name}: must be a string")
elif var_type == "integer":
try:
int(value)
except (ValueError, TypeError):
errors.append(f"{var.name}: must be an integer")
elif var_type == "float":
try:
float(value)
except (ValueError, TypeError):
errors.append(f"{var.name}: must be a number")
elif var_type == "boolean":
if isinstance(value, str):
if value.lower() not in ("true", "false", "0", "1"):
errors.append(f"{var.name}: must be a boolean")
elif var_type == "choice":
if var.choices and value not in var.choices:
errors.append(
f"{var.name}: must be one of {', '.join(var.choices)}"
)
return errors
def render_prompt(
self,
prompt_content: str,
variables: Dict[str, Any],
variable_definitions: List[PromptVariable],
) -> str:
"""Render a complete prompt with validation.
Args:
prompt_content: Raw prompt template content.
variables: Variable values.
variable_definitions: Variable definitions from prompt.
Returns:
Rendered prompt string.
"""
errors = self.validate_variables(variables, variable_definitions)
if errors:
raise MissingVariableError(f"Variable validation failed: {', '.join(errors)}")
return self.render(prompt_content, variables, variable_definitions)