j-js commited on
Commit
2da67ff
·
verified ·
1 Parent(s): 70a705d

Create conversation_logic.py

Browse files
Files changed (1) hide show
  1. conversation_logic.py +207 -0
conversation_logic.py ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ from context_parser import (
4
+ mentions_choice_letter,
5
+ parse_hidden_context,
6
+ user_is_referring_to_existing_question,
7
+ )
8
+ from formatting import format_reply
9
+ from models import SolverResult
10
+ from quant_solver import extract_choices, is_quant_question, solve_quant
11
+
12
+
13
+ def build_choice_explanation(chosen_letter: str, result: SolverResult, choices: dict[str, str], help_mode: str) -> str:
14
+ choice_text = choices.get(chosen_letter, "").strip()
15
+ value_text = result.answer_value.strip() if result.answer_value else ""
16
+
17
+ if help_mode == "hint":
18
+ if value_text and choice_text:
19
+ return f"Work out the value first, then compare it with choice {chosen_letter} ({choice_text})."
20
+ if choice_text:
21
+ return f"Focus on why choice {chosen_letter} fits the calculation better than the others."
22
+ return f"Focus on why choice {chosen_letter} matches the calculation."
23
+
24
+ if help_mode == "walkthrough":
25
+ if value_text and choice_text:
26
+ return (
27
+ f"The calculation gives {value_text}.\n"
28
+ f"Choice {chosen_letter} is {choice_text}, so it matches.\n"
29
+ f"That is why {chosen_letter} is the correct answer."
30
+ )
31
+ if choice_text:
32
+ return f"Choice {chosen_letter} matches the result of the calculation, so that is why it is correct."
33
+ return f"The solved result matches choice {chosen_letter}, so that is why it is correct."
34
+
35
+ if value_text and choice_text:
36
+ return f"Yes — it’s {chosen_letter}, because the calculation gives {value_text}, and choice {chosen_letter} is {choice_text}."
37
+ if choice_text:
38
+ return f"Yes — it’s {chosen_letter}, because that option matches the result."
39
+ return f"Yes — it’s {chosen_letter}."
40
+
41
+
42
+ def handle_conversational_followup(ctx, help_mode: str):
43
+ user_text = ctx.visible_user_text
44
+ lower = user_text.lower().strip()
45
+ question_block = ctx.combined_question_block
46
+
47
+ if not question_block:
48
+ return None
49
+
50
+ if not user_is_referring_to_existing_question(user_text, ctx.question_text):
51
+ return None
52
+
53
+ solved = solve_quant(question_block, "answer")
54
+
55
+ asked_letter = mentions_choice_letter(user_text)
56
+ choices = extract_choices(question_block)
57
+
58
+ if asked_letter and solved.answer_letter and asked_letter == solved.answer_letter:
59
+ reply = build_choice_explanation(asked_letter, solved, choices, help_mode)
60
+ return SolverResult(
61
+ reply=reply,
62
+ domain="quant",
63
+ solved=solved.solved,
64
+ help_mode=help_mode,
65
+ answer_letter=solved.answer_letter,
66
+ answer_value=solved.answer_value,
67
+ )
68
+
69
+ if asked_letter and solved.answer_letter and asked_letter != solved.answer_letter:
70
+ correct_choice_text = choices.get(solved.answer_letter, "").strip()
71
+ if help_mode == "hint":
72
+ reply = f"Check the calculation again and compare your result with choice {solved.answer_letter}, not {asked_letter}."
73
+ elif help_mode == "walkthrough":
74
+ reply = (
75
+ f"It is not {asked_letter}.\n"
76
+ f"The calculation leads to choice {solved.answer_letter}"
77
+ + (f", which is {correct_choice_text}." if correct_choice_text else ".")
78
+ )
79
+ else:
80
+ reply = f"It is not {asked_letter} — the correct choice is {solved.answer_letter}."
81
+ return SolverResult(
82
+ reply=reply,
83
+ domain="quant",
84
+ solved=solved.solved,
85
+ help_mode=help_mode,
86
+ answer_letter=solved.answer_letter,
87
+ answer_value=solved.answer_value,
88
+ )
89
+
90
+ if lower in {"help", "can you help", "help me", "i dont get it", "i don't get it"}:
91
+ if help_mode == "hint":
92
+ reply = solve_quant(question_block, "hint").reply
93
+ elif help_mode == "walkthrough":
94
+ reply = solve_quant(question_block, "walkthrough").reply
95
+ else:
96
+ reply = solve_quant(question_block, "answer").reply
97
+ return SolverResult(
98
+ reply=reply,
99
+ domain="quant",
100
+ solved=solved.solved,
101
+ help_mode=help_mode,
102
+ answer_letter=solved.answer_letter,
103
+ answer_value=solved.answer_value,
104
+ )
105
+
106
+ if "first step" in lower or "how do i start" in lower or "what do i do first" in lower:
107
+ hint_result = solve_quant(question_block, "hint")
108
+ return SolverResult(
109
+ reply=hint_result.reply,
110
+ domain="quant",
111
+ solved=hint_result.solved,
112
+ help_mode="hint",
113
+ answer_letter=hint_result.answer_letter,
114
+ answer_value=hint_result.answer_value,
115
+ )
116
+
117
+ if "why" in lower or "explain" in lower:
118
+ walkthrough_result = solve_quant(question_block, "walkthrough")
119
+ if solved.answer_letter and "why is it" not in lower:
120
+ choices = extract_choices(question_block)
121
+ choice_text = choices.get(solved.answer_letter, "").strip()
122
+ if choice_text:
123
+ extra = f"\n\nSo the correct choice is {solved.answer_letter} ({choice_text})."
124
+ else:
125
+ extra = f"\n\nSo the correct choice is {solved.answer_letter}."
126
+ walkthrough_result.reply += extra
127
+ return walkthrough_result
128
+
129
+ if "hint" in lower:
130
+ return solve_quant(question_block, "hint")
131
+
132
+ if "answer" in lower or "which one" in lower or "are you sure" in lower:
133
+ return solve_quant(question_block, "answer")
134
+
135
+ return None
136
+
137
+
138
+ def solve_verbal_or_general(user_text: str, help_mode: str) -> SolverResult:
139
+ lower = user_text.lower()
140
+
141
+ if any(k in lower for k in ["sentence correction", "grammar", "verbal", "critical reasoning", "reading comprehension"]):
142
+ if help_mode == "hint":
143
+ reply = (
144
+ "First identify the task:\n"
145
+ "- Sentence Correction: grammar + meaning\n"
146
+ "- Critical Reasoning: conclusion, evidence, assumption\n"
147
+ "- Reading Comprehension: passage role, inference, detail"
148
+ )
149
+ elif help_mode == "walkthrough":
150
+ reply = (
151
+ "I can help verbally too, but for now this backend is strongest on quant-style items. "
152
+ "For verbal, I’d use elimination based on grammar, logic, scope, or passage support."
153
+ )
154
+ else:
155
+ reply = "I can help with verbal strategy, but this version is strongest on quant-style questions right now."
156
+
157
+ return SolverResult(reply=reply, domain="verbal", solved=False, help_mode=help_mode)
158
+
159
+ if help_mode == "hint":
160
+ reply = "I can help. Ask for a hint, an explanation, or the answer, and I’ll use the current in-game question context when available."
161
+ elif help_mode == "walkthrough":
162
+ reply = "I can talk it through step by step using the current in-game question context."
163
+ else:
164
+ reply = "Send a message naturally and I’ll respond using the current question context."
165
+
166
+ return SolverResult(reply=reply, domain="fallback", solved=False, help_mode=help_mode)
167
+
168
+
169
+ def generate_response(
170
+ raw_user_text: str,
171
+ tone: float,
172
+ verbosity: float,
173
+ transparency: float,
174
+ help_mode: str,
175
+ ) -> SolverResult:
176
+ ctx = parse_hidden_context(raw_user_text)
177
+ visible_user_text = ctx.visible_user_text.strip()
178
+ question_block = ctx.combined_question_block.strip()
179
+
180
+ if not raw_user_text.strip():
181
+ result = SolverResult(
182
+ reply="Ask a question and I’ll help using the current in-game context.",
183
+ domain="fallback",
184
+ solved=False,
185
+ help_mode=help_mode,
186
+ )
187
+ result.reply = format_reply(result.reply, tone, verbosity, transparency, help_mode)
188
+ return result
189
+
190
+ followup = handle_conversational_followup(ctx, help_mode)
191
+ if followup is not None:
192
+ followup.reply = format_reply(followup.reply, tone, verbosity, transparency, followup.help_mode)
193
+ return followup
194
+
195
+ if question_block and is_quant_question(question_block):
196
+ result = solve_quant(question_block, help_mode)
197
+ result.reply = format_reply(result.reply, tone, verbosity, transparency, help_mode)
198
+ return result
199
+
200
+ if is_quant_question(visible_user_text):
201
+ result = solve_quant(visible_user_text, help_mode)
202
+ result.reply = format_reply(result.reply, tone, verbosity, transparency, help_mode)
203
+ return result
204
+
205
+ result = solve_verbal_or_general(visible_user_text or raw_user_text, help_mode)
206
+ result.reply = format_reply(result.reply, tone, verbosity, transparency, help_mode)
207
+ return result