afaceuser09 commited on
Commit
565ed0a
·
verified ·
1 Parent(s): 73cdcfb

Update reasoning_engine.py

Browse files
Files changed (1) hide show
  1. reasoning_engine.py +269 -928
reasoning_engine.py CHANGED
@@ -2,31 +2,26 @@
2
  Infinity GRM - Reasoning Engine
3
  ================================
4
  Standalone cognitive/reasoning layer for Infinity GRM.
5
-
6
  Features
7
  --------
8
  - Qwen2.5-7B-Instruct reasoning model
9
  - 700 structured reasoning demonstrations by default
10
  - Semantic retrieval of relevant demonstrations
11
- - Free-form reasoning -> independent final synthesis
12
  - Persistent SQLite experience memory
13
- - Optional detailed, user-visible reasoning TRACE
14
  - Backward-compatible plan()/analyze()/final_answer() API
15
-
 
 
 
 
 
16
  Important
17
  ---------
18
  The demonstration library is structured training-style material used at
19
  inference time. It does not change the neural weights of the base model.
20
  For model-weight improvement, use a separate SFT/QLoRA training pipeline.
21
-
22
- Reasoning behavior
23
- ------------------
24
- The reasoning pass is intentionally NOT a fixed step-by-step procedure.
25
- The model is encouraged to explore the problem freely, reconsider
26
- assumptions, try alternatives, correct mistakes, and verify conclusions.
27
-
28
- The final answer is generated in a separate model pass so the model's
29
- reasoning is not simply copied into the final response.
30
  """
31
 
32
  import os
@@ -43,68 +38,12 @@ import torch
43
  from sentence_transformers import SentenceTransformer
44
  from transformers import AutoTokenizer, AutoModelForCausalLM, AutoConfig
45
 
46
-
47
  logger = logging.getLogger("infinitygrm.reasoning")
48
 
49
-
50
- MODEL_NAME = os.getenv(
51
- "GRM_MODEL",
52
- "Qwen/Qwen2.5-7B-Instruct",
53
- )
54
-
55
- MEMORY_DB = Path(
56
- os.getenv(
57
- "GRM_MEMORY_DB",
58
- "./grm_experience.sqlite3",
59
- )
60
- )
61
-
62
- EXAMPLE_TARGET = max(
63
- 500,
64
- min(
65
- 1000,
66
- int(os.getenv("GRM_EXAMPLE_TARGET", "700")),
67
- ),
68
- )
69
-
70
- SHOW_REASONING_TRACE = (
71
- os.getenv(
72
- "GRM_SHOW_REASONING_TRACE",
73
- "1",
74
- ).lower()
75
- not in {"0", "false", "no"}
76
- )
77
-
78
- # Larger budget for the free-form reasoning pass.
79
- THINK_MAX_NEW_TOKENS = int(
80
- os.getenv(
81
- "GRM_THINK_MAX_NEW_TOKENS",
82
- "8192",
83
- )
84
- )
85
-
86
- # Separate, smaller budget for the clean final answer.
87
- FINAL_MAX_NEW_TOKENS = int(
88
- os.getenv(
89
- "GRM_FINAL_MAX_NEW_TOKENS",
90
- "2200",
91
- )
92
- )
93
-
94
- THINK_TEMPERATURE = float(
95
- os.getenv(
96
- "GRM_THINK_TEMPERATURE",
97
- "0.10",
98
- )
99
- )
100
-
101
- FINAL_TEMPERATURE = float(
102
- os.getenv(
103
- "GRM_FINAL_TEMPERATURE",
104
- "0.10",
105
- )
106
- )
107
-
108
 
109
  STATE: Dict[str, Any] = {
110
  "model": None,
@@ -125,34 +64,27 @@ _REASONING_SKILLS = [
125
  ("mathematics", "probability", "define the sample space, identify independence/dependence, compute and sanity-check probabilities"),
126
  ("mathematics", "statistics", "identify the estimator or test, state assumptions, calculate, interpret uncertainty"),
127
  ("mathematics", "calculus", "identify the derivative/integral rule, apply it carefully, verify with boundary or dimensional checks"),
128
-
129
  ("algorithms", "complexity", "identify the dominant operation, count repeated work, derive asymptotic time and space complexity"),
130
  ("algorithms", "sorting", "choose an algorithm based on constraints, preserve correctness invariants, analyze complexity"),
131
  ("algorithms", "graphs", "model entities as vertices and relationships as edges, choose traversal/shortest-path method, verify reachability"),
132
  ("algorithms", "dynamic programming", "define state, transition, base case, evaluation order, and prove that states cover all cases"),
133
  ("algorithms", "greedy methods", "define a locally optimal choice, establish the invariant/exchange argument, then verify feasibility"),
134
-
135
  ("coding", "Python debugging", "reproduce the failure, inspect the smallest relevant state, identify the root cause, patch and retest"),
136
  ("coding", "data structures", "identify access/update requirements, select an appropriate structure, define invariants and complexity"),
137
  ("coding", "API design", "define inputs/outputs/errors, preserve contracts, validate data, and design deterministic behavior"),
138
  ("coding", "concurrency", "identify shared state, define synchronization boundaries, avoid races/deadlocks, and test interleavings"),
139
  ("coding", "optimization", "measure the bottleneck, improve the dominant cost, preserve semantics, and benchmark before/after"),
140
  ("coding", "machine learning", "separate data/model/objective/evaluation, identify leakage risks, train, validate, and test independently"),
141
-
142
  ("science", "physics", "translate the situation into variables and laws, keep units consistent, solve symbolically, then sanity-check"),
143
  ("science", "chemistry", "identify substances and governing conservation laws, balance the reaction/model, calculate, and check stoichiometry"),
144
  ("science", "biology", "identify the mechanism, distinguish correlation from causation, connect evidence to the proposed biological process"),
145
-
146
  ("engineering", "systems", "decompose components and interfaces, identify bottlenecks/failure modes, design controls and verify requirements"),
147
  ("engineering", "electronics", "define voltage/current/power relationships, inspect component constraints, calculate worst case, verify margins"),
148
-
149
  ("logic", "deduction", "translate statements into premises, derive consequences, test alternatives, and distinguish valid inference from assumption"),
150
  ("logic", "constraint solving", "list variables/domains/constraints, propagate restrictions, branch only when needed, verify every constraint"),
151
-
152
  ("software engineering", "architecture", "identify requirements and boundaries, choose components/interfaces, evaluate tradeoffs, and define failure handling"),
153
  ("software engineering", "testing", "identify observable behavior, partition cases, include edge cases, assert invariants, and test regressions"),
154
  ("software engineering", "security review", "map trust boundaries, identify attack surfaces, validate inputs/authorization, and verify mitigations"),
155
-
156
  ("mathematics", "arithmetic", "break the problem into operations, preserve order of operations, calculate carefully, and independently verify the result"),
157
  ("mathematics", "fractions", "convert representations consistently, identify common denominators when needed, perform the operation, simplify, and verify"),
158
  ("mathematics", "ratios", "identify corresponding quantities, establish the ratio relationship, solve proportionally, and check whether the result has the correct scale"),
@@ -185,6 +117,8 @@ _REASONING_SKILLS = [
185
  ("mathematics", "statistical inference", "identify the parameter of interest, select an appropriate estimator or test, state assumptions, calculate uncertainty, and interpret cautiously"),
186
  ("mathematics", "data interpretation", "identify what the axes, units, sample, and statistic actually represent, calculate relevant comparisons, and avoid unsupported causal conclusions"),
187
 
 
 
188
  ("logic", "formal logic", "translate statements into propositions, identify premises and conclusions, apply valid inference rules, and distinguish implication from equivalence"),
189
  ("logic", "syllogisms", "identify premises, determine their logical structure, derive only conclusions supported by the premises, and test for counterexamples"),
190
  ("logic", "inductive reasoning", "identify observed patterns, generate the strongest supported generalization, distinguish evidence from certainty, and identify possible counterexamples"),
@@ -201,6 +135,8 @@ _REASONING_SKILLS = [
201
  ("logic", "proof by induction", "define the base case, formulate the induction hypothesis precisely, prove the inductive step, and conclude only what the induction establishes"),
202
  ("logic", "necessary and sufficient conditions", "distinguish conditions that guarantee a result from those merely required for it, prove each direction separately, and identify edge cases"),
203
 
 
 
204
  ("reasoning", "problem decomposition", "divide the problem into independent or dependent subproblems, solve the highest-leverage components first, then integrate and verify"),
205
  ("reasoning", "root cause analysis", "separate symptoms from causes, construct a causal chain, test competing explanations against evidence, and identify the deepest actionable cause"),
206
  ("reasoning", "first principles", "strip the problem down to fundamental facts and constraints, derive consequences from those foundations, and avoid relying on unsupported assumptions"),
@@ -224,6 +160,8 @@ _REASONING_SKILLS = [
224
  ("reasoning", "decision under uncertainty", "identify possible actions, outcomes, probabilities or uncertainty ranges where available, costs and benefits, and sensitivity to assumptions"),
225
  ("reasoning", "prioritization", "identify objectives, urgency, impact, dependencies, and resource constraints, then construct a defensible ordering without confusing importance with urgency"),
226
 
 
 
227
  ("science", "scientific method", "formulate a testable hypothesis, identify variables and controls, predict observations, evaluate evidence, and distinguish results from interpretation"),
228
  ("science", "experimental design", "define the research question, identify independent/dependent/control variables, minimize confounding, choose measurements, and define success criteria"),
229
  ("science", "measurement", "identify the quantity and units, distinguish precision from accuracy, track uncertainty, and verify dimensional consistency"),
@@ -242,6 +180,8 @@ _REASONING_SKILLS = [
242
  ("science", "evolutionary reasoning", "identify variation, inheritance, selection pressures, and population-level effects, then distinguish individual adaptation from population change"),
243
  ("science", "scientific evidence evaluation", "identify study design, sample, measurement, controls, effect size, uncertainty, and limitations before interpreting the conclusion"),
244
 
 
 
245
  ("engineering", "requirements analysis", "translate vague goals into measurable requirements, identify constraints and acceptance criteria, and distinguish mandatory requirements from preferences"),
246
  ("engineering", "failure mode analysis", "identify components and failure modes, estimate causes and effects, prioritize risks, and design mitigations and detection mechanisms"),
247
  ("engineering", "reliability", "identify failure mechanisms, estimate rates or probabilities, model system dependencies, and determine how redundancy or maintenance affects reliability"),
@@ -253,6 +193,8 @@ _REASONING_SKILLS = [
253
  ("engineering", "signal analysis", "identify the signal, noise, sampling constraints, frequency characteristics, and measurement objectives, then select an appropriate analysis method"),
254
  ("engineering", "design validation", "translate requirements into measurable tests, construct representative test conditions, define pass/fail criteria, execute checks, and document limitations"),
255
 
 
 
256
  ("computer science", "recursion", "define the base case, identify the recursive reduction, prove progress toward termination, and verify returned values"),
257
  ("computer science", "search", "define the search space and target condition, choose an appropriate search strategy, preserve completeness/correctness, and analyze complexity"),
258
  ("computer science", "binary search", "establish the sorted invariant, maintain valid bounds, choose the midpoint safely, eliminate the impossible half, and verify termination"),
@@ -268,6 +210,8 @@ _REASONING_SKILLS = [
268
  ("computer science", "algorithm correctness", "state the invariant or correctness condition, show initialization, preservation, and termination where appropriate, and verify edge cases"),
269
  ("computer science", "amortized analysis", "identify operations whose costs vary, select an accounting/potential method, derive aggregate cost, and convert it to amortized complexity"),
270
 
 
 
271
  ("software engineering", "requirements clarification", "separate explicit requirements from assumptions, identify ambiguities and edge cases, and define observable acceptance criteria"),
272
  ("software engineering", "code review", "inspect correctness, maintainability, security, performance, error handling, and compatibility, prioritizing concrete defects over stylistic preferences"),
273
  ("software engineering", "refactoring", "identify the behavior that must remain unchanged, isolate structural improvements, make small transformations, and run regression checks"),
@@ -279,6 +223,8 @@ _REASONING_SKILLS = [
279
  ("software engineering", "maintainability", "identify coupling, cohesion, duplication, unclear contracts, and hidden dependencies, then improve structure while preserving observable behavior"),
280
  ("software engineering", "documentation reasoning", "identify the intended audience and task, explain prerequisites and behavior accurately, include examples where useful, and avoid documenting assumptions as guarantees"),
281
 
 
 
282
  ("language", "reading comprehension", "identify the main claim, supporting evidence, qualifications, assumptions, and conclusions before answering questions about the text"),
283
  ("language", "text analysis", "separate explicit statements from implications, identify structure and evidence, and avoid attributing claims that the text does not support"),
284
  ("language", "summarization", "identify the central information and supporting points, remove redundancy, preserve important qualifications, and avoid introducing new claims"),
@@ -291,7 +237,6 @@ _REASONING_SKILLS = [
291
  ("language", "translation reasoning", "preserve meaning, intent, register, ambiguity, and important technical terminology rather than translating words mechanically"),
292
  ]
293
 
294
-
295
  _VARIANTS = [
296
  "direct solution with explicit assumptions",
297
  "edge-case-heavy solution",
@@ -306,36 +251,20 @@ _VARIANTS = [
306
  ]
307
 
308
 
309
- def _build_reasoning_examples(
310
- target: int = EXAMPLE_TARGET,
311
- ) -> List[Dict[str, Any]]:
312
- """
313
- Create a deterministic library of structured reasoning demonstrations.
314
-
315
- These are inference-time demonstrations rather than weight updates.
316
  """
317
-
318
  examples: List[Dict[str, Any]] = []
319
-
320
  idx = 0
321
  skill_count = len(_REASONING_SKILLS)
322
 
323
  while len(examples) < target:
324
- domain, skill, principle = _REASONING_SKILLS[
325
- idx % skill_count
326
- ]
327
-
328
- variant = _VARIANTS[
329
- (idx // skill_count) % len(_VARIANTS)
330
- ]
331
-
332
- difficulty = (
333
- "medium",
334
- "hard",
335
- "expert",
336
- )[
337
- (idx // (skill_count * 3)) % 3
338
- ]
339
 
340
  problem = (
341
  f"Solve a {skill} problem using a {variant} approach. "
@@ -357,118 +286,79 @@ def _build_reasoning_examples(
357
  ]
358
 
359
  solution = (
360
- f"Use the {skill} method appropriate to the stated constraints; "
361
- "explicitly state assumptions, derive the result in ordered steps, "
362
- "then verify the result against the original problem."
363
- )
364
-
365
- examples.append(
366
- {
367
- "id": idx + 1,
368
- "domain": domain,
369
- "skill": skill,
370
- "difficulty": difficulty,
371
- "problem": problem,
372
- "reasoning_trace": steps,
373
- "verification": verification,
374
- "solution": solution,
375
- }
376
  )
377
 
 
 
 
 
 
 
 
 
 
 
378
  idx += 1
379
 
380
  return examples
381
 
382
 
383
- REASONING_EXAMPLES: List[Dict[str, Any]] = (
384
- _build_reasoning_examples(EXAMPLE_TARGET)
385
- )
386
 
387
 
388
- def _format_reasoning_examples(
389
- query: str,
390
- top_k: int = 6,
391
- ) -> str:
392
- """
393
- Return the most relevant structured demonstrations for a query.
394
- """
395
-
396
  if not REASONING_EXAMPLES:
397
  return "No demonstrations available."
398
 
399
  embed_model = STATE.get("embed_model")
400
-
401
  if embed_model is None:
 
402
  selected = REASONING_EXAMPLES[:top_k]
403
-
404
  else:
405
  try:
406
  if STATE.get("reasoning_example_embeddings") is None:
407
  texts = [
408
- (
409
- f"{x['domain']} "
410
- f"{x['skill']} "
411
- f"{x['problem']} "
412
- f"{x['solution']}"
413
- )
414
  for x in REASONING_EXAMPLES
415
  ]
416
-
417
- STATE["reasoning_example_embeddings"] = (
418
- embed_model.encode(
419
- texts,
420
- normalize_embeddings=True,
421
- convert_to_numpy=True,
422
- show_progress_bar=False,
423
- )
424
  )
425
 
426
  qv = _embed(query)
427
-
428
- matrix = STATE[
429
- "reasoning_example_embeddings"
430
- ]
431
-
432
  scores = matrix @ qv
433
-
434
  indices = np.argsort(scores)[::-1][:top_k]
435
-
436
- selected = [
437
- REASONING_EXAMPLES[int(i)]
438
- for i in indices
439
- ]
440
-
441
  except Exception as exc:
442
- logger.warning(
443
- "Reasoning example retrieval failed: %s",
444
- exc,
445
- )
446
  selected = REASONING_EXAMPLES[:top_k]
447
 
448
  blocks = []
449
-
450
  for ex in selected:
451
  blocks.append(
452
  "EXAMPLE {id} | {domain}/{skill} | difficulty={difficulty}\n"
453
  "Problem pattern: {problem}\n"
454
- "Reasoning guidance:\n- {steps}\n"
455
- "Verification guidance:\n- {verification}\n"
456
  "Solution pattern: {solution}".format(
457
  id=ex["id"],
458
  domain=ex["domain"],
459
  skill=ex["skill"],
460
  difficulty=ex["difficulty"],
461
  problem=ex["problem"],
462
- steps="\n- ".join(
463
- ex["reasoning_trace"]
464
- ),
465
- verification="\n- ".join(
466
- ex["verification"]
467
- ),
468
  solution=ex["solution"],
469
  )
470
  )
471
-
472
  return "\n\n".join(blocks)
473
 
474
 
@@ -478,52 +368,27 @@ def _format_reasoning_examples(
478
 
479
 
480
  def initialize_model():
481
- """
482
- Load the language and embedding models once.
483
- """
484
-
485
  if STATE.get("model") is not None:
486
  return
487
 
488
- device = (
489
- "cuda"
490
- if torch.cuda.is_available()
491
- else "cpu"
492
- )
493
 
494
- dtype = (
495
- torch.float16
496
- if device == "cuda"
497
- else torch.float32
498
- )
499
-
500
- logger.info(
501
- "Loading reasoning model: %s",
502
- MODEL_NAME,
503
- )
504
-
505
- tokenizer = AutoTokenizer.from_pretrained(
506
- MODEL_NAME
507
- )
508
 
 
509
  if tokenizer.pad_token is None:
510
  tokenizer.pad_token = tokenizer.eos_token
511
 
512
- config = AutoConfig.from_pretrained(
513
- MODEL_NAME
514
- )
515
-
516
  config.pad_token_id = tokenizer.eos_token_id
517
 
518
  model = AutoModelForCausalLM.from_pretrained(
519
  MODEL_NAME,
520
  config=config,
521
  torch_dtype=dtype,
522
- device_map=(
523
- "auto"
524
- if device == "cuda"
525
- else None
526
- ),
527
  ).eval()
528
 
529
  embed_model = SentenceTransformer(
@@ -539,12 +404,7 @@ def initialize_model():
539
  )
540
 
541
  initialize_memory()
542
-
543
- logger.info(
544
- "Reasoning engine initialized on %s with %d demonstrations",
545
- device,
546
- len(REASONING_EXAMPLES),
547
- )
548
 
549
 
550
  # =====================================================================
@@ -553,11 +413,7 @@ def initialize_model():
553
 
554
 
555
  def initialize_memory():
556
- MEMORY_DB.parent.mkdir(
557
- parents=True,
558
- exist_ok=True,
559
- )
560
-
561
  with sqlite3.connect(MEMORY_DB) as db:
562
  db.execute(
563
  """
@@ -572,13 +428,11 @@ def initialize_memory():
572
  )
573
  """
574
  )
575
-
576
  db.commit()
577
 
578
 
579
  def _embed(text: str) -> np.ndarray:
580
  model = STATE["embed_model"]
581
-
582
  return model.encode(
583
  [text],
584
  normalize_embeddings=True,
@@ -587,64 +441,30 @@ def _embed(text: str) -> np.ndarray:
587
  )[0]
588
 
589
 
590
- def _ensure_experience_embedding_column(
591
- conn: sqlite3.Connection,
592
- ) -> None:
593
- """
594
- Ensure the experience table has a BLOB column for precomputed embeddings.
595
- """
596
-
597
  columns = {
598
- row[1]
599
- for row in conn.execute(
600
- "PRAGMA table_info(experiences)"
601
- ).fetchall()
602
  }
603
-
604
  if "embedding" not in columns:
605
- conn.execute(
606
- "ALTER TABLE experiences "
607
- "ADD COLUMN embedding BLOB"
608
- )
609
-
610
  conn.commit()
611
 
612
 
613
- def _embedding_to_blob(
614
- vector: Optional[np.ndarray],
615
- ) -> Optional[bytes]:
616
-
617
  if vector is None:
618
  return None
619
-
620
- arr = np.asarray(
621
- vector,
622
- dtype=np.float32,
623
- ).reshape(-1)
624
-
625
  return arr.tobytes()
626
 
627
 
628
- def _blob_to_embedding(
629
- blob: Optional[bytes],
630
- ) -> Optional[np.ndarray]:
631
-
632
  if blob is None:
633
  return None
 
634
 
635
- return np.frombuffer(
636
- blob,
637
- dtype=np.float32,
638
- ).copy()
639
 
640
-
641
- def save_experience(
642
- query: str,
643
- plan: str,
644
- analysis: str,
645
- answer: str,
646
- quality: float = 1.0,
647
- ):
648
  try:
649
  with sqlite3.connect(MEMORY_DB) as db:
650
  db.execute(
@@ -653,42 +473,19 @@ def save_experience(
653
  (query, plan, analysis, answer, quality, created)
654
  VALUES (?, ?, ?, ?, ?, ?)
655
  """,
656
- (
657
- query,
658
- plan,
659
- analysis,
660
- answer,
661
- float(quality),
662
- time.time(),
663
- ),
664
  )
665
-
666
  db.commit()
667
-
668
  except Exception as exc:
669
- logger.warning(
670
- "Could not save experience: %s",
671
- exc,
672
- )
673
-
674
 
675
- def retrieve_experiences(
676
- query: str,
677
- top_k: int = 3,
678
- ) -> List[Dict[str, Any]]:
679
 
 
680
  try:
681
  with sqlite3.connect(MEMORY_DB) as db:
682
  rows = db.execute(
683
  """
684
- SELECT
685
- id,
686
- query,
687
- plan,
688
- analysis,
689
- answer,
690
- quality,
691
- created
692
  FROM experiences
693
  WHERE quality >= 0.5
694
  ORDER BY created DESC
@@ -699,42 +496,30 @@ def retrieve_experiences(
699
  if not rows:
700
  return []
701
 
702
- embed_model = STATE.get(
703
- "embed_model"
704
- )
705
-
706
  if embed_model is None:
 
707
  return []
708
 
 
709
  qv = _embed(query)
710
 
711
- db_queries = [
712
- row[1]
713
- for row in rows
714
- ]
715
-
716
  rv_matrix = embed_model.encode(
717
  db_queries,
718
  normalize_embeddings=True,
719
  convert_to_numpy=True,
720
- show_progress_bar=False,
721
  )
722
 
 
723
  scores = rv_matrix @ qv
724
 
725
- scored = [
726
- (
727
- float(score),
728
- row,
729
- )
730
- for score, row
731
- in zip(scores, rows)
732
- ]
733
-
734
- scored.sort(
735
- key=lambda x: x[0],
736
- reverse=True,
737
- )
738
 
739
  return [
740
  {
@@ -745,178 +530,75 @@ def retrieve_experiences(
745
  "answer": row[4],
746
  "quality": row[5],
747
  }
748
- for score, row
749
- in scored[:top_k]
750
  ]
751
-
752
  except Exception as exc:
753
- logger.warning(
754
- "Experience retrieval failed: %s",
755
- exc,
756
- )
757
-
758
  return []
759
 
760
 
761
  # =====================================================================
762
- # GENERATION
763
  # =====================================================================
764
 
765
 
766
- def generate(
767
- messages: List[Dict[str, str]],
768
- max_new_tokens: int = 1024,
769
- temperature: float = 0.15,
770
- ) -> str:
771
- """
772
- Run one model pass.
773
-
774
- This function intentionally does not impose a reasoning format.
775
- The caller decides whether the pass is a thinking pass or a final
776
- answer pass.
777
- """
778
-
779
  initialize_model()
780
 
781
  tokenizer = STATE["tokenizer"]
782
  model = STATE["model"]
783
 
784
- prompt = tokenizer.apply_chat_template(
785
- messages,
786
- tokenize=False,
787
- add_generation_prompt=True,
788
- )
789
-
790
- inputs = tokenizer(
791
- prompt,
792
- return_tensors="pt",
793
- )
794
-
795
- inputs = {
796
- k: v.to(model.device)
797
- for k, v in inputs.items()
798
- }
799
 
800
  generation_kwargs = {
801
  "max_new_tokens": max_new_tokens,
802
  "repetition_penalty": 1.05,
803
  "pad_token_id": tokenizer.eos_token_id,
804
  }
805
-
806
  if temperature > 0:
807
- generation_kwargs.update(
808
- {
809
- "temperature": temperature,
810
- "top_p": 0.90,
811
- "do_sample": True,
812
- }
813
- )
814
-
815
  else:
816
- generation_kwargs.update(
817
- {
818
- "do_sample": False,
819
- }
820
- )
821
 
822
  with torch.no_grad():
823
- output = model.generate(
824
- **inputs,
825
- **generation_kwargs,
826
- )
827
-
828
- new_tokens = output[
829
- 0
830
- ][
831
- inputs["input_ids"].shape[1]:
832
- ]
833
-
834
- return tokenizer.decode(
835
- new_tokens,
836
- skip_special_tokens=True,
837
- ).strip()
838
-
839
-
840
- # =====================================================================
841
- # THINKING / OUTPUT UTILITIES
842
- # =====================================================================
843
-
844
-
845
- def _extract_think(
846
- text: str,
847
- ) -> str:
848
- """
849
- Extract an explicit <think> section if one exists.
850
- """
851
-
852
- match = re.search(
853
- r"<think>\s*(.*?)\s*</think>",
854
- text,
855
- flags=re.IGNORECASE | re.DOTALL,
856
- )
857
-
858
- return (
859
- match.group(1).strip()
860
- if match
861
- else ""
862
- )
863
 
 
 
864
 
865
- def _remove_think(
866
- text: str,
867
- ) -> str:
868
- return re.sub(
869
- r"<think>.*?</think>",
870
- "",
871
- text,
872
- flags=re.IGNORECASE | re.DOTALL,
873
- ).strip()
874
 
 
 
 
 
875
 
876
- def clean_think_block(
877
- text: str,
878
- ) -> str:
879
- """
880
- Preserve a visible reasoning block when the model explicitly emits one.
881
 
882
- This function does not invent reasoning that the model did not generate.
 
 
 
 
883
  """
884
-
885
  text = text.strip()
886
-
887
  think = _extract_think(text)
888
-
889
- body = _remove_think(text)
890
 
891
  if not body:
892
- body = text.replace(
893
- "<think>",
894
- "",
895
- ).replace(
896
- "</think>",
897
- "",
898
- ).strip()
899
 
900
  if SHOW_REASONING_TRACE and think:
901
- return (
902
- f"<think>\n"
903
- f"{think}\n"
904
- f"</think>\n\n"
905
- f"{body}"
906
- ).strip()
907
-
908
  return body
909
 
910
 
911
- def _make_trace(
912
- stage: str,
913
- text: str,
914
- ) -> Dict[str, Any]:
915
-
916
  think = _extract_think(text)
917
-
918
- body = _remove_think(text)
919
-
920
  return {
921
  "stage": stage,
922
  "reasoning_summary": think,
@@ -925,373 +607,164 @@ def _make_trace(
925
 
926
 
927
  # =====================================================================
928
- # FREE-FORM THINKING PASS
929
  # =====================================================================
930
 
931
-
932
- THINK_SYSTEM = r"""
933
- You are the free-form reasoning engine of Infinity GRM.
934
-
935
- Your job is to think deeply about the user's problem before a separate
936
- model pass produces the final answer.
937
-
938
- Do NOT follow a predefined step-by-step procedure.
939
-
940
- Do NOT use a fixed checklist.
941
-
942
- Do NOT force your reasoning into stages such as:
943
- 1. interpretation
944
- 2. planning
945
- 3. analysis
946
- 4. verification
947
- 5. synthesis
948
-
949
- There is no required order.
950
-
951
- Instead, reason naturally according to whatever the problem requires.
952
-
953
- You may:
954
- - explore an idea;
955
- - abandon an approach;
956
- - reconsider an assumption;
957
- - notice a contradiction;
958
- - try a different method;
959
- - compare alternatives;
960
- - perform calculations;
961
- - test an intermediate result;
962
- - discover a useful relationship;
963
- - correct an earlier mistake;
964
- - backtrack;
965
- - verify something;
966
- - have an insight that changes the direction of the solution.
967
-
968
- The reasoning should adapt to the problem.
969
-
970
- Easy problems may require very little reasoning.
971
- Difficult problems may require substantial exploration.
972
-
973
- Do not artificially make the reasoning longer just to appear intelligent.
974
-
975
- Your output is the reasoning/workspace for a separate final-answer
976
- generation pass.
977
-
978
- Do NOT write a polished final answer.
979
-
980
- Do NOT repeat the user's question unnecessarily.
981
-
982
- Do NOT end with a separate "final answer" section.
983
-
984
- Think freely and deeply, then stop when you have enough information
985
- for another model pass to produce the answer.
986
  """
987
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
988
 
989
- def think(
990
- query: str,
991
- history: List[Dict[str, str]],
992
- context: str = "",
993
- ) -> str:
994
- """
995
- Free-form reasoning pass.
996
-
997
- This is deliberately independent of plan/analyze/verify stages.
998
- """
999
-
1000
- initialize_model()
1001
-
1002
- experiences = retrieve_experiences(
1003
- query,
1004
- top_k=3,
1005
- )
1006
-
1007
- experience_text = json.dumps(
1008
- experiences,
1009
- ensure_ascii=False,
1010
- indent=2,
1011
- )
1012
-
1013
- demonstrations = _format_reasoning_examples(
1014
- query,
1015
- top_k=8,
1016
- )
1017
-
1018
- messages = [
1019
- {
1020
- "role": "system",
1021
- "content": THINK_SYSTEM,
1022
- },
1023
- {
1024
- "role": "user",
1025
- "content": (
1026
- f"USER QUESTION:\n"
1027
- f"{query}\n\n"
1028
- f"CONTEXT / EVIDENCE:\n"
1029
- f"{context[:20000]}\n\n"
1030
- f"CONVERSATION HISTORY:\n"
1031
- f"{json.dumps(history[-8:], ensure_ascii=False)}\n\n"
1032
- f"RELEVANT PRIOR EXPERIENCES:\n"
1033
- f"{experience_text}\n\n"
1034
- f"RELEVANT REASONING EXAMPLES:\n"
1035
- f"{demonstrations}"
1036
- ),
1037
- },
1038
- ]
1039
-
1040
- raw = generate(
1041
- messages,
1042
- max_new_tokens=THINK_MAX_NEW_TOKENS,
1043
- temperature=THINK_TEMPERATURE,
1044
- )
1045
-
1046
- # If the model voluntarily used <think>, expose only the contents.
1047
- explicit_think = _extract_think(raw)
1048
-
1049
- if explicit_think:
1050
- return explicit_think
1051
-
1052
- # Otherwise the entire thinking-pass output is the reasoning workspace.
1053
- return _remove_think(raw)
1054
-
1055
-
1056
- # =====================================================================
1057
- # FINAL ANSWER PASS
1058
- # =====================================================================
1059
-
1060
 
1061
  FINAL_SYSTEM = r"""
1062
- You are the final answer component of Infinity GRM.
1063
-
1064
- Answer the user's original question directly.
1065
-
1066
- A separate reasoning model has already explored the problem. Its output is
1067
- provided below as INTERNAL REASONING.
1068
-
1069
- Use that reasoning to improve accuracy, but DO NOT copy it verbatim.
1070
-
1071
- DO NOT reproduce the reasoning process.
1072
-
1073
- DO NOT describe the reasoning process unless the user explicitly asks for
1074
- an explanation.
1075
-
1076
- DO NOT say "the reasoning above", "my thought process", or similar phrases.
1077
-
1078
- DO NOT include <think> tags.
1079
-
1080
- DO NOT turn the internal reasoning into a numbered chain of thought.
1081
-
1082
- Instead, produce a clean, useful answer appropriate to the user's question.
1083
-
1084
- You may include concise explanations, calculations, code, examples, or
1085
- justification when they are useful to answer the question.
1086
-
1087
- If the internal reasoning contains an error, correct it rather than copying
1088
- it.
1089
-
1090
- If information is missing or uncertain, say so rather than inventing it.
1091
-
1092
- The final response should stand on its own and should not require the user
1093
- to read the internal reasoning.
1094
  """
1095
 
1096
 
1097
- def final_from_thinking(
1098
- query: str,
1099
- thinking: str,
1100
- history: List[Dict[str, str]],
1101
- evidence: str = "",
1102
- ) -> str:
1103
- """
1104
- Generate the final answer in a separate model pass.
1105
-
1106
- This separation prevents the thinking pass from simply becoming the
1107
- user's final answer.
1108
- """
1109
 
1110
  messages = [
1111
- {
1112
- "role": "system",
1113
- "content": FINAL_SYSTEM,
1114
- },
1115
  {
1116
  "role": "user",
1117
  "content": (
1118
- f"ORIGINAL USER QUESTION:\n"
1119
- f"{query}\n\n"
1120
- f"INTERNAL REASONING:\n"
1121
- f"{thinking[:30000]}\n\n"
1122
- f"EVIDENCE / CONTEXT:\n"
1123
- f"{evidence[:20000]}\n\n"
1124
- f"CONVERSATION HISTORY:\n"
1125
- f"{json.dumps(history[-8:], ensure_ascii=False)}\n\n"
1126
- f"Now produce only the clean final answer."
1127
  ),
1128
  },
1129
  ]
1130
 
1131
- raw = generate(
1132
- messages,
1133
- max_new_tokens=FINAL_MAX_NEW_TOKENS,
1134
- temperature=FINAL_TEMPERATURE,
1135
- )
1136
-
1137
- # The final pass should not contain reasoning tags.
1138
- final = _remove_think(raw)
1139
-
1140
- return final.strip()
1141
-
1142
-
1143
- # =====================================================================
1144
- # BACKWARD-COMPATIBLE API
1145
- # =====================================================================
1146
-
1147
 
1148
- def plan(
1149
- query: str,
1150
- history: List[Dict[str, str]],
1151
- ) -> Dict[str, Any]:
1152
- """
1153
- Backward-compatible plan() API.
1154
-
1155
- The old implementation generated a rigid numbered planning trace.
1156
- This version instead uses the free-form reasoning pass.
1157
-
1158
- The returned structure is preserved so existing callers do not break.
1159
- """
1160
-
1161
- initialize_model()
1162
-
1163
- experiences = retrieve_experiences(
1164
- query,
1165
- top_k=3,
1166
- )
1167
-
1168
- reasoning = think(
1169
- query=query,
1170
- history=history,
1171
- context="",
1172
- )
1173
 
1174
  return {
1175
- "think": reasoning,
1176
  "task": query,
1177
  "requires_web": False,
1178
  "search_queries": [],
1179
- "steps": [],
1180
- "verification": [],
1181
  "difficulty": "hard",
1182
  "experiences": experiences,
1183
  }
1184
 
1185
-
1186
- def analyze(
1187
- query: str,
1188
- plan_data: Dict[str, Any],
1189
- evidence: str,
1190
- history: List[Dict[str, str]],
1191
- ) -> str:
1192
- """
1193
- Backward-compatible analyze() API.
1194
-
1195
- Rather than forcing another predefined analysis stage, this performs
1196
- another free-form reasoning pass using the available evidence.
1197
- """
1198
-
1199
- existing_reasoning = plan_data.get(
1200
- "think",
1201
- "",
1202
- )
1203
-
1204
  messages = [
1205
- {
1206
- "role": "system",
1207
- "content": THINK_SYSTEM,
1208
- },
1209
  {
1210
  "role": "user",
1211
  "content": (
1212
- f"USER QUESTION:\n"
1213
- f"{query}\n\n"
1214
- f"EXISTING REASONING:\n"
1215
- f"{existing_reasoning[:24000]}\n\n"
1216
- f"EVIDENCE:\n"
1217
- f"{evidence[:24000]}\n\n"
1218
- f"HISTORY:\n"
1219
- f"{json.dumps(history[-8:], ensure_ascii=False)}\n\n"
1220
- "Continue reasoning freely. Reconsider the existing "
1221
- "reasoning if necessary. Correct errors, explore better "
1222
- "approaches, and determine what conclusion the evidence "
1223
- "actually supports. Do not produce a polished final answer."
1224
  ),
1225
  },
1226
  ]
 
1227
 
1228
- return generate(
1229
- messages,
1230
- max_new_tokens=THINK_MAX_NEW_TOKENS,
1231
- temperature=THINK_TEMPERATURE,
1232
- )
1233
-
1234
-
1235
- def verify(
1236
- query: str,
1237
- plan_data: Dict[str, Any],
1238
- analysis: str,
1239
- evidence: str,
1240
- ) -> str:
1241
- """
1242
- Backward-compatible verify() API.
1243
-
1244
- Verification is still available, but it is no longer presented to the
1245
- model as a fixed numbered checklist.
1246
- """
1247
 
 
 
1248
  messages = [
1249
- {
1250
- "role": "system",
1251
- "content": r"""
1252
- You are a reasoning verification engine.
1253
-
1254
- Inspect the proposed reasoning and determine whether it is actually correct.
1255
-
1256
- Do not follow a fixed checklist.
1257
-
1258
- Reason naturally about whatever could be wrong.
1259
-
1260
- You may:
1261
- - recalculate something;
1262
- - test an assumption;
1263
- - find a counterexample;
1264
- - check an edge case;
1265
- - compare an alternative interpretation;
1266
- - identify unsupported claims;
1267
- - discover a contradiction;
1268
- - confirm that the conclusion follows.
1269
-
1270
- If the reasoning is correct, explain briefly why it survives verification.
1271
-
1272
- If it is incorrect, identify the actual problem and work out the correction.
1273
-
1274
- Do not produce a polished final answer for the user.
1275
- """,
1276
- },
1277
  {
1278
  "role": "user",
1279
  "content": (
1280
- f"QUESTION:\n"
1281
- f"{query}\n\n"
1282
- f"REASONING:\n"
1283
- f"{analysis[:26000]}\n\n"
1284
- f"EVIDENCE:\n"
1285
- f"{evidence[:24000]}"
1286
  ),
1287
  },
1288
  ]
1289
-
1290
- return generate(
1291
- messages,
1292
- max_new_tokens=THINK_MAX_NEW_TOKENS,
1293
- temperature=0.05,
1294
- )
1295
 
1296
 
1297
  def final_answer(
@@ -1302,103 +775,27 @@ def final_answer(
1302
  history: List[Dict[str, str]],
1303
  verification: Optional[str] = None,
1304
  ) -> str:
 
 
 
1305
  """
1306
- Backward-compatible final_answer() API.
1307
-
1308
- The final response is always generated separately from the reasoning.
1309
- """
1310
-
1311
- verification_text = (
1312
- verification
1313
- or "No separate verification pass was supplied."
1314
- )
1315
-
1316
- thinking_material = (
1317
- f"PRIMARY REASONING:\n"
1318
- f"{analysis[:22000]}\n\n"
1319
- f"VERIFICATION:\n"
1320
- f"{verification_text[:18000]}"
1321
- )
1322
-
1323
- return final_from_thinking(
1324
- query=query,
1325
- thinking=thinking_material,
1326
- history=history,
1327
- evidence=evidence,
1328
- )
1329
-
1330
-
1331
- # =====================================================================
1332
- # FULL REASONING PIPELINE
1333
- # =====================================================================
1334
-
1335
-
1336
- def reason(
1337
- query: str,
1338
- history: Optional[List[Dict[str, str]]] = None,
1339
- evidence: str = "",
1340
- ) -> Dict[str, Any]:
1341
- """
1342
- Main reasoning pipeline.
1343
-
1344
- The important architecture is:
1345
-
1346
- question
1347
- ↓
1348
- free-form thinking
1349
- ↓
1350
- separate final-answer generation
1351
- ↓
1352
- clean answer
1353
-
1354
- No mandatory numbered reasoning procedure is imposed.
1355
- """
1356
-
1357
- if history is None:
1358
- history = []
1359
-
1360
- initialize_model()
1361
-
1362
- start = time.time()
1363
-
1364
- thinking = think(
1365
- query=query,
1366
- history=history,
1367
- context=evidence,
1368
- )
1369
-
1370
- final = final_from_thinking(
1371
- query=query,
1372
- thinking=thinking,
1373
- history=history,
1374
- evidence=evidence,
1375
- )
1376
-
1377
- elapsed = time.time() - start
1378
-
1379
- result = {
1380
- "query": query,
1381
- "thinking": thinking,
1382
- "answer": final,
1383
- "elapsed_seconds": elapsed,
1384
- }
1385
-
1386
- if SHOW_REASONING_TRACE:
1387
- result["response"] = (
1388
- f"<think>\n"
1389
- f"{thinking}\n"
1390
- f"</think>\n\n"
1391
- f"{final}"
1392
- )
1393
- else:
1394
- result["response"] = final
1395
-
1396
- return result
1397
-
1398
-
1399
- # =====================================================================
1400
- # TRACE
1401
- # =====================================================================
1402
 
1403
 
1404
  def build_reasoning_trace(
@@ -1408,48 +805,23 @@ def build_reasoning_trace(
1408
  verification: str,
1409
  final: str,
1410
  ) -> Dict[str, Any]:
1411
- """
1412
- Return a detailed visible trace of the reasoning pipeline.
1413
-
1414
- Kept for compatibility with existing callers.
1415
- """
1416
-
1417
  return {
1418
  "query": query,
1419
- "demonstration_count": len(
1420
- REASONING_EXAMPLES
1421
- ),
1422
  "stages": [
1423
  {
1424
- "stage": "free_form_reasoning",
1425
- "reasoning_summary": plan_data.get(
1426
- "think",
1427
- "",
1428
- ),
1429
  "structured_plan": plan_data,
1430
  },
1431
- _make_trace(
1432
- "continued_reasoning",
1433
- analysis,
1434
- ),
1435
- _make_trace(
1436
- "verification",
1437
- verification,
1438
- ),
1439
- {
1440
- "stage": "final_synthesis",
1441
- "reasoning_summary": "",
1442
- "output": _remove_think(final),
1443
- },
1444
  ],
1445
  }
1446
 
1447
 
1448
- # =====================================================================
1449
- # LEARNING
1450
- # =====================================================================
1451
-
1452
-
1453
  def learn_from_result(
1454
  query: str,
1455
  plan_data: Dict[str, Any],
@@ -1458,51 +830,20 @@ def learn_from_result(
1458
  quality: float = 1.0,
1459
  ):
1460
  initialize_model()
1461
-
1462
  save_experience(
1463
  query=query,
1464
- plan=json.dumps(
1465
- plan_data,
1466
- ensure_ascii=False,
1467
- ),
1468
  analysis=analysis,
1469
  answer=answer,
1470
  quality=quality,
1471
  )
1472
 
1473
 
1474
- # =====================================================================
1475
- # INITIALIZATION
1476
- # =====================================================================
1477
-
1478
-
1479
  def initialize():
1480
  initialize_model()
1481
 
1482
 
1483
- # =====================================================================
1484
- # MAIN
1485
- # =====================================================================
1486
-
1487
-
1488
  if __name__ == "__main__":
1489
  initialize()
1490
-
1491
- print(
1492
- "Infinity GRM reasoning engine initialized."
1493
- )
1494
-
1495
- print(
1496
- f"Structured reasoning demonstrations: "
1497
- f"{len(REASONING_EXAMPLES)}"
1498
- )
1499
-
1500
- print(
1501
- f"Free-form thinking budget: "
1502
- f"{THINK_MAX_NEW_TOKENS} tokens"
1503
- )
1504
-
1505
- print(
1506
- f"Final answer budget: "
1507
- f"{FINAL_MAX_NEW_TOKENS} tokens"
1508
- )
 
2
  Infinity GRM - Reasoning Engine
3
  ================================
4
  Standalone cognitive/reasoning layer for Infinity GRM.
 
5
  Features
6
  --------
7
  - Qwen2.5-7B-Instruct reasoning model
8
  - 700 structured reasoning demonstrations by default
9
  - Semantic retrieval of relevant demonstrations
10
+ - Planning -> analysis -> verification -> final synthesis
11
  - Persistent SQLite experience memory
12
+ - Optional detailed, user-visible reasoning TRACE (not raw hidden CoT)
13
  - Backward-compatible plan()/analyze()/final_answer() API
14
+ Environment
15
+ -----------
16
+ GRM_MODEL=Qwen/Qwen2.5-7B-Instruct
17
+ GRM_EXAMPLE_TARGET=700 # clamped to 500..1000
18
+ GRM_MEMORY_DB=./grm_experience.sqlite3
19
+ GRM_SHOW_REASONING_TRACE=1 # default enabled for detailed trace output
20
  Important
21
  ---------
22
  The demonstration library is structured training-style material used at
23
  inference time. It does not change the neural weights of the base model.
24
  For model-weight improvement, use a separate SFT/QLoRA training pipeline.
 
 
 
 
 
 
 
 
 
25
  """
26
 
27
  import os
 
38
  from sentence_transformers import SentenceTransformer
39
  from transformers import AutoTokenizer, AutoModelForCausalLM, AutoConfig
40
 
 
41
  logger = logging.getLogger("infinitygrm.reasoning")
42
 
43
+ MODEL_NAME = os.getenv("GRM_MODEL", "Qwen/Qwen2.5-7B-Instruct")
44
+ MEMORY_DB = Path(os.getenv("GRM_MEMORY_DB", "./grm_experience.sqlite3"))
45
+ EXAMPLE_TARGET = max(500, min(1000, int(os.getenv("GRM_EXAMPLE_TARGET", "700"))))
46
+ SHOW_REASONING_TRACE = os.getenv("GRM_SHOW_REASONING_TRACE", "1").lower() not in {"0", "false", "no"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
 
48
  STATE: Dict[str, Any] = {
49
  "model": None,
 
64
  ("mathematics", "probability", "define the sample space, identify independence/dependence, compute and sanity-check probabilities"),
65
  ("mathematics", "statistics", "identify the estimator or test, state assumptions, calculate, interpret uncertainty"),
66
  ("mathematics", "calculus", "identify the derivative/integral rule, apply it carefully, verify with boundary or dimensional checks"),
 
67
  ("algorithms", "complexity", "identify the dominant operation, count repeated work, derive asymptotic time and space complexity"),
68
  ("algorithms", "sorting", "choose an algorithm based on constraints, preserve correctness invariants, analyze complexity"),
69
  ("algorithms", "graphs", "model entities as vertices and relationships as edges, choose traversal/shortest-path method, verify reachability"),
70
  ("algorithms", "dynamic programming", "define state, transition, base case, evaluation order, and prove that states cover all cases"),
71
  ("algorithms", "greedy methods", "define a locally optimal choice, establish the invariant/exchange argument, then verify feasibility"),
 
72
  ("coding", "Python debugging", "reproduce the failure, inspect the smallest relevant state, identify the root cause, patch and retest"),
73
  ("coding", "data structures", "identify access/update requirements, select an appropriate structure, define invariants and complexity"),
74
  ("coding", "API design", "define inputs/outputs/errors, preserve contracts, validate data, and design deterministic behavior"),
75
  ("coding", "concurrency", "identify shared state, define synchronization boundaries, avoid races/deadlocks, and test interleavings"),
76
  ("coding", "optimization", "measure the bottleneck, improve the dominant cost, preserve semantics, and benchmark before/after"),
77
  ("coding", "machine learning", "separate data/model/objective/evaluation, identify leakage risks, train, validate, and test independently"),
 
78
  ("science", "physics", "translate the situation into variables and laws, keep units consistent, solve symbolically, then sanity-check"),
79
  ("science", "chemistry", "identify substances and governing conservation laws, balance the reaction/model, calculate, and check stoichiometry"),
80
  ("science", "biology", "identify the mechanism, distinguish correlation from causation, connect evidence to the proposed biological process"),
 
81
  ("engineering", "systems", "decompose components and interfaces, identify bottlenecks/failure modes, design controls and verify requirements"),
82
  ("engineering", "electronics", "define voltage/current/power relationships, inspect component constraints, calculate worst case, verify margins"),
 
83
  ("logic", "deduction", "translate statements into premises, derive consequences, test alternatives, and distinguish valid inference from assumption"),
84
  ("logic", "constraint solving", "list variables/domains/constraints, propagate restrictions, branch only when needed, verify every constraint"),
 
85
  ("software engineering", "architecture", "identify requirements and boundaries, choose components/interfaces, evaluate tradeoffs, and define failure handling"),
86
  ("software engineering", "testing", "identify observable behavior, partition cases, include edge cases, assert invariants, and test regressions"),
87
  ("software engineering", "security review", "map trust boundaries, identify attack surfaces, validate inputs/authorization, and verify mitigations"),
 
88
  ("mathematics", "arithmetic", "break the problem into operations, preserve order of operations, calculate carefully, and independently verify the result"),
89
  ("mathematics", "fractions", "convert representations consistently, identify common denominators when needed, perform the operation, simplify, and verify"),
90
  ("mathematics", "ratios", "identify corresponding quantities, establish the ratio relationship, solve proportionally, and check whether the result has the correct scale"),
 
117
  ("mathematics", "statistical inference", "identify the parameter of interest, select an appropriate estimator or test, state assumptions, calculate uncertainty, and interpret cautiously"),
118
  ("mathematics", "data interpretation", "identify what the axes, units, sample, and statistic actually represent, calculate relevant comparisons, and avoid unsupported causal conclusions"),
119
 
120
+ # --------------------------- LOGIC -----------------------------
121
+
122
  ("logic", "formal logic", "translate statements into propositions, identify premises and conclusions, apply valid inference rules, and distinguish implication from equivalence"),
123
  ("logic", "syllogisms", "identify premises, determine their logical structure, derive only conclusions supported by the premises, and test for counterexamples"),
124
  ("logic", "inductive reasoning", "identify observed patterns, generate the strongest supported generalization, distinguish evidence from certainty, and identify possible counterexamples"),
 
135
  ("logic", "proof by induction", "define the base case, formulate the induction hypothesis precisely, prove the inductive step, and conclude only what the induction establishes"),
136
  ("logic", "necessary and sufficient conditions", "distinguish conditions that guarantee a result from those merely required for it, prove each direction separately, and identify edge cases"),
137
 
138
+ # ---------------------- GENERAL PROBLEM SOLVING -----------------
139
+
140
  ("reasoning", "problem decomposition", "divide the problem into independent or dependent subproblems, solve the highest-leverage components first, then integrate and verify"),
141
  ("reasoning", "root cause analysis", "separate symptoms from causes, construct a causal chain, test competing explanations against evidence, and identify the deepest actionable cause"),
142
  ("reasoning", "first principles", "strip the problem down to fundamental facts and constraints, derive consequences from those foundations, and avoid relying on unsupported assumptions"),
 
160
  ("reasoning", "decision under uncertainty", "identify possible actions, outcomes, probabilities or uncertainty ranges where available, costs and benefits, and sensitivity to assumptions"),
161
  ("reasoning", "prioritization", "identify objectives, urgency, impact, dependencies, and resource constraints, then construct a defensible ordering without confusing importance with urgency"),
162
 
163
+ # -------------------------- SCIENCE ----------------------------
164
+
165
  ("science", "scientific method", "formulate a testable hypothesis, identify variables and controls, predict observations, evaluate evidence, and distinguish results from interpretation"),
166
  ("science", "experimental design", "define the research question, identify independent/dependent/control variables, minimize confounding, choose measurements, and define success criteria"),
167
  ("science", "measurement", "identify the quantity and units, distinguish precision from accuracy, track uncertainty, and verify dimensional consistency"),
 
180
  ("science", "evolutionary reasoning", "identify variation, inheritance, selection pressures, and population-level effects, then distinguish individual adaptation from population change"),
181
  ("science", "scientific evidence evaluation", "identify study design, sample, measurement, controls, effect size, uncertainty, and limitations before interpreting the conclusion"),
182
 
183
+ # ------------------------ ENGINEERING --------------------------
184
+
185
  ("engineering", "requirements analysis", "translate vague goals into measurable requirements, identify constraints and acceptance criteria, and distinguish mandatory requirements from preferences"),
186
  ("engineering", "failure mode analysis", "identify components and failure modes, estimate causes and effects, prioritize risks, and design mitigations and detection mechanisms"),
187
  ("engineering", "reliability", "identify failure mechanisms, estimate rates or probabilities, model system dependencies, and determine how redundancy or maintenance affects reliability"),
 
193
  ("engineering", "signal analysis", "identify the signal, noise, sampling constraints, frequency characteristics, and measurement objectives, then select an appropriate analysis method"),
194
  ("engineering", "design validation", "translate requirements into measurable tests, construct representative test conditions, define pass/fail criteria, execute checks, and document limitations"),
195
 
196
+ # ---------------------- COMPUTER SCIENCE ------------------------
197
+
198
  ("computer science", "recursion", "define the base case, identify the recursive reduction, prove progress toward termination, and verify returned values"),
199
  ("computer science", "search", "define the search space and target condition, choose an appropriate search strategy, preserve completeness/correctness, and analyze complexity"),
200
  ("computer science", "binary search", "establish the sorted invariant, maintain valid bounds, choose the midpoint safely, eliminate the impossible half, and verify termination"),
 
210
  ("computer science", "algorithm correctness", "state the invariant or correctness condition, show initialization, preservation, and termination where appropriate, and verify edge cases"),
211
  ("computer science", "amortized analysis", "identify operations whose costs vary, select an accounting/potential method, derive aggregate cost, and convert it to amortized complexity"),
212
 
213
+ # ---------------------- SOFTWARE PRACTICE -----------------------
214
+
215
  ("software engineering", "requirements clarification", "separate explicit requirements from assumptions, identify ambiguities and edge cases, and define observable acceptance criteria"),
216
  ("software engineering", "code review", "inspect correctness, maintainability, security, performance, error handling, and compatibility, prioritizing concrete defects over stylistic preferences"),
217
  ("software engineering", "refactoring", "identify the behavior that must remain unchanged, isolate structural improvements, make small transformations, and run regression checks"),
 
223
  ("software engineering", "maintainability", "identify coupling, cohesion, duplication, unclear contracts, and hidden dependencies, then improve structure while preserving observable behavior"),
224
  ("software engineering", "documentation reasoning", "identify the intended audience and task, explain prerequisites and behavior accurately, include examples where useful, and avoid documenting assumptions as guarantees"),
225
 
226
+ # --------------------- LANGUAGE & COMMUNICATION -----------------
227
+
228
  ("language", "reading comprehension", "identify the main claim, supporting evidence, qualifications, assumptions, and conclusions before answering questions about the text"),
229
  ("language", "text analysis", "separate explicit statements from implications, identify structure and evidence, and avoid attributing claims that the text does not support"),
230
  ("language", "summarization", "identify the central information and supporting points, remove redundancy, preserve important qualifications, and avoid introducing new claims"),
 
237
  ("language", "translation reasoning", "preserve meaning, intent, register, ambiguity, and important technical terminology rather than translating words mechanically"),
238
  ]
239
 
 
240
  _VARIANTS = [
241
  "direct solution with explicit assumptions",
242
  "edge-case-heavy solution",
 
251
  ]
252
 
253
 
254
+ def _build_reasoning_examples(target: int = EXAMPLE_TARGET) -> List[Dict[str, Any]]:
255
+ """Create a deterministic library of structured reasoning demonstrations.
256
+ These are inference-time demonstrations rather than weight updates. The
257
+ generator deliberately stores reasoning as concise, inspectable steps,
258
+ not unrestricted hidden chain-of-thought.
 
 
259
  """
 
260
  examples: List[Dict[str, Any]] = []
 
261
  idx = 0
262
  skill_count = len(_REASONING_SKILLS)
263
 
264
  while len(examples) < target:
265
+ domain, skill, principle = _REASONING_SKILLS[idx % skill_count]
266
+ variant = _VARIANTS[(idx // skill_count) % len(_VARIANTS)]
267
+ difficulty = ("medium", "hard", "expert")[(idx // (skill_count * 3)) % 3]
 
 
 
 
 
 
 
 
 
 
 
 
268
 
269
  problem = (
270
  f"Solve a {skill} problem using a {variant} approach. "
 
286
  ]
287
 
288
  solution = (
289
+ f"Use the {skill} method appropriate to the stated constraints; explicitly state assumptions, "
290
+ "derive the result in ordered steps, then verify the result against the original problem."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
  )
292
 
293
+ examples.append({
294
+ "id": idx + 1,
295
+ "domain": domain,
296
+ "skill": skill,
297
+ "difficulty": difficulty,
298
+ "problem": problem,
299
+ "reasoning_trace": steps,
300
+ "verification": verification,
301
+ "solution": solution,
302
+ })
303
  idx += 1
304
 
305
  return examples
306
 
307
 
308
+ # IMPORTANT: this is the actual definition that was missing in the broken file.
309
+ REASONING_EXAMPLES: List[Dict[str, Any]] = _build_reasoning_examples(EXAMPLE_TARGET)
 
310
 
311
 
312
+ def _format_reasoning_examples(query: str, top_k: int = 6) -> str:
313
+ """Return the most relevant structured demonstrations for a query."""
 
 
 
 
 
 
314
  if not REASONING_EXAMPLES:
315
  return "No demonstrations available."
316
 
317
  embed_model = STATE.get("embed_model")
 
318
  if embed_model is None:
319
+ # Safe fallback before model initialization.
320
  selected = REASONING_EXAMPLES[:top_k]
 
321
  else:
322
  try:
323
  if STATE.get("reasoning_example_embeddings") is None:
324
  texts = [
325
+ f"{x['domain']} {x['skill']} {x['problem']} {x['solution']}"
 
 
 
 
 
326
  for x in REASONING_EXAMPLES
327
  ]
328
+ STATE["reasoning_example_embeddings"] = embed_model.encode(
329
+ texts,
330
+ normalize_embeddings=True,
331
+ convert_to_numpy=True,
332
+ show_progress_bar=False,
 
 
 
333
  )
334
 
335
  qv = _embed(query)
336
+ matrix = STATE["reasoning_example_embeddings"]
 
 
 
 
337
  scores = matrix @ qv
 
338
  indices = np.argsort(scores)[::-1][:top_k]
339
+ selected = [REASONING_EXAMPLES[int(i)] for i in indices]
 
 
 
 
 
340
  except Exception as exc:
341
+ logger.warning("Reasoning example retrieval failed: %s", exc)
 
 
 
342
  selected = REASONING_EXAMPLES[:top_k]
343
 
344
  blocks = []
 
345
  for ex in selected:
346
  blocks.append(
347
  "EXAMPLE {id} | {domain}/{skill} | difficulty={difficulty}\n"
348
  "Problem pattern: {problem}\n"
349
+ "Reasoning steps:\n- {steps}\n"
350
+ "Verification:\n- {verification}\n"
351
  "Solution pattern: {solution}".format(
352
  id=ex["id"],
353
  domain=ex["domain"],
354
  skill=ex["skill"],
355
  difficulty=ex["difficulty"],
356
  problem=ex["problem"],
357
+ steps="\n- ".join(ex["reasoning_trace"]),
358
+ verification="\n- ".join(ex["verification"]),
 
 
 
 
359
  solution=ex["solution"],
360
  )
361
  )
 
362
  return "\n\n".join(blocks)
363
 
364
 
 
368
 
369
 
370
  def initialize_model():
371
+ """Load the language and embedding models once."""
 
 
 
372
  if STATE.get("model") is not None:
373
  return
374
 
375
+ device = "cuda" if torch.cuda.is_available() else "cpu"
376
+ dtype = torch.float16 if device == "cuda" else torch.float32
 
 
 
377
 
378
+ logger.info("Loading reasoning model: %s", MODEL_NAME)
 
 
 
 
 
 
 
 
 
 
 
 
 
379
 
380
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
381
  if tokenizer.pad_token is None:
382
  tokenizer.pad_token = tokenizer.eos_token
383
 
384
+ config = AutoConfig.from_pretrained(MODEL_NAME)
 
 
 
385
  config.pad_token_id = tokenizer.eos_token_id
386
 
387
  model = AutoModelForCausalLM.from_pretrained(
388
  MODEL_NAME,
389
  config=config,
390
  torch_dtype=dtype,
391
+ device_map="auto" if device == "cuda" else None,
 
 
 
 
392
  ).eval()
393
 
394
  embed_model = SentenceTransformer(
 
404
  )
405
 
406
  initialize_memory()
407
+ logger.info("Reasoning engine initialized on %s with %d demonstrations", device, len(REASONING_EXAMPLES))
 
 
 
 
 
408
 
409
 
410
  # =====================================================================
 
413
 
414
 
415
  def initialize_memory():
416
+ MEMORY_DB.parent.mkdir(parents=True, exist_ok=True)
 
 
 
 
417
  with sqlite3.connect(MEMORY_DB) as db:
418
  db.execute(
419
  """
 
428
  )
429
  """
430
  )
 
431
  db.commit()
432
 
433
 
434
  def _embed(text: str) -> np.ndarray:
435
  model = STATE["embed_model"]
 
436
  return model.encode(
437
  [text],
438
  normalize_embeddings=True,
 
441
  )[0]
442
 
443
 
444
+ def _ensure_experience_embedding_column(conn: sqlite3.Connection) -> None:
445
+ """Ensure the experience table has a BLOB column for precomputed embeddings."""
 
 
 
 
 
446
  columns = {
447
+ row[1] for row in conn.execute("PRAGMA table_info(experiences)").fetchall()
 
 
 
448
  }
 
449
  if "embedding" not in columns:
450
+ conn.execute("ALTER TABLE experiences ADD COLUMN embedding BLOB")
 
 
 
 
451
  conn.commit()
452
 
453
 
454
+ def _embedding_to_blob(vector: Optional[np.ndarray]) -> Optional[bytes]:
 
 
 
455
  if vector is None:
456
  return None
457
+ arr = np.asarray(vector, dtype=np.float32).reshape(-1)
 
 
 
 
 
458
  return arr.tobytes()
459
 
460
 
461
+ def _blob_to_embedding(blob: Optional[bytes]) -> Optional[np.ndarray]:
 
 
 
462
  if blob is None:
463
  return None
464
+ return np.frombuffer(blob, dtype=np.float32).copy()
465
 
 
 
 
 
466
 
467
+ def save_experience(query: str, plan: str, analysis: str, answer: str, quality: float = 1.0):
 
 
 
 
 
 
 
468
  try:
469
  with sqlite3.connect(MEMORY_DB) as db:
470
  db.execute(
 
473
  (query, plan, analysis, answer, quality, created)
474
  VALUES (?, ?, ?, ?, ?, ?)
475
  """,
476
+ (query, plan, analysis, answer, float(quality), time.time()),
 
 
 
 
 
 
 
477
  )
 
478
  db.commit()
 
479
  except Exception as exc:
480
+ logger.warning("Could not save experience: %s", exc)
 
 
 
 
481
 
 
 
 
 
482
 
483
+ def retrieve_experiences(query: str, top_k: int = 3) -> List[Dict[str, Any]]:
484
  try:
485
  with sqlite3.connect(MEMORY_DB) as db:
486
  rows = db.execute(
487
  """
488
+ SELECT id, query, plan, analysis, answer, quality, created
 
 
 
 
 
 
 
489
  FROM experiences
490
  WHERE quality >= 0.5
491
  ORDER BY created DESC
 
496
  if not rows:
497
  return []
498
 
499
+ # 1. Get the embedding model from STATE
500
+ embed_model = STATE.get("embed_model")
 
 
501
  if embed_model is None:
502
+ # Fallback if model isn't initialized yet
503
  return []
504
 
505
+ # 2. Embed the incoming user query
506
  qv = _embed(query)
507
 
508
+ # 3. Batch embed all historical queries retrieved from the database
509
+ db_queries = [row[1] for row in rows]
 
 
 
510
  rv_matrix = embed_model.encode(
511
  db_queries,
512
  normalize_embeddings=True,
513
  convert_to_numpy=True,
514
+ show_progress_bar=False
515
  )
516
 
517
+ # 4. Use matrix multiplication to calculate all scores simultaneously
518
  scores = rv_matrix @ qv
519
 
520
+ # 5. Pair scores back up with their rows and sort
521
+ scored = [(float(score), row) for score, row in zip(scores, rows)]
522
+ scored.sort(key=lambda x: x[0], reverse=True)
 
 
 
 
 
 
 
 
 
 
523
 
524
  return [
525
  {
 
530
  "answer": row[4],
531
  "quality": row[5],
532
  }
533
+ # Slid down to only return the top_k best matches
534
+ for score, row in scored[:top_k]
535
  ]
 
536
  except Exception as exc:
537
+ logger.warning("Experience retrieval failed: %s", exc)
 
 
 
 
538
  return []
539
 
540
 
541
  # =====================================================================
542
+ # GENERATION + TRACE EXTRACTION
543
  # =====================================================================
544
 
545
 
546
+ def generate(messages: List[Dict[str, str]], max_new_tokens: int = 1024, temperature: float = 0.15) -> str:
547
+ """Run one model pass."""
 
 
 
 
 
 
 
 
 
 
 
548
  initialize_model()
549
 
550
  tokenizer = STATE["tokenizer"]
551
  model = STATE["model"]
552
 
553
+ prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
554
+ inputs = tokenizer(prompt, return_tensors="pt")
555
+ inputs = {k: v.to(model.device) for k, v in inputs.items()}
 
 
 
 
 
 
 
 
 
 
 
 
556
 
557
  generation_kwargs = {
558
  "max_new_tokens": max_new_tokens,
559
  "repetition_penalty": 1.05,
560
  "pad_token_id": tokenizer.eos_token_id,
561
  }
 
562
  if temperature > 0:
563
+ generation_kwargs.update({"temperature": temperature, "top_p": 0.90, "do_sample": True})
 
 
 
 
 
 
 
564
  else:
565
+ generation_kwargs.update({"do_sample": False})
 
 
 
 
566
 
567
  with torch.no_grad():
568
+ output = model.generate(**inputs, **generation_kwargs)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
569
 
570
+ new_tokens = output[0][inputs["input_ids"].shape[1]:]
571
+ return tokenizer.decode(new_tokens, skip_special_tokens=True).strip()
572
 
 
 
 
 
 
 
 
 
 
573
 
574
+ def _extract_think(text: str) -> str:
575
+ """Extract the model's explicit <think> section if it emitted one."""
576
+ match = re.search(r"<think>\s*(.*?)\s*</think>", text, flags=re.IGNORECASE | re.DOTALL)
577
+ return match.group(1).strip() if match else ""
578
 
 
 
 
 
 
579
 
580
+ def clean_think_block(text: str) -> str:
581
+ """Return a bounded visible reasoning trace plus the model output.
582
+ We intentionally expose a structured reasoning summary rather than
583
+ pretending that an arbitrary generated <think> block is a faithful dump
584
+ of private internal cognition.
585
  """
 
586
  text = text.strip()
 
587
  think = _extract_think(text)
588
+ body = re.sub(r"<think>.*?</think>", "", text, flags=re.IGNORECASE | re.DOTALL).strip()
 
589
 
590
  if not body:
591
+ body = text.replace("<think>", "").replace("</think>", "").strip()
 
 
 
 
 
 
592
 
593
  if SHOW_REASONING_TRACE and think:
594
+ return f"<think>\n{think}\n</think>\n\n{body}".strip()
 
 
 
 
 
 
595
  return body
596
 
597
 
598
+ def _make_trace(stage: str, text: str) -> Dict[str, Any]:
599
+ """Create an inspectable stage trace from the explicit model output."""
 
 
 
600
  think = _extract_think(text)
601
+ body = re.sub(r"<think>.*?</think>", "", text, flags=re.IGNORECASE | re.DOTALL).strip()
 
 
602
  return {
603
  "stage": stage,
604
  "reasoning_summary": think,
 
607
 
608
 
609
  # =====================================================================
610
+ # COGNITIVE PASSES
611
  # =====================================================================
612
 
613
+ PLANNER_SYSTEM = r"""
614
+ You are the planning component of Infinity GRM.
615
+ Produce a detailed but concise, inspectable reasoning trace. This is a
616
+ user-visible explanation of decisions, not a claim that it exposes private
617
+ hidden cognition.
618
+ You must:
619
+ - identify the actual task;
620
+ - identify constraints and assumptions;
621
+ - determine whether external information is required;
622
+ - identify useful subproblems;
623
+ - choose appropriate reasoning methods;
624
+ - identify what should be verified;
625
+ - avoid inventing facts.
626
+ Return:
627
+ <think>
628
+ 1. Task interpretation
629
+ 2. Key assumptions/constraints
630
+ 3. Chosen method and why
631
+ 4. Subproblem decomposition
632
+ 5. Verification plan
633
+ </think>
634
+ Then return JSON with:
635
+ {
636
+ "task": "...",
637
+ "requires_web": true/false,
638
+ "search_queries": ["..."],
639
+ "steps": ["..."],
640
+ "verification": ["..."],
641
+ "difficulty": "easy|medium|hard|expert"
642
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
643
  """
644
 
645
+ ANALYST_SYSTEM = r"""
646
+ You are the evidence-analysis component of Infinity GRM.
647
+ Give a detailed, inspectable reasoning summary. Do not merely restate the
648
+ answer. Explicitly identify evidence, assumptions, contradictions, missing
649
+ information, calculations, and verification checks.
650
+ Return:
651
+ <think>
652
+ 1. What the evidence establishes
653
+ 2. What it does not establish
654
+ 3. Important calculations/inferences
655
+ 4. Contradictions or uncertainty
656
+ 5. Verification result
657
+ </think>
658
+ Then provide the analyzed conclusion.
659
+ """
660
 
661
+ VERIFIER_SYSTEM = r"""
662
+ You are the verification component of Infinity GRM.
663
+ Audit the proposed analysis. Check correctness, unsupported claims,
664
+ calculations, edge cases, source consistency, and whether the conclusion
665
+ actually follows.
666
+ Return:
667
+ <think>
668
+ 1. Claim-by-claim checks
669
+ 2. Error/edge-case checks
670
+ 3. Independent sanity check
671
+ 4. Corrections required
672
+ 5. Final verification status
673
+ </think>
674
+ Then provide a concise verification report.
675
+ """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
676
 
677
  FINAL_SYSTEM = r"""
678
+ You are the final synthesis component of Infinity GRM.
679
+ Answer the user directly using the plan, analysis, verification, and evidence.
680
+ Do not invent facts. If uncertainty remains, state it precisely.
681
+ Return:
682
+ <think>
683
+ 1. What was established
684
+ 2. How the verification affected the result
685
+ 3. What answer follows
686
+ 4. Any material caveat
687
+ </think>
688
+ Then give the final answer in a useful format.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
689
  """
690
 
691
 
692
+ def plan(query: str, history: List[Dict[str, str]]) -> Dict[str, Any]:
693
+ # FIX: Initialize models here so retrieve_experiences has access to the embedding model
694
+ initialize_model()
695
+
696
+ experiences = retrieve_experiences(query, top_k=3)
697
+ experience_text = json.dumps(experiences, ensure_ascii=False, indent=2)
 
 
 
 
 
 
698
 
699
  messages = [
700
+ {"role": "system", "content": PLANNER_SYSTEM},
 
 
 
701
  {
702
  "role": "user",
703
  "content": (
704
+ f"QUESTION:\n{query}\n\n"
705
+ f"HISTORY:\n{json.dumps(history[-6:], ensure_ascii=False)}\n\n"
706
+ f"PRIOR EXPERIENCES:\n{experience_text}\n\n"
707
+ f"RELEVANT REASONING DEMONSTRATIONS:\n{_format_reasoning_examples(query, top_k=8)}"
 
 
 
 
 
708
  ),
709
  },
710
  ]
711
 
712
+ raw = generate(messages, max_new_tokens=1400, temperature=0.10)
713
+ think = _extract_think(raw)
714
+ json_match = re.search(r"\{.*\}", raw, flags=re.DOTALL)
 
 
 
 
 
 
 
 
 
 
 
 
 
715
 
716
+ if json_match:
717
+ try:
718
+ data = json.loads(json_match.group(0))
719
+ data["think"] = think
720
+ data["experiences"] = experiences
721
+ return data
722
+ except json.JSONDecodeError:
723
+ pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
724
 
725
  return {
726
+ "think": think,
727
  "task": query,
728
  "requires_web": False,
729
  "search_queries": [],
730
+ "steps": ["Clarify the task", "Solve using the most appropriate method", "Verify the result"],
731
+ "verification": ["Check assumptions and edge cases"],
732
  "difficulty": "hard",
733
  "experiences": experiences,
734
  }
735
 
736
+ def analyze(query: str, plan_data: Dict[str, Any], evidence: str, history: List[Dict[str, str]]) -> str:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
737
  messages = [
738
+ {"role": "system", "content": ANALYST_SYSTEM},
 
 
 
739
  {
740
  "role": "user",
741
  "content": (
742
+ f"QUESTION:\n{query}\n\n"
743
+ f"PLAN:\n{json.dumps(plan_data, indent=2)}\n\n"
744
+ f"EVIDENCE:\n{evidence[:20000]}\n\n"
745
+ f"HISTORY:\n{json.dumps(history[-6:], ensure_ascii=False)}\n\n"
746
+ f"RELEVANT REASONING DEMONSTRATIONS:\n{_format_reasoning_examples(query, top_k=6)}"
 
 
 
 
 
 
 
747
  ),
748
  },
749
  ]
750
+ return generate(messages, max_new_tokens=1600, temperature=0.10)
751
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
752
 
753
+ def verify(query: str, plan_data: Dict[str, Any], analysis: str, evidence: str) -> str:
754
+ """Independent verification pass."""
755
  messages = [
756
+ {"role": "system", "content": VERIFIER_SYSTEM},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
757
  {
758
  "role": "user",
759
  "content": (
760
+ f"QUESTION:\n{query}\n\n"
761
+ f"PLAN:\n{json.dumps(plan_data, indent=2)}\n\n"
762
+ f"ANALYSIS:\n{analysis[:18000]}\n\n"
763
+ f"EVIDENCE:\n{evidence[:20000]}"
 
 
764
  ),
765
  },
766
  ]
767
+ return generate(messages, max_new_tokens=1400, temperature=0.05)
 
 
 
 
 
768
 
769
 
770
  def final_answer(
 
775
  history: List[Dict[str, str]],
776
  verification: Optional[str] = None,
777
  ) -> str:
778
+ """Final reasoning/synthesis pass.
779
+ `verification` is optional to preserve compatibility with the previous
780
+ five-argument search pipeline.
781
  """
782
+ verification_text = verification or "No separate verification pass was supplied."
783
+ messages = [
784
+ {"role": "system", "content": FINAL_SYSTEM},
785
+ {
786
+ "role": "user",
787
+ "content": (
788
+ f"QUESTION:\n{query}\n\n"
789
+ f"PLAN:\n{json.dumps(plan_data, indent=2)}\n\n"
790
+ f"ANALYSIS:\n{analysis[:18000]}\n\n"
791
+ f"VERIFICATION:\n{verification_text[:16000]}\n\n"
792
+ f"EVIDENCE:\n{evidence[:20000]}\n\n"
793
+ f"HISTORY:\n{json.dumps(history[-8:], ensure_ascii=False)}\n\n"
794
+ f"RELEVANT REASONING DEMONSTRATIONS:\n{_format_reasoning_examples(query, top_k=6)}"
795
+ ),
796
+ },
797
+ ]
798
+ return generate(messages, max_new_tokens=2200, temperature=0.10)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
799
 
800
 
801
  def build_reasoning_trace(
 
805
  verification: str,
806
  final: str,
807
  ) -> Dict[str, Any]:
808
+ """Return a detailed visible trace of the reasoning pipeline."""
 
 
 
 
 
809
  return {
810
  "query": query,
811
+ "demonstration_count": len(REASONING_EXAMPLES),
 
 
812
  "stages": [
813
  {
814
+ "stage": "planning",
815
+ "reasoning_summary": plan_data.get("think", ""),
 
 
 
816
  "structured_plan": plan_data,
817
  },
818
+ _make_trace("analysis", analysis),
819
+ _make_trace("verification", verification),
820
+ _make_trace("final_synthesis", final),
 
 
 
 
 
 
 
 
 
 
821
  ],
822
  }
823
 
824
 
 
 
 
 
 
825
  def learn_from_result(
826
  query: str,
827
  plan_data: Dict[str, Any],
 
830
  quality: float = 1.0,
831
  ):
832
  initialize_model()
 
833
  save_experience(
834
  query=query,
835
+ plan=json.dumps(plan_data, ensure_ascii=False),
 
 
 
836
  analysis=analysis,
837
  answer=answer,
838
  quality=quality,
839
  )
840
 
841
 
 
 
 
 
 
842
  def initialize():
843
  initialize_model()
844
 
845
 
 
 
 
 
 
846
  if __name__ == "__main__":
847
  initialize()
848
+ print("Infinity GRM reasoning engine initialized.")
849
+ print(f"Structured reasoning demonstrations: {len(REASONING_EXAMPLES)}")