Coverage for /home/admin/Documents/AI/applications/lexigram-dev/lexigram/experimental/ai/lexigram-ai-rag/src/lexigram/ai/rag/reasoning/base.py: 100%

45 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-25 07:19 +0800

1from __future__ import annotations 

2 

3from abc import ABC, abstractmethod 

4from dataclasses import dataclass, field 

5from enum import StrEnum 

6from typing import Any 

7 

8 

9class ReasoningStrategy(StrEnum): 

10 """Available reasoning strategies.""" 

11 

12 MULTI_HOP = "multi_hop" 

13 CHAIN_OF_THOUGHT = "chain_of_thought" 

14 DECOMPOSITION = "decomposition" 

15 ITERATIVE_REFINEMENT = "iterative_refinement" 

16 

17 

18@dataclass 

19class ReasoningStep: 

20 """A single step in the reasoning process. 

21 

22 Attributes: 

23 step_number: The step number in the reasoning sequence. 

24 question: The question being asked in this step. 

25 context: Retrieved context for this step. 

26 reasoning: The reasoning or thought process for this step. 

27 answer: The answer derived from this step. 

28 confidence: Confidence score for this step (0.0 to 1.0). 

29 metadata: Additional step metadata. 

30 """ 

31 

32 step_number: int 

33 question: str 

34 context: list[Any] = field(default_factory=list) 

35 reasoning: str = "" 

36 answer: str = "" 

37 confidence: float = 0.0 

38 metadata: dict = field(default_factory=dict) 

39 

40 def __repr__(self) -> str: 

41 """String representation.""" 

42 return ( 

43 f"ReasoningStep(step={self.step_number}, " 

44 f"question='{self.question[:50]}...', " 

45 f"confidence={self.confidence:.2f})" 

46 ) 

47 

48 

49@dataclass 

50class ReasoningResult: 

51 """Result of multi-hop reasoning. 

52 

53 Attributes: 

54 query: Original query. 

55 final_answer: Final answer after all reasoning steps. 

56 steps: List of reasoning steps taken. 

57 strategy: Strategy used for reasoning. 

58 total_hops: Total number of reasoning hops. 

59 overall_confidence: Overall confidence in the answer. 

60 metadata: Additional result metadata. 

61 """ 

62 

63 query: str 

64 final_answer: str 

65 steps: list[ReasoningStep] = field(default_factory=list) 

66 strategy: ReasoningStrategy = ReasoningStrategy.MULTI_HOP 

67 total_hops: int = 0 

68 overall_confidence: float = 0.0 

69 metadata: dict = field(default_factory=dict) 

70 

71 def __repr__(self) -> str: 

72 """String representation.""" 

73 return ( 

74 f"ReasoningResult(hops={self.total_hops}, " 

75 f"confidence={self.overall_confidence:.2f}, " 

76 f"answer='{self.final_answer[:50]}...')" 

77 ) 

78 

79 def get_reasoning_chain(self) -> str: 

80 """Get full reasoning chain as formatted string.""" 

81 chain = [f"Query: {self.query}\n"] 

82 for step in self.steps: 

83 chain.append(f"\nStep {step.step_number}:") 

84 chain.append(f" Question: {step.question}") 

85 chain.append(f" Reasoning: {step.reasoning}") 

86 chain.append(f" Answer: {step.answer}") 

87 chain.append(f" Confidence: {step.confidence:.2f}") 

88 chain.append(f"\nFinal Answer: {self.final_answer}") 

89 return "\n".join(chain) 

90 

91 

92class AbstractReasoner(ABC): 

93 """Base class for reasoning strategies.""" 

94 

95 @abstractmethod 

96 async def reason( 

97 self, 

98 query: str, 

99 initial_context: list[Any] | None = None, 

100 **kwargs, 

101 ) -> ReasoningResult: 

102 """Perform reasoning on the query. 

103 

104 Args: 

105 query: The query to reason about. 

106 initial_context: Optional initial context. 

107 **kwargs: Additional strategy-specific parameters. 

108 

109 Returns: 

110 ReasoningResult with steps and final answer. 

111 """