flashlite 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. flashlite/__init__.py +169 -0
  2. flashlite/cache/__init__.py +14 -0
  3. flashlite/cache/base.py +194 -0
  4. flashlite/cache/disk.py +285 -0
  5. flashlite/cache/memory.py +157 -0
  6. flashlite/client.py +671 -0
  7. flashlite/config.py +154 -0
  8. flashlite/conversation/__init__.py +30 -0
  9. flashlite/conversation/context.py +319 -0
  10. flashlite/conversation/manager.py +385 -0
  11. flashlite/conversation/multi_agent.py +378 -0
  12. flashlite/core/__init__.py +13 -0
  13. flashlite/core/completion.py +145 -0
  14. flashlite/core/messages.py +130 -0
  15. flashlite/middleware/__init__.py +18 -0
  16. flashlite/middleware/base.py +90 -0
  17. flashlite/middleware/cache.py +121 -0
  18. flashlite/middleware/logging.py +159 -0
  19. flashlite/middleware/rate_limit.py +211 -0
  20. flashlite/middleware/retry.py +149 -0
  21. flashlite/observability/__init__.py +34 -0
  22. flashlite/observability/callbacks.py +155 -0
  23. flashlite/observability/inspect_compat.py +266 -0
  24. flashlite/observability/logging.py +293 -0
  25. flashlite/observability/metrics.py +221 -0
  26. flashlite/py.typed +0 -0
  27. flashlite/structured/__init__.py +31 -0
  28. flashlite/structured/outputs.py +189 -0
  29. flashlite/structured/schema.py +165 -0
  30. flashlite/templating/__init__.py +11 -0
  31. flashlite/templating/engine.py +217 -0
  32. flashlite/templating/filters.py +143 -0
  33. flashlite/templating/registry.py +165 -0
  34. flashlite/tools/__init__.py +74 -0
  35. flashlite/tools/definitions.py +382 -0
  36. flashlite/tools/execution.py +353 -0
  37. flashlite/types.py +233 -0
  38. flashlite-0.1.0.dist-info/METADATA +173 -0
  39. flashlite-0.1.0.dist-info/RECORD +41 -0
  40. flashlite-0.1.0.dist-info/WHEEL +4 -0
  41. flashlite-0.1.0.dist-info/licenses/LICENSE.md +21 -0
@@ -0,0 +1,157 @@
1
+ """In-memory LRU cache with TTL support."""
2
+
3
+ import asyncio
4
+ import time
5
+ from collections import OrderedDict
6
+ from dataclasses import dataclass
7
+
8
+ from ..types import CompletionResponse
9
+ from .base import CacheBackend
10
+
11
+
12
+ @dataclass
13
+ class MemoryCacheEntry:
14
+ """An entry in the memory cache."""
15
+
16
+ response: CompletionResponse
17
+ created_at: float
18
+ ttl: float | None
19
+
20
+
21
+ class MemoryCache(CacheBackend):
22
+ """
23
+ In-memory LRU cache with optional TTL.
24
+
25
+ This cache uses an OrderedDict to maintain LRU ordering.
26
+ When the cache exceeds max_size, the least recently used
27
+ entries are evicted.
28
+
29
+ Example:
30
+ cache = MemoryCache(max_size=1000, default_ttl=3600)
31
+
32
+ # Store a response
33
+ await cache.set(key, response)
34
+
35
+ # Retrieve (returns None if expired or not found)
36
+ cached = await cache.get(key)
37
+ """
38
+
39
+ def __init__(
40
+ self,
41
+ max_size: int = 1000,
42
+ default_ttl: float | None = None,
43
+ ):
44
+ """
45
+ Initialize the memory cache.
46
+
47
+ Args:
48
+ max_size: Maximum number of entries to store
49
+ default_ttl: Default time-to-live in seconds (None = no expiration)
50
+ """
51
+ self._max_size = max_size
52
+ self._default_ttl = default_ttl
53
+ self._cache: OrderedDict[str, MemoryCacheEntry] = OrderedDict()
54
+ self._lock = asyncio.Lock()
55
+ self._hits = 0
56
+ self._misses = 0
57
+
58
+ async def get(self, key: str) -> CompletionResponse | None:
59
+ """Retrieve a cached response."""
60
+ async with self._lock:
61
+ entry = self._cache.get(key)
62
+
63
+ if entry is None:
64
+ self._misses += 1
65
+ return None
66
+
67
+ # Check expiration
68
+ if entry.ttl is not None:
69
+ if time.time() > entry.created_at + entry.ttl:
70
+ # Expired - remove and return None
71
+ del self._cache[key]
72
+ self._misses += 1
73
+ return None
74
+
75
+ # Move to end (most recently used)
76
+ self._cache.move_to_end(key)
77
+ self._hits += 1
78
+ return entry.response
79
+
80
+ async def set(
81
+ self,
82
+ key: str,
83
+ response: CompletionResponse,
84
+ ttl: float | None = None,
85
+ ) -> None:
86
+ """Store a response in the cache."""
87
+ async with self._lock:
88
+ # Use provided TTL or default
89
+ effective_ttl = ttl if ttl is not None else self._default_ttl
90
+
91
+ entry = MemoryCacheEntry(
92
+ response=response,
93
+ created_at=time.time(),
94
+ ttl=effective_ttl,
95
+ )
96
+
97
+ # If key exists, update and move to end
98
+ if key in self._cache:
99
+ self._cache[key] = entry
100
+ self._cache.move_to_end(key)
101
+ else:
102
+ # Add new entry
103
+ self._cache[key] = entry
104
+
105
+ # Evict LRU entries if over capacity
106
+ while len(self._cache) > self._max_size:
107
+ self._cache.popitem(last=False)
108
+
109
+ async def delete(self, key: str) -> bool:
110
+ """Delete a cached entry."""
111
+ async with self._lock:
112
+ if key in self._cache:
113
+ del self._cache[key]
114
+ return True
115
+ return False
116
+
117
+ async def clear(self) -> int:
118
+ """Clear all cached entries."""
119
+ async with self._lock:
120
+ count = len(self._cache)
121
+ self._cache.clear()
122
+ self._hits = 0
123
+ self._misses = 0
124
+ return count
125
+
126
+ async def size(self) -> int:
127
+ """Get the number of cached entries."""
128
+ async with self._lock:
129
+ return len(self._cache)
130
+
131
+ @property
132
+ def hits(self) -> int:
133
+ """Number of cache hits."""
134
+ return self._hits
135
+
136
+ @property
137
+ def misses(self) -> int:
138
+ """Number of cache misses."""
139
+ return self._misses
140
+
141
+ @property
142
+ def hit_rate(self) -> float:
143
+ """Cache hit rate (0.0 to 1.0)."""
144
+ total = self._hits + self._misses
145
+ if total == 0:
146
+ return 0.0
147
+ return self._hits / total
148
+
149
+ def stats(self) -> dict[str, int | float]:
150
+ """Get cache statistics."""
151
+ return {
152
+ "size": len(self._cache),
153
+ "max_size": self._max_size,
154
+ "hits": self._hits,
155
+ "misses": self._misses,
156
+ "hit_rate": self.hit_rate,
157
+ }