Coverage for /home/admin/Documents/AI/applications/lexigram-dev/lexigram/experimental/ai/lexigram-ai-memory/src/lexigram/ai/memory/retrieval/ranking.py: 50%

20 statements  

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

1"""Relevance ranker — re-ranks memory search results by combined score.""" 

2 

3from __future__ import annotations 

4 

5from datetime import UTC, datetime 

6import math 

7 

8from lexigram.contracts.ai.memory import MemoryQuery, MemorySearchResult 

9from lexigram.logging import ( 

10 get_logger, 

11) 

12 

13logger = get_logger(__name__) 

14 

15 

16class RelevanceRanker: 

17 """Re-ranks a list of MemorySearchResult by a multi-factor score. 

18 

19 Combines the raw retrieval score with recency and importance using 

20 the weights from the originating MemoryQuery. 

21 """ 

22 

23 def rank( 

24 self, 

25 results: list[MemorySearchResult], 

26 query: MemoryQuery, 

27 ) -> list[MemorySearchResult]: 

28 """Re-rank *results* and return a new sorted list. 

29 

30 Args: 

31 results: Raw search results to re-rank. 

32 query: Original query with weighting parameters. 

33 

34 Returns: 

35 Results sorted by descending combined score. 

36 """ 

37 reranked: list[MemorySearchResult] = [] 

38 for r in results: 

39 age_s = (datetime.now(UTC) - r.entry.timestamp).total_seconds() 

40 recency = math.exp(-age_s / 86400.0) 

41 combined = ( 

42 query.relevance_weight * r.score 

43 + query.recency_weight * recency 

44 + query.importance_weight * r.entry.importance 

45 ) 

46 reranked.append( 

47 MemorySearchResult(entry=r.entry, score=combined, source=r.source) 

48 ) 

49 reranked.sort(key=lambda x: x.score, reverse=True) 

50 return reranked 

51 

52 def top_k( 

53 self, 

54 results: list[MemorySearchResult], 

55 query: MemoryQuery, 

56 k: int | None = None, 

57 ) -> list[MemorySearchResult]: 

58 """Re-rank and return the top *k* results. 

59 

60 Args: 

61 results: Raw results to rank. 

62 query: Query parameters. 

63 k: Maximum results to return. Defaults to ``query.top_k``. 

64 

65 Returns: 

66 Top-k results after re-ranking. 

67 """ 

68 ranked = self.rank(results, query) 

69 return ranked[: k or query.top_k] 

70 

71 

72__all__ = ["RelevanceRanker"]