-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmemory-stats.lua
More file actions
344 lines (281 loc) · 11.3 KB
/
Copy pathmemory-stats.lua
File metadata and controls
344 lines (281 loc) · 11.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
-- Profile: memory (recommended)
-- Run with: llmspell -p memory run memory-stats.lua
-- Adaptive memory system
-- ============================================================
-- LLMSPELL FEATURES SHOWCASE
-- ============================================================
-- Phase: 13c.5.6 - Example Header Standardization
-- Category: features
-- Feature: Memory Statistics and Monitoring
-- Complexity: INTERMEDIATE
-- Real-World Use Case: Production monitoring, capacity planning
--
-- Purpose: Learn how to monitor memory system health, track growth,
-- and understand consolidation status. Essential for production
-- deployments and understanding memory usage patterns.
-- Pattern: Observability for memory subsystems
-- Crates Showcased: llmspell-memory, llmspell-bridge
-- Key Features:
-- • Real-time memory statistics
-- • Memory growth tracking
-- • Consolidation monitoring
-- • Session activity tracking
-- • Capacity planning metrics
--
-- Prerequisites:
-- • Completed getting-started/05-memory-rag-advanced.lua
-- • Basic understanding of episodic and semantic memory
--
-- HOW TO RUN:
-- ./target/debug/llmspell \
-- run examples/script-users/features/memory-stats.lua
--
-- EXPECTED OUTPUT:
-- Initial memory state snapshot
-- Memory growth metrics after data additions
-- Consolidation status and pending work
-- Session activity summary
--
-- Time to Complete: <10 seconds
-- ============================================================
print("=== Memory Statistics & Monitoring ===")
print("Feature: Tracking memory system health and usage\n")
-- ============================================================
-- Setup: Verify Memory Availability
-- ============================================================
if not Memory then
print("❌ Memory system not available")
return {success = false, error = "Memory not configured"}
end
print("✅ Memory system available\n")
-- ============================================================
-- Step 1: Capture Initial State
-- ============================================================
print("1. Capturing initial memory state...")
local stats_before = Memory.stats()
if stats_before then
print("📊 Initial state:")
print(string.format(" Episodic entries: %d", stats_before.episodic_count or 0))
print(string.format(" Semantic entries: %d", stats_before.semantic_count or 0))
if stats_before.sessions_with_unprocessed then
print(string.format(" Sessions with unprocessed data: %d",
stats_before.sessions_with_unprocessed))
end
if stats_before.consolidation_status then
print(string.format(" Consolidation status: %s",
stats_before.consolidation_status))
end
-- Capture all available metrics
print("\n All available metrics:")
for key, value in pairs(stats_before) do
print(string.format(" • %s: %s", key, tostring(value)))
end
else
print(" ⚠️ Could not retrieve statistics")
stats_before = {episodic_count = 0, semantic_count = 0}
end
print()
-- ============================================================
-- Step 2: Add Test Data to Track Growth
-- ============================================================
print("2. Adding test data to track memory growth...")
local session = "stats-demo-" .. os.time()
local exchanges_to_add = 20
print(string.format(" Creating session with %d exchanges...", exchanges_to_add))
local added_count = 0
local episodic_growth = 0
local semantic_growth = 0
for i = 1, exchanges_to_add do
local user_result = Memory.episodic.add(
session,
"user",
string.format("Test query number %d about memory statistics", i),
{test = true, iteration = i}
)
local assistant_result = Memory.episodic.add(
session,
"assistant",
string.format("Test response number %d explaining memory monitoring", i),
{test = true, iteration = i}
)
if user_result and assistant_result then
added_count = added_count + 2
end
end
print(string.format(" ✓ Added %d exchanges", added_count))
print()
-- ============================================================
-- Step 3: Capture After State
-- ============================================================
print("3. Capturing memory state after additions...")
local stats_after = Memory.stats()
if stats_after then
print("📊 After additions:")
print(string.format(" Episodic entries: %d", stats_after.episodic_count or 0))
print(string.format(" Semantic entries: %d", stats_after.semantic_count or 0))
-- Calculate growth
episodic_growth = (stats_after.episodic_count or 0) - (stats_before.episodic_count or 0)
semantic_growth = (stats_after.semantic_count or 0) - (stats_before.semantic_count or 0)
print("\n📈 Growth metrics:")
print(string.format(" Episodic entries added: +%d", episodic_growth))
print(string.format(" Semantic entries added: +%d", semantic_growth))
print(string.format(" Expected additions: %d", added_count))
if episodic_growth == added_count then
print(" ✓ Growth matches expected additions")
else
print(" ⚠️ Growth differs from expected (may include other sessions)")
end
else
print(" ⚠️ Could not retrieve statistics")
stats_after = {episodic_count = 0, semantic_count = 0}
end
print()
-- ============================================================
-- Step 4: Monitor Consolidation Status
-- ============================================================
print("4. Monitoring consolidation status...")
if stats_after.consolidation_status then
print(string.format(" Status: %s", stats_after.consolidation_status))
-- Check if consolidation is needed
if stats_after.sessions_with_unprocessed and
stats_after.sessions_with_unprocessed > 0 then
print(string.format(" ⚠️ %d sessions have unprocessed data",
stats_after.sessions_with_unprocessed))
print(" Consider running consolidation to extract knowledge")
else
print(" ✓ No sessions pending consolidation")
end
-- Show last consolidation time if available
if stats_after.last_consolidation then
print(string.format(" Last consolidation: %s", stats_after.last_consolidation))
end
-- Show pending count if available
if stats_after.pending_consolidation_count then
print(string.format(" Entries pending consolidation: %d",
stats_after.pending_consolidation_count))
end
else
print(" ℹ️ Consolidation status not available")
end
print()
-- ============================================================
-- Step 5: Session Activity Tracking
-- ============================================================
print("5. Session activity tracking...")
-- Search for our test session to verify it exists
local session_check = Memory.episodic.search(
session,
"memory statistics",
5
)
if session_check and type(session_check) == "table" and #session_check > 0 then
local entry_count = #session_check
print(string.format(" Session '%s' found", session:sub(1, 30) .. "..."))
print(string.format(" Entries in session: %d", entry_count))
print(" ✓ Session is active and queryable")
-- Show sample entry
if entry_count > 0 then
local sample = session_check[1]
local snippet = string.sub(sample.content, 1, 60)
if #sample.content > 60 then snippet = snippet .. "..." end
print(string.format(" Sample: [%s] %s", sample.role, snippet))
end
else
print(" ⚠️ Could not verify session activity")
end
print()
-- ============================================================
-- Step 6: Capacity Planning Insights
-- ============================================================
print("6. Capacity planning insights...")
-- Calculate memory per entry (rough estimate)
local total_entries = (stats_after.episodic_count or 0) + (stats_after.semantic_count or 0)
if total_entries > 0 then
print("📉 Usage patterns:")
print(string.format(" Total memory entries: %d", total_entries))
-- Calculate ratio
local episodic_pct = 0
if total_entries > 0 then
episodic_pct = ((stats_after.episodic_count or 0) / total_entries) * 100
end
print(string.format(" Episodic: %.1f%%", episodic_pct))
print(string.format(" Semantic: %.1f%%", 100 - episodic_pct))
-- Growth rate per session
if episodic_growth > 0 then
print(string.format("\n Average entries per exchange: %.1f",
episodic_growth / exchanges_to_add))
end
-- Rough capacity estimates
print("\n📊 Estimated capacity (at current rate):")
print(" 1,000 exchanges → ~1,000 episodic entries")
print(" 10,000 exchanges → ~10,000 episodic entries")
print(" (Actual usage depends on consolidation settings)")
else
print(" Insufficient data for capacity planning")
end
print()
-- ============================================================
-- Step 7: Health Check Summary
-- ============================================================
print("7. Memory system health check...")
local health = {
episodic_available = (stats_after.episodic_count ~= nil),
semantic_available = (stats_after.semantic_count ~= nil),
stats_available = (stats_after ~= nil),
growth_verified = (episodic_growth > 0),
consolidation_tracked = (stats_after.consolidation_status ~= nil)
}
print("🏥 Health indicators:")
for key, value in pairs(health) do
local status = value and "✓" or "✗"
print(string.format(" %s %s", status, key))
end
local health_score = 0
for _, value in pairs(health) do
if value then health_score = health_score + 1 end
end
local total_checks = 5
local health_pct = (health_score / total_checks) * 100
print(string.format("\n Overall health: %.0f%% (%d/%d checks passed)",
health_pct, health_score, total_checks))
if health_score == total_checks then
print(" ✓ Memory system is fully operational")
elseif health_score >= 3 then
print(" ⚠️ Memory system has minor issues")
else
print(" ❌ Memory system has significant issues")
end
print()
-- ============================================================
-- Summary
-- ============================================================
print("🎉 Memory Monitoring Completed!")
print("\n✓ Key Metrics Tracked:")
print(" • Episodic memory growth")
print(" • Semantic memory status")
print(" • Consolidation progress")
print(" • Session activity")
print(" • System health indicators")
print("\n📚 Monitoring Best Practices:")
print(" • Track stats before/after operations")
print(" • Monitor consolidation regularly")
print(" • Watch for unprocessed sessions")
print(" • Plan capacity based on growth rates")
print(" • Set up alerts for health checks")
print("\n🚀 Production Recommendations:")
print(" • Log stats periodically (hourly/daily)")
print(" • Set alerts for consolidation backlog")
print(" • Monitor growth trends over time")
print(" • Track query performance metrics")
-- Return monitoring summary
return {
success = true,
message = "Memory monitoring completed",
metrics = {
episodic_before = stats_before.episodic_count or 0,
episodic_after = stats_after.episodic_count or 0,
growth = episodic_growth,
health_score = health_pct,
session_id = session
}
}