Implement nested question remediation and review content

This commit is contained in:
hz
2026-07-16 21:46:56 -05:00
parent 0f5a1122d4
commit c8bfc26645
14 changed files with 1339 additions and 245 deletions
+12
View File
@@ -8,6 +8,7 @@ var current_index := 0
var mode := "Tutor"
var system_name := "All Systems"
var seconds_remaining := 0.0
var session_initial_seconds := 0.0
var block_started := false
var session_kind := "block"
var core_question_pool: Array = []
@@ -39,6 +40,7 @@ func start_block(selected_system: String, block_size: int, selected_mode: String
answers.resize(active_questions.size())
current_index = 0
seconds_remaining = float(active_questions.size() * 90)
session_initial_seconds = seconds_remaining
block_started = true
session_changed.emit()
@@ -52,6 +54,7 @@ func start_core_run() -> bool:
core_question_pool.clear()
current_index = -1
seconds_remaining = 0.0
session_initial_seconds = core_current_target_seconds
block_started = true
core_answer_count = 0
core_score = 0
@@ -82,6 +85,7 @@ func start_simulation_block(questions: Array, block_index: int, total_blocks: in
simulation_total_blocks = total_blocks
simulation_deadline_unix = deadline_unix
seconds_remaining = maxf(0.0, deadline_unix - Time.get_unix_time_from_system())
session_initial_seconds = maxf(seconds_remaining, float(active_questions.size() * 90))
block_started = true
current_question_started_at = Time.get_ticks_msec() / 1000.0
session_changed.emit()
@@ -335,6 +339,14 @@ func get_core_timer_ratio() -> float:
return clamp(ratio, 0.0, 1.0)
func get_session_timer_ratio() -> float:
if session_kind == "core":
return get_core_timer_ratio()
if session_initial_seconds <= 0.0:
return 1.0
return clamp(seconds_remaining / session_initial_seconds, 0.0, 1.0)
func pause_current_question_timer() -> void:
if session_kind == "core" and current_question_pause_started_at <= 0.0:
current_question_pause_started_at = Time.get_ticks_msec() / 1000.0
+19
View File
@@ -652,6 +652,9 @@ func _normalize_api_question(item: Variant) -> Dictionary:
"choices": item.get("choices", []),
"correct_choice_id": str(item.get("correctChoiceId", item.get("correct_choice_id", ""))),
"explanation": str(item.get("explanation", "")),
"key_takeaway": str(item.get("keyTakeaway", item.get("key_takeaway", ""))),
"usmle_pearl": str(item.get("usmlePearl", item.get("usmle_pearl", ""))),
"review_followups": _normalize_review_followups(item.get("reviewFollowups", item.get("review_followups", []))),
"choice_explanations": item.get("choiceExplanations", item.get("choice_explanations", {})),
"wrong_answer_followups": item.get("wrongAnswerFollowups", item.get("wrong_answer_followups", {})),
"choice_selection_percentages": item.get("choiceSelectionPercentages", item.get("choice_selection_percentages", {})),
@@ -668,6 +671,22 @@ func _normalize_api_question(item: Variant) -> Dictionary:
return normalized
func _normalize_review_followups(raw_followups: Variant) -> Array:
var normalized: Array = []
if typeof(raw_followups) != TYPE_ARRAY:
return normalized
for raw_followup in raw_followups:
if typeof(raw_followup) != TYPE_DICTIONARY:
continue
normalized.append({
"prompt": str(raw_followup.get("prompt", "")).strip_edges(),
"choices": raw_followup.get("choices", []),
"correct_choice_id": str(raw_followup.get("correctChoiceId", raw_followup.get("correct_choice_id", ""))),
"teaching_point": str(raw_followup.get("teachingPoint", raw_followup.get("teaching_point", ""))).strip_edges()
})
return normalized
func _normalize_references(raw_references: Variant) -> Array:
var normalized: Array = []
if typeof(raw_references) != TYPE_ARRAY: