Files

52 lines
2.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Editable prompts and validated payload templates."""
from pathlib import Path
from string import Template, Formatter
import yaml
from pydantic import model_validator
from llm.config import ConfigModel
DEFAULT_PROMPTS = Path(__file__).resolve().parents[1] / 'prompts.yaml'
class Prompts(ConfigModel):
teacher_system: str
teacher_user: str
teacher_retry: str
training_system: dict[str, str]
structured_system: dict[str, str]
training_user: str
task_instructions: dict[str, str]
object_names: dict[str, str]
action_templates: dict[str, str]
@model_validator(mode='after')
def validate_texts(self):
texts = [self.teacher_system, *self.training_system.values(), *self.structured_system.values(), *self.task_instructions.values()]
if any(not text.strip() for text in texts):
raise ValueError('Промпты не должны быть пустыми')
if set(self.training_system) != {'full', 'step', 'branch'}:
raise ValueError('training_system должен содержать full, step, branch')
if set(self.structured_system) != {'full', 'step', 'branch'}:
raise ValueError('structured_system должен содержать full, step, branch')
for value in (self.teacher_user, self.teacher_retry, self.training_user):
template = Template(value)
if not template.is_valid() or set(template.get_identifiers()) != {'payload'}:
raise ValueError('Шаблон должен содержать ${payload}; другие переменные не поддерживаются')
for value in self.action_templates.values():
if not value.strip():
raise ValueError('Пустой шаблон действия')
fields = {field for _, field, _, _ in Formatter().parse(value) if field is not None}
if fields - {'object', 'target'}:
raise ValueError('В action_templates допустимы только {object} и {target}')
value.format(object='объект', target='место')
return self
def load_prompts(path: Path = DEFAULT_PROMPTS) -> Prompts:
return Prompts.model_validate(yaml.safe_load(path.read_text(encoding='utf-8')))
def render(template: str, payload: str) -> str:
return Template(template).substitute(payload=payload)