@stackmemoryai/stackmemory 0.5.61 → 0.5.62
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/dist/scripts/initialize.js +68 -1
- package/dist/scripts/initialize.js.map +2 -2
- package/dist/src/core/retrieval/index.js +2 -0
- package/dist/src/core/retrieval/index.js.map +2 -2
- package/dist/src/core/retrieval/privacy-filter.js +129 -0
- package/dist/src/core/retrieval/privacy-filter.js.map +7 -0
- package/dist/src/core/retrieval/unified-context-assembler.js +273 -0
- package/dist/src/core/retrieval/unified-context-assembler.js.map +7 -0
- package/dist/src/hooks/diffmem-hooks.js +377 -0
- package/dist/src/hooks/diffmem-hooks.js.map +7 -0
- package/dist/src/integrations/diffmem/client.js +209 -0
- package/dist/src/integrations/diffmem/client.js.map +7 -0
- package/dist/src/integrations/diffmem/config.js +15 -0
- package/dist/src/integrations/diffmem/config.js.map +7 -0
- package/dist/src/integrations/diffmem/index.js +12 -0
- package/dist/src/integrations/diffmem/index.js.map +7 -0
- package/dist/src/integrations/diffmem/types.js +5 -0
- package/dist/src/integrations/diffmem/types.js.map +7 -0
- package/dist/src/integrations/mcp/handlers/diffmem-handlers.js +456 -0
- package/dist/src/integrations/mcp/handlers/diffmem-handlers.js.map +7 -0
- package/dist/src/integrations/mcp/server.js +121 -0
- package/dist/src/integrations/mcp/server.js.map +2 -2
- package/package.json +3 -1
- package/scripts/initialize.ts +83 -1
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import { fileURLToPath as __fileURLToPath } from 'url';
|
|
2
|
+
import { dirname as __pathDirname } from 'path';
|
|
3
|
+
const __filename = __fileURLToPath(import.meta.url);
|
|
4
|
+
const __dirname = __pathDirname(__filename);
|
|
5
|
+
import { logger } from "../core/monitoring/logger.js";
|
|
6
|
+
const DEFAULT_CONFIG = {
|
|
7
|
+
enabled: !!process.env.DIFFMEM_ENDPOINT,
|
|
8
|
+
endpoint: process.env.DIFFMEM_ENDPOINT || "http://localhost:3100",
|
|
9
|
+
autoFetchCategories: ["preference", "expertise", "pattern"],
|
|
10
|
+
autoLearnEnabled: true,
|
|
11
|
+
learningConfidenceThreshold: 0.7,
|
|
12
|
+
maxMemoriesPerSession: 50
|
|
13
|
+
};
|
|
14
|
+
class DiffMemHooks {
|
|
15
|
+
config;
|
|
16
|
+
fetchedMemories = [];
|
|
17
|
+
learningBuffer = [];
|
|
18
|
+
isConnected = false;
|
|
19
|
+
frameManager;
|
|
20
|
+
sessionStartTime = 0;
|
|
21
|
+
constructor(config = {}) {
|
|
22
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Register session hooks with the event emitter
|
|
26
|
+
*/
|
|
27
|
+
register(emitter, frameManager) {
|
|
28
|
+
this.frameManager = frameManager;
|
|
29
|
+
if (!this.config.enabled) {
|
|
30
|
+
logger.debug("DiffMem hooks disabled - skipping registration");
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
emitter.registerHandler("session_start", this.onSessionStart.bind(this));
|
|
34
|
+
emitter.registerHandler("session_end", this.onSessionEnd.bind(this));
|
|
35
|
+
logger.info("DiffMem hooks registered", {
|
|
36
|
+
endpoint: this.config.endpoint,
|
|
37
|
+
autoFetchCategories: this.config.autoFetchCategories,
|
|
38
|
+
autoLearnEnabled: this.config.autoLearnEnabled
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Handle session start - fetch user knowledge
|
|
43
|
+
*/
|
|
44
|
+
async onSessionStart(event) {
|
|
45
|
+
const sessionEvent = event;
|
|
46
|
+
this.sessionStartTime = Date.now();
|
|
47
|
+
try {
|
|
48
|
+
const status = await this.checkStatus();
|
|
49
|
+
this.isConnected = status.connected;
|
|
50
|
+
if (!this.isConnected) {
|
|
51
|
+
logger.debug("DiffMem not available - skipping memory fetch");
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const query = {
|
|
55
|
+
categories: this.config.autoFetchCategories,
|
|
56
|
+
limit: this.config.maxMemoriesPerSession,
|
|
57
|
+
minConfidence: this.config.learningConfidenceThreshold
|
|
58
|
+
};
|
|
59
|
+
this.fetchedMemories = await this.fetchMemories(query);
|
|
60
|
+
if (this.frameManager && this.fetchedMemories.length > 0) {
|
|
61
|
+
await this.injectAsAnchors(sessionEvent.data.sessionId);
|
|
62
|
+
}
|
|
63
|
+
logger.info("DiffMem session start completed", {
|
|
64
|
+
memoriesFetched: this.fetchedMemories.length,
|
|
65
|
+
sessionId: sessionEvent.data.sessionId
|
|
66
|
+
});
|
|
67
|
+
} catch (error) {
|
|
68
|
+
logger.warn("DiffMem session start failed", {
|
|
69
|
+
error: error instanceof Error ? error.message : String(error)
|
|
70
|
+
});
|
|
71
|
+
this.isConnected = false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Handle session end - sync buffered learnings
|
|
76
|
+
*/
|
|
77
|
+
async onSessionEnd(event) {
|
|
78
|
+
const sessionEvent = event;
|
|
79
|
+
if (!this.config.autoLearnEnabled || this.learningBuffer.length === 0) {
|
|
80
|
+
logger.debug("No learnings to sync on session end");
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (!this.isConnected) {
|
|
84
|
+
const status = await this.checkStatus();
|
|
85
|
+
if (!status.connected) {
|
|
86
|
+
logger.warn("DiffMem not available - learnings not synced", {
|
|
87
|
+
bufferedCount: this.learningBuffer.length
|
|
88
|
+
});
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
this.isConnected = true;
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
await this.syncLearnings();
|
|
95
|
+
const sessionDuration = Date.now() - this.sessionStartTime;
|
|
96
|
+
logger.info("DiffMem session end completed", {
|
|
97
|
+
learningSynced: this.learningBuffer.length,
|
|
98
|
+
sessionId: sessionEvent.data.sessionId,
|
|
99
|
+
sessionDurationMs: sessionDuration
|
|
100
|
+
});
|
|
101
|
+
this.learningBuffer = [];
|
|
102
|
+
} catch (error) {
|
|
103
|
+
logger.warn("DiffMem session end sync failed", {
|
|
104
|
+
error: error instanceof Error ? error.message : String(error),
|
|
105
|
+
bufferedCount: this.learningBuffer.length
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Record a learning during session
|
|
111
|
+
*/
|
|
112
|
+
recordLearning(insight) {
|
|
113
|
+
if (!this.config.autoLearnEnabled) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (insight.confidence < this.config.learningConfidenceThreshold) {
|
|
117
|
+
logger.debug("Learning below confidence threshold", {
|
|
118
|
+
confidence: insight.confidence,
|
|
119
|
+
threshold: this.config.learningConfidenceThreshold
|
|
120
|
+
});
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const learning = {
|
|
124
|
+
...insight,
|
|
125
|
+
timestamp: Date.now()
|
|
126
|
+
};
|
|
127
|
+
this.learningBuffer.push(learning);
|
|
128
|
+
logger.debug("Learning recorded", {
|
|
129
|
+
category: learning.category,
|
|
130
|
+
confidence: learning.confidence,
|
|
131
|
+
bufferSize: this.learningBuffer.length
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Get fetched memories
|
|
136
|
+
*/
|
|
137
|
+
getUserKnowledge() {
|
|
138
|
+
return [...this.fetchedMemories];
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Format memories for LLM context with token budget
|
|
142
|
+
*/
|
|
143
|
+
formatForContext(maxTokens = 2e3) {
|
|
144
|
+
if (this.fetchedMemories.length === 0) {
|
|
145
|
+
return "";
|
|
146
|
+
}
|
|
147
|
+
const sortedMemories = [...this.fetchedMemories].sort((a, b) => {
|
|
148
|
+
if (b.confidence !== a.confidence) {
|
|
149
|
+
return b.confidence - a.confidence;
|
|
150
|
+
}
|
|
151
|
+
return b.timestamp - a.timestamp;
|
|
152
|
+
});
|
|
153
|
+
const sections = /* @__PURE__ */ new Map();
|
|
154
|
+
for (const memory of sortedMemories) {
|
|
155
|
+
const category = memory.category;
|
|
156
|
+
if (!sections.has(category)) {
|
|
157
|
+
sections.set(category, []);
|
|
158
|
+
}
|
|
159
|
+
const categoryMemories = sections.get(category);
|
|
160
|
+
if (categoryMemories) {
|
|
161
|
+
categoryMemories.push(memory.content);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const lines = ["## User Knowledge"];
|
|
165
|
+
let estimatedTokens = 5;
|
|
166
|
+
const categoryLabels = {
|
|
167
|
+
preference: "Preferences",
|
|
168
|
+
expertise: "Expertise",
|
|
169
|
+
project_knowledge: "Project Knowledge",
|
|
170
|
+
pattern: "Patterns",
|
|
171
|
+
correction: "Corrections"
|
|
172
|
+
};
|
|
173
|
+
for (const [category, contents] of sections) {
|
|
174
|
+
const label = categoryLabels[category] || category;
|
|
175
|
+
const categoryHeader = `
|
|
176
|
+
### ${label}`;
|
|
177
|
+
const headerTokens = Math.ceil(categoryHeader.length / 4);
|
|
178
|
+
if (estimatedTokens + headerTokens > maxTokens) {
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
lines.push(categoryHeader);
|
|
182
|
+
estimatedTokens += headerTokens;
|
|
183
|
+
for (const content of contents) {
|
|
184
|
+
const contentLine = `- ${content}`;
|
|
185
|
+
const contentTokens = Math.ceil(contentLine.length / 4);
|
|
186
|
+
if (estimatedTokens + contentTokens > maxTokens) {
|
|
187
|
+
lines.push("- (additional items truncated for token budget)");
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
lines.push(contentLine);
|
|
191
|
+
estimatedTokens += contentTokens;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return lines.join("\n");
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Get current connection status
|
|
198
|
+
*/
|
|
199
|
+
getStatus() {
|
|
200
|
+
return {
|
|
201
|
+
connected: this.isConnected,
|
|
202
|
+
memoriesLoaded: this.fetchedMemories.length,
|
|
203
|
+
learningsBuffered: this.learningBuffer.length
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Update configuration
|
|
208
|
+
*/
|
|
209
|
+
updateConfig(config) {
|
|
210
|
+
this.config = { ...this.config, ...config };
|
|
211
|
+
logger.debug("DiffMem config updated", { config: this.config });
|
|
212
|
+
}
|
|
213
|
+
// Private methods
|
|
214
|
+
/**
|
|
215
|
+
* Check DiffMem service status
|
|
216
|
+
*/
|
|
217
|
+
async checkStatus() {
|
|
218
|
+
try {
|
|
219
|
+
const controller = new AbortController();
|
|
220
|
+
const timeoutId = setTimeout(() => controller.abort(), 3e3);
|
|
221
|
+
const response = await fetch(`${this.config.endpoint}/status`, {
|
|
222
|
+
method: "GET",
|
|
223
|
+
signal: controller.signal
|
|
224
|
+
});
|
|
225
|
+
clearTimeout(timeoutId);
|
|
226
|
+
if (!response.ok) {
|
|
227
|
+
return { connected: false, memoryCount: 0, lastSync: null };
|
|
228
|
+
}
|
|
229
|
+
const status = await response.json();
|
|
230
|
+
return {
|
|
231
|
+
connected: true,
|
|
232
|
+
memoryCount: status.memoryCount || 0,
|
|
233
|
+
lastSync: status.lastSync || null,
|
|
234
|
+
version: status.version
|
|
235
|
+
};
|
|
236
|
+
} catch {
|
|
237
|
+
return { connected: false, memoryCount: 0, lastSync: null };
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Fetch memories from DiffMem
|
|
242
|
+
*/
|
|
243
|
+
async fetchMemories(query) {
|
|
244
|
+
try {
|
|
245
|
+
const controller = new AbortController();
|
|
246
|
+
const timeoutId = setTimeout(() => controller.abort(), 5e3);
|
|
247
|
+
const response = await fetch(`${this.config.endpoint}/memories/query`, {
|
|
248
|
+
method: "POST",
|
|
249
|
+
headers: { "Content-Type": "application/json" },
|
|
250
|
+
body: JSON.stringify(query),
|
|
251
|
+
signal: controller.signal
|
|
252
|
+
});
|
|
253
|
+
clearTimeout(timeoutId);
|
|
254
|
+
if (!response.ok) {
|
|
255
|
+
logger.warn("DiffMem query failed", { status: response.status });
|
|
256
|
+
return [];
|
|
257
|
+
}
|
|
258
|
+
const data = await response.json();
|
|
259
|
+
return data.memories || [];
|
|
260
|
+
} catch (error) {
|
|
261
|
+
logger.debug("DiffMem fetch failed", {
|
|
262
|
+
error: error instanceof Error ? error.message : String(error)
|
|
263
|
+
});
|
|
264
|
+
return [];
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Sync buffered learnings to DiffMem
|
|
269
|
+
*/
|
|
270
|
+
async syncLearnings() {
|
|
271
|
+
if (this.learningBuffer.length === 0) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
const controller = new AbortController();
|
|
275
|
+
const timeoutId = setTimeout(() => controller.abort(), 1e4);
|
|
276
|
+
try {
|
|
277
|
+
const response = await fetch(`${this.config.endpoint}/memories/learn`, {
|
|
278
|
+
method: "POST",
|
|
279
|
+
headers: { "Content-Type": "application/json" },
|
|
280
|
+
body: JSON.stringify({ insights: this.learningBuffer }),
|
|
281
|
+
signal: controller.signal
|
|
282
|
+
});
|
|
283
|
+
clearTimeout(timeoutId);
|
|
284
|
+
if (!response.ok) {
|
|
285
|
+
throw new Error(`Sync failed with status ${response.status}`);
|
|
286
|
+
}
|
|
287
|
+
logger.info("Learnings synced to DiffMem", {
|
|
288
|
+
count: this.learningBuffer.length
|
|
289
|
+
});
|
|
290
|
+
} catch (error) {
|
|
291
|
+
clearTimeout(timeoutId);
|
|
292
|
+
throw error;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Inject fetched memories as frame anchors
|
|
297
|
+
*/
|
|
298
|
+
async injectAsAnchors(sessionId) {
|
|
299
|
+
if (!this.frameManager || this.fetchedMemories.length === 0) {
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
try {
|
|
303
|
+
const byCategory = /* @__PURE__ */ new Map();
|
|
304
|
+
for (const memory of this.fetchedMemories) {
|
|
305
|
+
if (!byCategory.has(memory.category)) {
|
|
306
|
+
byCategory.set(memory.category, []);
|
|
307
|
+
}
|
|
308
|
+
const categoryList = byCategory.get(memory.category);
|
|
309
|
+
if (categoryList) {
|
|
310
|
+
categoryList.push(memory);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
for (const [category, memories] of byCategory) {
|
|
314
|
+
const highConfidence = memories.filter((m) => m.confidence >= 0.8);
|
|
315
|
+
for (const memory of highConfidence.slice(0, 5)) {
|
|
316
|
+
const anchorType = this.categoryToAnchorType(category);
|
|
317
|
+
const priority = Math.round(memory.confidence * 10);
|
|
318
|
+
this.frameManager.addAnchor(anchorType, memory.content, priority, {
|
|
319
|
+
source: "diffmem",
|
|
320
|
+
category: memory.category,
|
|
321
|
+
memoryId: memory.id,
|
|
322
|
+
confidence: memory.confidence,
|
|
323
|
+
sessionId
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
logger.debug("Memories injected as anchors", {
|
|
328
|
+
totalMemories: this.fetchedMemories.length,
|
|
329
|
+
anchorsCreated: Math.min(
|
|
330
|
+
this.fetchedMemories.filter((m) => m.confidence >= 0.8).length,
|
|
331
|
+
25
|
|
332
|
+
)
|
|
333
|
+
});
|
|
334
|
+
} catch (error) {
|
|
335
|
+
logger.warn("Failed to inject memories as anchors", {
|
|
336
|
+
error: error instanceof Error ? error.message : String(error)
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Map memory category to anchor type
|
|
342
|
+
*/
|
|
343
|
+
categoryToAnchorType(category) {
|
|
344
|
+
switch (category) {
|
|
345
|
+
case "preference":
|
|
346
|
+
return "CONSTRAINT";
|
|
347
|
+
case "expertise":
|
|
348
|
+
return "FACT";
|
|
349
|
+
case "project_knowledge":
|
|
350
|
+
return "FACT";
|
|
351
|
+
case "pattern":
|
|
352
|
+
return "INTERFACE_CONTRACT";
|
|
353
|
+
case "correction":
|
|
354
|
+
return "DECISION";
|
|
355
|
+
default:
|
|
356
|
+
return "FACT";
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
let instance = null;
|
|
361
|
+
function getDiffMemHooks(config) {
|
|
362
|
+
if (!instance) {
|
|
363
|
+
instance = new DiffMemHooks(config);
|
|
364
|
+
} else if (config) {
|
|
365
|
+
instance.updateConfig(config);
|
|
366
|
+
}
|
|
367
|
+
return instance;
|
|
368
|
+
}
|
|
369
|
+
function resetDiffMemHooks() {
|
|
370
|
+
instance = null;
|
|
371
|
+
}
|
|
372
|
+
export {
|
|
373
|
+
DiffMemHooks,
|
|
374
|
+
getDiffMemHooks,
|
|
375
|
+
resetDiffMemHooks
|
|
376
|
+
};
|
|
377
|
+
//# sourceMappingURL=diffmem-hooks.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/hooks/diffmem-hooks.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * DiffMem Session Hooks\n * Integrates DiffMem user memory with StackMemory session lifecycle\n */\n\nimport { logger } from '../core/monitoring/logger.js';\nimport type { HookEventEmitter, HookEventData } from './events.js';\nimport type { RefactoredFrameManager } from '../core/context/refactored-frame-manager.js';\nimport type {\n UserMemory,\n MemoryQuery,\n LearnedInsight,\n DiffMemStatus,\n} from '../integrations/diffmem/types.js';\n\nexport interface DiffMemHookConfig {\n enabled: boolean;\n endpoint: string;\n autoFetchCategories: string[];\n autoLearnEnabled: boolean;\n learningConfidenceThreshold: number;\n maxMemoriesPerSession: number;\n}\n\ninterface SessionStartEvent extends HookEventData {\n type: 'session_start';\n data: {\n sessionId?: string;\n projectId?: string;\n context?: Record<string, unknown>;\n };\n}\n\ninterface SessionEndEvent extends HookEventData {\n type: 'session_end';\n data: {\n sessionId?: string;\n duration?: number;\n exitCode?: number | null;\n };\n}\n\nconst DEFAULT_CONFIG: DiffMemHookConfig = {\n enabled: !!process.env.DIFFMEM_ENDPOINT,\n endpoint: process.env.DIFFMEM_ENDPOINT || 'http://localhost:3100',\n autoFetchCategories: ['preference', 'expertise', 'pattern'],\n autoLearnEnabled: true,\n learningConfidenceThreshold: 0.7,\n maxMemoriesPerSession: 50,\n};\n\n/**\n * DiffMem Session Hooks\n * Manages user memory fetch on session start and sync on session end\n */\nexport class DiffMemHooks {\n private config: DiffMemHookConfig;\n private fetchedMemories: UserMemory[] = [];\n private learningBuffer: LearnedInsight[] = [];\n private isConnected: boolean = false;\n private frameManager?: RefactoredFrameManager;\n private sessionStartTime: number = 0;\n\n constructor(config: Partial<DiffMemHookConfig> = {}) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Register session hooks with the event emitter\n */\n register(\n emitter: HookEventEmitter,\n frameManager?: RefactoredFrameManager\n ): void {\n this.frameManager = frameManager;\n\n if (!this.config.enabled) {\n logger.debug('DiffMem hooks disabled - skipping registration');\n return;\n }\n\n emitter.registerHandler('session_start', this.onSessionStart.bind(this));\n emitter.registerHandler('session_end', this.onSessionEnd.bind(this));\n\n logger.info('DiffMem hooks registered', {\n endpoint: this.config.endpoint,\n autoFetchCategories: this.config.autoFetchCategories,\n autoLearnEnabled: this.config.autoLearnEnabled,\n });\n }\n\n /**\n * Handle session start - fetch user knowledge\n */\n async onSessionStart(event: HookEventData): Promise<void> {\n const sessionEvent = event as SessionStartEvent;\n this.sessionStartTime = Date.now();\n\n try {\n // Check DiffMem connectivity\n const status = await this.checkStatus();\n this.isConnected = status.connected;\n\n if (!this.isConnected) {\n logger.debug('DiffMem not available - skipping memory fetch');\n return;\n }\n\n // Fetch user memories for configured categories\n const query: MemoryQuery = {\n categories: this.config.autoFetchCategories,\n limit: this.config.maxMemoriesPerSession,\n minConfidence: this.config.learningConfidenceThreshold,\n };\n\n this.fetchedMemories = await this.fetchMemories(query);\n\n // Inject as frame anchors if frame manager available\n if (this.frameManager && this.fetchedMemories.length > 0) {\n await this.injectAsAnchors(sessionEvent.data.sessionId);\n }\n\n logger.info('DiffMem session start completed', {\n memoriesFetched: this.fetchedMemories.length,\n sessionId: sessionEvent.data.sessionId,\n });\n } catch (error) {\n // Graceful degradation - log and continue\n logger.warn('DiffMem session start failed', {\n error: error instanceof Error ? error.message : String(error),\n });\n this.isConnected = false;\n }\n }\n\n /**\n * Handle session end - sync buffered learnings\n */\n async onSessionEnd(event: HookEventData): Promise<void> {\n const sessionEvent = event as SessionEndEvent;\n\n if (!this.config.autoLearnEnabled || this.learningBuffer.length === 0) {\n logger.debug('No learnings to sync on session end');\n return;\n }\n\n if (!this.isConnected) {\n // Try to reconnect before giving up\n const status = await this.checkStatus();\n if (!status.connected) {\n logger.warn('DiffMem not available - learnings not synced', {\n bufferedCount: this.learningBuffer.length,\n });\n return;\n }\n this.isConnected = true;\n }\n\n try {\n await this.syncLearnings();\n\n const sessionDuration = Date.now() - this.sessionStartTime;\n logger.info('DiffMem session end completed', {\n learningSynced: this.learningBuffer.length,\n sessionId: sessionEvent.data.sessionId,\n sessionDurationMs: sessionDuration,\n });\n\n // Clear buffer after successful sync\n this.learningBuffer = [];\n } catch (error) {\n logger.warn('DiffMem session end sync failed', {\n error: error instanceof Error ? error.message : String(error),\n bufferedCount: this.learningBuffer.length,\n });\n }\n }\n\n /**\n * Record a learning during session\n */\n recordLearning(insight: Omit<LearnedInsight, 'timestamp'>): void {\n if (!this.config.autoLearnEnabled) {\n return;\n }\n\n // Filter by confidence threshold\n if (insight.confidence < this.config.learningConfidenceThreshold) {\n logger.debug('Learning below confidence threshold', {\n confidence: insight.confidence,\n threshold: this.config.learningConfidenceThreshold,\n });\n return;\n }\n\n const learning: LearnedInsight = {\n ...insight,\n timestamp: Date.now(),\n };\n\n this.learningBuffer.push(learning);\n\n logger.debug('Learning recorded', {\n category: learning.category,\n confidence: learning.confidence,\n bufferSize: this.learningBuffer.length,\n });\n }\n\n /**\n * Get fetched memories\n */\n getUserKnowledge(): UserMemory[] {\n return [...this.fetchedMemories];\n }\n\n /**\n * Format memories for LLM context with token budget\n */\n formatForContext(maxTokens: number = 2000): string {\n if (this.fetchedMemories.length === 0) {\n return '';\n }\n\n // Sort by confidence (highest first) then by timestamp (newest first)\n const sortedMemories = [...this.fetchedMemories].sort((a, b) => {\n if (b.confidence !== a.confidence) {\n return b.confidence - a.confidence;\n }\n return b.timestamp - a.timestamp;\n });\n\n const sections: Map<string, string[]> = new Map();\n\n // Group by category\n for (const memory of sortedMemories) {\n const category = memory.category;\n if (!sections.has(category)) {\n sections.set(category, []);\n }\n const categoryMemories = sections.get(category);\n if (categoryMemories) {\n categoryMemories.push(memory.content);\n }\n }\n\n // Build output with token estimation (~4 chars per token)\n const lines: string[] = ['## User Knowledge'];\n let estimatedTokens = 5; // Header\n\n const categoryLabels: Record<string, string> = {\n preference: 'Preferences',\n expertise: 'Expertise',\n project_knowledge: 'Project Knowledge',\n pattern: 'Patterns',\n correction: 'Corrections',\n };\n\n for (const [category, contents] of sections) {\n const label = categoryLabels[category] || category;\n const categoryHeader = `\\n### ${label}`;\n const headerTokens = Math.ceil(categoryHeader.length / 4);\n\n if (estimatedTokens + headerTokens > maxTokens) {\n break;\n }\n\n lines.push(categoryHeader);\n estimatedTokens += headerTokens;\n\n for (const content of contents) {\n const contentLine = `- ${content}`;\n const contentTokens = Math.ceil(contentLine.length / 4);\n\n if (estimatedTokens + contentTokens > maxTokens) {\n lines.push('- (additional items truncated for token budget)');\n break;\n }\n\n lines.push(contentLine);\n estimatedTokens += contentTokens;\n }\n }\n\n return lines.join('\\n');\n }\n\n /**\n * Get current connection status\n */\n getStatus(): {\n connected: boolean;\n memoriesLoaded: number;\n learningsBuffered: number;\n } {\n return {\n connected: this.isConnected,\n memoriesLoaded: this.fetchedMemories.length,\n learningsBuffered: this.learningBuffer.length,\n };\n }\n\n /**\n * Update configuration\n */\n updateConfig(config: Partial<DiffMemHookConfig>): void {\n this.config = { ...this.config, ...config };\n logger.debug('DiffMem config updated', { config: this.config });\n }\n\n // Private methods\n\n /**\n * Check DiffMem service status\n */\n private async checkStatus(): Promise<DiffMemStatus> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 3000);\n\n const response = await fetch(`${this.config.endpoint}/status`, {\n method: 'GET',\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n return { connected: false, memoryCount: 0, lastSync: null };\n }\n\n const status = await response.json();\n return {\n connected: true,\n memoryCount: status.memoryCount || 0,\n lastSync: status.lastSync || null,\n version: status.version,\n };\n } catch {\n return { connected: false, memoryCount: 0, lastSync: null };\n }\n }\n\n /**\n * Fetch memories from DiffMem\n */\n private async fetchMemories(query: MemoryQuery): Promise<UserMemory[]> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 5000);\n\n const response = await fetch(`${this.config.endpoint}/memories/query`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(query),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n logger.warn('DiffMem query failed', { status: response.status });\n return [];\n }\n\n const data = await response.json();\n return data.memories || [];\n } catch (error) {\n logger.debug('DiffMem fetch failed', {\n error: error instanceof Error ? error.message : String(error),\n });\n return [];\n }\n }\n\n /**\n * Sync buffered learnings to DiffMem\n */\n private async syncLearnings(): Promise<void> {\n if (this.learningBuffer.length === 0) {\n return;\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 10000);\n\n try {\n const response = await fetch(`${this.config.endpoint}/memories/learn`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ insights: this.learningBuffer }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new Error(`Sync failed with status ${response.status}`);\n }\n\n logger.info('Learnings synced to DiffMem', {\n count: this.learningBuffer.length,\n });\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Inject fetched memories as frame anchors\n */\n private async injectAsAnchors(sessionId?: string): Promise<void> {\n if (!this.frameManager || this.fetchedMemories.length === 0) {\n return;\n }\n\n try {\n // Group by category for efficient anchor creation\n const byCategory = new Map<string, UserMemory[]>();\n for (const memory of this.fetchedMemories) {\n if (!byCategory.has(memory.category)) {\n byCategory.set(memory.category, []);\n }\n const categoryList = byCategory.get(memory.category);\n if (categoryList) {\n categoryList.push(memory);\n }\n }\n\n // Create anchors for high-confidence memories\n for (const [category, memories] of byCategory) {\n const highConfidence = memories.filter((m) => m.confidence >= 0.8);\n\n for (const memory of highConfidence.slice(0, 5)) {\n const anchorType = this.categoryToAnchorType(category);\n const priority = Math.round(memory.confidence * 10);\n\n this.frameManager.addAnchor(anchorType, memory.content, priority, {\n source: 'diffmem',\n category: memory.category,\n memoryId: memory.id,\n confidence: memory.confidence,\n sessionId,\n });\n }\n }\n\n logger.debug('Memories injected as anchors', {\n totalMemories: this.fetchedMemories.length,\n anchorsCreated: Math.min(\n this.fetchedMemories.filter((m) => m.confidence >= 0.8).length,\n 25\n ),\n });\n } catch (error) {\n logger.warn('Failed to inject memories as anchors', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Map memory category to anchor type\n */\n private categoryToAnchorType(\n category: string\n ):\n | 'FACT'\n | 'DECISION'\n | 'CONSTRAINT'\n | 'INTERFACE_CONTRACT'\n | 'TODO'\n | 'RISK' {\n switch (category) {\n case 'preference':\n return 'CONSTRAINT';\n case 'expertise':\n return 'FACT';\n case 'project_knowledge':\n return 'FACT';\n case 'pattern':\n return 'INTERFACE_CONTRACT';\n case 'correction':\n return 'DECISION';\n default:\n return 'FACT';\n }\n }\n}\n\n// Singleton instance\nlet instance: DiffMemHooks | null = null;\n\n/**\n * Get the singleton DiffMemHooks instance\n */\nexport function getDiffMemHooks(\n config?: Partial<DiffMemHookConfig>\n): DiffMemHooks {\n if (!instance) {\n instance = new DiffMemHooks(config);\n } else if (config) {\n instance.updateConfig(config);\n }\n return instance;\n}\n\n/**\n * Reset the singleton (for testing)\n */\nexport function resetDiffMemHooks(): void {\n instance = null;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { fileURLToPath as __fileURLToPath } from 'url';
|
|
2
|
+
import { dirname as __pathDirname } from 'path';
|
|
3
|
+
const __filename = __fileURLToPath(import.meta.url);
|
|
4
|
+
const __dirname = __pathDirname(__filename);
|
|
5
|
+
import { DEFAULT_DIFFMEM_CONFIG } from "./config.js";
|
|
6
|
+
class DiffMemClientError extends Error {
|
|
7
|
+
constructor(message, code, statusCode) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.code = code;
|
|
10
|
+
this.statusCode = statusCode;
|
|
11
|
+
this.name = "DiffMemClientError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
class DiffMemClient {
|
|
15
|
+
endpoint;
|
|
16
|
+
userId;
|
|
17
|
+
timeout;
|
|
18
|
+
maxRetries;
|
|
19
|
+
constructor(config = {}) {
|
|
20
|
+
const mergedConfig = { ...DEFAULT_DIFFMEM_CONFIG, ...config };
|
|
21
|
+
this.endpoint = mergedConfig.endpoint.replace(/\/$/, "");
|
|
22
|
+
this.userId = mergedConfig.userId;
|
|
23
|
+
this.timeout = mergedConfig.timeout;
|
|
24
|
+
this.maxRetries = mergedConfig.maxRetries;
|
|
25
|
+
}
|
|
26
|
+
async request(path, options = {}) {
|
|
27
|
+
const controller = new AbortController();
|
|
28
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
29
|
+
let lastError;
|
|
30
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
31
|
+
try {
|
|
32
|
+
const response = await fetch(`${this.endpoint}${path}`, {
|
|
33
|
+
...options,
|
|
34
|
+
signal: controller.signal,
|
|
35
|
+
headers: {
|
|
36
|
+
"Content-Type": "application/json",
|
|
37
|
+
...options.headers
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
clearTimeout(timeoutId);
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
const errorBody = await response.text().catch(() => "");
|
|
43
|
+
throw new DiffMemClientError(
|
|
44
|
+
`Request failed: ${response.statusText}`,
|
|
45
|
+
"HTTP_ERROR",
|
|
46
|
+
response.status
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return await response.json();
|
|
50
|
+
} catch (error) {
|
|
51
|
+
lastError = error;
|
|
52
|
+
if (error instanceof DiffMemClientError) {
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
if (error.name === "AbortError") {
|
|
56
|
+
throw new DiffMemClientError("Request timeout", "TIMEOUT");
|
|
57
|
+
}
|
|
58
|
+
if (attempt < this.maxRetries) {
|
|
59
|
+
await new Promise(
|
|
60
|
+
(resolve) => setTimeout(resolve, Math.pow(2, attempt) * 100)
|
|
61
|
+
);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
clearTimeout(timeoutId);
|
|
67
|
+
throw new DiffMemClientError(
|
|
68
|
+
lastError?.message || "Request failed after retries",
|
|
69
|
+
"NETWORK_ERROR"
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get user context/memories from DiffMem
|
|
74
|
+
* Maps to POST /memory/{user_id}/context
|
|
75
|
+
*/
|
|
76
|
+
async getMemories(query = {}) {
|
|
77
|
+
try {
|
|
78
|
+
const conversation = query.query ? [{ role: "user", content: query.query }] : [{ role: "user", content: "What do you know about me?" }];
|
|
79
|
+
const response = await this.request(`/memory/${this.userId}/context`, {
|
|
80
|
+
method: "POST",
|
|
81
|
+
body: JSON.stringify({
|
|
82
|
+
conversation,
|
|
83
|
+
depth: "wide"
|
|
84
|
+
})
|
|
85
|
+
});
|
|
86
|
+
if (response.entities) {
|
|
87
|
+
return response.entities.slice(0, query.limit || 10).map((entity) => ({
|
|
88
|
+
id: entity.id,
|
|
89
|
+
content: entity.content,
|
|
90
|
+
category: "project_knowledge",
|
|
91
|
+
confidence: entity.score || 0.7,
|
|
92
|
+
timestamp: Date.now()
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
return [];
|
|
96
|
+
} catch {
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Store an insight/learning in DiffMem
|
|
102
|
+
* Maps to POST /memory/{user_id}/process-and-commit
|
|
103
|
+
*/
|
|
104
|
+
async storeInsight(insight) {
|
|
105
|
+
const response = await this.request(`/memory/${this.userId}/process-and-commit`, {
|
|
106
|
+
method: "POST",
|
|
107
|
+
body: JSON.stringify({
|
|
108
|
+
memory_input: `[${insight.category}] ${insight.content}`,
|
|
109
|
+
session_id: `sm-${Date.now()}`,
|
|
110
|
+
session_date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0]
|
|
111
|
+
})
|
|
112
|
+
});
|
|
113
|
+
return { id: response.session_id || `insight-${Date.now()}` };
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Search memories in DiffMem
|
|
117
|
+
* Maps to POST /memory/{user_id}/search
|
|
118
|
+
*/
|
|
119
|
+
async search(query) {
|
|
120
|
+
try {
|
|
121
|
+
const response = await this.request(`/memory/${this.userId}/search`, {
|
|
122
|
+
method: "POST",
|
|
123
|
+
body: JSON.stringify({
|
|
124
|
+
query: query.query || "",
|
|
125
|
+
k: query.limit || 10
|
|
126
|
+
})
|
|
127
|
+
});
|
|
128
|
+
if (response.results) {
|
|
129
|
+
return response.results.map((result) => ({
|
|
130
|
+
id: result.snippet.id,
|
|
131
|
+
content: result.snippet.content,
|
|
132
|
+
category: "project_knowledge",
|
|
133
|
+
confidence: result.score,
|
|
134
|
+
timestamp: Date.now(),
|
|
135
|
+
metadata: { filePath: result.snippet.file_path }
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
return [];
|
|
139
|
+
} catch {
|
|
140
|
+
return [];
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Get DiffMem server status
|
|
145
|
+
* Maps to GET /health
|
|
146
|
+
*/
|
|
147
|
+
async getStatus() {
|
|
148
|
+
try {
|
|
149
|
+
const health = await this.request("/health", { method: "GET" });
|
|
150
|
+
return {
|
|
151
|
+
connected: health.status === "healthy",
|
|
152
|
+
memoryCount: health.active_contexts || 0,
|
|
153
|
+
lastSync: Date.now(),
|
|
154
|
+
version: health.version
|
|
155
|
+
};
|
|
156
|
+
} catch {
|
|
157
|
+
return {
|
|
158
|
+
connected: false,
|
|
159
|
+
memoryCount: 0,
|
|
160
|
+
lastSync: null
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Batch sync multiple insights
|
|
166
|
+
* Processes each insight individually since DiffMem doesn't have batch API
|
|
167
|
+
*/
|
|
168
|
+
async batchSync(insights) {
|
|
169
|
+
if (insights.length === 0) {
|
|
170
|
+
return { synced: 0, failed: 0 };
|
|
171
|
+
}
|
|
172
|
+
let synced = 0;
|
|
173
|
+
let failed = 0;
|
|
174
|
+
for (const insight of insights) {
|
|
175
|
+
try {
|
|
176
|
+
await this.storeInsight(insight);
|
|
177
|
+
synced++;
|
|
178
|
+
} catch {
|
|
179
|
+
failed++;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return { synced, failed };
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Onboard a new user in DiffMem
|
|
186
|
+
*/
|
|
187
|
+
async onboardUser(userInfo) {
|
|
188
|
+
try {
|
|
189
|
+
const response = await this.request(
|
|
190
|
+
`/memory/${this.userId}/onboard`,
|
|
191
|
+
{
|
|
192
|
+
method: "POST",
|
|
193
|
+
body: JSON.stringify({
|
|
194
|
+
user_info: userInfo,
|
|
195
|
+
session_id: `onboard-${Date.now()}`
|
|
196
|
+
})
|
|
197
|
+
}
|
|
198
|
+
);
|
|
199
|
+
return { success: response.status === "success" };
|
|
200
|
+
} catch {
|
|
201
|
+
return { success: false };
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
export {
|
|
206
|
+
DiffMemClient,
|
|
207
|
+
DiffMemClientError
|
|
208
|
+
};
|
|
209
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/integrations/diffmem/client.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * DiffMem API Client\n * Handles communication with the DiffMem memory service\n */\n\nimport type {\n UserMemory,\n MemoryQuery,\n LearnedInsight,\n DiffMemStatus,\n} from './types.js';\nimport type { DiffMemIntegrationConfig } from './config.js';\nimport { DEFAULT_DIFFMEM_CONFIG } from './config.js';\n\nexport class DiffMemClientError extends Error {\n constructor(\n message: string,\n public readonly code?: string,\n public readonly statusCode?: number\n ) {\n super(message);\n this.name = 'DiffMemClientError';\n }\n}\n\nexport class DiffMemClient {\n private readonly endpoint: string;\n private readonly userId: string;\n private readonly timeout: number;\n private readonly maxRetries: number;\n\n constructor(config: Partial<DiffMemIntegrationConfig> = {}) {\n const mergedConfig = { ...DEFAULT_DIFFMEM_CONFIG, ...config };\n this.endpoint = mergedConfig.endpoint.replace(/\\/$/, '');\n this.userId = mergedConfig.userId;\n this.timeout = mergedConfig.timeout;\n this.maxRetries = mergedConfig.maxRetries;\n }\n\n private async request<T>(\n path: string,\n options: RequestInit = {}\n ): Promise<T> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n try {\n const response = await fetch(`${this.endpoint}${path}`, {\n ...options,\n signal: controller.signal,\n headers: {\n 'Content-Type': 'application/json',\n ...options.headers,\n },\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorBody = await response.text().catch(() => '');\n throw new DiffMemClientError(\n `Request failed: ${response.statusText}`,\n 'HTTP_ERROR',\n response.status\n );\n }\n\n return (await response.json()) as T;\n } catch (error) {\n lastError = error as Error;\n\n if (error instanceof DiffMemClientError) {\n throw error;\n }\n\n if ((error as Error).name === 'AbortError') {\n throw new DiffMemClientError('Request timeout', 'TIMEOUT');\n }\n\n // Retry on network errors\n if (attempt < this.maxRetries) {\n await new Promise((resolve) =>\n setTimeout(resolve, Math.pow(2, attempt) * 100)\n );\n continue;\n }\n }\n }\n\n clearTimeout(timeoutId);\n throw new DiffMemClientError(\n lastError?.message || 'Request failed after retries',\n 'NETWORK_ERROR'\n );\n }\n\n /**\n * Get user context/memories from DiffMem\n * Maps to POST /memory/{user_id}/context\n */\n async getMemories(query: MemoryQuery = {}): Promise<UserMemory[]> {\n try {\n // DiffMem uses conversation-based context retrieval\n const conversation = query.query\n ? [{ role: 'user', content: query.query }]\n : [{ role: 'user', content: 'What do you know about me?' }];\n\n const response = await this.request<{\n status: string;\n context?: string;\n entities?: Array<{ id: string; content: string; score?: number }>;\n }>(`/memory/${this.userId}/context`, {\n method: 'POST',\n body: JSON.stringify({\n conversation,\n depth: 'wide',\n }),\n });\n\n // Transform DiffMem response to UserMemory format\n if (response.entities) {\n return response.entities.slice(0, query.limit || 10).map((entity) => ({\n id: entity.id,\n content: entity.content,\n category: 'project_knowledge' as const,\n confidence: entity.score || 0.7,\n timestamp: Date.now(),\n }));\n }\n\n return [];\n } catch {\n return [];\n }\n }\n\n /**\n * Store an insight/learning in DiffMem\n * Maps to POST /memory/{user_id}/process-and-commit\n */\n async storeInsight(insight: LearnedInsight): Promise<{ id: string }> {\n const response = await this.request<{\n status: string;\n session_id?: string;\n }>(`/memory/${this.userId}/process-and-commit`, {\n method: 'POST',\n body: JSON.stringify({\n memory_input: `[${insight.category}] ${insight.content}`,\n session_id: `sm-${Date.now()}`,\n session_date: new Date().toISOString().split('T')[0],\n }),\n });\n\n return { id: response.session_id || `insight-${Date.now()}` };\n }\n\n /**\n * Search memories in DiffMem\n * Maps to POST /memory/{user_id}/search\n */\n async search(query: MemoryQuery): Promise<UserMemory[]> {\n try {\n const response = await this.request<{\n status: string;\n results?: Array<{\n score: number;\n snippet: { id: string; content: string; file_path?: string };\n }>;\n }>(`/memory/${this.userId}/search`, {\n method: 'POST',\n body: JSON.stringify({\n query: query.query || '',\n k: query.limit || 10,\n }),\n });\n\n if (response.results) {\n return response.results.map((result) => ({\n id: result.snippet.id,\n content: result.snippet.content,\n category: 'project_knowledge' as const,\n confidence: result.score,\n timestamp: Date.now(),\n metadata: { filePath: result.snippet.file_path },\n }));\n }\n\n return [];\n } catch {\n return [];\n }\n }\n\n /**\n * Get DiffMem server status\n * Maps to GET /health\n */\n async getStatus(): Promise<DiffMemStatus> {\n try {\n const health = await this.request<{\n status: string;\n active_contexts?: number;\n version?: string;\n }>('/health', { method: 'GET' });\n\n return {\n connected: health.status === 'healthy',\n memoryCount: health.active_contexts || 0,\n lastSync: Date.now(),\n version: health.version,\n };\n } catch {\n return {\n connected: false,\n memoryCount: 0,\n lastSync: null,\n };\n }\n }\n\n /**\n * Batch sync multiple insights\n * Processes each insight individually since DiffMem doesn't have batch API\n */\n async batchSync(\n insights: LearnedInsight[]\n ): Promise<{ synced: number; failed: number }> {\n if (insights.length === 0) {\n return { synced: 0, failed: 0 };\n }\n\n let synced = 0;\n let failed = 0;\n\n for (const insight of insights) {\n try {\n await this.storeInsight(insight);\n synced++;\n } catch {\n failed++;\n }\n }\n\n return { synced, failed };\n }\n\n /**\n * Onboard a new user in DiffMem\n */\n async onboardUser(userInfo: string): Promise<{ success: boolean }> {\n try {\n const response = await this.request<{ status: string }>(\n `/memory/${this.userId}/onboard`,\n {\n method: 'POST',\n body: JSON.stringify({\n user_info: userInfo,\n session_id: `onboard-${Date.now()}`,\n }),\n }\n );\n\n return { success: response.status === 'success' };\n } catch {\n return { success: false };\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { fileURLToPath as __fileURLToPath } from 'url';
|
|
2
|
+
import { dirname as __pathDirname } from 'path';
|
|
3
|
+
const __filename = __fileURLToPath(import.meta.url);
|
|
4
|
+
const __dirname = __pathDirname(__filename);
|
|
5
|
+
const DEFAULT_DIFFMEM_CONFIG = {
|
|
6
|
+
endpoint: process.env.DIFFMEM_ENDPOINT || "http://localhost:8000",
|
|
7
|
+
userId: process.env.DIFFMEM_USER_ID || "default",
|
|
8
|
+
timeout: 5e3,
|
|
9
|
+
maxRetries: 3,
|
|
10
|
+
enabled: process.env.DIFFMEM_ENABLED === "true" || !!process.env.DIFFMEM_ENDPOINT
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
DEFAULT_DIFFMEM_CONFIG
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=config.js.map
|