Source code for design_research_agents._prompts._library

"""Loader and renderer for packaged prompt templates.

Prompt files live in package resources so they can be versioned independently
from agent code and loaded consistently across environments.
"""

from __future__ import annotations

from collections.abc import Mapping
from functools import cache
from importlib.resources import files
from string import Template
from typing import Final

_PROMPT_FILES: Final[dict[str, str]] = {
    "tool_calling_system": "tool_calling_system.md",
    "tool_calling_user_select_tool": "tool_calling_user_select_tool.md",
    "code_action_step_system": "code_action_step_system.md",
    "code_action_step_user_plan": "code_action_step_user_plan.md",
    "multi_step_continue_system": "multi_step_continue_system.md",
    "multi_step_continue_user": "multi_step_continue_user.md",
    "multi_step_step_user": "multi_step_step_user.md",
    "multi_step_json_step_user": "multi_step_json_step_user.md",
    "multi_step_direct_controller_system": "multi_step_direct_controller_system.md",
    "multi_step_direct_controller_user": "multi_step_direct_controller_user.md",
}

PROMPT_NAMES: Final[tuple[str, ...]] = tuple(sorted(_PROMPT_FILES))


[docs] @cache def load_prompt(name: str) -> str: """Load a prompt template by logical name from packaged resources. The function validates that the name is registered and that the resolved file is non-empty, then returns a stripped text template ready for rendering. Args: name: Logical prompt template name in the registry. Returns: The stripped prompt template text. Raises: ValueError: If the prompt name is unknown or the template is empty. """ filename = _PROMPT_FILES.get(name) if filename is None: raise ValueError(f"Unknown prompt template '{name}'.") resource = files("design_research_agents._prompts").joinpath(filename) with resource.open("r", encoding="utf-8") as prompt_file: content = prompt_file.read().strip() if not content: raise ValueError(f"Prompt template '{name}' is empty.") return content
[docs] def render_prompt(name: str, *, variables: Mapping[str, object]) -> str: """Render a prompt template with ``string.Template`` variable substitution. All variable values are coerced to strings before substitution. Missing variables raise ``ValueError`` with the missing key name for easier debugging. Args: name: Logical prompt template name in the registry. variables: Mapping of template variable names to replacement values. Returns: The rendered prompt text. Raises: ValueError: If the prompt name is unknown or a variable is missing. """ normalized_variables = {key: str(value) for key, value in variables.items()} template = Template(load_prompt(name)) try: return template.substitute(normalized_variables) except KeyError as exc: missing_key = exc.args[0] if exc.args else "unknown" raise ValueError(f"Prompt template '{name}' is missing required variable '{missing_key}'.") from exc