119 lines
4.1 KiB
Python
119 lines
4.1 KiB
Python
|
|
"""
|
|||
|
|
Zentrale Mustache-Variablen für Planungs-KI-Prompts.
|
|||
|
|
|
|||
|
|
Orchestratoren bauen domänenspezifische Basis-Variablen; dieses Modul merged
|
|||
|
|
erweiterbare Provider (Katalog-Slots, später weitere Kontexte).
|
|||
|
|
"""
|
|||
|
|
from __future__ import annotations
|
|||
|
|
|
|||
|
|
from typing import Any, Callable, Dict, Mapping, Optional
|
|||
|
|
|
|||
|
|
from catalog_prompt_slots import all_placeholder_keys, empty_catalog_variables
|
|||
|
|
from planning_catalog_context import ProgressionPlanningCatalogContext
|
|||
|
|
|
|||
|
|
PlanningPromptVariableProvider = Callable[..., Dict[str, str]]
|
|||
|
|
|
|||
|
|
|
|||
|
|
def _catalog_slot_variables(
|
|||
|
|
*,
|
|||
|
|
cur,
|
|||
|
|
catalog: Optional[ProgressionPlanningCatalogContext] = None,
|
|||
|
|
slug: Optional[str] = None,
|
|||
|
|
**_: Any,
|
|||
|
|
) -> Dict[str, str]:
|
|||
|
|
if cur is None or catalog is None:
|
|||
|
|
return empty_catalog_variables()
|
|||
|
|
from catalog_prompt_slots import resolve_catalog_prompt_variables
|
|||
|
|
|
|||
|
|
resolved = resolve_catalog_prompt_variables(cur, catalog, slug=slug)
|
|||
|
|
return {k: str(resolved.get(k) or "") for k in all_placeholder_keys()}
|
|||
|
|
|
|||
|
|
|
|||
|
|
_PLANNING_PROMPT_VARIABLE_PROVIDERS: tuple[PlanningPromptVariableProvider, ...] = (
|
|||
|
|
_catalog_slot_variables,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
def merge_planning_prompt_variables(
|
|||
|
|
cur,
|
|||
|
|
base_variables: Mapping[str, str],
|
|||
|
|
*,
|
|||
|
|
catalog: Optional[ProgressionPlanningCatalogContext] = None,
|
|||
|
|
slug: Optional[str] = None,
|
|||
|
|
) -> Dict[str, str]:
|
|||
|
|
"""Merged Basis-Variablen mit allen registrierten Planungs-Providern."""
|
|||
|
|
out = {str(k): "" if v is None else str(v) for k, v in base_variables.items()}
|
|||
|
|
ctx: Dict[str, Any] = {"cur": cur, "catalog": catalog, "slug": slug}
|
|||
|
|
for provider in _PLANNING_PROMPT_VARIABLE_PROVIDERS:
|
|||
|
|
out.update(provider(**ctx))
|
|||
|
|
return out
|
|||
|
|
|
|||
|
|
|
|||
|
|
def planning_prompt_placeholder_catalog() -> dict:
|
|||
|
|
"""Platzhalter-Katalog für Admin — Slot-Typ × Dimension + Aggregat."""
|
|||
|
|
from catalog_prompt_slots import CATALOG_KINDS, SLOT_KEYS, placeholder_key
|
|||
|
|
|
|||
|
|
slot_labels = {
|
|||
|
|
"description": "Allgemeine Beschreibung",
|
|||
|
|
"hints_on_progression": "Hinweise Progressionsgraph / Stufen",
|
|||
|
|
"hints_on_exercise": "Hinweise Übungsanlage / Gap-Fill",
|
|||
|
|
"hints_on_path_qa": "Bewertungsmaßstäbe Pfad-QS",
|
|||
|
|
"anti_patterns": "Anti-Patterns (Fehlbewertung vermeiden)",
|
|||
|
|
"rematch_guard": "Rematch-Guard (primär Code, optional Prompt)",
|
|||
|
|
}
|
|||
|
|
kind_labels = {c.kind: c.label_de for c in CATALOG_KINDS}
|
|||
|
|
|
|||
|
|
slugs_common = [
|
|||
|
|
"planning_exercise_path_qa",
|
|||
|
|
"planning_progression_roadmap",
|
|||
|
|
"planning_progression_stage_spec",
|
|||
|
|
"planning_progression_goal_analysis",
|
|||
|
|
"planning_progression_start_target",
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
defs = []
|
|||
|
|
for cfg in CATALOG_KINDS:
|
|||
|
|
for slot in SLOT_KEYS:
|
|||
|
|
key = placeholder_key(cfg.kind, slot)
|
|||
|
|
defs.append(
|
|||
|
|
{
|
|||
|
|
"key": key,
|
|||
|
|
"placeholder": "{{" + key + "}}",
|
|||
|
|
"description": (
|
|||
|
|
f"{kind_labels.get(cfg.kind, cfg.kind)} — "
|
|||
|
|
f"{slot_labels.get(slot, slot)} (aktiver Eintrag aus planning_catalog_context)."
|
|||
|
|
),
|
|||
|
|
"used_by_slugs": slugs_common,
|
|||
|
|
}
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
defs.extend(
|
|||
|
|
[
|
|||
|
|
{
|
|||
|
|
"key": "catalog_guidance_block",
|
|||
|
|
"placeholder": "{{catalog_guidance_block}}",
|
|||
|
|
"description": "Aggregierter Markdown-Block aus aktiven Slots (slug-spezifisches Profil).",
|
|||
|
|
"used_by_slugs": slugs_common,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"key": "catalog_context_json",
|
|||
|
|
"placeholder": "{{catalog_context_json}}",
|
|||
|
|
"description": "Audit-JSON der gewählten Katalog-Einträge und befüllten Slots.",
|
|||
|
|
"used_by_slugs": slugs_common[:3],
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"key": "has_catalog_guidance",
|
|||
|
|
"placeholder": "{{has_catalog_guidance}}",
|
|||
|
|
"description": "„true“ wenn mindestens ein LLM-Slot gesetzt; sonst leer.",
|
|||
|
|
"used_by_slugs": slugs_common[:3],
|
|||
|
|
},
|
|||
|
|
]
|
|||
|
|
)
|
|||
|
|
return {"context": "planning", "placeholders": defs}
|
|||
|
|
|
|||
|
|
|
|||
|
|
__all__ = [
|
|||
|
|
"merge_planning_prompt_variables",
|
|||
|
|
"planning_prompt_placeholder_catalog",
|
|||
|
|
]
|