"""Stufe 1 der Pipeline: erfassen, was im Aufgabentext steht – Teilfragen und Zahlen, noch kein Modell.""" from pathlib import Path from typing import List from core.llm import LLMSession from core.model_schema import CheckIssue, FigureInput, FigureReading, TaskUnderstanding from understanding.figures import image_parts UNDERSTAND_PROMPT_FILE = Path(__file__).parent / "Verstehen-Prompt.txt" FIGURE_PROMPT_FILE = Path(__file__).parent / "Abbildungs-Prompt.txt" def _content(text: str, figures: List[FigureInput]): """Reiner Text – oder, mit Abbildungen, eine Liste aus Text und Bildern (OpenAI-Format).""" if not figures: return text hinweis = (f"\n\nDER AUFGABE LIEGEN {len(figures)} ABBILDUNG(EN) BEI – sie folgen als Bilder; " "übertrage jede vollständig in figures.") return [{"type": "text", "text": text + hinweis}, *image_parts(figures)] def _create_with_images(session: LLMSession, response_model, messages, step: str, figures): """Wie session.create – mit verständlicher Meldung, falls das Modell keine Bilder annimmt.""" try: return session.create(response_model, messages, step=step) except Exception as exc: if figures and any(w in str(exc).lower() for w in ("image", "vision", "modalit", "multimodal")): raise RuntimeError(f"Das Modell dieser Stufe nimmt offenbar keine Bilder an ({str(exc)[:160]}). " "Ein Bildmodell über LLM_MODEL_UNDERSTANDING wählen.") from exc raise def understand_task(session: LLMSession, task: str, issues: List[CheckIssue] = (), data_prompt: str = "", figures: List[FigureInput] = ()) -> TaskUnderstanding: """Stufe 1: erfassen, was im Text steht – Teilfragen, Zahlen, Machbarkeit, Abbildungen. Noch kein Modell.""" nachtrag = "" if issues: nachtrag = ("\n\nDEIN VORIGER VERSUCH WAR UNVOLLSTÄNDIG:\n" + "\n".join(f"- [{i.code}] {i.message}" for i in issues) + "\nErfasse die fehlenden Punkte, behalte den Rest bei.") text = f"AUFGABENTEXT:\n{task}\n\n{data_prompt}{nachtrag}".strip() return _create_with_images(session, TaskUnderstanding, [ {"role": "system", "content": UNDERSTAND_PROMPT_FILE.read_text(encoding="utf-8")}, {"role": "user", "content": _content(text, list(figures))}, ], "Verstehen", figures) def read_figures(session: LLMSession, task: str, figures: List[FigureInput]) -> FigureReading: """Unabhängige Übertragung nur der Abbildungen – die Gegenprobe zur Verstehensstufe.""" text = f"AUFGABENTEXT (nur zur Einordnung der Abbildungen):\n{task}" return _create_with_images(session, FigureReading, [ {"role": "system", "content": FIGURE_PROMPT_FILE.read_text(encoding="utf-8")}, {"role": "user", "content": _content(text, figures)}, ], "Abbildungen", figures)