File size: 1,480 Bytes
6bff5d9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
"""Builds the planner LLM prompt from question + catalog.

Renders the catalog into a compact textual form that fits the LLM context
window. For users with ≤50 tables the full catalog goes in verbatim.
"""

from __future__ import annotations

from ...catalog.models import Catalog
from ...catalog.render import render_source


def render_catalog(catalog: Catalog) -> str:
    """Render every Source in the catalog as text. One blank line between sources."""
    if not catalog.sources:
        return "(catalog is empty — the user has not registered any structured data yet)"
    return "\n\n".join(render_source(s) for s in catalog.sources)


def build_planner_prompt(
    question: str,
    catalog: Catalog,
    previous_error: str | None = None,
) -> str:
    """Return the human-message content for the planner LLM.

    Composed of three sections in order:
      1. The user's question.
      2. The user's full catalog (rendered).
      3. (optional) The previous attempt's error, on retry.

    The system prompt (`config/prompts/query_planner.md`) is loaded
    separately by `QueryPlannerService`.
    """
    sections = [
        f"# Question\n\n{question}",
        f"# Catalog\n\n{render_catalog(catalog)}",
    ]
    if previous_error:
        sections.append(
            "# Previous attempt failed validation\n\n"
            f"{previous_error}\n\n"
            "Emit a corrected IR. Do not repeat the same mistake."
        )
    return "\n\n".join(sections)