Source code for evoproc_procedures.builders
"""High-level builders for creating + validating procedures (backend-agnostic)."""
from __future__ import annotations
from typing import Any, Dict, Callable, Optional
import json
from evoproc_procedures.models import Procedure
from evoproc_procedures.prompts import create_procedure_prompt
from evoproc_procedures.repairs import repair_procedure_structured
JSON = Dict[str, Any]
QueryFn = Callable[[str, str, Optional[Dict[str, Any]], Optional[int]], str]
[docs]
def create_and_validate_procedure_structured(
idx: int,
task: str,
*,
model: str,
query_fn: QueryFn,
seed: Optional[int] = 1234,
print_diagnostics: bool = False,
) -> JSON:
"""Create a procedure for `task` and repair it until valid.
Steps:
1) Build a creation prompt (`create_procedure_prompt(task)`).
2) Ask for a structured Procedure object using `query_fn` with the Pydantic schema.
3) Parse the JSON and run `repair_procedure_structured(...)`.
Args:
idx: Index/id for logging.
task: Natural-language task description.
model: LLM model name.
query_fn: Backend function to call the LLM.
seed: Random seed for the backend (if supported).
print_diagnostics: If True, print repair diagnostics.
Returns:
A structurally valid procedure JSON.
Raises:
ValueError: If the model response is not valid JSON.
"""
# 1) Build prompt
prompt = create_procedure_prompt(task)
# 2) Structured call
schema = Procedure.model_json_schema()
raw = query_fn(prompt, model, schema, seed)
try:
proc = json.loads(raw) if isinstance(raw, str) else raw
except Exception as e:
raise ValueError(f"[{idx}] Non-JSON response from model: {e}") from e
# 3) Repair until valid
proc = repair_procedure_structured(
proc, model=model, query_fn=query_fn, print_diagnostics=print_diagnostics
)
return proc