claude_memory 0.4.0 → 0.5.0
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.
- checksums.yaml +4 -4
- data/.claude/CLAUDE.md +1 -1
- data/.claude/rules/claude_memory.generated.md +14 -1
- data/.claude/skills/check-memory/SKILL.md +10 -0
- data/.claude/skills/improve/SKILL.md +12 -1
- data/.claude-plugin/plugin.json +1 -1
- data/CHANGELOG.md +70 -0
- data/db/migrations/008_add_provenance_line_range.rb +21 -0
- data/db/migrations/009_add_docid.rb +39 -0
- data/db/migrations/010_add_llm_cache.rb +30 -0
- data/docs/improvements.md +72 -1084
- data/docs/influence/claude-supermemory.md +498 -0
- data/docs/influence/qmd.md +424 -2022
- data/docs/quality_review.md +64 -705
- data/lib/claude_memory/commands/doctor_command.rb +45 -4
- data/lib/claude_memory/commands/explain_command.rb +11 -6
- data/lib/claude_memory/commands/stats_command.rb +1 -1
- data/lib/claude_memory/core/fact_graph.rb +122 -0
- data/lib/claude_memory/core/fact_query_builder.rb +34 -14
- data/lib/claude_memory/core/fact_ranker.rb +3 -20
- data/lib/claude_memory/core/relative_time.rb +45 -0
- data/lib/claude_memory/core/result_sorter.rb +2 -2
- data/lib/claude_memory/core/rr_fusion.rb +57 -0
- data/lib/claude_memory/core/snippet_extractor.rb +97 -0
- data/lib/claude_memory/domain/fact.rb +3 -1
- data/lib/claude_memory/index/index_query.rb +2 -0
- data/lib/claude_memory/index/lexical_fts.rb +18 -0
- data/lib/claude_memory/infrastructure/operation_tracker.rb +7 -21
- data/lib/claude_memory/infrastructure/schema_validator.rb +30 -25
- data/lib/claude_memory/ingest/content_sanitizer.rb +8 -1
- data/lib/claude_memory/ingest/ingester.rb +67 -56
- data/lib/claude_memory/ingest/tool_extractor.rb +1 -1
- data/lib/claude_memory/ingest/tool_filter.rb +55 -0
- data/lib/claude_memory/logging/logger.rb +112 -0
- data/lib/claude_memory/mcp/query_guide.rb +96 -0
- data/lib/claude_memory/mcp/response_formatter.rb +86 -23
- data/lib/claude_memory/mcp/server.rb +34 -4
- data/lib/claude_memory/mcp/text_summary.rb +257 -0
- data/lib/claude_memory/mcp/tool_definitions.rb +20 -4
- data/lib/claude_memory/mcp/tools.rb +133 -120
- data/lib/claude_memory/publish.rb +12 -2
- data/lib/claude_memory/recall/expansion_detector.rb +44 -0
- data/lib/claude_memory/recall.rb +93 -41
- data/lib/claude_memory/resolve/resolver.rb +72 -40
- data/lib/claude_memory/store/sqlite_store.rb +99 -24
- data/lib/claude_memory/sweep/sweeper.rb +6 -0
- data/lib/claude_memory/version.rb +1 -1
- data/lib/claude_memory.rb +21 -0
- metadata +14 -2
- data/docs/remaining_improvements.md +0 -330
|
@@ -1,330 +0,0 @@
|
|
|
1
|
-
# Remaining Improvements from Analysis
|
|
2
|
-
|
|
3
|
-
This document contains the improvements that have NOT yet been implemented from the episodic-memory and claude-mem analysis.
|
|
4
|
-
|
|
5
|
-
**Note:** The "index" command to generate embeddings for existing facts has been completed (2026-01-23). FastEmbed integration (BAAI/bge-small-en-v1.5 via fastembed-rb) was added for high-quality local embeddings (2026-02-02), replacing TF-IDF as the primary embedding approach for benchmarks.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## 1. Background Processing for Hooks
|
|
10
|
-
|
|
11
|
-
### What Episodic-Memory Does
|
|
12
|
-
|
|
13
|
-
**Background Sync**:
|
|
14
|
-
```bash
|
|
15
|
-
# SessionStart hook
|
|
16
|
-
episodic-memory sync --background
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
Runs in background, user continues working immediately.
|
|
20
|
-
|
|
21
|
-
**File**: `src/sync.ts`
|
|
22
|
-
|
|
23
|
-
### What We Should Do
|
|
24
|
-
|
|
25
|
-
**Priority**: MEDIUM
|
|
26
|
-
|
|
27
|
-
**Implementation**:
|
|
28
|
-
|
|
29
|
-
1. **Background processing flag**:
|
|
30
|
-
```ruby
|
|
31
|
-
# lib/claude_memory/commands/hook_command.rb
|
|
32
|
-
def call(args)
|
|
33
|
-
opts = parse_options(args, { async: false })
|
|
34
|
-
|
|
35
|
-
if opts[:async]
|
|
36
|
-
# Fork and detach
|
|
37
|
-
pid = fork do
|
|
38
|
-
Process.setsid # Detach from terminal
|
|
39
|
-
execute_hook(subcommand, payload)
|
|
40
|
-
end
|
|
41
|
-
Process.detach(pid)
|
|
42
|
-
|
|
43
|
-
stdout.puts "Hook execution started in background (PID: #{pid})"
|
|
44
|
-
return Hook::ExitCodes::SUCCESS
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
execute_hook(subcommand, payload)
|
|
48
|
-
end
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
2. **Hook configuration**:
|
|
52
|
-
```json
|
|
53
|
-
{
|
|
54
|
-
"hooks": {
|
|
55
|
-
"SessionStart": [{
|
|
56
|
-
"matcher": "startup|resume",
|
|
57
|
-
"hooks": [{
|
|
58
|
-
"type": "command",
|
|
59
|
-
"command": "claude-memory hook ingest --async",
|
|
60
|
-
"async": true
|
|
61
|
-
}]
|
|
62
|
-
}]
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
**Benefits**:
|
|
68
|
-
- Non-blocking hooks (user continues working immediately)
|
|
69
|
-
- Better user experience for long-running operations
|
|
70
|
-
- Doesn't delay session startup
|
|
71
|
-
|
|
72
|
-
**Trade-offs**:
|
|
73
|
-
- Background process management complexity
|
|
74
|
-
- Need logging for background execution
|
|
75
|
-
- Potential race conditions if multiple sessions start simultaneously
|
|
76
|
-
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
## 2. ROI Metrics and Token Economics
|
|
80
|
-
|
|
81
|
-
### What claude-mem Does
|
|
82
|
-
|
|
83
|
-
**Discovery Token Tracking**:
|
|
84
|
-
- `discovery_tokens` field on observations table
|
|
85
|
-
- Tracks tokens spent discovering each piece of knowledge
|
|
86
|
-
- Cumulative metrics in session summaries
|
|
87
|
-
- Footer displays ROI: "Access 10k tokens for 2,500t"
|
|
88
|
-
|
|
89
|
-
**File**: `src/services/sqlite/Database.ts`
|
|
90
|
-
|
|
91
|
-
```typescript
|
|
92
|
-
observations: {
|
|
93
|
-
id: INTEGER PRIMARY KEY,
|
|
94
|
-
title: TEXT,
|
|
95
|
-
narrative: TEXT,
|
|
96
|
-
discovery_tokens: INTEGER, // ← Cost tracking
|
|
97
|
-
created_at_epoch: INTEGER
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
session_summaries: {
|
|
101
|
-
cumulative_discovery_tokens: INTEGER, // ← Running total
|
|
102
|
-
observation_count: INTEGER
|
|
103
|
-
}
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
**Context Footer Example**:
|
|
107
|
-
```markdown
|
|
108
|
-
💡 **Token Economics:**
|
|
109
|
-
- Context shown: 2,500 tokens
|
|
110
|
-
- Research captured: 10,000 tokens
|
|
111
|
-
- ROI: 4x compression
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### What We Should Do
|
|
115
|
-
|
|
116
|
-
**Priority**: MEDIUM
|
|
117
|
-
|
|
118
|
-
**Implementation**:
|
|
119
|
-
|
|
120
|
-
1. **Add metrics table**:
|
|
121
|
-
```ruby
|
|
122
|
-
create_table :ingestion_metrics do
|
|
123
|
-
primary_key :id
|
|
124
|
-
foreign_key :content_item_id, :content_items
|
|
125
|
-
Integer :input_tokens
|
|
126
|
-
Integer :output_tokens
|
|
127
|
-
Integer :facts_extracted
|
|
128
|
-
DateTime :created_at
|
|
129
|
-
end
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
2. **Track during distillation**:
|
|
133
|
-
```ruby
|
|
134
|
-
# lib/claude_memory/distill/distiller.rb
|
|
135
|
-
def distill(content)
|
|
136
|
-
response = api_call(content)
|
|
137
|
-
facts = extract_facts(response)
|
|
138
|
-
|
|
139
|
-
store_metrics(
|
|
140
|
-
input_tokens: response.usage.input_tokens,
|
|
141
|
-
output_tokens: response.usage.output_tokens,
|
|
142
|
-
facts_extracted: facts.size
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
facts
|
|
146
|
-
end
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
3. **Display in CLI**:
|
|
150
|
-
```ruby
|
|
151
|
-
# claude-memory stats
|
|
152
|
-
def stats_cmd
|
|
153
|
-
metrics = store.aggregate_metrics
|
|
154
|
-
puts "Token Economics:"
|
|
155
|
-
puts " Input: #{metrics[:input_tokens]} tokens"
|
|
156
|
-
puts " Output: #{metrics[:output_tokens]} tokens"
|
|
157
|
-
puts " Facts: #{metrics[:facts_extracted]}"
|
|
158
|
-
puts " Efficiency: #{metrics[:facts_extracted] / metrics[:input_tokens].to_f} facts/token"
|
|
159
|
-
end
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
4. **Add to published snapshot**:
|
|
163
|
-
```markdown
|
|
164
|
-
<!-- At bottom of .claude/rules/claude_memory.generated.md -->
|
|
165
|
-
|
|
166
|
-
---
|
|
167
|
-
|
|
168
|
-
*Memory stats: 145 facts from 12,500 ingested tokens (86 facts/1k tokens)*
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
**Benefits**:
|
|
172
|
-
- Visibility into memory system efficiency
|
|
173
|
-
- Justifies API costs (shows compression ratio)
|
|
174
|
-
- Helps tune distillation prompts for better extraction
|
|
175
|
-
|
|
176
|
-
**Trade-offs**:
|
|
177
|
-
- Requires API usage tracking
|
|
178
|
-
- Adds database complexity
|
|
179
|
-
- May not be meaningful for all distiller implementations
|
|
180
|
-
|
|
181
|
-
---
|
|
182
|
-
|
|
183
|
-
## 3. Structured Logging
|
|
184
|
-
|
|
185
|
-
### Implementation
|
|
186
|
-
|
|
187
|
-
**Priority**: LOW
|
|
188
|
-
|
|
189
|
-
1. **Add structured logger**:
|
|
190
|
-
```ruby
|
|
191
|
-
# lib/claude_memory/logging/logger.rb
|
|
192
|
-
module ClaudeMemory
|
|
193
|
-
module Logging
|
|
194
|
-
class Logger
|
|
195
|
-
def initialize(output = $stderr, level: :info)
|
|
196
|
-
@output = output
|
|
197
|
-
@level = level
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
def info(message, metadata = {})
|
|
201
|
-
log(:info, message, metadata)
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
def error(message, exception: nil, metadata = {})
|
|
205
|
-
log(:error, message, metadata.merge(exception: exception&.message))
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
private
|
|
209
|
-
|
|
210
|
-
def log(level, message, metadata)
|
|
211
|
-
return if should_skip?(level)
|
|
212
|
-
|
|
213
|
-
log_entry = {
|
|
214
|
-
timestamp: Time.now.iso8601,
|
|
215
|
-
level: level,
|
|
216
|
-
message: message
|
|
217
|
-
}.merge(metadata)
|
|
218
|
-
|
|
219
|
-
@output.puts JSON.generate(log_entry)
|
|
220
|
-
end
|
|
221
|
-
end
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
2. **Usage in Ingester**:
|
|
227
|
-
```ruby
|
|
228
|
-
def ingest(...)
|
|
229
|
-
logger.info("Starting ingestion",
|
|
230
|
-
session_id: session_id,
|
|
231
|
-
transcript_path: transcript_path
|
|
232
|
-
)
|
|
233
|
-
|
|
234
|
-
begin
|
|
235
|
-
# ... ingestion logic ...
|
|
236
|
-
|
|
237
|
-
logger.info("Ingestion complete",
|
|
238
|
-
content_items_created: 1,
|
|
239
|
-
facts_extracted: facts.size
|
|
240
|
-
)
|
|
241
|
-
rescue => e
|
|
242
|
-
logger.error("Ingestion failed",
|
|
243
|
-
exception: e,
|
|
244
|
-
session_id: session_id
|
|
245
|
-
)
|
|
246
|
-
raise
|
|
247
|
-
end
|
|
248
|
-
end
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
**Benefits**:
|
|
252
|
-
- Better debugging with structured data
|
|
253
|
-
- Easy log parsing and analysis
|
|
254
|
-
- Consistent log format
|
|
255
|
-
|
|
256
|
-
**Trade-offs**:
|
|
257
|
-
- Additional complexity
|
|
258
|
-
- Log output may be verbose
|
|
259
|
-
|
|
260
|
-
---
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
## Features to Avoid
|
|
264
|
-
|
|
265
|
-
### 1. Chroma Vector Database
|
|
266
|
-
|
|
267
|
-
**Their Approach**: Hybrid SQLite FTS5 + Chroma vector search.
|
|
268
|
-
|
|
269
|
-
**Our Take**: **Skip it.** Adds significant complexity:
|
|
270
|
-
|
|
271
|
-
- Python dependency
|
|
272
|
-
- ChromaDB server
|
|
273
|
-
- Embedding generation
|
|
274
|
-
- Sync overhead
|
|
275
|
-
|
|
276
|
-
**Alternative**: We use [fastembed-rb](https://github.com/khasinski/fastembed-rb) with BAAI/bge-small-en-v1.5 for high-quality local embeddings (384-dim, no API key, ONNX runtime). Benchmark results: Recall@5=0.786 aggregate, 0.696 on semantic paraphrase queries.
|
|
277
|
-
|
|
278
|
-
### 2. Claude Agent SDK for Distillation
|
|
279
|
-
|
|
280
|
-
**Their Approach**: Use `@anthropic-ai/claude-agent-sdk` for observation compression.
|
|
281
|
-
|
|
282
|
-
**Our Take**: **Skip it.** We already have `Distill::Distiller` interface. SDK adds:
|
|
283
|
-
|
|
284
|
-
- Node.js dependency
|
|
285
|
-
- Subprocess management
|
|
286
|
-
- Complex event loop
|
|
287
|
-
|
|
288
|
-
**Alternative**: Direct API calls via `anthropic-rb` gem (if we implement distiller).
|
|
289
|
-
|
|
290
|
-
### 3. Worker Service Background Process
|
|
291
|
-
|
|
292
|
-
**Their Approach**: Long-running worker with HTTP API + MCP wrapper.
|
|
293
|
-
|
|
294
|
-
**Our Take**: **Skip it.** We use MCP server directly:
|
|
295
|
-
|
|
296
|
-
- No background process to manage
|
|
297
|
-
- No port conflicts
|
|
298
|
-
- No PID files
|
|
299
|
-
- Simpler deployment
|
|
300
|
-
|
|
301
|
-
**Alternative**: Keep stdio-based MCP server. Add HTTP transport only if needed.
|
|
302
|
-
|
|
303
|
-
### 4. Web Viewer UI
|
|
304
|
-
|
|
305
|
-
**Their Approach**: React-based web UI at `http://localhost:37777`.
|
|
306
|
-
|
|
307
|
-
**Our Take**: **Skip for MVP.** Significant effort for uncertain value:
|
|
308
|
-
|
|
309
|
-
- React + esbuild
|
|
310
|
-
- SSE implementation
|
|
311
|
-
- State management
|
|
312
|
-
- CSS/theming
|
|
313
|
-
|
|
314
|
-
**Alternative**: CLI output is sufficient. Add web UI if users request it.
|
|
315
|
-
|
|
316
|
-
---
|
|
317
|
-
|
|
318
|
-
## Implementation Priorities
|
|
319
|
-
|
|
320
|
-
### Medium Priority
|
|
321
|
-
|
|
322
|
-
1. **Background Processing** - Non-blocking hooks for better UX
|
|
323
|
-
2. **ROI Metrics** - Track token economics for distillation
|
|
324
|
-
|
|
325
|
-
### Low Priority
|
|
326
|
-
|
|
327
|
-
3. **Structured Logging** - Better debugging with JSON logs
|
|
328
|
-
4. **Health Monitoring** - Only if we add background worker
|
|
329
|
-
5. **Web Viewer UI** - Only if users request visualization
|
|
330
|
-
6. **Configuration-Driven Context** - Only if users request snapshot customization
|