shinkan-jinkendo/backend/tests/test_planning_exercise_suggest.py
Lars 45e3b5f4f6
All checks were successful
Deploy Development / deploy (push) Successful in 43s
Test Suite / pytest-backend (push) Successful in 43s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 13s
Test Suite / k6 /health Baseline (push) Successful in 34s
Test Suite / playwright-tests (push) Successful in 1m14s
Implement Phase 1 of Planning Exercise Suggestion with Scenario Pipeline and LLM Intent Overlay
- Introduced the Scenario Pipeline for planning exercises, allowing for more nuanced query handling and exercise suggestions based on user intent.
- Enhanced the `suggestPlanningExercises` API to include `include_llm_intent`, `scenario_kind`, and `query_intent_summary`, improving the context provided to the frontend.
- Updated the `ExercisePickerModal` to display new information related to query intent and scenario classification, enhancing user experience during exercise selection.
- Incremented application version to 0.8.171 and updated changelog to document the new features and improvements in the planning AI capabilities.
2026-05-22 22:15:19 +02:00

72 lines
2.9 KiB
Python

"""Tests Planungs-Übungssuche: Intent, Szenario-Pipeline, LLM-Parser."""
from planning_exercise_suggest import resolve_planning_exercise_intent
from planning_exercise_intent import parse_planning_query_intent_response
from planning_exercise_llm_rank import parse_planning_exercise_rank_response
from planning_exercise_target_pipeline import (
SCENARIO_ADDITIVE,
SCENARIO_PRESET_NEXT,
classify_planning_scenario,
compose_retrieval_phase,
is_simple_preset_query,
should_run_llm_intent_pipeline,
)
def test_resolve_planning_exercise_intent_defaults():
assert resolve_planning_exercise_intent("", None) == "suggest_next"
assert resolve_planning_exercise_intent(" ", "suggest_next") == "suggest_next"
def test_resolve_planning_exercise_intent_keywords():
assert resolve_planning_exercise_intent("Vertiefung Partner", None) == "deepen_exercise"
assert resolve_planning_exercise_intent("nächste übung", None) == "suggest_next"
assert resolve_planning_exercise_intent("progression graph", None) == "progression_next"
def test_classify_planning_scenario_preset():
assert is_simple_preset_query("Schlage mir die nächste Übung vor")
assert classify_planning_scenario("", "suggest_next") == SCENARIO_PRESET_NEXT
assert classify_planning_scenario("nächste übung", "suggest_next") == SCENARIO_PRESET_NEXT
def test_classify_planning_scenario_additive():
q = "Baut auf der Planung auf und trainiert zusätzlich Schnellkraft"
assert classify_planning_scenario(q, "continue_plan_goal") == SCENARIO_ADDITIVE
assert should_run_llm_intent_pipeline(q, SCENARIO_ADDITIVE, include_llm_intent=True)
def test_should_skip_llm_for_preset():
assert not should_run_llm_intent_pipeline("", SCENARIO_PRESET_NEXT, include_llm_intent=True)
assert not should_run_llm_intent_pipeline(
"nächste übung",
SCENARIO_PRESET_NEXT,
include_llm_intent=True,
)
def test_compose_retrieval_phase():
assert compose_retrieval_phase(query_intent=False, llm_rank=False) == "profile_v1"
assert compose_retrieval_phase(query_intent=True, llm_rank=True) == "profile_v1+query_intent+llm_rank"
def test_parse_planning_query_intent_response():
parsed = parse_planning_query_intent_response(
'{"intent":"continue_plan_goal","scenario":"additive_constraint",'
'"skill_hints":[{"name":"Schnellkraft","weight":1}],"emphasis":"additive",'
'"rationale":"Zusatz Schnellkraft"}'
)
assert parsed.intent == "continue_plan_goal"
assert parsed.scenario == "additive_constraint"
assert parsed.skill_hints[0].name == "Schnellkraft"
def test_parse_planning_exercise_rank_response_filters_ids():
allowed = {10, 20, 30}
ranked, reasons = parse_planning_exercise_rank_response(
'{"ranked_ids":[20,999,20,10],"reasons":{"20":"Passt gut","999":"ignore"}}',
allowed,
)
assert ranked == [20, 10]
assert reasons[20] == "Passt gut"
assert 999 not in reasons