Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| import json | |
| from pathlib import Path | |
| from ..inference.endpoint import EndpointCapability | |
| from ..models.schema import TEISchema | |
| from ..models.spans import SpanDescriptor | |
| try: | |
| from jinja2 import Environment, FileSystemLoader | |
| _HAS_JINJA = True | |
| except ImportError: | |
| _HAS_JINJA = False | |
| _TEMPLATE_DIR = Path(__file__).parent / "templates" | |
| def _get_env() -> "Environment": | |
| if not _HAS_JINJA: | |
| raise ImportError( | |
| "jinja2 is required for prompt building. Install it with: pip install jinja2" | |
| ) | |
| env = Environment(loader=FileSystemLoader(str(_TEMPLATE_DIR)), keep_trailing_newline=True) | |
| env.filters["tojson"] = lambda x, **kw: json.dumps(x, ensure_ascii=False, **kw) | |
| return env | |
| def build_prompt( | |
| source_text: str, | |
| schema: TEISchema, | |
| capability: EndpointCapability, | |
| candidates: list[SpanDescriptor] | None = None, | |
| ) -> str: | |
| """ | |
| Build an LLM prompt for the given endpoint capability. | |
| Raises ValueError for EXTRACTION endpoints (they don't use text prompts). | |
| """ | |
| if capability == EndpointCapability.EXTRACTION: | |
| raise ValueError( | |
| "EXTRACTION endpoints use their own native format; no text prompt needed." | |
| ) | |
| env = _get_env() | |
| template_name = ( | |
| "text_gen.jinja2" | |
| if capability == EndpointCapability.TEXT_GENERATION | |
| else "json_enforced.jinja2" | |
| ) | |
| template = env.get_template(template_name) | |
| candidate_dicts: list[dict] | None = None | |
| if candidates: | |
| candidate_dicts = [ | |
| { | |
| "element": c.element, | |
| "text": c.text, | |
| "context": c.context, | |
| "attrs": c.attrs, | |
| **({"confidence": c.confidence} if c.confidence is not None else {}), | |
| } | |
| for c in candidates | |
| ] | |
| return template.render( | |
| schema=schema, | |
| source_text=source_text, | |
| candidates=candidate_dicts, | |
| ) | |
| def make_correction_prompt(original_response: str, error_message: str) -> str: | |
| """Build a self-correction retry prompt that includes the bad response and the error.""" | |
| return ( | |
| "Your previous response could not be parsed as JSON.\n" | |
| f"Error: {error_message}\n\n" | |
| f"Your previous response was:\n{original_response}\n\n" | |
| "Please fix the JSON and return only a valid JSON array of span objects. " | |
| "Do not include any markdown formatting or explanation." | |
| ) | |