Coverage for /home/admin/Documents/AI/applications/lexigram-dev/lexigram/experimental/ai/lexigram-ai-llm/src/lexigram/ai/llm/routing/loggers/memory.py: 53%

19 statements  

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

1"""In-memory inference logger for LLM routing. 

2 

3Stores a bounded FIFO queue of ``InferenceLog`` entries in memory. 

4Suitable for development and single-process deployments. State is lost 

5on process restart; use ``DatabaseInferenceLogger`` for production. 

6""" 

7 

8from __future__ import annotations 

9 

10import asyncio 

11from typing import TYPE_CHECKING 

12 

13from lexigram.logging import ( 

14 get_logger, 

15) 

16 

17if TYPE_CHECKING: 

18 from lexigram.ai.llm.routing.types import InferenceLog 

19 

20logger = get_logger(__name__) 

21 

22__all__ = ["InMemoryInferenceLogger"] 

23 

24 

25class InMemoryInferenceLogger: 

26 """Bounded FIFO in-memory inference logger. 

27 

28 Stores up to *max_size* ``InferenceLog`` entries. When the limit is 

29 reached, the oldest entry is evicted before inserting the new one 

30 (FIFO eviction). 

31 

32 Example: 

33 >>> inference_logger = InMemoryInferenceLogger(max_size=500) 

34 >>> await inference_logger.log(some_log) 

35 >>> recent = await inference_logger.get_recent(limit=10) 

36 """ 

37 

38 def __init__(self, max_size: int = 1000) -> None: 

39 """Initialise the in-memory inference logger. 

40 

41 Args: 

42 max_size: Maximum number of log entries to retain. 

43 """ 

44 self._max_size = max_size 

45 self._entries: list[InferenceLog] = [] 

46 self._lock = asyncio.Lock() 

47 

48 async def log(self, entry: InferenceLog) -> None: 

49 """Record one ``InferenceLog`` entry. 

50 

51 Evicts the oldest entry when ``max_size`` is reached. 

52 

53 Args: 

54 entry: :class:`~lexigram.ai.llm.routing.types.InferenceLog` instance. 

55 """ 

56 async with self._lock: 

57 if len(self._entries) >= self._max_size: 

58 self._entries.pop(0) 

59 self._entries.append(entry) 

60 

61 async def get_recent(self, limit: int = 100) -> list[InferenceLog]: 

62 """Return the most recent *limit* log entries (newest-first). 

63 

64 Args: 

65 limit: Maximum number of entries to return. 

66 

67 Returns: 

68 Reversed slice of the internal list (newest first). 

69 """ 

70 async with self._lock: 

71 return list(reversed(self._entries[-limit:]))