j-js commited on
Commit
d4ad9bd
·
verified ·
1 Parent(s): 48bbfa8

Update conversation_logic.py

Browse files
Files changed (1) hide show
  1. conversation_logic.py +40 -128
conversation_logic.py CHANGED
@@ -55,6 +55,16 @@ FOLLOWUP_ONLY_INPUTS = {
55
  "can i have a hint",
56
  "next hint",
57
  "another hint",
 
 
 
 
 
 
 
 
 
 
58
  "next step",
59
  "continue",
60
  "go on",
@@ -293,8 +303,6 @@ def _classify_input_type(raw_user_text: str) -> str:
293
  "first step",
294
  "where do i start",
295
  "how should i start",
296
- "give me a hint",
297
- "can i have a hint",
298
  ]
299
  ):
300
  return "hint"
@@ -302,19 +310,18 @@ def _classify_input_type(raw_user_text: str) -> str:
302
  if text in {"hint", "a hint", "give me a hint", "can i have a hint"} or text.startswith("hint:"):
303
  return "hint"
304
  if any(
305
- p in text
306
- for p in [
307
  "next hint",
308
  "another hint",
309
  "more hint",
310
  "more hints",
311
  "second hint",
312
  "third hint",
313
- "fourth hint",
314
  "second next hint",
315
- "next step",
316
  "what do i do next",
317
  "what should i do next",
 
318
  "continue",
319
  "go on",
320
  ]
@@ -624,87 +631,6 @@ def _looks_like_simple_linear_equation(question_text: str) -> bool:
624
  )
625
 
626
 
627
- def _extract_simple_linear_equation_hint_data(question_text: str) -> Optional[Dict[str, Any]]:
628
- q = _clean_text(question_text)
629
- if not q:
630
- return None
631
-
632
- low = q.lower().replace("−", "-").replace("–", "-")
633
- low = re.sub(r"\s+", " ", low)
634
- var_match = re.search(r"\bwhat is\s+([a-z])\b", low)
635
- if not var_match:
636
- return None
637
- var = var_match.group(1)
638
-
639
- eq_match = re.search(
640
- rf"([+-]?\d*)\s*{var}\s*([+-])\s*(\d+(?:\.\d+)?)\s*=\s*([+-]?\d+(?:\.\d+)?)",
641
- low,
642
- )
643
- if not eq_match:
644
- eq_match = re.search(
645
- rf"([+-]?\d+(?:\.\d+)?)\s*([+-])\s*([+-]?\d*)\s*{var}\s*=\s*([+-]?\d+(?:\.\d+)?)",
646
- low,
647
- )
648
- if not eq_match:
649
- return None
650
- constant = eq_match.group(1)
651
- op = eq_match.group(2)
652
- coeff_raw = eq_match.group(3)
653
- rhs = eq_match.group(4)
654
- else:
655
- coeff_raw = eq_match.group(1)
656
- op = eq_match.group(2)
657
- constant = eq_match.group(3)
658
- rhs = eq_match.group(4)
659
-
660
- if coeff_raw in {"", "+", None}:
661
- coeff = 1.0
662
- elif coeff_raw == "-":
663
- coeff = -1.0
664
- else:
665
- try:
666
- coeff = float(coeff_raw)
667
- except Exception:
668
- return None
669
-
670
- try:
671
- const_val = float(constant)
672
- rhs_val = float(rhs)
673
- except Exception:
674
- return None
675
-
676
- first_inverse = "add" if op == "-" else "subtract"
677
- after_inverse = rhs_val + const_val if op == "-" else rhs_val - const_val
678
- second_inverse = "divide" if abs(coeff) != 1 else "keep"
679
- final_value = after_inverse / coeff if coeff != 0 else None
680
-
681
- def _fmt_num(value: float) -> str:
682
- try:
683
- if float(value).is_integer():
684
- return str(int(value))
685
- except Exception:
686
- pass
687
- return str(value)
688
-
689
- return {
690
- "variable": var,
691
- "coefficient": coeff,
692
- "constant": const_val,
693
- "rhs": rhs_val,
694
- "operator": op,
695
- "first_inverse": first_inverse,
696
- "after_inverse": after_inverse,
697
- "second_inverse": second_inverse,
698
- "final_value": final_value,
699
- "equation_text": f"{_fmt_num(coeff)}{var} {op} {_fmt_num(const_val)} = {_fmt_num(rhs_val)}",
700
- "coefficient_text": _fmt_num(coeff),
701
- "constant_text": _fmt_num(const_val),
702
- "rhs_text": _fmt_num(rhs_val),
703
- "after_inverse_text": _fmt_num(after_inverse),
704
- "final_value_text": _fmt_num(final_value) if final_value is not None else None,
705
- }
706
-
707
-
708
  def _question_specific_ratio_reply(question_text: str) -> str:
709
  q = _clean_text(question_text)
710
  low = q.lower()
@@ -968,18 +894,6 @@ def _question_specific_hint_ladder(
968
  topic = (classified_topic or "general").lower()
969
 
970
  if _looks_like_simple_linear_equation(q) or topic == "algebra":
971
- eq_data = _extract_simple_linear_equation_hint_data(q)
972
- if eq_data:
973
- var = eq_data["variable"]
974
- constant_text = eq_data["constant_text"]
975
- rhs_text = eq_data["rhs_text"]
976
- after_inverse_text = eq_data["after_inverse_text"]
977
- coefficient_text = eq_data["coefficient_text"]
978
- return [
979
- f"Focus on the constant term attached to the variable side: {eq_data['operator']} {constant_text}.",
980
- f"Undo that first by {eq_data['first_inverse']}ing {constant_text} on both sides, which changes the right side from {rhs_text} to {after_inverse_text}.",
981
- f"Then divide both sides by {coefficient_text} so {var} stands alone.",
982
- ]
983
  return [
984
  "Look at the variable side and ask which operation is furthest away from the variable.",
985
  "Undo the addition or subtraction first by doing the opposite on both sides.",
@@ -1140,8 +1054,14 @@ def _should_prefer_question_support(help_mode: str, fallback_pack: Dict[str, Any
1140
  if not fallback_pack:
1141
  return False
1142
  support_source = str(fallback_pack.get("support_source", "")).strip().lower()
1143
- has_specific_content = support_source in {"question_bank", "question_id", "question_text"}
1144
- if help_mode in {"hint", "walkthrough", "instruction", "step_by_step", "explain"}:
 
 
 
 
 
 
1145
  return has_specific_content or bool(fallback_pack)
1146
  return False
1147
 
@@ -1323,7 +1243,7 @@ class ConversationEngine:
1323
  result.help_mode = resolved_help_mode
1324
  result.meta = result.meta or {}
1325
  result.meta["hint_stage"] = hint_stage
1326
- result.meta["max_stage"] = 3
1327
  result.meta["recovered_question_text"] = solver_input
1328
  result.meta["question_id"] = question_id
1329
  result.meta["classified_topic"] = question_topic if question_topic else "general"
@@ -1401,14 +1321,21 @@ class ConversationEngine:
1401
  if input_type in {"hint", "next_hint"}:
1402
  hint_lines: List[str] = []
1403
 
1404
- custom_ladder = _question_specific_hint_ladder(
1405
- question_text=solver_input,
1406
- options_text=options_text,
1407
- classified_topic=question_topic,
1408
- )
1409
- if custom_ladder:
1410
- idx = min(max(hint_stage - 1, 0), len(custom_ladder) - 1)
1411
- hint_lines = [custom_ladder[idx]]
 
 
 
 
 
 
 
1412
 
1413
  if not hint_lines and explainer_scaffold:
1414
  ladder = _safe_meta_list(explainer_scaffold.get("hint_ladder", []))
@@ -1423,12 +1350,6 @@ class ConversationEngine:
1423
  elif next_hint_text:
1424
  hint_lines = [next_hint_text]
1425
 
1426
- if not hint_lines and fallback_pack:
1427
- fallback_hints = _safe_meta_list(fallback_pack.get("hint_ladder", []))
1428
- if fallback_hints:
1429
- idx = min(max(hint_stage - 1, 0), len(fallback_hints) - 1)
1430
- hint_lines = [fallback_hints[idx]]
1431
-
1432
  if not hint_lines and fallback_reply_core:
1433
  split_lines = [line.strip("- ").strip() for line in fallback_reply_core.splitlines() if line.strip()]
1434
  if split_lines:
@@ -1456,18 +1377,7 @@ class ConversationEngine:
1456
 
1457
  elif question_specific_reply_core and (
1458
  input_type not in {"hint", "next_hint"}
1459
- and not any(
1460
- phrase in _clean_text(user_text).lower()
1461
- for phrase in [
1462
- "next hint",
1463
- "another hint",
1464
- "what do i do next",
1465
- "what should i do next",
1466
- "next step",
1467
- "continue",
1468
- "go on",
1469
- ]
1470
- )
1471
  and (
1472
  _is_help_first_mode(resolved_help_mode)
1473
  or input_type in {"other", "confusion"}
@@ -1477,6 +1387,8 @@ class ConversationEngine:
1477
  "how do i solve",
1478
  "what do i do first",
1479
  "what should i do first",
 
 
1480
  "how should i start",
1481
  ]
1482
  )
 
55
  "can i have a hint",
56
  "next hint",
57
  "another hint",
58
+ "more hint",
59
+ "more hints",
60
+ "second hint",
61
+ "third hint",
62
+ "second next hint",
63
+ "what do i do first",
64
+ "what should i do first",
65
+ "what do i do next",
66
+ "what should i do next",
67
+ "first step",
68
  "next step",
69
  "continue",
70
  "go on",
 
303
  "first step",
304
  "where do i start",
305
  "how should i start",
 
 
306
  ]
307
  ):
308
  return "hint"
 
310
  if text in {"hint", "a hint", "give me a hint", "can i have a hint"} or text.startswith("hint:"):
311
  return "hint"
312
  if any(
313
+ phrase in text
314
+ for phrase in [
315
  "next hint",
316
  "another hint",
317
  "more hint",
318
  "more hints",
319
  "second hint",
320
  "third hint",
 
321
  "second next hint",
 
322
  "what do i do next",
323
  "what should i do next",
324
+ "next step",
325
  "continue",
326
  "go on",
327
  ]
 
631
  )
632
 
633
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
634
  def _question_specific_ratio_reply(question_text: str) -> str:
635
  q = _clean_text(question_text)
636
  low = q.lower()
 
894
  topic = (classified_topic or "general").lower()
895
 
896
  if _looks_like_simple_linear_equation(q) or topic == "algebra":
 
 
 
 
 
 
 
 
 
 
 
 
897
  return [
898
  "Look at the variable side and ask which operation is furthest away from the variable.",
899
  "Undo the addition or subtraction first by doing the opposite on both sides.",
 
1054
  if not fallback_pack:
1055
  return False
1056
  support_source = str(fallback_pack.get("support_source", "")).strip().lower()
1057
+ has_specific_content = support_source in {
1058
+ "question_bank",
1059
+ "question_bank_refined",
1060
+ "question_id",
1061
+ "question_text",
1062
+ "generated_question_specific",
1063
+ }
1064
+ if help_mode in {"hint", "walkthrough", "instruction", "step_by_step", "explain", "method"}:
1065
  return has_specific_content or bool(fallback_pack)
1066
  return False
1067
 
 
1243
  result.help_mode = resolved_help_mode
1244
  result.meta = result.meta or {}
1245
  result.meta["hint_stage"] = hint_stage
1246
+ result.meta["max_stage"] = 4
1247
  result.meta["recovered_question_text"] = solver_input
1248
  result.meta["question_id"] = question_id
1249
  result.meta["classified_topic"] = question_topic if question_topic else "general"
 
1321
  if input_type in {"hint", "next_hint"}:
1322
  hint_lines: List[str] = []
1323
 
1324
+ if fallback_pack:
1325
+ fallback_hints = _safe_meta_list(fallback_pack.get("hint_ladder", []))
1326
+ if fallback_hints:
1327
+ idx = min(max(hint_stage - 1, 0), len(fallback_hints) - 1)
1328
+ hint_lines = [fallback_hints[idx]]
1329
+
1330
+ if not hint_lines:
1331
+ custom_ladder = _question_specific_hint_ladder(
1332
+ question_text=solver_input,
1333
+ options_text=options_text,
1334
+ classified_topic=question_topic,
1335
+ )
1336
+ if custom_ladder:
1337
+ idx = min(max(hint_stage - 1, 0), len(custom_ladder) - 1)
1338
+ hint_lines = [custom_ladder[idx]]
1339
 
1340
  if not hint_lines and explainer_scaffold:
1341
  ladder = _safe_meta_list(explainer_scaffold.get("hint_ladder", []))
 
1350
  elif next_hint_text:
1351
  hint_lines = [next_hint_text]
1352
 
 
 
 
 
 
 
1353
  if not hint_lines and fallback_reply_core:
1354
  split_lines = [line.strip("- ").strip() for line in fallback_reply_core.splitlines() if line.strip()]
1355
  if split_lines:
 
1377
 
1378
  elif question_specific_reply_core and (
1379
  input_type not in {"hint", "next_hint"}
1380
+ and not (prefer_question_support and fallback_reply_core)
 
 
 
 
 
 
 
 
 
 
 
1381
  and (
1382
  _is_help_first_mode(resolved_help_mode)
1383
  or input_type in {"other", "confusion"}
 
1387
  "how do i solve",
1388
  "what do i do first",
1389
  "what should i do first",
1390
+ "what do i do next",
1391
+ "what should i do next",
1392
  "how should i start",
1393
  ]
1394
  )