@mnemoai/core 1.1.0 → 1.1.1
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/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +7 -0
- package/dist/cli.js.map +7 -0
- package/dist/index.d.ts +128 -0
- package/dist/index.d.ts.map +1 -0
- package/{index.ts → dist/index.js} +526 -1333
- package/dist/index.js.map +7 -0
- package/dist/src/access-tracker.d.ts +97 -0
- package/dist/src/access-tracker.d.ts.map +1 -0
- package/dist/src/access-tracker.js +184 -0
- package/dist/src/access-tracker.js.map +7 -0
- package/dist/src/adapters/chroma.d.ts +31 -0
- package/dist/src/adapters/chroma.d.ts.map +1 -0
- package/{src/adapters/chroma.ts → dist/src/adapters/chroma.js} +45 -107
- package/dist/src/adapters/chroma.js.map +7 -0
- package/dist/src/adapters/lancedb.d.ts +29 -0
- package/dist/src/adapters/lancedb.d.ts.map +1 -0
- package/{src/adapters/lancedb.ts → dist/src/adapters/lancedb.js} +41 -109
- package/dist/src/adapters/lancedb.js.map +7 -0
- package/dist/src/adapters/pgvector.d.ts +33 -0
- package/dist/src/adapters/pgvector.d.ts.map +1 -0
- package/{src/adapters/pgvector.ts → dist/src/adapters/pgvector.js} +42 -104
- package/dist/src/adapters/pgvector.js.map +7 -0
- package/dist/src/adapters/qdrant.d.ts +34 -0
- package/dist/src/adapters/qdrant.d.ts.map +1 -0
- package/dist/src/adapters/qdrant.js +132 -0
- package/dist/src/adapters/qdrant.js.map +7 -0
- package/dist/src/adaptive-retrieval.d.ts +14 -0
- package/dist/src/adaptive-retrieval.d.ts.map +1 -0
- package/dist/src/adaptive-retrieval.js +52 -0
- package/dist/src/adaptive-retrieval.js.map +7 -0
- package/dist/src/audit-log.d.ts +56 -0
- package/dist/src/audit-log.d.ts.map +1 -0
- package/dist/src/audit-log.js +139 -0
- package/dist/src/audit-log.js.map +7 -0
- package/dist/src/chunker.d.ts +45 -0
- package/dist/src/chunker.d.ts.map +1 -0
- package/dist/src/chunker.js +157 -0
- package/dist/src/chunker.js.map +7 -0
- package/dist/src/config.d.ts +70 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +142 -0
- package/dist/src/config.js.map +7 -0
- package/dist/src/decay-engine.d.ts +73 -0
- package/dist/src/decay-engine.d.ts.map +1 -0
- package/dist/src/decay-engine.js +119 -0
- package/dist/src/decay-engine.js.map +7 -0
- package/dist/src/embedder.d.ts +94 -0
- package/dist/src/embedder.d.ts.map +1 -0
- package/{src/embedder.ts → dist/src/embedder.js} +119 -317
- package/dist/src/embedder.js.map +7 -0
- package/dist/src/extraction-prompts.d.ts +12 -0
- package/dist/src/extraction-prompts.d.ts.map +1 -0
- package/dist/src/extraction-prompts.js +311 -0
- package/dist/src/extraction-prompts.js.map +7 -0
- package/dist/src/license.d.ts +29 -0
- package/dist/src/license.d.ts.map +1 -0
- package/{src/license.ts → dist/src/license.js} +42 -113
- package/dist/src/license.js.map +7 -0
- package/dist/src/llm-client.d.ts +23 -0
- package/dist/src/llm-client.d.ts.map +1 -0
- package/{src/llm-client.ts → dist/src/llm-client.js} +22 -55
- package/dist/src/llm-client.js.map +7 -0
- package/dist/src/logger.d.ts +33 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +35 -0
- package/dist/src/logger.js.map +7 -0
- package/dist/src/mcp-server.d.ts +16 -0
- package/dist/src/mcp-server.d.ts.map +1 -0
- package/{src/mcp-server.ts → dist/src/mcp-server.js} +81 -181
- package/dist/src/mcp-server.js.map +7 -0
- package/dist/src/memory-categories.d.ts +40 -0
- package/dist/src/memory-categories.d.ts.map +1 -0
- package/dist/src/memory-categories.js +33 -0
- package/dist/src/memory-categories.js.map +7 -0
- package/dist/src/memory-upgrader.d.ts +71 -0
- package/dist/src/memory-upgrader.d.ts.map +1 -0
- package/dist/src/memory-upgrader.js +238 -0
- package/dist/src/memory-upgrader.js.map +7 -0
- package/dist/src/migrate.d.ts +47 -0
- package/dist/src/migrate.d.ts.map +1 -0
- package/{src/migrate.ts → dist/src/migrate.js} +57 -165
- package/dist/src/migrate.js.map +7 -0
- package/dist/src/mnemo.d.ts +67 -0
- package/dist/src/mnemo.d.ts.map +1 -0
- package/dist/src/mnemo.js +66 -0
- package/dist/src/mnemo.js.map +7 -0
- package/dist/src/noise-filter.d.ts +23 -0
- package/dist/src/noise-filter.d.ts.map +1 -0
- package/dist/src/noise-filter.js +62 -0
- package/dist/src/noise-filter.js.map +7 -0
- package/dist/src/noise-prototypes.d.ts +40 -0
- package/dist/src/noise-prototypes.d.ts.map +1 -0
- package/dist/src/noise-prototypes.js +116 -0
- package/dist/src/noise-prototypes.js.map +7 -0
- package/dist/src/observability.d.ts +16 -0
- package/dist/src/observability.d.ts.map +1 -0
- package/dist/src/observability.js +53 -0
- package/dist/src/observability.js.map +7 -0
- package/dist/src/query-tracker.d.ts +27 -0
- package/dist/src/query-tracker.d.ts.map +1 -0
- package/dist/src/query-tracker.js +32 -0
- package/dist/src/query-tracker.js.map +7 -0
- package/dist/src/reflection-event-store.d.ts +44 -0
- package/dist/src/reflection-event-store.d.ts.map +1 -0
- package/dist/src/reflection-event-store.js +50 -0
- package/dist/src/reflection-event-store.js.map +7 -0
- package/dist/src/reflection-item-store.d.ts +58 -0
- package/dist/src/reflection-item-store.d.ts.map +1 -0
- package/dist/src/reflection-item-store.js +69 -0
- package/dist/src/reflection-item-store.js.map +7 -0
- package/dist/src/reflection-mapped-metadata.d.ts +47 -0
- package/dist/src/reflection-mapped-metadata.d.ts.map +1 -0
- package/dist/src/reflection-mapped-metadata.js +40 -0
- package/dist/src/reflection-mapped-metadata.js.map +7 -0
- package/dist/src/reflection-metadata.d.ts +11 -0
- package/dist/src/reflection-metadata.d.ts.map +1 -0
- package/dist/src/reflection-metadata.js +24 -0
- package/dist/src/reflection-metadata.js.map +7 -0
- package/dist/src/reflection-ranking.d.ts +13 -0
- package/dist/src/reflection-ranking.d.ts.map +1 -0
- package/{src/reflection-ranking.ts → dist/src/reflection-ranking.js} +12 -21
- package/dist/src/reflection-ranking.js.map +7 -0
- package/dist/src/reflection-retry.d.ts +30 -0
- package/dist/src/reflection-retry.d.ts.map +1 -0
- package/{src/reflection-retry.ts → dist/src/reflection-retry.js} +24 -64
- package/dist/src/reflection-retry.js.map +7 -0
- package/dist/src/reflection-slices.d.ts +42 -0
- package/dist/src/reflection-slices.d.ts.map +1 -0
- package/{src/reflection-slices.ts → dist/src/reflection-slices.js} +60 -136
- package/dist/src/reflection-slices.js.map +7 -0
- package/dist/src/reflection-store.d.ts +85 -0
- package/dist/src/reflection-store.d.ts.map +1 -0
- package/dist/src/reflection-store.js +407 -0
- package/dist/src/reflection-store.js.map +7 -0
- package/dist/src/resonance-state.d.ts +19 -0
- package/dist/src/resonance-state.d.ts.map +1 -0
- package/{src/resonance-state.ts → dist/src/resonance-state.js} +13 -42
- package/dist/src/resonance-state.js.map +7 -0
- package/dist/src/retriever.d.ts +228 -0
- package/dist/src/retriever.d.ts.map +1 -0
- package/dist/src/retriever.js +1006 -0
- package/dist/src/retriever.js.map +7 -0
- package/dist/src/scopes.d.ts +58 -0
- package/dist/src/scopes.d.ts.map +1 -0
- package/dist/src/scopes.js +252 -0
- package/dist/src/scopes.js.map +7 -0
- package/dist/src/self-improvement-files.d.ts +20 -0
- package/dist/src/self-improvement-files.d.ts.map +1 -0
- package/{src/self-improvement-files.ts → dist/src/self-improvement-files.js} +24 -49
- package/dist/src/self-improvement-files.js.map +7 -0
- package/dist/src/semantic-gate.d.ts +24 -0
- package/dist/src/semantic-gate.d.ts.map +1 -0
- package/dist/src/semantic-gate.js +86 -0
- package/dist/src/semantic-gate.js.map +7 -0
- package/dist/src/session-recovery.d.ts +9 -0
- package/dist/src/session-recovery.d.ts.map +1 -0
- package/{src/session-recovery.ts → dist/src/session-recovery.js} +40 -57
- package/dist/src/session-recovery.js.map +7 -0
- package/dist/src/smart-extractor.d.ts +107 -0
- package/dist/src/smart-extractor.d.ts.map +1 -0
- package/{src/smart-extractor.ts → dist/src/smart-extractor.js} +130 -383
- package/dist/src/smart-extractor.js.map +7 -0
- package/dist/src/smart-metadata.d.ts +103 -0
- package/dist/src/smart-metadata.d.ts.map +1 -0
- package/dist/src/smart-metadata.js +361 -0
- package/dist/src/smart-metadata.js.map +7 -0
- package/dist/src/storage-adapter.d.ts +102 -0
- package/dist/src/storage-adapter.d.ts.map +1 -0
- package/dist/src/storage-adapter.js +22 -0
- package/dist/src/storage-adapter.js.map +7 -0
- package/dist/src/store.d.ts +108 -0
- package/dist/src/store.d.ts.map +1 -0
- package/dist/src/store.js +939 -0
- package/dist/src/store.js.map +7 -0
- package/dist/src/tier-manager.d.ts +57 -0
- package/dist/src/tier-manager.d.ts.map +1 -0
- package/dist/src/tier-manager.js +80 -0
- package/dist/src/tier-manager.js.map +7 -0
- package/dist/src/tools.d.ts +43 -0
- package/dist/src/tools.d.ts.map +1 -0
- package/dist/src/tools.js +1075 -0
- package/dist/src/tools.js.map +7 -0
- package/dist/src/wal-recovery.d.ts +30 -0
- package/dist/src/wal-recovery.d.ts.map +1 -0
- package/{src/wal-recovery.ts → dist/src/wal-recovery.js} +26 -79
- package/dist/src/wal-recovery.js.map +7 -0
- package/package.json +21 -2
- package/openclaw.plugin.json +0 -815
- package/src/access-tracker.ts +0 -341
- package/src/adapters/README.md +0 -78
- package/src/adapters/qdrant.ts +0 -191
- package/src/adaptive-retrieval.ts +0 -90
- package/src/audit-log.ts +0 -238
- package/src/chunker.ts +0 -254
- package/src/config.ts +0 -271
- package/src/decay-engine.ts +0 -238
- package/src/extraction-prompts.ts +0 -339
- package/src/memory-categories.ts +0 -71
- package/src/memory-upgrader.ts +0 -388
- package/src/mnemo.ts +0 -142
- package/src/noise-filter.ts +0 -97
- package/src/noise-prototypes.ts +0 -164
- package/src/observability.ts +0 -81
- package/src/query-tracker.ts +0 -57
- package/src/reflection-event-store.ts +0 -98
- package/src/reflection-item-store.ts +0 -112
- package/src/reflection-mapped-metadata.ts +0 -84
- package/src/reflection-metadata.ts +0 -23
- package/src/reflection-store.ts +0 -602
- package/src/retriever.ts +0 -1510
- package/src/scopes.ts +0 -375
- package/src/semantic-gate.ts +0 -121
- package/src/smart-metadata.ts +0 -561
- package/src/storage-adapter.ts +0 -153
- package/src/store.ts +0 -1330
- package/src/tier-manager.ts +0 -189
- package/src/tools.ts +0 -1292
- package/test/core.test.mjs +0 -301
|
@@ -1,111 +1,52 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
/**
|
|
3
|
-
* Migration Utilities
|
|
4
|
-
* Migrates data from old memory-lancedb plugin to memory-lancedb-pro
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
1
|
import { homedir } from "node:os";
|
|
8
2
|
import { join } from "node:path";
|
|
9
3
|
import fs from "node:fs/promises";
|
|
10
|
-
import type { MemoryStore, MemoryEntry } from "./store.js";
|
|
11
4
|
import { loadLanceDB } from "./store.js";
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
// Types
|
|
15
|
-
// ============================================================================
|
|
16
|
-
|
|
17
|
-
interface LegacyMemoryEntry {
|
|
18
|
-
id: string;
|
|
19
|
-
text: string;
|
|
20
|
-
vector: number[];
|
|
21
|
-
importance: number;
|
|
22
|
-
category: "preference" | "fact" | "decision" | "entity" | "other";
|
|
23
|
-
createdAt: number;
|
|
24
|
-
scope?: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
interface MigrationResult {
|
|
28
|
-
success: boolean;
|
|
29
|
-
migratedCount: number;
|
|
30
|
-
skippedCount: number;
|
|
31
|
-
errors: string[];
|
|
32
|
-
summary: string;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
interface MigrationOptions {
|
|
36
|
-
sourceDbPath?: string;
|
|
37
|
-
dryRun?: boolean;
|
|
38
|
-
defaultScope?: string;
|
|
39
|
-
skipExisting?: boolean;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function normalizeLegacyVector(value: unknown): number[] {
|
|
5
|
+
import { log } from "./logger.js";
|
|
6
|
+
function normalizeLegacyVector(value) {
|
|
43
7
|
if (Array.isArray(value)) {
|
|
44
8
|
return value.map((n) => Number(n));
|
|
45
9
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
value &&
|
|
49
|
-
typeof value === "object" &&
|
|
50
|
-
Symbol.iterator in (value as Record<PropertyKey, unknown>)
|
|
51
|
-
) {
|
|
52
|
-
return Array.from(value as Iterable<unknown>, (n) => Number(n));
|
|
10
|
+
if (value && typeof value === "object" && Symbol.iterator in value) {
|
|
11
|
+
return Array.from(value, (n) => Number(n));
|
|
53
12
|
}
|
|
54
|
-
|
|
55
13
|
return [];
|
|
56
14
|
}
|
|
57
|
-
|
|
58
|
-
// ============================================================================
|
|
59
|
-
// Default Paths
|
|
60
|
-
// ============================================================================
|
|
61
|
-
|
|
62
|
-
function getDefaultLegacyPaths(): string[] {
|
|
15
|
+
function getDefaultLegacyPaths() {
|
|
63
16
|
const home = homedir();
|
|
64
17
|
return [
|
|
65
18
|
join(home, ".openclaw", "memory", "lancedb"),
|
|
66
|
-
join(home, ".claude", "memory", "lancedb")
|
|
19
|
+
join(home, ".claude", "memory", "lancedb")
|
|
67
20
|
// Add more legacy paths as needed
|
|
68
21
|
];
|
|
69
22
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
constructor(private targetStore: MemoryStore) {}
|
|
77
|
-
|
|
78
|
-
async migrate(options: MigrationOptions = {}): Promise<MigrationResult> {
|
|
79
|
-
const result: MigrationResult = {
|
|
23
|
+
class MemoryMigrator {
|
|
24
|
+
constructor(targetStore) {
|
|
25
|
+
this.targetStore = targetStore;
|
|
26
|
+
}
|
|
27
|
+
async migrate(options = {}) {
|
|
28
|
+
const result = {
|
|
80
29
|
success: false,
|
|
81
30
|
migratedCount: 0,
|
|
82
31
|
skippedCount: 0,
|
|
83
32
|
errors: [],
|
|
84
|
-
summary: ""
|
|
33
|
+
summary: ""
|
|
85
34
|
};
|
|
86
|
-
|
|
87
35
|
try {
|
|
88
|
-
// Find source database
|
|
89
36
|
const sourceDbPath = await this.findSourceDatabase(options.sourceDbPath);
|
|
90
37
|
if (!sourceDbPath) {
|
|
91
38
|
result.errors.push("No legacy database found to migrate from");
|
|
92
39
|
result.summary = "Migration failed: No source database found";
|
|
93
40
|
return result;
|
|
94
41
|
}
|
|
95
|
-
|
|
96
|
-
console.log(`Migrating from: ${sourceDbPath}`);
|
|
97
|
-
|
|
98
|
-
// Load legacy data
|
|
42
|
+
log.info(`Migrating from: ${sourceDbPath}`);
|
|
99
43
|
const legacyEntries = await this.loadLegacyData(sourceDbPath);
|
|
100
44
|
if (legacyEntries.length === 0) {
|
|
101
45
|
result.summary = "Migration completed: No data to migrate";
|
|
102
46
|
result.success = true;
|
|
103
47
|
return result;
|
|
104
48
|
}
|
|
105
|
-
|
|
106
|
-
console.log(`Found ${legacyEntries.length} entries to migrate`);
|
|
107
|
-
|
|
108
|
-
// Migrate entries
|
|
49
|
+
log.info(`Found ${legacyEntries.length} entries to migrate`);
|
|
109
50
|
if (!options.dryRun) {
|
|
110
51
|
const migrationStats = await this.migrateEntries(legacyEntries, options);
|
|
111
52
|
result.migratedCount = migrationStats.migrated;
|
|
@@ -116,20 +57,15 @@ export class MemoryMigrator {
|
|
|
116
57
|
result.success = true;
|
|
117
58
|
return result;
|
|
118
59
|
}
|
|
119
|
-
|
|
120
60
|
result.success = result.errors.length === 0;
|
|
121
|
-
result.summary = `Migration ${result.success ?
|
|
122
|
-
`${result.migratedCount} migrated, ${result.skippedCount} skipped`;
|
|
123
|
-
|
|
61
|
+
result.summary = `Migration ${result.success ? "completed" : "completed with errors"}: ${result.migratedCount} migrated, ${result.skippedCount} skipped`;
|
|
124
62
|
} catch (error) {
|
|
125
63
|
result.errors.push(`Migration failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
126
64
|
result.summary = "Migration failed due to unexpected error";
|
|
127
65
|
}
|
|
128
|
-
|
|
129
66
|
return result;
|
|
130
67
|
}
|
|
131
|
-
|
|
132
|
-
private async findSourceDatabase(explicitPath?: string): Promise<string | null> {
|
|
68
|
+
async findSourceDatabase(explicitPath) {
|
|
133
69
|
if (explicitPath) {
|
|
134
70
|
try {
|
|
135
71
|
await fs.access(explicitPath);
|
|
@@ -138,79 +74,65 @@ export class MemoryMigrator {
|
|
|
138
74
|
return null;
|
|
139
75
|
}
|
|
140
76
|
}
|
|
141
|
-
|
|
142
|
-
// Check default legacy paths
|
|
143
77
|
for (const path of getDefaultLegacyPaths()) {
|
|
144
78
|
try {
|
|
145
79
|
await fs.access(path);
|
|
146
80
|
const files = await fs.readdir(path);
|
|
147
|
-
|
|
148
|
-
if (files.some(f => f.endsWith('.lance') || f === 'memories.lance')) {
|
|
81
|
+
if (files.some((f) => f.endsWith(".lance") || f === "memories.lance")) {
|
|
149
82
|
return path;
|
|
150
83
|
}
|
|
151
84
|
} catch {
|
|
152
85
|
continue;
|
|
153
86
|
}
|
|
154
87
|
}
|
|
155
|
-
|
|
156
88
|
return null;
|
|
157
89
|
}
|
|
158
|
-
|
|
159
|
-
private async loadLegacyData(sourceDbPath: string, limit?: number): Promise<LegacyMemoryEntry[]> {
|
|
90
|
+
async loadLegacyData(sourceDbPath, limit) {
|
|
160
91
|
const lancedb = await loadLanceDB();
|
|
161
92
|
const db = await lancedb.connect(sourceDbPath);
|
|
162
|
-
|
|
163
93
|
try {
|
|
164
94
|
const table = await db.openTable("memories");
|
|
165
95
|
let query = table.query();
|
|
166
96
|
if (limit) query = query.limit(limit);
|
|
167
97
|
const entries = await query.toArray();
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
text: row.text as string,
|
|
98
|
+
return entries.map((row) => ({
|
|
99
|
+
id: row.id,
|
|
100
|
+
text: row.text,
|
|
172
101
|
vector: normalizeLegacyVector(row.vector),
|
|
173
102
|
importance: Number(row.importance),
|
|
174
|
-
category:
|
|
103
|
+
category: row.category || "other",
|
|
175
104
|
createdAt: Number(row.createdAt),
|
|
176
|
-
scope: row.scope
|
|
105
|
+
scope: row.scope
|
|
177
106
|
}));
|
|
178
107
|
} catch (error) {
|
|
179
|
-
|
|
108
|
+
log.warn(`Failed to load legacy data: ${error}`);
|
|
180
109
|
return [];
|
|
181
110
|
}
|
|
182
111
|
}
|
|
183
|
-
|
|
184
|
-
private async migrateEntries(
|
|
185
|
-
legacyEntries: LegacyMemoryEntry[],
|
|
186
|
-
options: MigrationOptions
|
|
187
|
-
): Promise<{ migrated: number; skipped: number; errors: string[] }> {
|
|
112
|
+
async migrateEntries(legacyEntries, options) {
|
|
188
113
|
let migrated = 0;
|
|
189
114
|
let skipped = 0;
|
|
190
|
-
const errors
|
|
191
|
-
|
|
115
|
+
const errors = [];
|
|
192
116
|
const defaultScope = options.defaultScope || "global";
|
|
193
|
-
|
|
194
117
|
for (const legacy of legacyEntries) {
|
|
195
118
|
try {
|
|
196
|
-
// Check if entry already exists (if skipExisting is enabled)
|
|
197
119
|
if (options.skipExisting) {
|
|
198
|
-
if (legacy.id &&
|
|
120
|
+
if (legacy.id && await this.targetStore.hasId(legacy.id)) {
|
|
199
121
|
skipped++;
|
|
200
122
|
continue;
|
|
201
123
|
}
|
|
202
|
-
|
|
203
124
|
const existing = await this.targetStore.vectorSearch(
|
|
204
|
-
legacy.vector,
|
|
125
|
+
legacy.vector,
|
|
126
|
+
1,
|
|
127
|
+
0.9,
|
|
128
|
+
[legacy.scope || defaultScope]
|
|
205
129
|
);
|
|
206
130
|
if (existing.length > 0 && existing[0].score > 0.95) {
|
|
207
131
|
skipped++;
|
|
208
132
|
continue;
|
|
209
133
|
}
|
|
210
134
|
}
|
|
211
|
-
|
|
212
|
-
// Convert legacy entry to new format while preserving legacy identity.
|
|
213
|
-
const newEntry: MemoryEntry = {
|
|
135
|
+
const newEntry = {
|
|
214
136
|
id: legacy.id,
|
|
215
137
|
text: legacy.text,
|
|
216
138
|
vector: legacy.vector,
|
|
@@ -221,66 +143,47 @@ export class MemoryMigrator {
|
|
|
221
143
|
metadata: JSON.stringify({
|
|
222
144
|
migratedFrom: "memory-lancedb",
|
|
223
145
|
originalId: legacy.id,
|
|
224
|
-
originalCreatedAt: legacy.createdAt
|
|
225
|
-
})
|
|
146
|
+
originalCreatedAt: legacy.createdAt
|
|
147
|
+
})
|
|
226
148
|
};
|
|
227
|
-
|
|
228
149
|
await this.targetStore.importEntry(newEntry);
|
|
229
150
|
migrated++;
|
|
230
|
-
|
|
231
151
|
if (migrated % 100 === 0) {
|
|
232
|
-
|
|
152
|
+
log.info(`Migrated ${migrated}/${legacyEntries.length} entries...`);
|
|
233
153
|
}
|
|
234
|
-
|
|
235
154
|
} catch (error) {
|
|
236
155
|
errors.push(`Failed to migrate entry ${legacy.id}: ${error}`);
|
|
237
156
|
skipped++;
|
|
238
157
|
}
|
|
239
158
|
}
|
|
240
|
-
|
|
241
159
|
return { migrated, skipped, errors };
|
|
242
160
|
}
|
|
243
|
-
|
|
244
|
-
async checkMigrationNeeded(sourceDbPath?: string): Promise<{
|
|
245
|
-
needed: boolean;
|
|
246
|
-
sourceFound: boolean;
|
|
247
|
-
sourceDbPath?: string;
|
|
248
|
-
entryCount?: number;
|
|
249
|
-
}> {
|
|
161
|
+
async checkMigrationNeeded(sourceDbPath) {
|
|
250
162
|
const sourcePath = await this.findSourceDatabase(sourceDbPath);
|
|
251
|
-
|
|
252
163
|
if (!sourcePath) {
|
|
253
164
|
return {
|
|
254
165
|
needed: false,
|
|
255
|
-
sourceFound: false
|
|
166
|
+
sourceFound: false
|
|
256
167
|
};
|
|
257
168
|
}
|
|
258
|
-
|
|
259
169
|
try {
|
|
260
170
|
const entries = await this.loadLegacyData(sourcePath, 1);
|
|
261
171
|
return {
|
|
262
172
|
needed: entries.length > 0,
|
|
263
173
|
sourceFound: true,
|
|
264
174
|
sourceDbPath: sourcePath,
|
|
265
|
-
entryCount: entries.length > 0 ?
|
|
175
|
+
entryCount: entries.length > 0 ? void 0 : 0
|
|
266
176
|
};
|
|
267
177
|
} catch (error) {
|
|
268
178
|
return {
|
|
269
179
|
needed: false,
|
|
270
180
|
sourceFound: true,
|
|
271
|
-
sourceDbPath: sourcePath
|
|
181
|
+
sourceDbPath: sourcePath
|
|
272
182
|
};
|
|
273
183
|
}
|
|
274
184
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
valid: boolean;
|
|
278
|
-
sourceCount: number;
|
|
279
|
-
targetCount: number;
|
|
280
|
-
issues: string[];
|
|
281
|
-
}> {
|
|
282
|
-
const issues: string[] = [];
|
|
283
|
-
|
|
185
|
+
async verifyMigration(sourceDbPath) {
|
|
186
|
+
const issues = [];
|
|
284
187
|
try {
|
|
285
188
|
const sourcePath = await this.findSourceDatabase(sourceDbPath);
|
|
286
189
|
if (!sourcePath) {
|
|
@@ -288,65 +191,48 @@ export class MemoryMigrator {
|
|
|
288
191
|
valid: false,
|
|
289
192
|
sourceCount: 0,
|
|
290
193
|
targetCount: 0,
|
|
291
|
-
issues: ["Source database not found"]
|
|
194
|
+
issues: ["Source database not found"]
|
|
292
195
|
};
|
|
293
196
|
}
|
|
294
|
-
|
|
295
197
|
const sourceEntries = await this.loadLegacyData(sourcePath);
|
|
296
198
|
const targetStats = await this.targetStore.stats();
|
|
297
|
-
|
|
298
199
|
const sourceCount = sourceEntries.length;
|
|
299
200
|
const targetCount = targetStats.totalCount;
|
|
300
|
-
|
|
301
201
|
if (targetCount < sourceCount) {
|
|
302
202
|
issues.push(`Target has fewer entries (${targetCount}) than source (${sourceCount})`);
|
|
303
203
|
}
|
|
304
|
-
|
|
305
204
|
return {
|
|
306
205
|
valid: issues.length === 0,
|
|
307
206
|
sourceCount,
|
|
308
207
|
targetCount,
|
|
309
|
-
issues
|
|
208
|
+
issues
|
|
310
209
|
};
|
|
311
|
-
|
|
312
210
|
} catch (error) {
|
|
313
211
|
return {
|
|
314
212
|
valid: false,
|
|
315
213
|
sourceCount: 0,
|
|
316
214
|
targetCount: 0,
|
|
317
|
-
issues: [`Verification failed: ${error}`]
|
|
215
|
+
issues: [`Verification failed: ${error}`]
|
|
318
216
|
};
|
|
319
217
|
}
|
|
320
218
|
}
|
|
321
219
|
}
|
|
322
|
-
|
|
323
|
-
export function createMigrator(targetStore: MemoryStore): MemoryMigrator {
|
|
220
|
+
function createMigrator(targetStore) {
|
|
324
221
|
return new MemoryMigrator(targetStore);
|
|
325
222
|
}
|
|
326
|
-
|
|
327
|
-
export async function migrateFromLegacy(
|
|
328
|
-
targetStore: MemoryStore,
|
|
329
|
-
options: MigrationOptions = {}
|
|
330
|
-
): Promise<MigrationResult> {
|
|
223
|
+
async function migrateFromLegacy(targetStore, options = {}) {
|
|
331
224
|
const migrator = createMigrator(targetStore);
|
|
332
225
|
return migrator.migrate(options);
|
|
333
226
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
found: boolean;
|
|
337
|
-
paths: string[];
|
|
338
|
-
totalEntries: number;
|
|
339
|
-
}> {
|
|
340
|
-
const paths: string[] = [];
|
|
227
|
+
async function checkForLegacyData() {
|
|
228
|
+
const paths = [];
|
|
341
229
|
let totalEntries = 0;
|
|
342
|
-
|
|
343
230
|
for (const path of getDefaultLegacyPaths()) {
|
|
344
231
|
try {
|
|
345
232
|
const lancedb = await loadLanceDB();
|
|
346
233
|
const db = await lancedb.connect(path);
|
|
347
234
|
const table = await db.openTable("memories");
|
|
348
235
|
const entries = await table.query().select(["id"]).toArray();
|
|
349
|
-
|
|
350
236
|
if (entries.length > 0) {
|
|
351
237
|
paths.push(path);
|
|
352
238
|
totalEntries += entries.length;
|
|
@@ -355,10 +241,16 @@ export async function checkForLegacyData(): Promise<{
|
|
|
355
241
|
continue;
|
|
356
242
|
}
|
|
357
243
|
}
|
|
358
|
-
|
|
359
244
|
return {
|
|
360
245
|
found: paths.length > 0,
|
|
361
246
|
paths,
|
|
362
|
-
totalEntries
|
|
247
|
+
totalEntries
|
|
363
248
|
};
|
|
364
249
|
}
|
|
250
|
+
export {
|
|
251
|
+
MemoryMigrator,
|
|
252
|
+
checkForLegacyData,
|
|
253
|
+
createMigrator,
|
|
254
|
+
migrateFromLegacy
|
|
255
|
+
};
|
|
256
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/migrate.ts"],
|
|
4
|
+
"sourcesContent": ["// SPDX-License-Identifier: MIT\n/**\n * Migration Utilities\n * Migrates data from old memory-lancedb plugin to memory-lancedb-pro\n */\n\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport fs from \"node:fs/promises\";\nimport type { MemoryStore, MemoryEntry } from \"./store.js\";\nimport { loadLanceDB } from \"./store.js\";\nimport { log } from \"./logger.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface LegacyMemoryEntry {\n id: string;\n text: string;\n vector: number[];\n importance: number;\n category: \"preference\" | \"fact\" | \"decision\" | \"entity\" | \"other\";\n createdAt: number;\n scope?: string;\n}\n\ninterface MigrationResult {\n success: boolean;\n migratedCount: number;\n skippedCount: number;\n errors: string[];\n summary: string;\n}\n\ninterface MigrationOptions {\n sourceDbPath?: string;\n dryRun?: boolean;\n defaultScope?: string;\n skipExisting?: boolean;\n}\n\nfunction normalizeLegacyVector(value: unknown): number[] {\n if (Array.isArray(value)) {\n return value.map((n) => Number(n));\n }\n\n if (\n value &&\n typeof value === \"object\" &&\n Symbol.iterator in (value as Record<PropertyKey, unknown>)\n ) {\n return Array.from(value as Iterable<unknown>, (n) => Number(n));\n }\n\n return [];\n}\n\n// ============================================================================\n// Default Paths\n// ============================================================================\n\nfunction getDefaultLegacyPaths(): string[] {\n const home = homedir();\n return [\n join(home, \".openclaw\", \"memory\", \"lancedb\"),\n join(home, \".claude\", \"memory\", \"lancedb\"),\n // Add more legacy paths as needed\n ];\n}\n\n// ============================================================================\n// Migration Functions\n// ============================================================================\n\nexport class MemoryMigrator {\n constructor(private targetStore: MemoryStore) {}\n\n async migrate(options: MigrationOptions = {}): Promise<MigrationResult> {\n const result: MigrationResult = {\n success: false,\n migratedCount: 0,\n skippedCount: 0,\n errors: [],\n summary: \"\",\n };\n\n try {\n // Find source database\n const sourceDbPath = await this.findSourceDatabase(options.sourceDbPath);\n if (!sourceDbPath) {\n result.errors.push(\"No legacy database found to migrate from\");\n result.summary = \"Migration failed: No source database found\";\n return result;\n }\n\n log.info(`Migrating from: ${sourceDbPath}`);\n\n // Load legacy data\n const legacyEntries = await this.loadLegacyData(sourceDbPath);\n if (legacyEntries.length === 0) {\n result.summary = \"Migration completed: No data to migrate\";\n result.success = true;\n return result;\n }\n\n log.info(`Found ${legacyEntries.length} entries to migrate`);\n\n // Migrate entries\n if (!options.dryRun) {\n const migrationStats = await this.migrateEntries(legacyEntries, options);\n result.migratedCount = migrationStats.migrated;\n result.skippedCount = migrationStats.skipped;\n result.errors.push(...migrationStats.errors);\n } else {\n result.summary = `Dry run: Would migrate ${legacyEntries.length} entries`;\n result.success = true;\n return result;\n }\n\n result.success = result.errors.length === 0;\n result.summary = `Migration ${result.success ? 'completed' : 'completed with errors'}: ` +\n `${result.migratedCount} migrated, ${result.skippedCount} skipped`;\n\n } catch (error) {\n result.errors.push(`Migration failed: ${error instanceof Error ? error.message : String(error)}`);\n result.summary = \"Migration failed due to unexpected error\";\n }\n\n return result;\n }\n\n private async findSourceDatabase(explicitPath?: string): Promise<string | null> {\n if (explicitPath) {\n try {\n await fs.access(explicitPath);\n return explicitPath;\n } catch {\n return null;\n }\n }\n\n // Check default legacy paths\n for (const path of getDefaultLegacyPaths()) {\n try {\n await fs.access(path);\n const files = await fs.readdir(path);\n // Check for LanceDB files\n if (files.some(f => f.endsWith('.lance') || f === 'memories.lance')) {\n return path;\n }\n } catch {\n continue;\n }\n }\n\n return null;\n }\n\n private async loadLegacyData(sourceDbPath: string, limit?: number): Promise<LegacyMemoryEntry[]> {\n const lancedb = await loadLanceDB();\n const db = await lancedb.connect(sourceDbPath);\n\n try {\n const table = await db.openTable(\"memories\");\n let query = table.query();\n if (limit) query = query.limit(limit);\n const entries = await query.toArray();\n\n return entries.map((row): LegacyMemoryEntry => ({\n id: row.id as string,\n text: row.text as string,\n vector: normalizeLegacyVector(row.vector),\n importance: Number(row.importance),\n category: (row.category as LegacyMemoryEntry[\"category\"]) || \"other\",\n createdAt: Number(row.createdAt),\n scope: row.scope as string | undefined,\n }));\n } catch (error) {\n log.warn(`Failed to load legacy data: ${error}`);\n return [];\n }\n }\n\n private async migrateEntries(\n legacyEntries: LegacyMemoryEntry[],\n options: MigrationOptions\n ): Promise<{ migrated: number; skipped: number; errors: string[] }> {\n let migrated = 0;\n let skipped = 0;\n const errors: string[] = [];\n\n const defaultScope = options.defaultScope || \"global\";\n\n for (const legacy of legacyEntries) {\n try {\n // Check if entry already exists (if skipExisting is enabled)\n if (options.skipExisting) {\n if (legacy.id && (await this.targetStore.hasId(legacy.id))) {\n skipped++;\n continue;\n }\n\n const existing = await this.targetStore.vectorSearch(\n legacy.vector, 1, 0.9, [legacy.scope || defaultScope]\n );\n if (existing.length > 0 && existing[0].score > 0.95) {\n skipped++;\n continue;\n }\n }\n\n // Convert legacy entry to new format while preserving legacy identity.\n const newEntry: MemoryEntry = {\n id: legacy.id,\n text: legacy.text,\n vector: legacy.vector,\n category: legacy.category,\n scope: legacy.scope || defaultScope,\n importance: legacy.importance,\n timestamp: Number.isFinite(legacy.createdAt) ? legacy.createdAt : Date.now(),\n metadata: JSON.stringify({\n migratedFrom: \"memory-lancedb\",\n originalId: legacy.id,\n originalCreatedAt: legacy.createdAt,\n }),\n };\n\n await this.targetStore.importEntry(newEntry);\n migrated++;\n\n if (migrated % 100 === 0) {\n log.info(`Migrated ${migrated}/${legacyEntries.length} entries...`);\n }\n\n } catch (error) {\n errors.push(`Failed to migrate entry ${legacy.id}: ${error}`);\n skipped++;\n }\n }\n\n return { migrated, skipped, errors };\n }\n\n async checkMigrationNeeded(sourceDbPath?: string): Promise<{\n needed: boolean;\n sourceFound: boolean;\n sourceDbPath?: string;\n entryCount?: number;\n }> {\n const sourcePath = await this.findSourceDatabase(sourceDbPath);\n\n if (!sourcePath) {\n return {\n needed: false,\n sourceFound: false,\n };\n }\n\n try {\n const entries = await this.loadLegacyData(sourcePath, 1);\n return {\n needed: entries.length > 0,\n sourceFound: true,\n sourceDbPath: sourcePath,\n entryCount: entries.length > 0 ? undefined : 0,\n };\n } catch (error) {\n return {\n needed: false,\n sourceFound: true,\n sourceDbPath: sourcePath,\n };\n }\n }\n\n async verifyMigration(sourceDbPath?: string): Promise<{\n valid: boolean;\n sourceCount: number;\n targetCount: number;\n issues: string[];\n }> {\n const issues: string[] = [];\n\n try {\n const sourcePath = await this.findSourceDatabase(sourceDbPath);\n if (!sourcePath) {\n return {\n valid: false,\n sourceCount: 0,\n targetCount: 0,\n issues: [\"Source database not found\"],\n };\n }\n\n const sourceEntries = await this.loadLegacyData(sourcePath);\n const targetStats = await this.targetStore.stats();\n\n const sourceCount = sourceEntries.length;\n const targetCount = targetStats.totalCount;\n\n if (targetCount < sourceCount) {\n issues.push(`Target has fewer entries (${targetCount}) than source (${sourceCount})`);\n }\n\n return {\n valid: issues.length === 0,\n sourceCount,\n targetCount,\n issues,\n };\n\n } catch (error) {\n return {\n valid: false,\n sourceCount: 0,\n targetCount: 0,\n issues: [`Verification failed: ${error}`],\n };\n }\n }\n}\n\nexport function createMigrator(targetStore: MemoryStore): MemoryMigrator {\n return new MemoryMigrator(targetStore);\n}\n\nexport async function migrateFromLegacy(\n targetStore: MemoryStore,\n options: MigrationOptions = {}\n): Promise<MigrationResult> {\n const migrator = createMigrator(targetStore);\n return migrator.migrate(options);\n}\n\nexport async function checkForLegacyData(): Promise<{\n found: boolean;\n paths: string[];\n totalEntries: number;\n}> {\n const paths: string[] = [];\n let totalEntries = 0;\n\n for (const path of getDefaultLegacyPaths()) {\n try {\n const lancedb = await loadLanceDB();\n const db = await lancedb.connect(path);\n const table = await db.openTable(\"memories\");\n const entries = await table.query().select([\"id\"]).toArray();\n\n if (entries.length > 0) {\n paths.push(path);\n totalEntries += entries.length;\n }\n } catch {\n continue;\n }\n }\n\n return {\n found: paths.length > 0,\n paths,\n totalEntries,\n };\n}\n"],
|
|
5
|
+
"mappings": "AAMA,SAAS,eAAe;AACxB,SAAS,YAAY;AACrB,OAAO,QAAQ;AAEf,SAAS,mBAAmB;AAC5B,SAAS,WAAW;AA+BpB,SAAS,sBAAsB,OAA0B;AACvD,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,CAAC,MAAM,OAAO,CAAC,CAAC;AAAA,EACnC;AAEA,MACE,SACA,OAAO,UAAU,YACjB,OAAO,YAAa,OACpB;AACA,WAAO,MAAM,KAAK,OAA4B,CAAC,MAAM,OAAO,CAAC,CAAC;AAAA,EAChE;AAEA,SAAO,CAAC;AACV;AAMA,SAAS,wBAAkC;AACzC,QAAM,OAAO,QAAQ;AACrB,SAAO;AAAA,IACL,KAAK,MAAM,aAAa,UAAU,SAAS;AAAA,IAC3C,KAAK,MAAM,WAAW,UAAU,SAAS;AAAA;AAAA,EAE3C;AACF;AAMO,MAAM,eAAe;AAAA,EAC1B,YAAoB,aAA0B;AAA1B;AAAA,EAA2B;AAAA,EAE/C,MAAM,QAAQ,UAA4B,CAAC,GAA6B;AACtE,UAAM,SAA0B;AAAA,MAC9B,SAAS;AAAA,MACT,eAAe;AAAA,MACf,cAAc;AAAA,MACd,QAAQ,CAAC;AAAA,MACT,SAAS;AAAA,IACX;AAEA,QAAI;AAEF,YAAM,eAAe,MAAM,KAAK,mBAAmB,QAAQ,YAAY;AACvE,UAAI,CAAC,cAAc;AACjB,eAAO,OAAO,KAAK,0CAA0C;AAC7D,eAAO,UAAU;AACjB,eAAO;AAAA,MACT;AAEA,UAAI,KAAK,mBAAmB,YAAY,EAAE;AAG1C,YAAM,gBAAgB,MAAM,KAAK,eAAe,YAAY;AAC5D,UAAI,cAAc,WAAW,GAAG;AAC9B,eAAO,UAAU;AACjB,eAAO,UAAU;AACjB,eAAO;AAAA,MACT;AAEA,UAAI,KAAK,SAAS,cAAc,MAAM,qBAAqB;AAG3D,UAAI,CAAC,QAAQ,QAAQ;AACnB,cAAM,iBAAiB,MAAM,KAAK,eAAe,eAAe,OAAO;AACvE,eAAO,gBAAgB,eAAe;AACtC,eAAO,eAAe,eAAe;AACrC,eAAO,OAAO,KAAK,GAAG,eAAe,MAAM;AAAA,MAC7C,OAAO;AACL,eAAO,UAAU,0BAA0B,cAAc,MAAM;AAC/D,eAAO,UAAU;AACjB,eAAO;AAAA,MACT;AAEA,aAAO,UAAU,OAAO,OAAO,WAAW;AAC1C,aAAO,UAAU,aAAa,OAAO,UAAU,cAAc,uBAAuB,KAC/E,OAAO,aAAa,cAAc,OAAO,YAAY;AAAA,IAE5D,SAAS,OAAO;AACd,aAAO,OAAO,KAAK,qBAAqB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAChG,aAAO,UAAU;AAAA,IACnB;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,mBAAmB,cAA+C;AAC9E,QAAI,cAAc;AAChB,UAAI;AACF,cAAM,GAAG,OAAO,YAAY;AAC5B,eAAO;AAAA,MACT,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AAGA,eAAW,QAAQ,sBAAsB,GAAG;AAC1C,UAAI;AACF,cAAM,GAAG,OAAO,IAAI;AACpB,cAAM,QAAQ,MAAM,GAAG,QAAQ,IAAI;AAEnC,YAAI,MAAM,KAAK,OAAK,EAAE,SAAS,QAAQ,KAAK,MAAM,gBAAgB,GAAG;AACnE,iBAAO;AAAA,QACT;AAAA,MACF,QAAQ;AACN;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,eAAe,cAAsB,OAA8C;AAC/F,UAAM,UAAU,MAAM,YAAY;AAClC,UAAM,KAAK,MAAM,QAAQ,QAAQ,YAAY;AAE7C,QAAI;AACF,YAAM,QAAQ,MAAM,GAAG,UAAU,UAAU;AAC3C,UAAI,QAAQ,MAAM,MAAM;AACxB,UAAI,MAAO,SAAQ,MAAM,MAAM,KAAK;AACpC,YAAM,UAAU,MAAM,MAAM,QAAQ;AAEpC,aAAO,QAAQ,IAAI,CAAC,SAA4B;AAAA,QAC9C,IAAI,IAAI;AAAA,QACR,MAAM,IAAI;AAAA,QACV,QAAQ,sBAAsB,IAAI,MAAM;AAAA,QACxC,YAAY,OAAO,IAAI,UAAU;AAAA,QACjC,UAAW,IAAI,YAA8C;AAAA,QAC7D,WAAW,OAAO,IAAI,SAAS;AAAA,QAC/B,OAAO,IAAI;AAAA,MACb,EAAE;AAAA,IACJ,SAAS,OAAO;AACd,UAAI,KAAK,+BAA+B,KAAK,EAAE;AAC/C,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAc,eACZ,eACA,SACkE;AAClE,QAAI,WAAW;AACf,QAAI,UAAU;AACd,UAAM,SAAmB,CAAC;AAE1B,UAAM,eAAe,QAAQ,gBAAgB;AAE7C,eAAW,UAAU,eAAe;AAClC,UAAI;AAEF,YAAI,QAAQ,cAAc;AACxB,cAAI,OAAO,MAAO,MAAM,KAAK,YAAY,MAAM,OAAO,EAAE,GAAI;AAC1D;AACA;AAAA,UACF;AAEA,gBAAM,WAAW,MAAM,KAAK,YAAY;AAAA,YACtC,OAAO;AAAA,YAAQ;AAAA,YAAG;AAAA,YAAK,CAAC,OAAO,SAAS,YAAY;AAAA,UACtD;AACA,cAAI,SAAS,SAAS,KAAK,SAAS,CAAC,EAAE,QAAQ,MAAM;AACnD;AACA;AAAA,UACF;AAAA,QACF;AAGA,cAAM,WAAwB;AAAA,UAC5B,IAAI,OAAO;AAAA,UACX,MAAM,OAAO;AAAA,UACb,QAAQ,OAAO;AAAA,UACf,UAAU,OAAO;AAAA,UACjB,OAAO,OAAO,SAAS;AAAA,UACvB,YAAY,OAAO;AAAA,UACnB,WAAW,OAAO,SAAS,OAAO,SAAS,IAAI,OAAO,YAAY,KAAK,IAAI;AAAA,UAC3E,UAAU,KAAK,UAAU;AAAA,YACvB,cAAc;AAAA,YACd,YAAY,OAAO;AAAA,YACnB,mBAAmB,OAAO;AAAA,UAC5B,CAAC;AAAA,QACH;AAEA,cAAM,KAAK,YAAY,YAAY,QAAQ;AAC3C;AAEA,YAAI,WAAW,QAAQ,GAAG;AACxB,cAAI,KAAK,YAAY,QAAQ,IAAI,cAAc,MAAM,aAAa;AAAA,QACpE;AAAA,MAEF,SAAS,OAAO;AACd,eAAO,KAAK,2BAA2B,OAAO,EAAE,KAAK,KAAK,EAAE;AAC5D;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,UAAU,SAAS,OAAO;AAAA,EACrC;AAAA,EAEA,MAAM,qBAAqB,cAKxB;AACD,UAAM,aAAa,MAAM,KAAK,mBAAmB,YAAY;AAE7D,QAAI,CAAC,YAAY;AACf,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,aAAa;AAAA,MACf;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,eAAe,YAAY,CAAC;AACvD,aAAO;AAAA,QACL,QAAQ,QAAQ,SAAS;AAAA,QACzB,aAAa;AAAA,QACb,cAAc;AAAA,QACd,YAAY,QAAQ,SAAS,IAAI,SAAY;AAAA,MAC/C;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,gBAAgB,cAKnB;AACD,UAAM,SAAmB,CAAC;AAE1B,QAAI;AACF,YAAM,aAAa,MAAM,KAAK,mBAAmB,YAAY;AAC7D,UAAI,CAAC,YAAY;AACf,eAAO;AAAA,UACL,OAAO;AAAA,UACP,aAAa;AAAA,UACb,aAAa;AAAA,UACb,QAAQ,CAAC,2BAA2B;AAAA,QACtC;AAAA,MACF;AAEA,YAAM,gBAAgB,MAAM,KAAK,eAAe,UAAU;AAC1D,YAAM,cAAc,MAAM,KAAK,YAAY,MAAM;AAEjD,YAAM,cAAc,cAAc;AAClC,YAAM,cAAc,YAAY;AAEhC,UAAI,cAAc,aAAa;AAC7B,eAAO,KAAK,6BAA6B,WAAW,kBAAkB,WAAW,GAAG;AAAA,MACtF;AAEA,aAAO;AAAA,QACL,OAAO,OAAO,WAAW;AAAA,QACzB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IAEF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,OAAO;AAAA,QACP,aAAa;AAAA,QACb,aAAa;AAAA,QACb,QAAQ,CAAC,wBAAwB,KAAK,EAAE;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,eAAe,aAA0C;AACvE,SAAO,IAAI,eAAe,WAAW;AACvC;AAEA,eAAsB,kBACpB,aACA,UAA4B,CAAC,GACH;AAC1B,QAAM,WAAW,eAAe,WAAW;AAC3C,SAAO,SAAS,QAAQ,OAAO;AACjC;AAEA,eAAsB,qBAInB;AACD,QAAM,QAAkB,CAAC;AACzB,MAAI,eAAe;AAEnB,aAAW,QAAQ,sBAAsB,GAAG;AAC1C,QAAI;AACF,YAAM,UAAU,MAAM,YAAY;AAClC,YAAM,KAAK,MAAM,QAAQ,QAAQ,IAAI;AACrC,YAAM,QAAQ,MAAM,GAAG,UAAU,UAAU;AAC3C,YAAM,UAAU,MAAM,MAAM,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ;AAE3D,UAAI,QAAQ,SAAS,GAAG;AACtB,cAAM,KAAK,IAAI;AACf,wBAAgB,QAAQ;AAAA,MAC1B;AAAA,IACF,QAAQ;AACN;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,MAAM,SAAS;AAAA,IACtB;AAAA,IACA;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mnemo Core — simplified entry point
|
|
3
|
+
* Usage: const mnemo = await createMnemo(config)
|
|
4
|
+
*/
|
|
5
|
+
export interface MnemoConfig {
|
|
6
|
+
embedding: {
|
|
7
|
+
provider: "openai-compatible";
|
|
8
|
+
apiKey: string;
|
|
9
|
+
baseURL?: string;
|
|
10
|
+
model?: string;
|
|
11
|
+
dimensions?: number;
|
|
12
|
+
taskQuery?: string;
|
|
13
|
+
taskPassage?: string;
|
|
14
|
+
};
|
|
15
|
+
dbPath: string;
|
|
16
|
+
decay?: {
|
|
17
|
+
recencyHalfLifeDays?: number;
|
|
18
|
+
recencyWeight?: number;
|
|
19
|
+
frequencyWeight?: number;
|
|
20
|
+
intrinsicWeight?: number;
|
|
21
|
+
};
|
|
22
|
+
tier?: {
|
|
23
|
+
coreAccessThreshold?: number;
|
|
24
|
+
coreImportanceThreshold?: number;
|
|
25
|
+
peripheralAgeDays?: number;
|
|
26
|
+
};
|
|
27
|
+
llm?: {
|
|
28
|
+
model?: string;
|
|
29
|
+
baseURL?: string;
|
|
30
|
+
apiKey?: string;
|
|
31
|
+
};
|
|
32
|
+
retrieval?: {
|
|
33
|
+
candidatePoolSize?: number;
|
|
34
|
+
rerank?: "cross-encoder" | "lightweight" | "none";
|
|
35
|
+
rerankApiKey?: string;
|
|
36
|
+
rerankModel?: string;
|
|
37
|
+
rerankEndpoint?: string;
|
|
38
|
+
rerankProvider?: string;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export interface MnemoInstance {
|
|
42
|
+
store(entry: {
|
|
43
|
+
text: string;
|
|
44
|
+
category?: string;
|
|
45
|
+
importance?: number;
|
|
46
|
+
scope?: string;
|
|
47
|
+
}): Promise<{
|
|
48
|
+
id: string;
|
|
49
|
+
}>;
|
|
50
|
+
recall(query: string, options?: {
|
|
51
|
+
limit?: number;
|
|
52
|
+
scopeFilter?: string[];
|
|
53
|
+
category?: string;
|
|
54
|
+
}): Promise<Array<{
|
|
55
|
+
text: string;
|
|
56
|
+
score: number;
|
|
57
|
+
category: string;
|
|
58
|
+
importance: number;
|
|
59
|
+
timestamp: number;
|
|
60
|
+
}>>;
|
|
61
|
+
stats(): Promise<{
|
|
62
|
+
totalEntries: number;
|
|
63
|
+
}>;
|
|
64
|
+
close(): Promise<void>;
|
|
65
|
+
}
|
|
66
|
+
export declare function createMnemo(config: MnemoConfig): Promise<MnemoInstance>;
|
|
67
|
+
//# sourceMappingURL=mnemo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mnemo.d.ts","sourceRoot":"","sources":["../../src/mnemo.ts"],"names":[],"mappings":"AACA;;;GAGG;AASH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE;QACT,QAAQ,EAAE,mBAAmB,CAAC;QAC9B,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE;QACN,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,IAAI,CAAC,EAAE;QACL,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,uBAAuB,CAAC,EAAE,MAAM,CAAC;QACjC,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF,GAAG,CAAC,EAAE;QACJ,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,SAAS,CAAC,EAAE;QACV,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,MAAM,CAAC,EAAE,eAAe,GAAG,aAAa,GAAG,MAAM,CAAC;QAClD,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,KAAK,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE5B,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;QACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,KAAK,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC,CAAC;IAEJ,KAAK,IAAI,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE3C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAkE7E"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { MemoryStore } from "./store.js";
|
|
2
|
+
import { createRetriever, DEFAULT_RETRIEVAL_CONFIG } from "./retriever.js";
|
|
3
|
+
import { Embedder } from "./embedder.js";
|
|
4
|
+
import { createDecayEngine, DEFAULT_DECAY_CONFIG } from "./decay-engine.js";
|
|
5
|
+
async function createMnemo(config) {
|
|
6
|
+
const embedder = new Embedder({
|
|
7
|
+
apiKey: config.embedding.apiKey,
|
|
8
|
+
baseURL: config.embedding.baseURL,
|
|
9
|
+
model: config.embedding.model || "voyage-3-large",
|
|
10
|
+
dimensions: config.embedding.dimensions || 1024,
|
|
11
|
+
taskQuery: config.embedding.taskQuery,
|
|
12
|
+
taskPassage: config.embedding.taskPassage
|
|
13
|
+
});
|
|
14
|
+
const store = new MemoryStore({
|
|
15
|
+
dbPath: config.dbPath,
|
|
16
|
+
embedder
|
|
17
|
+
});
|
|
18
|
+
await store.initialize();
|
|
19
|
+
const decayEngine = createDecayEngine({
|
|
20
|
+
...DEFAULT_DECAY_CONFIG,
|
|
21
|
+
...config.decay || {}
|
|
22
|
+
});
|
|
23
|
+
const retriever = createRetriever(store, embedder, {
|
|
24
|
+
...DEFAULT_RETRIEVAL_CONFIG,
|
|
25
|
+
...config.retrieval || {}
|
|
26
|
+
}, { decayEngine });
|
|
27
|
+
return {
|
|
28
|
+
async store(entry) {
|
|
29
|
+
const vector = await embedder.embed(entry.text);
|
|
30
|
+
const result = await store.store({
|
|
31
|
+
text: entry.text,
|
|
32
|
+
vector,
|
|
33
|
+
category: entry.category || "fact",
|
|
34
|
+
importance: entry.importance ?? 0.7,
|
|
35
|
+
scope: entry.scope || "global"
|
|
36
|
+
});
|
|
37
|
+
return { id: result.id };
|
|
38
|
+
},
|
|
39
|
+
async recall(query, options = {}) {
|
|
40
|
+
const results = await retriever.retrieve({
|
|
41
|
+
query,
|
|
42
|
+
limit: options.limit ?? 5,
|
|
43
|
+
scopeFilter: options.scopeFilter,
|
|
44
|
+
category: options.category,
|
|
45
|
+
source: "manual"
|
|
46
|
+
});
|
|
47
|
+
return results.map((r) => ({
|
|
48
|
+
text: r.entry.text,
|
|
49
|
+
score: r.score,
|
|
50
|
+
category: r.entry.category || "fact",
|
|
51
|
+
importance: r.entry.importance ?? 0.7,
|
|
52
|
+
timestamp: r.entry.timestamp ?? Date.now()
|
|
53
|
+
}));
|
|
54
|
+
},
|
|
55
|
+
async stats() {
|
|
56
|
+
const count = await store.count();
|
|
57
|
+
return { totalEntries: count };
|
|
58
|
+
},
|
|
59
|
+
async close() {
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export {
|
|
64
|
+
createMnemo
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=mnemo.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/mnemo.ts"],
|
|
4
|
+
"sourcesContent": ["// SPDX-License-Identifier: MIT\n/**\n * Mnemo Core \u2014 simplified entry point\n * Usage: const mnemo = await createMnemo(config)\n */\n\nimport { MemoryStore } from \"./store.js\";\nimport { createRetriever, DEFAULT_RETRIEVAL_CONFIG } from \"./retriever.js\";\nimport { Embedder } from \"./embedder.js\";\nimport { createDecayEngine, DEFAULT_DECAY_CONFIG } from \"./decay-engine.js\";\nimport { SmartExtractor } from \"./smart-extractor.js\";\nimport { createLlmClient } from \"./llm-client.js\";\n\nexport interface MnemoConfig {\n embedding: {\n provider: \"openai-compatible\";\n apiKey: string;\n baseURL?: string;\n model?: string;\n dimensions?: number;\n taskQuery?: string;\n taskPassage?: string;\n };\n dbPath: string;\n decay?: {\n recencyHalfLifeDays?: number;\n recencyWeight?: number;\n frequencyWeight?: number;\n intrinsicWeight?: number;\n };\n tier?: {\n coreAccessThreshold?: number;\n coreImportanceThreshold?: number;\n peripheralAgeDays?: number;\n };\n llm?: {\n model?: string;\n baseURL?: string;\n apiKey?: string;\n };\n retrieval?: {\n candidatePoolSize?: number;\n rerank?: \"cross-encoder\" | \"lightweight\" | \"none\";\n rerankApiKey?: string;\n rerankModel?: string;\n rerankEndpoint?: string;\n rerankProvider?: string;\n };\n}\n\nexport interface MnemoInstance {\n store(entry: {\n text: string;\n category?: string;\n importance?: number;\n scope?: string;\n }): Promise<{ id: string }>;\n\n recall(query: string, options?: {\n limit?: number;\n scopeFilter?: string[];\n category?: string;\n }): Promise<Array<{\n text: string;\n score: number;\n category: string;\n importance: number;\n timestamp: number;\n }>>;\n\n stats(): Promise<{ totalEntries: number }>;\n\n close(): Promise<void>;\n}\n\nexport async function createMnemo(config: MnemoConfig): Promise<MnemoInstance> {\n const embedder = new Embedder({\n apiKey: config.embedding.apiKey,\n baseURL: config.embedding.baseURL,\n model: config.embedding.model || \"voyage-3-large\",\n dimensions: config.embedding.dimensions || 1024,\n taskQuery: config.embedding.taskQuery,\n taskPassage: config.embedding.taskPassage,\n });\n\n const store = new MemoryStore({\n dbPath: config.dbPath,\n embedder,\n });\n\n await store.initialize();\n\n const decayEngine = createDecayEngine({\n ...DEFAULT_DECAY_CONFIG,\n ...(config.decay || {}),\n });\n\n const retriever = createRetriever(store, embedder, {\n ...DEFAULT_RETRIEVAL_CONFIG,\n ...(config.retrieval || {}),\n }, { decayEngine });\n\n return {\n async store(entry) {\n const vector = await embedder.embed(entry.text);\n const result = await store.store({\n text: entry.text,\n vector,\n category: entry.category || \"fact\",\n importance: entry.importance ?? 0.7,\n scope: entry.scope || \"global\",\n });\n return { id: result.id };\n },\n\n async recall(query, options = {}) {\n const results = await retriever.retrieve({\n query,\n limit: options.limit ?? 5,\n scopeFilter: options.scopeFilter,\n category: options.category,\n source: \"manual\",\n });\n return results.map(r => ({\n text: r.entry.text,\n score: r.score,\n category: r.entry.category || \"fact\",\n importance: r.entry.importance ?? 0.7,\n timestamp: r.entry.timestamp ?? Date.now(),\n }));\n },\n\n async stats() {\n const count = await store.count();\n return { totalEntries: count };\n },\n\n async close() {\n // LanceDB handles cleanup automatically\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "AAMA,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB,gCAAgC;AAC1D,SAAS,gBAAgB;AACzB,SAAS,mBAAmB,4BAA4B;AAkExD,eAAsB,YAAY,QAA6C;AAC7E,QAAM,WAAW,IAAI,SAAS;AAAA,IAC5B,QAAQ,OAAO,UAAU;AAAA,IACzB,SAAS,OAAO,UAAU;AAAA,IAC1B,OAAO,OAAO,UAAU,SAAS;AAAA,IACjC,YAAY,OAAO,UAAU,cAAc;AAAA,IAC3C,WAAW,OAAO,UAAU;AAAA,IAC5B,aAAa,OAAO,UAAU;AAAA,EAChC,CAAC;AAED,QAAM,QAAQ,IAAI,YAAY;AAAA,IAC5B,QAAQ,OAAO;AAAA,IACf;AAAA,EACF,CAAC;AAED,QAAM,MAAM,WAAW;AAEvB,QAAM,cAAc,kBAAkB;AAAA,IACpC,GAAG;AAAA,IACH,GAAI,OAAO,SAAS,CAAC;AAAA,EACvB,CAAC;AAED,QAAM,YAAY,gBAAgB,OAAO,UAAU;AAAA,IACjD,GAAG;AAAA,IACH,GAAI,OAAO,aAAa,CAAC;AAAA,EAC3B,GAAG,EAAE,YAAY,CAAC;AAElB,SAAO;AAAA,IACL,MAAM,MAAM,OAAO;AACjB,YAAM,SAAS,MAAM,SAAS,MAAM,MAAM,IAAI;AAC9C,YAAM,SAAS,MAAM,MAAM,MAAM;AAAA,QAC/B,MAAM,MAAM;AAAA,QACZ;AAAA,QACA,UAAU,MAAM,YAAY;AAAA,QAC5B,YAAY,MAAM,cAAc;AAAA,QAChC,OAAO,MAAM,SAAS;AAAA,MACxB,CAAC;AACD,aAAO,EAAE,IAAI,OAAO,GAAG;AAAA,IACzB;AAAA,IAEA,MAAM,OAAO,OAAO,UAAU,CAAC,GAAG;AAChC,YAAM,UAAU,MAAM,UAAU,SAAS;AAAA,QACvC;AAAA,QACA,OAAO,QAAQ,SAAS;AAAA,QACxB,aAAa,QAAQ;AAAA,QACrB,UAAU,QAAQ;AAAA,QAClB,QAAQ;AAAA,MACV,CAAC;AACD,aAAO,QAAQ,IAAI,QAAM;AAAA,QACvB,MAAM,EAAE,MAAM;AAAA,QACd,OAAO,EAAE;AAAA,QACT,UAAU,EAAE,MAAM,YAAY;AAAA,QAC9B,YAAY,EAAE,MAAM,cAAc;AAAA,QAClC,WAAW,EAAE,MAAM,aAAa,KAAK,IAAI;AAAA,MAC3C,EAAE;AAAA,IACJ;AAAA,IAEA,MAAM,QAAQ;AACZ,YAAM,QAAQ,MAAM,MAAM,MAAM;AAChC,aAAO,EAAE,cAAc,MAAM;AAAA,IAC/B;AAAA,IAEA,MAAM,QAAQ;AAAA,IAEd;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Noise Filter
|
|
3
|
+
* Filters out low-quality memories (meta-questions, agent denials, session boilerplate)
|
|
4
|
+
* Inspired by openclaw-plugin-continuity's noise filtering approach.
|
|
5
|
+
*/
|
|
6
|
+
export interface NoiseFilterOptions {
|
|
7
|
+
/** Filter agent denial responses (default: true) */
|
|
8
|
+
filterDenials?: boolean;
|
|
9
|
+
/** Filter meta-questions about memory (default: true) */
|
|
10
|
+
filterMetaQuestions?: boolean;
|
|
11
|
+
/** Filter session boilerplate (default: true) */
|
|
12
|
+
filterBoilerplate?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Check if a memory text is noise that should be filtered out.
|
|
16
|
+
* Returns true if the text is noise.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isNoise(text: string, options?: NoiseFilterOptions): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Filter an array of items, removing noise entries.
|
|
21
|
+
*/
|
|
22
|
+
export declare function filterNoise<T>(items: T[], getText: (item: T) => string, options?: NoiseFilterOptions): T[];
|
|
23
|
+
//# sourceMappingURL=noise-filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noise-filter.d.ts","sourceRoot":"","sources":["../../src/noise-filter.ts"],"names":[],"mappings":"AACA;;;;GAIG;AAgDH,MAAM,WAAW,kBAAkB;IACjC,oDAAoD;IACpD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,yDAAyD;IACzD,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,iDAAiD;IACjD,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAQD;;;GAGG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAY/E;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,KAAK,EAAE,CAAC,EAAE,EACV,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,EAC5B,OAAO,CAAC,EAAE,kBAAkB,GAC3B,CAAC,EAAE,CAGL"}
|