@whenmoon-afk/memory-mcp 2.0.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.
- package/LICENSE +21 -0
- package/README.md +263 -0
- package/dist/database/connection.d.ts +47 -0
- package/dist/database/connection.d.ts.map +1 -0
- package/dist/database/connection.js +151 -0
- package/dist/database/connection.js.map +1 -0
- package/dist/database/schema.d.ts +33 -0
- package/dist/database/schema.d.ts.map +1 -0
- package/dist/database/schema.js +293 -0
- package/dist/database/schema.js.map +1 -0
- package/dist/extractors/entity-extractor.d.ts +25 -0
- package/dist/extractors/entity-extractor.d.ts.map +1 -0
- package/dist/extractors/entity-extractor.js +195 -0
- package/dist/extractors/entity-extractor.js.map +1 -0
- package/dist/extractors/fact-extractor.d.ts +38 -0
- package/dist/extractors/fact-extractor.d.ts.map +1 -0
- package/dist/extractors/fact-extractor.js +172 -0
- package/dist/extractors/fact-extractor.js.map +1 -0
- package/dist/extractors/summary-generator.d.ts +28 -0
- package/dist/extractors/summary-generator.d.ts.map +1 -0
- package/dist/extractors/summary-generator.js +149 -0
- package/dist/extractors/summary-generator.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +229 -0
- package/dist/index.js.map +1 -0
- package/dist/scoring/importance.d.ts +39 -0
- package/dist/scoring/importance.d.ts.map +1 -0
- package/dist/scoring/importance.js +150 -0
- package/dist/scoring/importance.js.map +1 -0
- package/dist/scoring/ttl-manager.d.ts +33 -0
- package/dist/scoring/ttl-manager.d.ts.map +1 -0
- package/dist/scoring/ttl-manager.js +99 -0
- package/dist/scoring/ttl-manager.js.map +1 -0
- package/dist/search/semantic-search.d.ts +15 -0
- package/dist/search/semantic-search.d.ts.map +1 -0
- package/dist/search/semantic-search.js +236 -0
- package/dist/search/semantic-search.js.map +1 -0
- package/dist/tools/memory-forget.d.ts +10 -0
- package/dist/tools/memory-forget.d.ts.map +1 -0
- package/dist/tools/memory-forget.js +34 -0
- package/dist/tools/memory-forget.js.map +1 -0
- package/dist/tools/memory-recall.d.ts +12 -0
- package/dist/tools/memory-recall.d.ts.map +1 -0
- package/dist/tools/memory-recall.js +106 -0
- package/dist/tools/memory-recall.js.map +1 -0
- package/dist/tools/memory-store.d.ts +13 -0
- package/dist/tools/memory-store.d.ts.map +1 -0
- package/dist/tools/memory-store.js +279 -0
- package/dist/tools/memory-store.js.map +1 -0
- package/dist/tools/response-formatter.d.ts +71 -0
- package/dist/tools/response-formatter.d.ts.map +1 -0
- package/dist/tools/response-formatter.js +180 -0
- package/dist/tools/response-formatter.js.map +1 -0
- package/dist/types/index.d.ts +244 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +29 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/token-estimator.d.ts +33 -0
- package/dist/utils/token-estimator.d.ts.map +1 -0
- package/dist/utils/token-estimator.js +54 -0
- package/dist/utils/token-estimator.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory recall tool - Token-aware semantic search
|
|
3
|
+
* v3.0: Dual-response pattern (index + details) for skill-like progressive loading
|
|
4
|
+
*/
|
|
5
|
+
import { semanticSearch } from '../search/semantic-search.js';
|
|
6
|
+
import { formatMemory, formatMemoryList, getMemoryTokenCount } from './response-formatter.js';
|
|
7
|
+
import { now } from '../database/connection.js';
|
|
8
|
+
import { estimateTokens } from '../utils/token-estimator.js';
|
|
9
|
+
/**
|
|
10
|
+
* Recall memories using semantic search with intelligent token budgeting
|
|
11
|
+
* Returns: index (all matches as summaries) + details (top matches with full content)
|
|
12
|
+
*/
|
|
13
|
+
export async function memoryRecall(db, options) {
|
|
14
|
+
try {
|
|
15
|
+
console.error('[memoryRecall] Starting recall with options:', JSON.stringify(options));
|
|
16
|
+
// Set defaults
|
|
17
|
+
const limit = Math.min(options.limit || 20, 50); // Max 50
|
|
18
|
+
const maxTokens = options.max_tokens || 1000; // Default 1k token budget
|
|
19
|
+
console.error(`[memoryRecall] Processed options - limit: ${limit}, maxTokens: ${maxTokens}`);
|
|
20
|
+
// Perform semantic search (get all matches up to limit)
|
|
21
|
+
const searchOptions = {
|
|
22
|
+
query: options.query,
|
|
23
|
+
limit,
|
|
24
|
+
offset: 0,
|
|
25
|
+
includeExpired: false,
|
|
26
|
+
};
|
|
27
|
+
if (options.type)
|
|
28
|
+
searchOptions.type = options.type;
|
|
29
|
+
if (options.entities)
|
|
30
|
+
searchOptions.entities = options.entities;
|
|
31
|
+
console.error('[memoryRecall] Calling semanticSearch...');
|
|
32
|
+
const { results, totalCount } = semanticSearch(db, searchOptions);
|
|
33
|
+
console.error(`[memoryRecall] Search returned ${results.length} results, total count: ${totalCount}`);
|
|
34
|
+
// Track access for frequency tracking
|
|
35
|
+
const currentTime = now();
|
|
36
|
+
for (const result of results) {
|
|
37
|
+
// Increment access_count and update last_accessed
|
|
38
|
+
db.prepare(`UPDATE memories
|
|
39
|
+
SET access_count = access_count + 1, last_accessed = ?
|
|
40
|
+
WHERE id = ?`).run(currentTime, result.id);
|
|
41
|
+
}
|
|
42
|
+
// Build options map for formatting (includes entities and provenance)
|
|
43
|
+
const optionsMap = new Map();
|
|
44
|
+
for (const result of results) {
|
|
45
|
+
optionsMap.set(result.id, {
|
|
46
|
+
entities: result.entities,
|
|
47
|
+
provenance: result.provenance,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
// Convert MemorySearchResult[] to Memory[] for formatting
|
|
51
|
+
const memories = results.map((result) => ({
|
|
52
|
+
id: result.id,
|
|
53
|
+
content: result.content,
|
|
54
|
+
summary: result.summary,
|
|
55
|
+
type: result.type,
|
|
56
|
+
importance: result.importance,
|
|
57
|
+
created_at: result.created_at,
|
|
58
|
+
last_accessed: result.last_accessed,
|
|
59
|
+
access_count: result.access_count,
|
|
60
|
+
expires_at: result.expires_at,
|
|
61
|
+
metadata: result.metadata,
|
|
62
|
+
is_deleted: result.is_deleted,
|
|
63
|
+
}));
|
|
64
|
+
// PHASE 1: Create index (all matches as minimal summaries)
|
|
65
|
+
const index = formatMemoryList(memories, 'minimal');
|
|
66
|
+
const indexTokens = estimateTokens(index);
|
|
67
|
+
// PHASE 2: Fill remaining budget with detailed content
|
|
68
|
+
const details = [];
|
|
69
|
+
let tokensUsed = indexTokens;
|
|
70
|
+
for (const memory of memories) {
|
|
71
|
+
// Format with standard detail (content + entities + timestamps)
|
|
72
|
+
const options = optionsMap.get(memory.id) || {};
|
|
73
|
+
const formatted = formatMemory(memory, 'standard', options);
|
|
74
|
+
const memoryTokens = getMemoryTokenCount(formatted);
|
|
75
|
+
// Check if it fits in remaining budget
|
|
76
|
+
if (tokensUsed + memoryTokens <= maxTokens) {
|
|
77
|
+
details.push(formatted);
|
|
78
|
+
tokensUsed += memoryTokens;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
// Budget exhausted, stop adding details
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Build response with dual structure
|
|
86
|
+
const response = {
|
|
87
|
+
index,
|
|
88
|
+
details,
|
|
89
|
+
total_count: totalCount,
|
|
90
|
+
has_more: totalCount > limit,
|
|
91
|
+
tokens_used: tokensUsed,
|
|
92
|
+
query: options.query,
|
|
93
|
+
};
|
|
94
|
+
console.error(`[memoryRecall] Built response - index: ${index.length} items, details: ${details.length} items, tokens: ${tokensUsed}`);
|
|
95
|
+
console.error('[memoryRecall] Recall completed successfully');
|
|
96
|
+
return response;
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
console.error('[memoryRecall] ERROR:', error);
|
|
100
|
+
if (error instanceof Error) {
|
|
101
|
+
console.error('[memoryRecall] Error stack:', error.stack);
|
|
102
|
+
}
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=memory-recall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-recall.js","sourceRoot":"","sources":["../../src/tools/memory-recall.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory store tool - Store or update memories with auto-extraction
|
|
3
|
+
* v2.0: Merged create + update functionality with summary generation
|
|
4
|
+
*/
|
|
5
|
+
import type Database from 'better-sqlite3';
|
|
6
|
+
import type { MemoryInput, StandardMemory } from '../types/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* Store or update a memory
|
|
9
|
+
* If input.id is provided, updates existing memory
|
|
10
|
+
* If input.id is not provided, creates new memory
|
|
11
|
+
*/
|
|
12
|
+
export declare function memoryStore(db: Database.Database, input: MemoryInput): Promise<StandardMemory>;
|
|
13
|
+
//# sourceMappingURL=memory-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-store.d.ts","sourceRoot":"","sources":["../../src/tools/memory-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAkB,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA8CrF;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC,cAAc,CAAC,CASzB"}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory store tool - Store or update memories with auto-extraction
|
|
3
|
+
* v2.0: Merged create + update functionality with summary generation
|
|
4
|
+
*/
|
|
5
|
+
import { extractEntities, createEntityInput, deduplicateEntities, } from '../extractors/entity-extractor.js';
|
|
6
|
+
import { classifyMemoryType, normalizeContent, validateContent, } from '../extractors/fact-extractor.js';
|
|
7
|
+
import { calculateImportance } from '../scoring/importance.js';
|
|
8
|
+
import { calculateTTLDays, calculateExpiresAt } from '../scoring/ttl-manager.js';
|
|
9
|
+
import { generateId, now, serializeMetadata, deserializeMetadata, } from '../database/connection.js';
|
|
10
|
+
import { ValidationError } from '../types/index.js';
|
|
11
|
+
import { generateSummary } from '../extractors/summary-generator.js';
|
|
12
|
+
import { formatMemory } from './response-formatter.js';
|
|
13
|
+
/**
|
|
14
|
+
* Store or update a memory
|
|
15
|
+
* If input.id is provided, updates existing memory
|
|
16
|
+
* If input.id is not provided, creates new memory
|
|
17
|
+
*/
|
|
18
|
+
export async function memoryStore(db, input) {
|
|
19
|
+
// Determine if this is an update or create
|
|
20
|
+
const isUpdate = !!input.id;
|
|
21
|
+
if (isUpdate) {
|
|
22
|
+
return updateMemory(db, input);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
return createMemory(db, input);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Create a new memory
|
|
30
|
+
*/
|
|
31
|
+
async function createMemory(db, input) {
|
|
32
|
+
// Validate content
|
|
33
|
+
const validation = validateContent(input.content, input.type);
|
|
34
|
+
if (!validation.valid) {
|
|
35
|
+
throw new ValidationError(validation.errors.join(', '));
|
|
36
|
+
}
|
|
37
|
+
// Normalize content
|
|
38
|
+
const normalizedContent = normalizeContent(input.content);
|
|
39
|
+
// Generate summary
|
|
40
|
+
const summary = generateSummary(normalizedContent);
|
|
41
|
+
// Extract entities if not provided
|
|
42
|
+
let entities = input.entities || [];
|
|
43
|
+
if (entities.length === 0) {
|
|
44
|
+
entities = extractEntities(normalizedContent);
|
|
45
|
+
entities = deduplicateEntities(entities);
|
|
46
|
+
}
|
|
47
|
+
// Auto-classify type if needed
|
|
48
|
+
const finalType = input.type || classifyMemoryType(normalizedContent, entities);
|
|
49
|
+
// Calculate importance
|
|
50
|
+
const importance = input.importance ??
|
|
51
|
+
calculateImportance(normalizedContent, finalType, entities, input.metadata || {}, input.provenance !== undefined);
|
|
52
|
+
// Calculate TTL
|
|
53
|
+
let expiresAt = null;
|
|
54
|
+
if (input.expires_at) {
|
|
55
|
+
expiresAt = new Date(input.expires_at).getTime();
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
const ttlDays = input.ttl_days !== undefined
|
|
59
|
+
? input.ttl_days
|
|
60
|
+
: calculateTTLDays(importance);
|
|
61
|
+
expiresAt = calculateExpiresAt(ttlDays, importance, now());
|
|
62
|
+
}
|
|
63
|
+
// Create memory
|
|
64
|
+
const memoryId = generateId('mem');
|
|
65
|
+
const createdAt = now();
|
|
66
|
+
const metadata = input.metadata || {};
|
|
67
|
+
// Merge tags into metadata if provided
|
|
68
|
+
if (input.tags && input.tags.length > 0) {
|
|
69
|
+
metadata.tags = input.tags;
|
|
70
|
+
}
|
|
71
|
+
db.prepare(`
|
|
72
|
+
INSERT INTO memories (
|
|
73
|
+
id, content, summary, type, importance, embedding,
|
|
74
|
+
created_at, last_accessed, access_count, expires_at, metadata, is_deleted
|
|
75
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)
|
|
76
|
+
`).run(memoryId, normalizedContent, summary, finalType, importance, null, // No longer using embeddings
|
|
77
|
+
createdAt, createdAt, 0, // Initial access_count
|
|
78
|
+
expiresAt, serializeMetadata(metadata));
|
|
79
|
+
// Create or link entities
|
|
80
|
+
const entityObjects = [];
|
|
81
|
+
for (const entityName of entities) {
|
|
82
|
+
const entityId = createOrGetEntity(db, entityName, normalizedContent);
|
|
83
|
+
// Fetch entity details
|
|
84
|
+
const entityRow = db
|
|
85
|
+
.prepare('SELECT * FROM entities WHERE id = ?')
|
|
86
|
+
.get(entityId);
|
|
87
|
+
if (entityRow) {
|
|
88
|
+
entityObjects.push({
|
|
89
|
+
id: entityRow.id,
|
|
90
|
+
name: entityRow.name,
|
|
91
|
+
type: entityRow.type,
|
|
92
|
+
metadata: deserializeMetadata(entityRow.metadata),
|
|
93
|
+
created_at: entityRow.created_at,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
// Link memory to entity
|
|
97
|
+
db.prepare(`INSERT INTO memory_entities (memory_id, entity_id, created_at) VALUES (?, ?, ?)`).run(memoryId, entityId, createdAt);
|
|
98
|
+
}
|
|
99
|
+
// Create provenance record
|
|
100
|
+
const provenanceId = generateId('prov');
|
|
101
|
+
const provenance = input.provenance || {
|
|
102
|
+
source: 'user',
|
|
103
|
+
timestamp: new Date().toISOString(),
|
|
104
|
+
};
|
|
105
|
+
db.prepare(`
|
|
106
|
+
INSERT INTO provenance (
|
|
107
|
+
id, memory_id, operation, timestamp, source, context, user_id, changes
|
|
108
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
109
|
+
`).run(provenanceId, memoryId, 'create', createdAt, provenance.source, provenance.context || null, provenance.user_id || null, null);
|
|
110
|
+
// Build Memory object for formatting
|
|
111
|
+
const memory = {
|
|
112
|
+
id: memoryId,
|
|
113
|
+
content: normalizedContent,
|
|
114
|
+
summary,
|
|
115
|
+
type: finalType,
|
|
116
|
+
importance,
|
|
117
|
+
created_at: createdAt,
|
|
118
|
+
last_accessed: createdAt,
|
|
119
|
+
access_count: 0,
|
|
120
|
+
expires_at: expiresAt,
|
|
121
|
+
metadata,
|
|
122
|
+
is_deleted: false,
|
|
123
|
+
};
|
|
124
|
+
// Format response using standard detail level (NO embeddings)
|
|
125
|
+
const formattedResponse = formatMemory(memory, 'standard', { entities: entityObjects });
|
|
126
|
+
return formattedResponse;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Update an existing memory
|
|
130
|
+
*/
|
|
131
|
+
async function updateMemory(db, input) {
|
|
132
|
+
// Check if memory exists
|
|
133
|
+
const existing = db
|
|
134
|
+
.prepare('SELECT * FROM memories WHERE id = ? AND is_deleted = 0')
|
|
135
|
+
.get(input.id ?? '');
|
|
136
|
+
if (!existing) {
|
|
137
|
+
throw new ValidationError(`Memory ${input.id} not found or is deleted`);
|
|
138
|
+
}
|
|
139
|
+
const changes = {};
|
|
140
|
+
const currentTime = now();
|
|
141
|
+
let newContent = existing.content;
|
|
142
|
+
let newSummary = existing.summary;
|
|
143
|
+
// Update content if provided
|
|
144
|
+
if (input.content !== undefined) {
|
|
145
|
+
newContent = normalizeContent(input.content);
|
|
146
|
+
newSummary = generateSummary(newContent);
|
|
147
|
+
db.prepare('UPDATE memories SET content = ?, summary = ? WHERE id = ?').run(newContent, newSummary, input.id);
|
|
148
|
+
changes['content'] = { from: existing.content, to: newContent };
|
|
149
|
+
changes['summary'] = { from: existing.summary, to: newSummary };
|
|
150
|
+
}
|
|
151
|
+
// Update importance if provided
|
|
152
|
+
if (input.importance !== undefined) {
|
|
153
|
+
db.prepare('UPDATE memories SET importance = ? WHERE id = ?').run(input.importance, input.id);
|
|
154
|
+
changes['importance'] = {
|
|
155
|
+
from: existing.importance,
|
|
156
|
+
to: input.importance,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
// Update metadata if provided
|
|
160
|
+
let updatedMetadata = deserializeMetadata(existing.metadata);
|
|
161
|
+
if (input.metadata !== undefined) {
|
|
162
|
+
updatedMetadata = { ...updatedMetadata, ...input.metadata };
|
|
163
|
+
db.prepare('UPDATE memories SET metadata = ? WHERE id = ?').run(serializeMetadata(updatedMetadata), input.id);
|
|
164
|
+
changes['metadata'] = { merged: input.metadata };
|
|
165
|
+
}
|
|
166
|
+
// Update tags in metadata if provided
|
|
167
|
+
if (input.tags !== undefined) {
|
|
168
|
+
updatedMetadata.tags = input.tags;
|
|
169
|
+
db.prepare('UPDATE memories SET metadata = ? WHERE id = ?').run(serializeMetadata(updatedMetadata), input.id);
|
|
170
|
+
changes['tags'] = { to: input.tags };
|
|
171
|
+
}
|
|
172
|
+
// Update TTL if provided
|
|
173
|
+
let newExpiresAt = existing.expires_at;
|
|
174
|
+
if (input.ttl_days !== undefined || input.expires_at !== undefined) {
|
|
175
|
+
if (input.expires_at) {
|
|
176
|
+
newExpiresAt = new Date(input.expires_at).getTime();
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
const newImportance = input.importance ?? existing.importance;
|
|
180
|
+
const ttlDays = input.ttl_days ?? calculateTTLDays(newImportance);
|
|
181
|
+
newExpiresAt = calculateExpiresAt(ttlDays, newImportance, currentTime);
|
|
182
|
+
}
|
|
183
|
+
db.prepare('UPDATE memories SET expires_at = ? WHERE id = ?').run(newExpiresAt, input.id);
|
|
184
|
+
changes['expires_at'] = {
|
|
185
|
+
from: existing.expires_at,
|
|
186
|
+
to: newExpiresAt,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
// Update entities if provided
|
|
190
|
+
let entityObjects = [];
|
|
191
|
+
if (input.entities !== undefined) {
|
|
192
|
+
// Remove existing entity links
|
|
193
|
+
db.prepare('DELETE FROM memory_entities WHERE memory_id = ?').run(input.id);
|
|
194
|
+
// Create new entity links
|
|
195
|
+
for (const entityName of input.entities) {
|
|
196
|
+
const entityId = createOrGetEntity(db, entityName, newContent);
|
|
197
|
+
// Fetch entity details
|
|
198
|
+
const entityRow = db
|
|
199
|
+
.prepare('SELECT * FROM entities WHERE id = ?')
|
|
200
|
+
.get(entityId);
|
|
201
|
+
if (entityRow) {
|
|
202
|
+
entityObjects.push({
|
|
203
|
+
id: entityRow.id,
|
|
204
|
+
name: entityRow.name,
|
|
205
|
+
type: entityRow.type,
|
|
206
|
+
metadata: deserializeMetadata(entityRow.metadata),
|
|
207
|
+
created_at: entityRow.created_at,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
db.prepare(`INSERT INTO memory_entities (memory_id, entity_id, created_at) VALUES (?, ?, ?)`).run(input.id, entityId, currentTime);
|
|
211
|
+
}
|
|
212
|
+
changes['entities'] = { to: input.entities };
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
// Fetch existing entities
|
|
216
|
+
const entityRows = db
|
|
217
|
+
.prepare(`
|
|
218
|
+
SELECT e.* FROM entities e
|
|
219
|
+
JOIN memory_entities me ON e.id = me.entity_id
|
|
220
|
+
WHERE me.memory_id = ?
|
|
221
|
+
`)
|
|
222
|
+
.all(input.id);
|
|
223
|
+
entityObjects = entityRows.map((row) => ({
|
|
224
|
+
id: row.id,
|
|
225
|
+
name: row.name,
|
|
226
|
+
type: row.type,
|
|
227
|
+
metadata: deserializeMetadata(row.metadata),
|
|
228
|
+
created_at: row.created_at,
|
|
229
|
+
}));
|
|
230
|
+
}
|
|
231
|
+
// Create provenance record
|
|
232
|
+
const provenanceId = generateId('prov');
|
|
233
|
+
const provenance = input.provenance || {
|
|
234
|
+
source: 'user',
|
|
235
|
+
};
|
|
236
|
+
db.prepare(`
|
|
237
|
+
INSERT INTO provenance (
|
|
238
|
+
id, memory_id, operation, timestamp, source, context, user_id, changes
|
|
239
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
240
|
+
`).run(provenanceId, input.id, 'update', currentTime, provenance.source, provenance.context || `Updated ${Object.keys(changes).length} field(s)`, provenance.user_id || null, serializeMetadata(changes));
|
|
241
|
+
// Build Memory object for formatting
|
|
242
|
+
const memory = {
|
|
243
|
+
id: input.id ?? existing.id,
|
|
244
|
+
content: newContent,
|
|
245
|
+
summary: newSummary,
|
|
246
|
+
type: existing.type,
|
|
247
|
+
importance: input.importance ?? existing.importance,
|
|
248
|
+
created_at: existing.created_at,
|
|
249
|
+
last_accessed: existing.last_accessed,
|
|
250
|
+
access_count: existing.access_count,
|
|
251
|
+
expires_at: newExpiresAt,
|
|
252
|
+
metadata: updatedMetadata,
|
|
253
|
+
is_deleted: false,
|
|
254
|
+
};
|
|
255
|
+
// Format response using standard detail level (NO embeddings)
|
|
256
|
+
const formattedResponse = formatMemory(memory, 'standard', { entities: entityObjects });
|
|
257
|
+
return formattedResponse;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Create or get existing entity
|
|
261
|
+
*/
|
|
262
|
+
function createOrGetEntity(db, name, context) {
|
|
263
|
+
// Check if entity exists
|
|
264
|
+
const existing = db
|
|
265
|
+
.prepare('SELECT id FROM entities WHERE name = ?')
|
|
266
|
+
.get(name);
|
|
267
|
+
if (existing) {
|
|
268
|
+
return existing.id;
|
|
269
|
+
}
|
|
270
|
+
// Create new entity
|
|
271
|
+
const entityInput = createEntityInput(name, context);
|
|
272
|
+
const entityId = generateId('ent');
|
|
273
|
+
db.prepare(`
|
|
274
|
+
INSERT INTO entities (id, name, type, metadata, created_at)
|
|
275
|
+
VALUES (?, ?, ?, ?, ?)
|
|
276
|
+
`).run(entityId, entityInput.name, entityInput.type || 'other', serializeMetadata(entityInput.metadata || {}), now());
|
|
277
|
+
return entityId;
|
|
278
|
+
}
|
|
279
|
+
//# sourceMappingURL=memory-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-store.js","sourceRoot":"","sources":["../../src/tools/memory-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response Formatter - Format memories with tiered detail levels
|
|
3
|
+
*
|
|
4
|
+
* Critical: NEVER include embedding or vector fields in responses
|
|
5
|
+
* Token targets: minimal=30, standard=200, full=500
|
|
6
|
+
*/
|
|
7
|
+
import type { Memory, DetailLevel, FormattedMemory, Entity, Provenance } from '../types/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Format options for memory formatting
|
|
10
|
+
*/
|
|
11
|
+
export interface FormatOptions {
|
|
12
|
+
entities?: Entity[];
|
|
13
|
+
provenance?: Provenance[];
|
|
14
|
+
tags?: string[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Format a single memory according to detail level
|
|
18
|
+
*
|
|
19
|
+
* @param memory - The memory to format
|
|
20
|
+
* @param detailLevel - Level of detail to include
|
|
21
|
+
* @param options - Optional entities, provenance, and tags
|
|
22
|
+
* @returns Formatted memory (NO embeddings)
|
|
23
|
+
*/
|
|
24
|
+
export declare function formatMemory(memory: Memory, detailLevel: DetailLevel, options?: FormatOptions): FormattedMemory;
|
|
25
|
+
/**
|
|
26
|
+
* Format a list of memories
|
|
27
|
+
*
|
|
28
|
+
* @param memories - Array of memories to format
|
|
29
|
+
* @param detailLevel - Level of detail to include
|
|
30
|
+
* @param optionsMap - Map of memory IDs to format options
|
|
31
|
+
* @returns Array of formatted memories
|
|
32
|
+
*/
|
|
33
|
+
export declare function formatMemoryList(memories: Memory[], detailLevel: DetailLevel, optionsMap?: Map<string, FormatOptions>): FormattedMemory[];
|
|
34
|
+
/**
|
|
35
|
+
* Get estimated token count for a formatted memory
|
|
36
|
+
*
|
|
37
|
+
* @param memory - Formatted memory to estimate
|
|
38
|
+
* @returns Estimated token count
|
|
39
|
+
*/
|
|
40
|
+
export declare function getMemoryTokenCount(memory: FormattedMemory): number;
|
|
41
|
+
/**
|
|
42
|
+
* Validate that a memory list fits within token budget
|
|
43
|
+
*
|
|
44
|
+
* @param memories - Array of formatted memories
|
|
45
|
+
* @param maxTokens - Maximum allowed tokens
|
|
46
|
+
* @returns Validation result
|
|
47
|
+
*/
|
|
48
|
+
export declare function validateMemoryBudget(memories: FormattedMemory[], maxTokens: number): {
|
|
49
|
+
fits: boolean;
|
|
50
|
+
estimated: number;
|
|
51
|
+
count: number;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Truncate memory list to fit within token budget
|
|
55
|
+
*
|
|
56
|
+
* @param memories - Array of formatted memories
|
|
57
|
+
* @param maxTokens - Maximum token budget
|
|
58
|
+
* @returns Truncated array that fits within budget
|
|
59
|
+
*/
|
|
60
|
+
export declare function truncateToTokenBudget(memories: FormattedMemory[], maxTokens: number): FormattedMemory[];
|
|
61
|
+
/**
|
|
62
|
+
* Debug: Get token statistics for a memory
|
|
63
|
+
*
|
|
64
|
+
* @param memory - Formatted memory to analyze
|
|
65
|
+
* @returns Token statistics
|
|
66
|
+
*/
|
|
67
|
+
export declare function getMemoryTokenStats(memory: FormattedMemory): {
|
|
68
|
+
total: number;
|
|
69
|
+
byField: Record<string, number>;
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=response-formatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-formatter.d.ts","sourceRoot":"","sources":["../../src/tools/response-formatter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,MAAM,EACN,WAAW,EAIX,eAAe,EACf,MAAM,EACN,UAAU,EACX,MAAM,mBAAmB,CAAC;AAG3B;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,OAAO,GAAE,aAAkB,GAC1B,eAAe,CAWjB;AA4FD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAAE,EAClB,WAAW,EAAE,WAAW,EACxB,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GACtC,eAAe,EAAE,CAKnB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAEnE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,eAAe,EAAE,EAC3B,SAAS,EAAE,MAAM,GAChB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAOrD;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,eAAe,EAAE,EAC3B,SAAS,EAAE,MAAM,GAChB,eAAe,EAAE,CAenB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC,CAWA"}
|