j-js commited on
Commit
1c8257c
·
verified ·
1 Parent(s): 1460fe5

Update conversation_logic.py

Browse files
Files changed (1) hide show
  1. conversation_logic.py +121 -256
conversation_logic.py CHANGED
@@ -35,64 +35,26 @@ DIRECT_SOLVE_PATTERNS = [
35
 
36
  STRUCTURE_KEYWORDS = {
37
  "algebra": [
38
- "equation",
39
- "solve",
40
- "isolate",
41
- "variable",
42
- "linear",
43
- "expression",
44
- "unknown",
45
- "algebra",
46
- "substitute",
47
- "rearrange",
48
  ],
49
  "percent": [
50
- "percent",
51
- "%",
52
- "percentage",
53
- "increase",
54
- "decrease",
55
- "of",
56
  ],
57
  "ratio": [
58
- "ratio",
59
- "proportion",
60
- "proportional",
61
- "part",
62
- "share",
63
  ],
64
  "statistics": [
65
- "mean",
66
- "median",
67
- "mode",
68
- "range",
69
- "average",
70
- "standard deviation",
71
  ],
72
  "probability": [
73
- "probability",
74
- "chance",
75
- "likely",
76
- "odds",
77
- "event",
78
  ],
79
  "geometry": [
80
- "triangle",
81
- "circle",
82
- "angle",
83
- "area",
84
- "perimeter",
85
- "radius",
86
- "diameter",
87
  ],
88
  "number_properties": [
89
- "integer",
90
- "odd",
91
- "even",
92
- "prime",
93
- "divisible",
94
- "factor",
95
- "multiple",
96
  ],
97
  }
98
 
@@ -109,45 +71,26 @@ INTENT_KEYWORDS = {
109
 
110
  MISMATCH_TERMS = {
111
  "algebra": [
112
- "absolute value",
113
- "modulus",
114
- "square root",
115
- "quadratic",
116
- "inequality",
117
- "roots",
118
- "parabola",
119
- "simultaneous equations",
120
  ],
121
  "percent": [
122
- "triangle",
123
- "circle",
124
- "prime",
125
- "absolute value",
126
  ],
127
  "ratio": [
128
- "absolute value",
129
- "quadratic",
130
- "circle",
131
  ],
132
  "statistics": [
133
- "absolute value",
134
- "prime",
135
- "triangle",
136
  ],
137
  "probability": [
138
- "absolute value",
139
- "circle area",
140
- "quadratic",
141
  ],
142
  "geometry": [
143
- "absolute value",
144
- "prime",
145
- "median salary",
146
  ],
147
  "number_properties": [
148
- "circle",
149
- "triangle",
150
- "absolute value",
151
  ],
152
  }
153
 
@@ -361,7 +304,7 @@ def _build_retrieval_query(
361
  ) -> str:
362
  parts: List[str] = []
363
 
364
- base = question_text.strip() if (question_text or "").strip() else (raw_user_text or "").strip()
365
  if base:
366
  parts.append(base)
367
 
@@ -382,144 +325,15 @@ def _build_retrieval_query(
382
  return " ".join(parts).strip()
383
 
384
 
385
- def generate_response(
386
- raw_user_text: str,
387
- tone: float = 0.5,
388
- verbosity: float = 0.5,
389
- transparency: float = 0.5,
390
- retrieval_engine: Optional[RetrievalEngine] = None,
391
- generator_engine: Optional[GeneratorEngine] = None,
392
- retrieval_context: Optional[List[RetrievedChunk]] = None,
393
- chat_history: Optional[List[Dict[str, Any]]] = None,
394
- question_text: Optional[str] = None,
395
- ) -> Dict[str, Any]:
396
- solver_input = (question_text or raw_user_text or "").strip()
397
- user_text = (raw_user_text or "").strip()
398
-
399
- intent = detect_intent(user_text)
400
- help_mode = intent_to_help_mode(intent)
401
- reveal_answer = help_mode == "answer" or transparency >= 0.8
402
-
403
- result = SolverResult(
404
- domain="general",
405
- solved=False,
406
- help_mode=help_mode,
407
- answer_letter=None,
408
- answer_value=None,
409
- topic=None,
410
- used_retrieval=False,
411
- used_generator=False,
412
- internal_answer=None,
413
- steps=[],
414
- teaching_chunks=[],
415
- meta={},
416
- )
417
-
418
- selected_chunks: List[RetrievedChunk] = []
419
-
420
- if is_quant_question(solver_input):
421
- result = solve_quant(solver_input)
422
- if not result.help_mode:
423
- result.help_mode = help_mode
424
-
425
- reply = _compose_quant_reply(
426
- result=result,
427
- intent=intent,
428
- reveal_answer=reveal_answer,
429
- verbosity=verbosity,
430
- )
431
-
432
- allow_retrieval = should_retrieve(
433
- intent=intent,
434
- solved=bool(result.solved),
435
- raw_user_text=user_text or solver_input,
436
- )
437
-
438
- if allow_retrieval and retrieval_context:
439
- filtered = _filter_retrieved_chunks(
440
- chunks=retrieval_context,
441
- intent=intent,
442
- topic=result.topic,
443
- question_text=solver_input,
444
- )
445
- if filtered:
446
- selected_chunks = filtered
447
- result.used_retrieval = True
448
- result.teaching_chunks = filtered
449
-
450
- elif allow_retrieval and retrieval_engine is not None:
451
- query = _build_retrieval_query(
452
- raw_user_text=user_text,
453
- question_text=solver_input,
454
- intent=intent,
455
- topic=result.topic,
456
- solved=bool(result.solved),
457
- )
458
- retrieved = retrieval_engine.search(query, top_k=6)
459
- filtered = _filter_retrieved_chunks(
460
- chunks=retrieved,
461
- intent=intent,
462
- topic=result.topic,
463
- question_text=solver_input,
464
- )
465
- if filtered:
466
- selected_chunks = filtered
467
- result.used_retrieval = True
468
- result.teaching_chunks = filtered
469
-
470
- if selected_chunks:
471
- reply = f"{reply}\n\nRelevant study notes:\n" + "\n".join(_teaching_lines(selected_chunks))
472
-
473
- if not result.solved and generator_engine is not None:
474
- try:
475
- generated = generator_engine.generate(
476
- user_text=user_text or solver_input,
477
- intent=intent,
478
- topic=result.topic,
479
- chat_history=chat_history or [],
480
- )
481
- if generated and generated.strip():
482
- reply = generated.strip()
483
- result.used_generator = True
484
- except Exception:
485
- pass
486
-
487
- reply = format_reply(
488
- text=reply,
489
- tone=tone,
490
- verbosity=verbosity,
491
- transparency=transparency,
492
- )
493
-
494
- result.reply = short_lines(reply)
495
- result.help_mode = help_mode
496
-
497
- return {
498
- "reply": result.reply,
499
- "meta": {
500
- "domain": result.domain,
501
- "solved": result.solved,
502
- "help_mode": result.help_mode,
503
- "answer_letter": result.answer_letter,
504
- "answer_value": result.answer_value,
505
- "topic": result.topic,
506
- "used_retrieval": result.used_retrieval,
507
- "used_generator": result.used_generator,
508
- },
509
- }
510
-
511
-
512
  class ConversationEngine:
513
  def __init__(
514
  self,
515
  retriever: Optional[RetrievalEngine] = None,
516
  generator: Optional[GeneratorEngine] = None,
517
- retrieval_engine: Optional[RetrievalEngine] = None,
518
- generator_engine: Optional[GeneratorEngine] = None,
519
  **kwargs,
520
  ) -> None:
521
- self.retrieval_engine = retrieval_engine or retriever
522
- self.generator_engine = generator_engine or generator
523
 
524
  def generate_response(
525
  self,
@@ -527,66 +341,117 @@ class ConversationEngine:
527
  tone: float = 0.5,
528
  verbosity: float = 0.5,
529
  transparency: float = 0.5,
 
 
530
  retrieval_context: Optional[List[RetrievedChunk]] = None,
531
  chat_history: Optional[List[Dict[str, Any]]] = None,
532
  question_text: Optional[str] = None,
533
- message: Optional[str] = None,
534
- prompt: Optional[str] = None,
535
- query: Optional[str] = None,
536
- text: Optional[str] = None,
537
- user_message: Optional[str] = None,
538
  **kwargs,
539
- ) -> Dict[str, Any]:
540
- resolved_text = (
541
- raw_user_text
542
- or message
543
- or prompt
544
- or query
545
- or text
546
- or user_message
547
- or ""
 
 
 
 
 
 
 
 
 
 
 
 
548
  )
549
 
550
- return generate_response(
551
- raw_user_text=resolved_text,
552
- tone=tone,
 
 
 
 
 
 
 
553
  verbosity=verbosity,
554
- transparency=transparency,
555
- retrieval_engine=self.retrieval_engine,
556
- generator_engine=self.generator_engine,
557
- retrieval_context=retrieval_context,
558
- chat_history=chat_history,
559
- question_text=question_text,
560
  )
561
 
562
- def __call__(
563
- self,
564
- raw_user_text: Optional[str] = None,
565
- tone: float = 0.5,
566
- verbosity: float = 0.5,
567
- transparency: float = 0.5,
568
- retrieval_context: Optional[List[RetrievedChunk]] = None,
569
- chat_history: Optional[List[Dict[str, Any]]] = None,
570
- question_text: Optional[str] = None,
571
- message: Optional[str] = None,
572
- prompt: Optional[str] = None,
573
- query: Optional[str] = None,
574
- text: Optional[str] = None,
575
- user_message: Optional[str] = None,
576
- **kwargs,
577
- ) -> Dict[str, Any]:
578
- return self.generate_response(
579
- raw_user_text=raw_user_text,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
580
  tone=tone,
581
  verbosity=verbosity,
582
  transparency=transparency,
583
- retrieval_context=retrieval_context,
584
- chat_history=chat_history,
585
- question_text=question_text,
586
- message=message,
587
- prompt=prompt,
588
- query=query,
589
- text=text,
590
- user_message=user_message,
591
- **kwargs,
592
- )
 
 
35
 
36
  STRUCTURE_KEYWORDS = {
37
  "algebra": [
38
+ "equation", "solve", "isolate", "variable", "linear", "expression",
39
+ "unknown", "algebra", "substitute", "rearrange"
 
 
 
 
 
 
 
 
40
  ],
41
  "percent": [
42
+ "percent", "%", "percentage", "increase", "decrease", "of"
 
 
 
 
 
43
  ],
44
  "ratio": [
45
+ "ratio", "proportion", "proportional", "part", "share"
 
 
 
 
46
  ],
47
  "statistics": [
48
+ "mean", "median", "mode", "range", "average", "standard deviation"
 
 
 
 
 
49
  ],
50
  "probability": [
51
+ "probability", "chance", "likely", "odds", "event"
 
 
 
 
52
  ],
53
  "geometry": [
54
+ "triangle", "circle", "angle", "area", "perimeter", "radius", "diameter"
 
 
 
 
 
 
55
  ],
56
  "number_properties": [
57
+ "integer", "odd", "even", "prime", "divisible", "factor", "multiple"
 
 
 
 
 
 
58
  ],
59
  }
60
 
 
71
 
72
  MISMATCH_TERMS = {
73
  "algebra": [
74
+ "absolute value", "modulus", "square root", "quadratic", "inequality",
75
+ "roots", "parabola", "simultaneous equations"
 
 
 
 
 
 
76
  ],
77
  "percent": [
78
+ "triangle", "circle", "prime", "absolute value"
 
 
 
79
  ],
80
  "ratio": [
81
+ "absolute value", "quadratic", "circle"
 
 
82
  ],
83
  "statistics": [
84
+ "absolute value", "prime", "triangle"
 
 
85
  ],
86
  "probability": [
87
+ "absolute value", "circle area", "quadratic"
 
 
88
  ],
89
  "geometry": [
90
+ "absolute value", "prime", "median salary"
 
 
91
  ],
92
  "number_properties": [
93
+ "circle", "triangle", "absolute value"
 
 
94
  ],
95
  }
96
 
 
304
  ) -> str:
305
  parts: List[str] = []
306
 
307
+ base = (question_text or "").strip() or (raw_user_text or "").strip()
308
  if base:
309
  parts.append(base)
310
 
 
325
  return " ".join(parts).strip()
326
 
327
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
328
  class ConversationEngine:
329
  def __init__(
330
  self,
331
  retriever: Optional[RetrievalEngine] = None,
332
  generator: Optional[GeneratorEngine] = None,
 
 
333
  **kwargs,
334
  ) -> None:
335
+ self.retriever = retriever
336
+ self.generator = generator
337
 
338
  def generate_response(
339
  self,
 
341
  tone: float = 0.5,
342
  verbosity: float = 0.5,
343
  transparency: float = 0.5,
344
+ intent: Optional[str] = None,
345
+ help_mode: Optional[str] = None,
346
  retrieval_context: Optional[List[RetrievedChunk]] = None,
347
  chat_history: Optional[List[Dict[str, Any]]] = None,
348
  question_text: Optional[str] = None,
349
+ options_text: Optional[List[str]] = None,
 
 
 
 
350
  **kwargs,
351
+ ) -> SolverResult:
352
+ solver_input = (question_text or raw_user_text or "").strip()
353
+ user_text = (raw_user_text or "").strip()
354
+
355
+ resolved_intent = intent or detect_intent(user_text, help_mode)
356
+ resolved_help_mode = help_mode or intent_to_help_mode(resolved_intent)
357
+ reveal_answer = resolved_help_mode == "answer" or transparency >= 0.8
358
+
359
+ result = SolverResult(
360
+ domain="general",
361
+ solved=False,
362
+ help_mode=resolved_help_mode,
363
+ answer_letter=None,
364
+ answer_value=None,
365
+ topic=None,
366
+ used_retrieval=False,
367
+ used_generator=False,
368
+ internal_answer=None,
369
+ steps=[],
370
+ teaching_chunks=[],
371
+ meta={},
372
  )
373
 
374
+ selected_chunks: List[RetrievedChunk] = []
375
+
376
+ if is_quant_question(solver_input):
377
+ result = solve_quant(solver_input)
378
+ result.help_mode = resolved_help_mode
379
+
380
+ reply = _compose_quant_reply(
381
+ result=result,
382
+ intent=resolved_intent,
383
+ reveal_answer=reveal_answer,
384
  verbosity=verbosity,
 
 
 
 
 
 
385
  )
386
 
387
+ allow_retrieval = should_retrieve(
388
+ intent=resolved_intent,
389
+ solved=bool(result.solved),
390
+ raw_user_text=user_text or solver_input,
391
+ )
392
+
393
+ if allow_retrieval and retrieval_context:
394
+ filtered = _filter_retrieved_chunks(
395
+ chunks=retrieval_context,
396
+ intent=resolved_intent,
397
+ topic=result.topic,
398
+ question_text=solver_input,
399
+ )
400
+ if filtered:
401
+ selected_chunks = filtered
402
+ result.used_retrieval = True
403
+ result.teaching_chunks = filtered
404
+
405
+ elif allow_retrieval and self.retriever is not None:
406
+ query = _build_retrieval_query(
407
+ raw_user_text=user_text,
408
+ question_text=solver_input,
409
+ intent=resolved_intent,
410
+ topic=result.topic,
411
+ solved=bool(result.solved),
412
+ )
413
+ retrieved = self.retriever.search(query, top_k=6)
414
+ filtered = _filter_retrieved_chunks(
415
+ chunks=retrieved,
416
+ intent=resolved_intent,
417
+ topic=result.topic,
418
+ question_text=solver_input,
419
+ )
420
+ if filtered:
421
+ selected_chunks = filtered
422
+ result.used_retrieval = True
423
+ result.teaching_chunks = filtered
424
+
425
+ if selected_chunks:
426
+ reply = f"{reply}\n\nRelevant study notes:\n" + "\n".join(_teaching_lines(selected_chunks))
427
+
428
+ if not result.solved and self.generator is not None:
429
+ try:
430
+ generated = self.generator.generate(
431
+ user_text=user_text or solver_input,
432
+ intent=resolved_intent,
433
+ topic=result.topic,
434
+ chat_history=chat_history or [],
435
+ )
436
+ if generated and generated.strip():
437
+ reply = generated.strip()
438
+ result.used_generator = True
439
+ except Exception:
440
+ pass
441
+
442
+ reply = format_reply(
443
+ text=reply,
444
  tone=tone,
445
  verbosity=verbosity,
446
  transparency=transparency,
447
+ )
448
+
449
+ result.reply = short_lines(reply)
450
+ result.help_mode = resolved_help_mode
451
+ result.meta = {
452
+ "intent": resolved_intent,
453
+ "question_text": question_text or "",
454
+ "options_count": len(options_text or []),
455
+ }
456
+
457
+ return result