Coverage for /home/admin/Documents/AI/applications/lexigram-dev/lexigram/experimental/ai/lexigram-ai-rag/src/lexigram/ai/rag/hyde/types.py: 98%

40 statements  

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

1"""Type definitions for HyDE (Hypothetical Document Embeddings).""" 

2 

3from __future__ import annotations 

4 

5from dataclasses import dataclass, field 

6from datetime import UTC, datetime 

7from enum import StrEnum 

8from typing import Any 

9 

10 

11class HyDEStrategy(StrEnum): 

12 """Strategy for generating hypothetical documents.""" 

13 

14 SINGLE = "single" # Generate single hypothetical document 

15 MULTIPLE = "multiple" # Generate multiple hypothetical documents 

16 WEIGHTED = "weighted" # Generate and weight multiple documents 

17 REVERSE = "reverse" # Generate query from hypothetical doc 

18 

19 

20@dataclass 

21class HypotheticalDocument: 

22 """A hypothetical document generated for a query.""" 

23 

24 content: str 

25 query: str 

26 confidence: float = 1.0 

27 metadata: dict[str, Any] = field(default_factory=dict) 

28 timestamp: str = field( 

29 default_factory=lambda: datetime.now(UTC).isoformat(), 

30 ) 

31 

32 def __repr__(self) -> str: 

33 """Return string representation.""" 

34 return ( 

35 f"HypotheticalDocument(length={len(self.content)}, " 

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

37 ) 

38 

39 

40@dataclass 

41class HyDEResult: 

42 """Result of HyDE generation.""" 

43 

44 query: str 

45 hypothetical_docs: list[HypotheticalDocument] 

46 strategy: HyDEStrategy 

47 aggregated_embedding: list[float] | None = None 

48 metadata: dict[str, Any] = field(default_factory=dict) 

49 timestamp: str = field( 

50 default_factory=lambda: datetime.now(UTC).isoformat(), 

51 ) 

52 

53 @property 

54 def num_documents(self) -> int: 

55 """Number of hypothetical documents generated.""" 

56 return len(self.hypothetical_docs) 

57 

58 @property 

59 def avg_confidence(self) -> float: 

60 """Average confidence across documents.""" 

61 if not self.hypothetical_docs: 

62 return 0.0 

63 return sum(doc.confidence for doc in self.hypothetical_docs) / len( 

64 self.hypothetical_docs, 

65 ) 

66 

67 @property 

68 def total_length(self) -> int: 

69 """Total length of all hypothetical documents.""" 

70 return sum(len(doc.content) for doc in self.hypothetical_docs) 

71 

72 def __repr__(self) -> str: 

73 """Return string representation.""" 

74 return ( 

75 f"HyDEResult(strategy={self.strategy.value}, " 

76 f"docs={self.num_documents}, " 

77 f"avg_conf={self.avg_confidence:.2f})" 

78 )