cmp-memory-system 1.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/README.md +541 -0
- package/dist/analytics/index.d.ts +5 -0
- package/dist/analytics/index.d.ts.map +1 -0
- package/dist/analytics/index.js +5 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/analytics/tracker.d.ts +107 -0
- package/dist/analytics/tracker.d.ts.map +1 -0
- package/dist/analytics/tracker.js +333 -0
- package/dist/analytics/tracker.js.map +1 -0
- package/dist/auto-improve/eslint-generator.d.ts +36 -0
- package/dist/auto-improve/eslint-generator.d.ts.map +1 -0
- package/dist/auto-improve/eslint-generator.js +280 -0
- package/dist/auto-improve/eslint-generator.js.map +1 -0
- package/dist/auto-improve/index.d.ts +6 -0
- package/dist/auto-improve/index.d.ts.map +1 -0
- package/dist/auto-improve/index.js +6 -0
- package/dist/auto-improve/index.js.map +1 -0
- package/dist/auto-improve/pattern-detector.d.ts +92 -0
- package/dist/auto-improve/pattern-detector.d.ts.map +1 -0
- package/dist/auto-improve/pattern-detector.js +231 -0
- package/dist/auto-improve/pattern-detector.js.map +1 -0
- package/dist/cli/index.d.ts +16 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +636 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/dashboard/index.d.ts +6 -0
- package/dist/dashboard/index.d.ts.map +1 -0
- package/dist/dashboard/index.js +6 -0
- package/dist/dashboard/index.js.map +1 -0
- package/dist/dashboard/server.d.ts +15 -0
- package/dist/dashboard/server.d.ts.map +1 -0
- package/dist/dashboard/server.js +373 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/dashboard/ui.d.ts +9 -0
- package/dist/dashboard/ui.d.ts.map +1 -0
- package/dist/dashboard/ui.js +530 -0
- package/dist/dashboard/ui.js.map +1 -0
- package/dist/db/client.d.ts +66 -0
- package/dist/db/client.d.ts.map +1 -0
- package/dist/db/client.js +159 -0
- package/dist/db/client.js.map +1 -0
- package/dist/db/drizzle-client.d.ts +302 -0
- package/dist/db/drizzle-client.d.ts.map +1 -0
- package/dist/db/drizzle-client.js +404 -0
- package/dist/db/drizzle-client.js.map +1 -0
- package/dist/db/index.d.ts +5 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +5 -0
- package/dist/db/index.js.map +1 -0
- package/dist/feedback/collector.d.ts +74 -0
- package/dist/feedback/collector.d.ts.map +1 -0
- package/dist/feedback/collector.js +231 -0
- package/dist/feedback/collector.js.map +1 -0
- package/dist/feedback/index.d.ts +5 -0
- package/dist/feedback/index.d.ts.map +1 -0
- package/dist/feedback/index.js +5 -0
- package/dist/feedback/index.js.map +1 -0
- package/dist/hooks/index.d.ts +8 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +8 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/memory-checkpoint.d.ts +43 -0
- package/dist/hooks/memory-checkpoint.d.ts.map +1 -0
- package/dist/hooks/memory-checkpoint.js +257 -0
- package/dist/hooks/memory-checkpoint.js.map +1 -0
- package/dist/hooks/post-tool-use.d.ts +61 -0
- package/dist/hooks/post-tool-use.d.ts.map +1 -0
- package/dist/hooks/post-tool-use.js +262 -0
- package/dist/hooks/post-tool-use.js.map +1 -0
- package/dist/hooks/pre-tool-use.d.ts +34 -0
- package/dist/hooks/pre-tool-use.d.ts.map +1 -0
- package/dist/hooks/pre-tool-use.js +358 -0
- package/dist/hooks/pre-tool-use.js.map +1 -0
- package/dist/hooks/session-start.d.ts +38 -0
- package/dist/hooks/session-start.d.ts.map +1 -0
- package/dist/hooks/session-start.js +274 -0
- package/dist/hooks/session-start.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/index.d.ts +5 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +5 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +42 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +599 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/registry/embeddings.d.ts +38 -0
- package/dist/registry/embeddings.d.ts.map +1 -0
- package/dist/registry/embeddings.js +110 -0
- package/dist/registry/embeddings.js.map +1 -0
- package/dist/registry/generator.d.ts +41 -0
- package/dist/registry/generator.d.ts.map +1 -0
- package/dist/registry/generator.js +323 -0
- package/dist/registry/generator.js.map +1 -0
- package/dist/registry/index.d.ts +6 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +6 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/services/IdeaCollector.d.ts +103 -0
- package/dist/services/IdeaCollector.d.ts.map +1 -0
- package/dist/services/IdeaCollector.js +371 -0
- package/dist/services/IdeaCollector.js.map +1 -0
- package/dist/services/TaskTracker.d.ts +89 -0
- package/dist/services/TaskTracker.d.ts.map +1 -0
- package/dist/services/TaskTracker.js +324 -0
- package/dist/services/TaskTracker.js.map +1 -0
- package/dist/services/WorkPlanManager.d.ts +107 -0
- package/dist/services/WorkPlanManager.d.ts.map +1 -0
- package/dist/services/WorkPlanManager.js +440 -0
- package/dist/services/WorkPlanManager.js.map +1 -0
- package/dist/services/auto-inject.d.ts +77 -0
- package/dist/services/auto-inject.d.ts.map +1 -0
- package/dist/services/auto-inject.js +289 -0
- package/dist/services/auto-inject.js.map +1 -0
- package/dist/services/auto-tag.d.ts +61 -0
- package/dist/services/auto-tag.d.ts.map +1 -0
- package/dist/services/auto-tag.js +203 -0
- package/dist/services/auto-tag.js.map +1 -0
- package/dist/services/cross-project-sync.d.ts +76 -0
- package/dist/services/cross-project-sync.d.ts.map +1 -0
- package/dist/services/cross-project-sync.js +235 -0
- package/dist/services/cross-project-sync.js.map +1 -0
- package/dist/services/index.d.ts +15 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +18 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/memory-consolidation.d.ts +77 -0
- package/dist/services/memory-consolidation.d.ts.map +1 -0
- package/dist/services/memory-consolidation.js +298 -0
- package/dist/services/memory-consolidation.js.map +1 -0
- package/dist/services/semantic-search.d.ts +93 -0
- package/dist/services/semantic-search.d.ts.map +1 -0
- package/dist/services/semantic-search.js +278 -0
- package/dist/services/semantic-search.js.map +1 -0
- package/dist/services/weekly-digest.d.ts +105 -0
- package/dist/services/weekly-digest.d.ts.map +1 -0
- package/dist/services/weekly-digest.js +292 -0
- package/dist/services/weekly-digest.js.map +1 -0
- package/dist/types/index.d.ts +274 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +84 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/config.d.ts +21 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +89 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/paths.d.ts +28 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +80 -0
- package/dist/utils/paths.js.map +1 -0
- package/package.json +89 -0
- package/templates/memory-config.json +82 -0
- package/templates/memory-config.schema.json +212 -0
- package/templates/settings.json +58 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-Project Sync Service
|
|
3
|
+
*
|
|
4
|
+
* Synchronizes memories across different projects in the MetaNautical ecosystem.
|
|
5
|
+
* - Shares relevant learnings between projects
|
|
6
|
+
* - Maintains project isolation while enabling knowledge transfer
|
|
7
|
+
* - Syncs common patterns and gotchas
|
|
8
|
+
*/
|
|
9
|
+
import { createDrizzleClient } from '../db/drizzle-client.js';
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// ECOSYSTEM SYSTEMS
|
|
12
|
+
// =============================================================================
|
|
13
|
+
export const ECOSYSTEM_SYSTEMS = [
|
|
14
|
+
'SWARMSCALE',
|
|
15
|
+
'PANEL',
|
|
16
|
+
'ECOSYSTEM',
|
|
17
|
+
'ELLIOT',
|
|
18
|
+
'CONNECTA_HOTEL',
|
|
19
|
+
'CONNECTA_CREW',
|
|
20
|
+
];
|
|
21
|
+
// =============================================================================
|
|
22
|
+
// CROSS-PROJECT SYNC SERVICE
|
|
23
|
+
// =============================================================================
|
|
24
|
+
export class CrossProjectSyncService {
|
|
25
|
+
clients = new Map();
|
|
26
|
+
/**
|
|
27
|
+
* Get or create a client for a system
|
|
28
|
+
*/
|
|
29
|
+
getClient(system) {
|
|
30
|
+
let client = this.clients.get(system);
|
|
31
|
+
if (!client) {
|
|
32
|
+
client = createDrizzleClient(system);
|
|
33
|
+
this.clients.set(system, client);
|
|
34
|
+
}
|
|
35
|
+
return client;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Sync memories from source to target systems
|
|
39
|
+
*/
|
|
40
|
+
async sync(config) {
|
|
41
|
+
const result = {
|
|
42
|
+
synced: 0,
|
|
43
|
+
skipped: 0,
|
|
44
|
+
errors: [],
|
|
45
|
+
};
|
|
46
|
+
const sourceClient = this.getClient(config.sourceSystem);
|
|
47
|
+
// Get shareable memories from source
|
|
48
|
+
const memories = await this.getShareableMemories(sourceClient, config);
|
|
49
|
+
for (const memory of memories) {
|
|
50
|
+
const content = memory.content;
|
|
51
|
+
if (!content)
|
|
52
|
+
continue;
|
|
53
|
+
// Sync to each target system
|
|
54
|
+
for (const targetSystem of config.targetSystems) {
|
|
55
|
+
if (targetSystem === config.sourceSystem)
|
|
56
|
+
continue;
|
|
57
|
+
try {
|
|
58
|
+
const synced = await this.syncMemoryToSystem(memory, content, config.sourceSystem, targetSystem);
|
|
59
|
+
if (synced) {
|
|
60
|
+
result.synced++;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
result.skipped++;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
result.errors.push(`Failed to sync ${memory.id} to ${targetSystem}: ${error}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get ecosystem-wide patterns (shared across all systems)
|
|
75
|
+
*/
|
|
76
|
+
async getEcosystemPatterns() {
|
|
77
|
+
const allPatterns = [];
|
|
78
|
+
for (const system of ECOSYSTEM_SYSTEMS) {
|
|
79
|
+
try {
|
|
80
|
+
const client = this.getClient(system);
|
|
81
|
+
const patterns = await client.getTriggeredPatterns(3);
|
|
82
|
+
allPatterns.push(...patterns);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// Skip systems that fail
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Deduplicate by pattern ID
|
|
89
|
+
const uniquePatterns = new Map();
|
|
90
|
+
for (const pattern of allPatterns) {
|
|
91
|
+
const content = pattern.content;
|
|
92
|
+
const patternId = content?.patternId;
|
|
93
|
+
if (patternId && !uniquePatterns.has(patternId)) {
|
|
94
|
+
uniquePatterns.set(patternId, pattern);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return Array.from(uniquePatterns.values());
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get memories shared across all systems (tagged with 'ecosystem' or 'shared')
|
|
101
|
+
*/
|
|
102
|
+
async getSharedMemories() {
|
|
103
|
+
const sharedMemories = [];
|
|
104
|
+
for (const system of ECOSYSTEM_SYSTEMS) {
|
|
105
|
+
try {
|
|
106
|
+
const client = this.getClient(system);
|
|
107
|
+
const memories = await client.list({
|
|
108
|
+
type: 'memory',
|
|
109
|
+
tags: ['ecosystem', 'shared'],
|
|
110
|
+
limit: 50,
|
|
111
|
+
});
|
|
112
|
+
for (const memory of memories) {
|
|
113
|
+
sharedMemories.push({ ...memory, system });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// Skip systems that fail
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return sharedMemories;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Share a memory to the ecosystem (tag it for sync)
|
|
124
|
+
*/
|
|
125
|
+
async shareToEcosystem(memoryId, sourceSystem) {
|
|
126
|
+
const client = this.getClient(sourceSystem);
|
|
127
|
+
const memory = await client.get(memoryId);
|
|
128
|
+
if (!memory)
|
|
129
|
+
return false;
|
|
130
|
+
const existingTags = memory.tags ?? [];
|
|
131
|
+
if (existingTags.includes('ecosystem'))
|
|
132
|
+
return true;
|
|
133
|
+
await client.update(memoryId, {
|
|
134
|
+
tags: [...existingTags, 'ecosystem', 'shared'],
|
|
135
|
+
});
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get sync status for a system
|
|
140
|
+
*/
|
|
141
|
+
async getSyncStatus(system) {
|
|
142
|
+
const client = this.getClient(system);
|
|
143
|
+
const [all, shared, received] = await Promise.all([
|
|
144
|
+
client.list({ type: 'memory', limit: 1000 }),
|
|
145
|
+
client.list({ type: 'memory', tags: ['shared'], limit: 1000 }),
|
|
146
|
+
client.list({ type: 'memory', tags: ['synced-from'], limit: 1000 }),
|
|
147
|
+
]);
|
|
148
|
+
return {
|
|
149
|
+
totalMemories: all.length,
|
|
150
|
+
sharedMemories: shared.length,
|
|
151
|
+
receivedMemories: received.length,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
// ===========================================================================
|
|
155
|
+
// PRIVATE METHODS
|
|
156
|
+
// ===========================================================================
|
|
157
|
+
/**
|
|
158
|
+
* Get memories that should be synced
|
|
159
|
+
*/
|
|
160
|
+
async getShareableMemories(client, config) {
|
|
161
|
+
// Get memories with sync tags
|
|
162
|
+
const memories = await client.list({
|
|
163
|
+
type: 'memory',
|
|
164
|
+
limit: 200,
|
|
165
|
+
});
|
|
166
|
+
return memories.filter(m => {
|
|
167
|
+
const tags = m.tags ?? [];
|
|
168
|
+
// Must have at least one sync tag
|
|
169
|
+
const hasSyncTag = config.syncTags.some(t => tags.includes(t));
|
|
170
|
+
if (!hasSyncTag)
|
|
171
|
+
return false;
|
|
172
|
+
// Must not have exclude tags
|
|
173
|
+
const hasExcludeTag = config.excludeTags.some(t => tags.includes(t));
|
|
174
|
+
if (hasExcludeTag)
|
|
175
|
+
return false;
|
|
176
|
+
return true;
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Sync a single memory to a target system
|
|
181
|
+
*/
|
|
182
|
+
async syncMemoryToSystem(memory, content, sourceSystem, targetSystem) {
|
|
183
|
+
const targetClient = this.getClient(targetSystem);
|
|
184
|
+
// Check if already synced
|
|
185
|
+
const existing = await targetClient.list({
|
|
186
|
+
type: 'memory',
|
|
187
|
+
tags: [`synced-from:${memory.id}`],
|
|
188
|
+
limit: 1,
|
|
189
|
+
});
|
|
190
|
+
if (existing.length > 0) {
|
|
191
|
+
// Already synced, update if newer
|
|
192
|
+
const existingItem = existing[0];
|
|
193
|
+
const existingTime = existingItem.updatedAt?.getTime() ?? 0;
|
|
194
|
+
const memoryTime = memory.updatedAt?.getTime() ?? 0;
|
|
195
|
+
if (memoryTime > existingTime) {
|
|
196
|
+
// Update the synced copy
|
|
197
|
+
await targetClient.update(existingItem.id, {
|
|
198
|
+
content: {
|
|
199
|
+
...content,
|
|
200
|
+
syncedFrom: {
|
|
201
|
+
system: sourceSystem,
|
|
202
|
+
id: memory.id,
|
|
203
|
+
syncedAt: new Date().toISOString(),
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
return false; // No update needed
|
|
210
|
+
}
|
|
211
|
+
// Create synced copy
|
|
212
|
+
await targetClient.createMemory({
|
|
213
|
+
title: `[${sourceSystem}] ${content.title}`,
|
|
214
|
+
body: content.body,
|
|
215
|
+
domain: content.domain,
|
|
216
|
+
source: 'system',
|
|
217
|
+
}, [
|
|
218
|
+
'synced',
|
|
219
|
+
`synced-from:${memory.id}`,
|
|
220
|
+
`synced-from-system:${sourceSystem}`,
|
|
221
|
+
...(memory.tags ?? []).filter(t => !t.startsWith('synced')),
|
|
222
|
+
]);
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// =============================================================================
|
|
227
|
+
// FACTORY
|
|
228
|
+
// =============================================================================
|
|
229
|
+
/**
|
|
230
|
+
* Create a cross-project sync service
|
|
231
|
+
*/
|
|
232
|
+
export function createCrossProjectSyncService() {
|
|
233
|
+
return new CrossProjectSyncService();
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=cross-project-sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cross-project-sync.js","sourceRoot":"","sources":["../../src/services/cross-project-sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Services Index
|
|
3
|
+
*
|
|
4
|
+
* Export all memory services for easy consumption.
|
|
5
|
+
*/
|
|
6
|
+
export { SemanticSearchService, createSemanticSearchService, type SemanticSearchResult, type MemoryWithEmbedding, } from './semantic-search.js';
|
|
7
|
+
export { AutoInjectService, createAutoInjectService, type SessionContext, type InjectedMemory, type InjectedPattern, type SessionStats, } from './auto-inject.js';
|
|
8
|
+
export { MemoryConsolidationService, createConsolidationService, type ConsolidationResult, type ConflictInfo, type DecayResult, } from './memory-consolidation.js';
|
|
9
|
+
export { AutoTagService, createAutoTagService, type AutoTagResult, type BatchTagResult, } from './auto-tag.js';
|
|
10
|
+
export { CrossProjectSyncService, createCrossProjectSyncService, ECOSYSTEM_SYSTEMS, type SyncConfig, type SyncResult, type SharedMemory, } from './cross-project-sync.js';
|
|
11
|
+
export { WeeklyDigestService, createWeeklyDigestService, type WeeklyDigest, type DigestSummary, type DigestHighlight, type DigestPattern, type DigestRecommendation, type DigestTrend, } from './weekly-digest.js';
|
|
12
|
+
export { TaskTracker, getTaskTracker, createTaskTracker, type StartTaskOptions, type UpdateTaskOptions, type CompleteTaskOptions, } from './TaskTracker.js';
|
|
13
|
+
export { IdeaCollector, getIdeaCollector, createIdeaCollector, type IdeaInput, type ImprovementInput, type IdeaStats, type ImprovementStats, } from './IdeaCollector.js';
|
|
14
|
+
export { WorkPlanManager, getWorkPlanManager, createWorkPlanManager, type CreatePlanOptions, type PlanTask, type PlanSummary, } from './WorkPlanManager.js';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,qBAAqB,EACrB,2BAA2B,EAC3B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACzB,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,YAAY,GAClB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,KAAK,WAAW,GACjB,MAAM,2BAA2B,CAAA;AAElC,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,KAAK,aAAa,EAClB,KAAK,cAAc,GACpB,MAAM,eAAe,CAAA;AAEtB,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,iBAAiB,EACjB,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,yBAAyB,CAAA;AAEhC,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,WAAW,GACjB,MAAM,oBAAoB,CAAA;AAM3B,OAAO,EACL,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,GACzB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,KAAK,gBAAgB,GACtB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACb,KAAK,WAAW,GACjB,MAAM,sBAAsB,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Services Index
|
|
3
|
+
*
|
|
4
|
+
* Export all memory services for easy consumption.
|
|
5
|
+
*/
|
|
6
|
+
export { SemanticSearchService, createSemanticSearchService, } from './semantic-search.js';
|
|
7
|
+
export { AutoInjectService, createAutoInjectService, } from './auto-inject.js';
|
|
8
|
+
export { MemoryConsolidationService, createConsolidationService, } from './memory-consolidation.js';
|
|
9
|
+
export { AutoTagService, createAutoTagService, } from './auto-tag.js';
|
|
10
|
+
export { CrossProjectSyncService, createCrossProjectSyncService, ECOSYSTEM_SYSTEMS, } from './cross-project-sync.js';
|
|
11
|
+
export { WeeklyDigestService, createWeeklyDigestService, } from './weekly-digest.js';
|
|
12
|
+
// =============================================================================
|
|
13
|
+
// WORKFLOW SERVICES (NEW)
|
|
14
|
+
// =============================================================================
|
|
15
|
+
export { TaskTracker, getTaskTracker, createTaskTracker, } from './TaskTracker.js';
|
|
16
|
+
export { IdeaCollector, getIdeaCollector, createIdeaCollector, } from './IdeaCollector.js';
|
|
17
|
+
export { WorkPlanManager, getWorkPlanManager, createWorkPlanManager, } from './WorkPlanManager.js';
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,qBAAqB,EACrB,2BAA2B,GAG5B,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EACL,iBAAiB,EACjB,uBAAuB,GAKxB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,GAI3B,MAAM,2BAA2B,CAAA;AAElC,OAAO,EACL,cAAc,EACd,oBAAoB,GAGrB,MAAM,eAAe,CAAA;AAEtB,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,iBAAiB,GAIlB,MAAM,yBAAyB,CAAA;AAEhC,OAAO,EACL,mBAAmB,EACnB,yBAAyB,GAO1B,MAAM,oBAAoB,CAAA;AAE3B,gFAAgF;AAChF,0BAA0B;AAC1B,gFAAgF;AAEhF,OAAO,EACL,WAAW,EACX,cAAc,EACd,iBAAiB,GAIlB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,mBAAmB,GAKpB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,qBAAqB,GAItB,MAAM,sBAAsB,CAAA"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Consolidation Service
|
|
3
|
+
*
|
|
4
|
+
* Automatically consolidates and cleans up memories:
|
|
5
|
+
* - Merges similar/duplicate memories
|
|
6
|
+
* - Archives stale memories (decay)
|
|
7
|
+
* - Detects conflicts between memories
|
|
8
|
+
*/
|
|
9
|
+
import { SemanticSearchService } from './semantic-search.js';
|
|
10
|
+
import type { DrizzleMemoryClient } from '../db/drizzle-client.js';
|
|
11
|
+
import type { DevItem, MemoryContent } from '../types/index.js';
|
|
12
|
+
export interface ConsolidationResult {
|
|
13
|
+
analyzed: number;
|
|
14
|
+
merged: number;
|
|
15
|
+
archived: number;
|
|
16
|
+
conflicts: ConflictInfo[];
|
|
17
|
+
}
|
|
18
|
+
export interface ConflictInfo {
|
|
19
|
+
memoryIds: string[];
|
|
20
|
+
titles: string[];
|
|
21
|
+
reason: string;
|
|
22
|
+
suggestion: string;
|
|
23
|
+
}
|
|
24
|
+
export interface DecayResult {
|
|
25
|
+
analyzed: number;
|
|
26
|
+
decayed: number;
|
|
27
|
+
archived: number;
|
|
28
|
+
}
|
|
29
|
+
export interface MemoryWithMeta extends MemoryContent {
|
|
30
|
+
accessCount?: number;
|
|
31
|
+
lastAccessed?: string;
|
|
32
|
+
mergedFrom?: string[];
|
|
33
|
+
decayScore?: number;
|
|
34
|
+
}
|
|
35
|
+
export declare class MemoryConsolidationService {
|
|
36
|
+
private client;
|
|
37
|
+
private searchService;
|
|
38
|
+
constructor(client: DrizzleMemoryClient, searchService: SemanticSearchService);
|
|
39
|
+
/**
|
|
40
|
+
* Run full consolidation process
|
|
41
|
+
*/
|
|
42
|
+
consolidate(options?: {
|
|
43
|
+
similarityThreshold?: number;
|
|
44
|
+
maxMerges?: number;
|
|
45
|
+
dryRun?: boolean;
|
|
46
|
+
}): Promise<ConsolidationResult>;
|
|
47
|
+
/**
|
|
48
|
+
* Apply memory decay - reduce priority of unused memories
|
|
49
|
+
*/
|
|
50
|
+
applyDecay(options?: {
|
|
51
|
+
daysThreshold?: number;
|
|
52
|
+
decayFactor?: number;
|
|
53
|
+
archiveThreshold?: number;
|
|
54
|
+
dryRun?: boolean;
|
|
55
|
+
}): Promise<DecayResult>;
|
|
56
|
+
/**
|
|
57
|
+
* Detect conflicts between memories
|
|
58
|
+
*/
|
|
59
|
+
detectConflicts(memories?: DevItem[]): Promise<ConflictInfo[]>;
|
|
60
|
+
/**
|
|
61
|
+
* Record memory access (for decay algorithm)
|
|
62
|
+
*/
|
|
63
|
+
recordAccess(memoryId: string): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Merge multiple memories into one
|
|
66
|
+
*/
|
|
67
|
+
private mergeMemories;
|
|
68
|
+
/**
|
|
69
|
+
* Check for contradictions between two memories
|
|
70
|
+
*/
|
|
71
|
+
private checkContradiction;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Create a memory consolidation service
|
|
75
|
+
*/
|
|
76
|
+
export declare function createConsolidationService(client: DrizzleMemoryClient, searchService: SemanticSearchService): MemoryConsolidationService;
|
|
77
|
+
//# sourceMappingURL=memory-consolidation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-consolidation.d.ts","sourceRoot":"","sources":["../../src/services/memory-consolidation.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAClE,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAM/D,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,YAAY,EAAE,CAAA;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,cAAe,SAAQ,aAAa;IACnD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAMD,qBAAa,0BAA0B;IACrC,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,aAAa,CAAuB;gBAG1C,MAAM,EAAE,mBAAmB,EAC3B,aAAa,EAAE,qBAAqB;IAMtC;;OAEG;IACG,WAAW,CAAC,OAAO,CAAC,EAAE;QAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAA;QAC5B,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,MAAM,CAAC,EAAE,OAAO,CAAA;KACjB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAkEhC;;OAEG;IACG,UAAU,CAAC,OAAO,CAAC,EAAE;QACzB,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,gBAAgB,CAAC,EAAE,MAAM,CAAA;QACzB,MAAM,CAAC,EAAE,OAAO,CAAA;KACjB,GAAG,OAAO,CAAC,WAAW,CAAC;IA4DxB;;OAEG;IACG,eAAe,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IA6CpE;;OAEG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBnD;;OAEG;YACW,aAAa;IA0D3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAyC3B;AAMD;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,mBAAmB,EAC3B,aAAa,EAAE,qBAAqB,GACnC,0BAA0B,CAE5B"}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Consolidation Service
|
|
3
|
+
*
|
|
4
|
+
* Automatically consolidates and cleans up memories:
|
|
5
|
+
* - Merges similar/duplicate memories
|
|
6
|
+
* - Archives stale memories (decay)
|
|
7
|
+
* - Detects conflicts between memories
|
|
8
|
+
*/
|
|
9
|
+
// =============================================================================
|
|
10
|
+
// MEMORY CONSOLIDATION SERVICE
|
|
11
|
+
// =============================================================================
|
|
12
|
+
export class MemoryConsolidationService {
|
|
13
|
+
client;
|
|
14
|
+
searchService;
|
|
15
|
+
constructor(client, searchService) {
|
|
16
|
+
this.client = client;
|
|
17
|
+
this.searchService = searchService;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Run full consolidation process
|
|
21
|
+
*/
|
|
22
|
+
async consolidate(options) {
|
|
23
|
+
const threshold = options?.similarityThreshold ?? 0.85;
|
|
24
|
+
const maxMerges = options?.maxMerges ?? 50;
|
|
25
|
+
const dryRun = options?.dryRun ?? false;
|
|
26
|
+
const result = {
|
|
27
|
+
analyzed: 0,
|
|
28
|
+
merged: 0,
|
|
29
|
+
archived: 0,
|
|
30
|
+
conflicts: [],
|
|
31
|
+
};
|
|
32
|
+
// Get all memories
|
|
33
|
+
const memories = await this.client.list({ type: 'memory', limit: 500 });
|
|
34
|
+
result.analyzed = memories.length;
|
|
35
|
+
// Find similar pairs
|
|
36
|
+
const processed = new Set();
|
|
37
|
+
const mergeGroups = [];
|
|
38
|
+
for (const memory of memories) {
|
|
39
|
+
if (processed.has(memory.id))
|
|
40
|
+
continue;
|
|
41
|
+
const content = memory.content;
|
|
42
|
+
if (!content)
|
|
43
|
+
continue;
|
|
44
|
+
// Find similar memories
|
|
45
|
+
const similar = await this.searchService.search(`${content.title}\n${content.body}`, { threshold, limit: 10 });
|
|
46
|
+
// Group similar memories
|
|
47
|
+
const group = similar
|
|
48
|
+
.filter(s => s.item.id !== memory.id && !processed.has(s.item.id))
|
|
49
|
+
.filter(s => s.score >= threshold);
|
|
50
|
+
if (group.length > 0) {
|
|
51
|
+
const groupItems = [memory, ...group.map(g => g.item)];
|
|
52
|
+
mergeGroups.push(groupItems);
|
|
53
|
+
groupItems.forEach(item => processed.add(item.id));
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
processed.add(memory.id);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Check for conflicts (same domain, different content)
|
|
60
|
+
result.conflicts = await this.detectConflicts(memories);
|
|
61
|
+
// Merge groups
|
|
62
|
+
if (!dryRun) {
|
|
63
|
+
for (const group of mergeGroups.slice(0, maxMerges)) {
|
|
64
|
+
const merged = await this.mergeMemories(group);
|
|
65
|
+
if (merged) {
|
|
66
|
+
result.merged++;
|
|
67
|
+
result.archived += group.length - 1;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
result.merged = Math.min(mergeGroups.length, maxMerges);
|
|
73
|
+
result.archived = mergeGroups.reduce((sum, g) => sum + g.length - 1, 0);
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Apply memory decay - reduce priority of unused memories
|
|
79
|
+
*/
|
|
80
|
+
async applyDecay(options) {
|
|
81
|
+
const daysThreshold = options?.daysThreshold ?? 30;
|
|
82
|
+
const decayFactor = options?.decayFactor ?? 0.8;
|
|
83
|
+
const archiveThreshold = options?.archiveThreshold ?? 0.2;
|
|
84
|
+
const dryRun = options?.dryRun ?? false;
|
|
85
|
+
const result = {
|
|
86
|
+
analyzed: 0,
|
|
87
|
+
decayed: 0,
|
|
88
|
+
archived: 0,
|
|
89
|
+
};
|
|
90
|
+
const memories = await this.client.list({ type: 'memory', status: 'active', limit: 500 });
|
|
91
|
+
result.analyzed = memories.length;
|
|
92
|
+
const now = Date.now();
|
|
93
|
+
const thresholdMs = daysThreshold * 24 * 60 * 60 * 1000;
|
|
94
|
+
for (const memory of memories) {
|
|
95
|
+
const content = memory.content;
|
|
96
|
+
if (!content)
|
|
97
|
+
continue;
|
|
98
|
+
// Calculate age
|
|
99
|
+
const updatedAt = memory.updatedAt ? new Date(memory.updatedAt).getTime() : now;
|
|
100
|
+
const lastAccessed = content.lastAccessed
|
|
101
|
+
? new Date(content.lastAccessed).getTime()
|
|
102
|
+
: updatedAt;
|
|
103
|
+
const age = now - Math.max(updatedAt, lastAccessed);
|
|
104
|
+
if (age > thresholdMs) {
|
|
105
|
+
// Calculate decay score
|
|
106
|
+
const currentScore = content.decayScore ?? 1.0;
|
|
107
|
+
const newScore = currentScore * decayFactor;
|
|
108
|
+
if (!dryRun) {
|
|
109
|
+
if (newScore < archiveThreshold) {
|
|
110
|
+
// Archive the memory
|
|
111
|
+
await this.client.update(memory.id, { status: 'archived' });
|
|
112
|
+
result.archived++;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// Update decay score
|
|
116
|
+
await this.client.update(memory.id, {
|
|
117
|
+
content: { ...content, decayScore: newScore },
|
|
118
|
+
});
|
|
119
|
+
result.decayed++;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
if (newScore < archiveThreshold) {
|
|
124
|
+
result.archived++;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
result.decayed++;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return result;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Detect conflicts between memories
|
|
136
|
+
*/
|
|
137
|
+
async detectConflicts(memories) {
|
|
138
|
+
const items = memories ?? await this.client.list({ type: 'memory', limit: 500 });
|
|
139
|
+
const conflicts = [];
|
|
140
|
+
// Group by domain
|
|
141
|
+
const byDomain = new Map();
|
|
142
|
+
for (const item of items) {
|
|
143
|
+
const content = item.content;
|
|
144
|
+
if (!content?.domain)
|
|
145
|
+
continue;
|
|
146
|
+
const domainItems = byDomain.get(content.domain) ?? [];
|
|
147
|
+
domainItems.push(item);
|
|
148
|
+
byDomain.set(content.domain, domainItems);
|
|
149
|
+
}
|
|
150
|
+
// Check each domain for conflicts
|
|
151
|
+
for (const [domain, domainItems] of byDomain) {
|
|
152
|
+
if (domainItems.length < 2)
|
|
153
|
+
continue;
|
|
154
|
+
// Look for conflicting information
|
|
155
|
+
for (let i = 0; i < domainItems.length; i++) {
|
|
156
|
+
for (let j = i + 1; j < domainItems.length; j++) {
|
|
157
|
+
const a = domainItems[i];
|
|
158
|
+
const b = domainItems[j];
|
|
159
|
+
const contentA = a.content;
|
|
160
|
+
const contentB = b.content;
|
|
161
|
+
// Check for contradictions in titles
|
|
162
|
+
const conflict = this.checkContradiction(contentA, contentB);
|
|
163
|
+
if (conflict) {
|
|
164
|
+
conflicts.push({
|
|
165
|
+
memoryIds: [a.id, b.id],
|
|
166
|
+
titles: [contentA.title, contentB.title],
|
|
167
|
+
reason: conflict.reason,
|
|
168
|
+
suggestion: conflict.suggestion,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return conflicts;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Record memory access (for decay algorithm)
|
|
178
|
+
*/
|
|
179
|
+
async recordAccess(memoryId) {
|
|
180
|
+
const memory = await this.client.get(memoryId);
|
|
181
|
+
if (!memory)
|
|
182
|
+
return;
|
|
183
|
+
const content = memory.content;
|
|
184
|
+
if (!content)
|
|
185
|
+
return;
|
|
186
|
+
const updated = {
|
|
187
|
+
...content,
|
|
188
|
+
accessCount: (content.accessCount ?? 0) + 1,
|
|
189
|
+
lastAccessed: new Date().toISOString(),
|
|
190
|
+
decayScore: 1.0, // Reset decay on access
|
|
191
|
+
};
|
|
192
|
+
await this.client.update(memoryId, {
|
|
193
|
+
content: updated,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
// ===========================================================================
|
|
197
|
+
// PRIVATE METHODS
|
|
198
|
+
// ===========================================================================
|
|
199
|
+
/**
|
|
200
|
+
* Merge multiple memories into one
|
|
201
|
+
*/
|
|
202
|
+
async mergeMemories(group) {
|
|
203
|
+
if (group.length < 2)
|
|
204
|
+
return null;
|
|
205
|
+
// Sort by priority and date (newest first)
|
|
206
|
+
const sorted = group.sort((a, b) => {
|
|
207
|
+
const priorityOrder = { critical: 4, high: 3, medium: 2, low: 1 };
|
|
208
|
+
const pA = priorityOrder[a.priority] ?? 2;
|
|
209
|
+
const pB = priorityOrder[b.priority] ?? 2;
|
|
210
|
+
if (pA !== pB)
|
|
211
|
+
return pB - pA;
|
|
212
|
+
const dateA = a.updatedAt ? new Date(a.updatedAt).getTime() : 0;
|
|
213
|
+
const dateB = b.updatedAt ? new Date(b.updatedAt).getTime() : 0;
|
|
214
|
+
return dateB - dateA;
|
|
215
|
+
});
|
|
216
|
+
const primary = sorted[0];
|
|
217
|
+
const primaryContent = primary.content;
|
|
218
|
+
const others = sorted.slice(1);
|
|
219
|
+
// Merge content
|
|
220
|
+
const mergedBody = [
|
|
221
|
+
primaryContent.body,
|
|
222
|
+
'',
|
|
223
|
+
'---',
|
|
224
|
+
'Merged from related memories:',
|
|
225
|
+
...others.map(o => {
|
|
226
|
+
const c = o.content;
|
|
227
|
+
return `- ${c.title}: ${c.body.slice(0, 100)}...`;
|
|
228
|
+
}),
|
|
229
|
+
].join('\n');
|
|
230
|
+
// Collect all tags
|
|
231
|
+
const allTags = new Set();
|
|
232
|
+
for (const item of group) {
|
|
233
|
+
const tags = item.tags ?? [];
|
|
234
|
+
tags.forEach(t => allTags.add(t));
|
|
235
|
+
}
|
|
236
|
+
// Update primary with merged content
|
|
237
|
+
const mergedContent = {
|
|
238
|
+
...primaryContent,
|
|
239
|
+
body: mergedBody,
|
|
240
|
+
mergedFrom: others.map(o => o.id),
|
|
241
|
+
};
|
|
242
|
+
await this.client.update(primary.id, {
|
|
243
|
+
content: mergedContent,
|
|
244
|
+
tags: Array.from(allTags),
|
|
245
|
+
});
|
|
246
|
+
// Archive others
|
|
247
|
+
for (const other of others) {
|
|
248
|
+
await this.client.update(other.id, { status: 'archived' });
|
|
249
|
+
}
|
|
250
|
+
return primary;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Check for contradictions between two memories
|
|
254
|
+
*/
|
|
255
|
+
checkContradiction(a, b) {
|
|
256
|
+
// Look for negation patterns
|
|
257
|
+
const negationPatterns = [
|
|
258
|
+
{ pos: /should/i, neg: /should not|shouldn't/i },
|
|
259
|
+
{ pos: /must/i, neg: /must not|mustn't/i },
|
|
260
|
+
{ pos: /always/i, neg: /never/i },
|
|
261
|
+
{ pos: /use/i, neg: /don't use|avoid/i },
|
|
262
|
+
{ pos: /enable/i, neg: /disable/i },
|
|
263
|
+
];
|
|
264
|
+
for (const pattern of negationPatterns) {
|
|
265
|
+
const aHasPos = pattern.pos.test(a.body) && !pattern.neg.test(a.body);
|
|
266
|
+
const bHasNeg = pattern.neg.test(b.body);
|
|
267
|
+
const bHasPos = pattern.pos.test(b.body) && !pattern.neg.test(b.body);
|
|
268
|
+
const aHasNeg = pattern.neg.test(a.body);
|
|
269
|
+
if ((aHasPos && bHasNeg) || (bHasPos && aHasNeg)) {
|
|
270
|
+
return {
|
|
271
|
+
reason: 'Potential contradiction detected in recommendations',
|
|
272
|
+
suggestion: 'Review these memories and consolidate into a single, consistent guideline',
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
// Check for version/date conflicts
|
|
277
|
+
const datePattern = /\b(2024|2025)\b/;
|
|
278
|
+
const aDate = a.body.match(datePattern)?.[0];
|
|
279
|
+
const bDate = b.body.match(datePattern)?.[0];
|
|
280
|
+
if (aDate && bDate && aDate !== bDate) {
|
|
281
|
+
return {
|
|
282
|
+
reason: `References different time periods (${aDate} vs ${bDate})`,
|
|
283
|
+
suggestion: 'Consider archiving the older memory or updating it',
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
// =============================================================================
|
|
290
|
+
// FACTORY
|
|
291
|
+
// =============================================================================
|
|
292
|
+
/**
|
|
293
|
+
* Create a memory consolidation service
|
|
294
|
+
*/
|
|
295
|
+
export function createConsolidationService(client, searchService) {
|
|
296
|
+
return new MemoryConsolidationService(client, searchService);
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=memory-consolidation.js.map
|