From d4b1780193933462f82b1629c44be50b85684213 Mon Sep 17 00:00:00 2001 From: Lars Date: Tue, 9 Jun 2026 16:27:03 +0200 Subject: [PATCH] Enhance Gap Fill Offer with Context Preview and Update Version - Added `context_preview` to the `build_gap_fill_offer` function, providing a structured overview of the roadmap snapshot. - Introduced `gapOfferContextDisplayLines` utility to format context information for UI display, improving clarity for users. - Updated `ExerciseProgressionPathBuilder` and related components to utilize the new context preview, enhancing the user experience. - Incremented application version to 0.8.213 to reflect these changes. --- backend/planning_exercise_path_ai_fill.py | 3 + .../test_planning_exercise_path_ai_fill.py | 23 ++++++- backend/version.py | 2 +- .../ExerciseAiSuggestPreviewModal.jsx | 26 ++++++++ .../ExerciseProgressionPathBuilder.jsx | 66 ++++++++++++++++--- .../src/utils/planningContextForExerciseAi.js | 28 ++++++++ 6 files changed, 136 insertions(+), 12 deletions(-) diff --git a/backend/planning_exercise_path_ai_fill.py b/backend/planning_exercise_path_ai_fill.py index f1cec92..25e28da 100644 --- a/backend/planning_exercise_path_ai_fill.py +++ b/backend/planning_exercise_path_ai_fill.py @@ -349,6 +349,7 @@ def build_gap_fill_offer( step_b=step_b, roadmap_snapshot=roadmap_snapshot, ) + ctx_preview = dict(roadmap_snapshot) if roadmap_snapshot else None offer: Dict[str, Any] = { "offer_id": offer_id, "source": spec.get("source"), @@ -357,12 +358,14 @@ def build_gap_fill_offer( "title_hint": spec.get("title_hint"), "sketch": spec.get("sketch"), "goal_for_ai": goal_for_ai or spec.get("sketch"), + "context_preview": ctx_preview, "phase": spec.get("phase"), "rationale": spec.get("rationale"), "has_ai_payload": False, "from_title": (step_a or {}).get("title"), "to_title": (step_b or {}).get("title"), "primary_topic": (brief.primary_topic if brief else None), + "roadmap_major_step_index": spec.get("roadmap_major_step_index"), } if proposal: offer["has_ai_payload"] = True diff --git a/backend/tests/test_planning_exercise_path_ai_fill.py b/backend/tests/test_planning_exercise_path_ai_fill.py index e6b6bbd..54b317a 100644 --- a/backend/tests/test_planning_exercise_path_ai_fill.py +++ b/backend/tests/test_planning_exercise_path_ai_fill.py @@ -1,5 +1,9 @@ """Tests Planungs-KI Phase E3 — Lücken-Angebote und Off-Topic.""" -from planning_exercise_path_ai_fill import build_gap_fill_goal_text, collect_gap_fill_specs +from planning_exercise_path_ai_fill import ( + build_gap_fill_goal_text, + build_gap_fill_offer, + collect_gap_fill_specs, +) from planning_exercise_path_qa import parse_llm_suggested_new_exercises, strip_off_topic_steps_from_path from planning_exercise_semantics import build_semantic_brief @@ -113,3 +117,20 @@ def test_build_gap_fill_goal_text_includes_roadmap_snapshot(): assert "explosiver Angriff" in text assert "variable Rhythmen" in text assert "timing" in text + + +def test_build_gap_fill_offer_exposes_context_preview(): + brief = build_semantic_brief("Kumite Beinarbeit") + offer = build_gap_fill_offer( + spec={"source": "roadmap_unfilled", "phase": "vertiefung", "title_hint": "Rhythmen"}, + steps=[{"title": "A"}, {"title": "B"}], + goal_query="Kumite Beinarbeit", + brief=brief, + roadmap_snapshot={ + "start_situation": "Steppbewegung", + "target_state": "explosiver Angriff", + "stage_learning_goal": "variable Rhythmen", + }, + ) + assert offer["context_preview"]["start_situation"] == "Steppbewegung" + assert "variable Rhythmen" in offer["goal_for_ai"] diff --git a/backend/version.py b/backend/version.py index b378672..f3eec53 100644 --- a/backend/version.py +++ b/backend/version.py @@ -1,6 +1,6 @@ # Shinkan Jinkendo Version Information -APP_VERSION = "0.8.212" +APP_VERSION = "0.8.213" BUILD_DATE = "2026-06-07" DB_SCHEMA_VERSION = "20260607087" diff --git a/frontend/src/components/ExerciseAiSuggestPreviewModal.jsx b/frontend/src/components/ExerciseAiSuggestPreviewModal.jsx index b7bdc29..661987c 100644 --- a/frontend/src/components/ExerciseAiSuggestPreviewModal.jsx +++ b/frontend/src/components/ExerciseAiSuggestPreviewModal.jsx @@ -21,6 +21,7 @@ export default function ExerciseAiSuggestPreviewModal({ applyLabel = 'Übung anlegen', applyDisabled = false, zIndex = 2000, + planningContextLines = [], }) { useEffect(() => { if (!draft) return undefined @@ -86,6 +87,31 @@ export default function ExerciseAiSuggestPreviewModal({

{dialogTitle}

{hint}

+ {Array.isArray(planningContextLines) && planningContextLines.length > 0 ? ( +
+ + Planungskontext (an KI übergeben) + +
+ {planningContextLines.map(({ label, value }) => ( +
+
{label}
+
{value}
+
+ ))} +
+
+ ) : null} +