@slorenzot/memento-core 0.7.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.es.md +446 -0
- package/README.md +117 -115
- package/dist/ConfigManager.d.ts +90 -0
- package/dist/ConfigManager.d.ts.map +1 -1
- package/dist/ConfigManager.js +263 -7
- package/dist/ConfigManager.js.map +1 -1
- package/dist/EmbeddingService.d.ts +54 -0
- package/dist/EmbeddingService.d.ts.map +1 -0
- package/dist/EmbeddingService.js +135 -0
- package/dist/EmbeddingService.js.map +1 -0
- package/dist/MemoryEngine.d.ts +238 -8
- package/dist/MemoryEngine.d.ts.map +1 -1
- package/dist/MemoryEngine.js +2267 -52
- package/dist/MemoryEngine.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +290 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +9 -4
- package/dist/db/schema.d.ts +0 -353
- package/dist/db/schema.d.ts.map +0 -1
- package/dist/db/schema.js +0 -40
- package/dist/db/schema.js.map +0 -1
- package/drizzle.config.ts +0 -10
- package/src/ConfigManager.test.ts +0 -248
- package/src/ConfigManager.ts +0 -131
- package/src/MemoryEngine.test.ts +0 -456
- package/src/MemoryEngine.ts +0 -450
- package/src/db/schema.js +0 -39
- package/src/db/schema.ts +0 -40
- package/src/index.ts +0 -3
- package/src/types.ts +0 -52
- package/tsconfig.json +0 -18
- package/tsconfig.json.bak +0 -30
package/dist/ConfigManager.js
CHANGED
|
@@ -1,20 +1,65 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LEGACY_CONFIG_FILE = exports.NEW_CONFIG_FILE = exports.NEW_CONFIG_DIR = exports.GLOBAL_CONFIG_PATH = exports.GLOBAL_CONFIG_DIR = exports.DEFAULT_STALE_THRESHOLD_MS = void 0;
|
|
4
|
+
exports.normalizeProjectId = normalizeProjectId;
|
|
3
5
|
exports.findProjectConfig = findProjectConfig;
|
|
6
|
+
exports.findConfigPath = findConfigPath;
|
|
7
|
+
exports.getStaleThresholdMs = getStaleThresholdMs;
|
|
4
8
|
exports.loadConfig = loadConfig;
|
|
5
9
|
exports.resolveStoragePath = resolveStoragePath;
|
|
6
10
|
exports.resolveDbPath = resolveDbPath;
|
|
7
11
|
exports.getProjectId = getProjectId;
|
|
12
|
+
exports.createConfig = createConfig;
|
|
13
|
+
exports.migrateConfig = migrateConfig;
|
|
8
14
|
const fs_1 = require("fs");
|
|
9
15
|
const path_1 = require("path");
|
|
10
16
|
const os_1 = require("os");
|
|
17
|
+
/** Default stale threshold: 24 hours in milliseconds */
|
|
18
|
+
exports.DEFAULT_STALE_THRESHOLD_MS = 24 * 60 * 60 * 1000;
|
|
19
|
+
// ─── Constants ──────────────────────────────────────────────
|
|
11
20
|
const DEFAULT_CONFIG = {
|
|
12
21
|
storageMethod: 'database',
|
|
13
22
|
dbPath: '.memento/db/memento.db',
|
|
14
23
|
storagePath: 'database/storage',
|
|
15
24
|
};
|
|
16
|
-
const
|
|
17
|
-
|
|
25
|
+
const LEGACY_CONFIG_FILE = '.mementorc';
|
|
26
|
+
exports.LEGACY_CONFIG_FILE = LEGACY_CONFIG_FILE;
|
|
27
|
+
const NEW_CONFIG_DIR = '.memento';
|
|
28
|
+
exports.NEW_CONFIG_DIR = NEW_CONFIG_DIR;
|
|
29
|
+
const NEW_CONFIG_FILE = 'config.json';
|
|
30
|
+
exports.NEW_CONFIG_FILE = NEW_CONFIG_FILE;
|
|
31
|
+
const GLOBAL_CONFIG_DIR = (0, path_1.join)((0, os_1.homedir)(), '.memento');
|
|
32
|
+
exports.GLOBAL_CONFIG_DIR = GLOBAL_CONFIG_DIR;
|
|
33
|
+
const GLOBAL_CONFIG_FILE = 'config.json';
|
|
34
|
+
const GLOBAL_CONFIG_PATH = (0, path_1.join)(GLOBAL_CONFIG_DIR, GLOBAL_CONFIG_FILE);
|
|
35
|
+
exports.GLOBAL_CONFIG_PATH = GLOBAL_CONFIG_PATH;
|
|
36
|
+
// ─── Project ID Normalization ──────────────────────────────
|
|
37
|
+
/**
|
|
38
|
+
* Normalize a project identifier to a canonical form.
|
|
39
|
+
* - Lowercase
|
|
40
|
+
* - Replace spaces, underscores, and special chars with hyphens
|
|
41
|
+
* - Collapse multiple consecutive hyphens into one
|
|
42
|
+
* - Strip leading/trailing hyphens
|
|
43
|
+
*
|
|
44
|
+
* Examples:
|
|
45
|
+
* "sura chile autos" → "sura-chile-autos"
|
|
46
|
+
* "suratech-salesforce-CL-app" → "suratech-salesforce-cl-app"
|
|
47
|
+
* "my__cool project" → "my-cool-project"
|
|
48
|
+
* "--leading-trailing--" → "leading-trailing"
|
|
49
|
+
* " spaces everywhere " → "spaces-everywhere"
|
|
50
|
+
*/
|
|
51
|
+
function normalizeProjectId(name) {
|
|
52
|
+
if (!name || typeof name !== 'string') {
|
|
53
|
+
return 'default';
|
|
54
|
+
}
|
|
55
|
+
return name
|
|
56
|
+
.trim()
|
|
57
|
+
.toLowerCase()
|
|
58
|
+
.replace(/[^a-z0-9]+/g, '-') // replace non-alphanumeric sequences with single hyphen
|
|
59
|
+
.replace(/^-+|-+$/g, '') // strip leading/trailing hyphens
|
|
60
|
+
|| 'default'; // fallback if result is empty
|
|
61
|
+
}
|
|
62
|
+
// ─── Internal Helpers ───────────────────────────────────────
|
|
18
63
|
function loadJSONFile(path) {
|
|
19
64
|
if (!(0, fs_1.existsSync)(path)) {
|
|
20
65
|
return null;
|
|
@@ -27,14 +72,46 @@ function loadJSONFile(path) {
|
|
|
27
72
|
return null;
|
|
28
73
|
}
|
|
29
74
|
}
|
|
75
|
+
function isConfigV1(config) {
|
|
76
|
+
return (typeof config === 'object' &&
|
|
77
|
+
config !== null &&
|
|
78
|
+
config.version === 1 &&
|
|
79
|
+
typeof config.project === 'string' &&
|
|
80
|
+
typeof config.database?.path === 'string');
|
|
81
|
+
}
|
|
82
|
+
function deriveProjectName(dir) {
|
|
83
|
+
// Try package.json first
|
|
84
|
+
const packageJsonPath = (0, path_1.join)(dir, 'package.json');
|
|
85
|
+
const packageJson = loadJSONFile(packageJsonPath);
|
|
86
|
+
if (packageJson?.name) {
|
|
87
|
+
// Strip @scope/ prefix
|
|
88
|
+
return packageJson.name.replace(/^@[^/]+\//, '');
|
|
89
|
+
}
|
|
90
|
+
// Fall back to directory name
|
|
91
|
+
return (0, path_1.basename)(dir);
|
|
92
|
+
}
|
|
93
|
+
// ─── Config Discovery ──────────────────────────────────────
|
|
94
|
+
/**
|
|
95
|
+
* Find project config searching upward from startDir.
|
|
96
|
+
* Priority: .memento/config.json → .mementorc (legacy)
|
|
97
|
+
*/
|
|
30
98
|
function findProjectConfig(startDir = process.cwd()) {
|
|
31
99
|
let currentDir = startDir;
|
|
32
100
|
const maxDepth = 10;
|
|
33
101
|
let depth = 0;
|
|
34
102
|
while (depth < maxDepth) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
103
|
+
// New format first: .memento/config.json
|
|
104
|
+
const newConfigPath = (0, path_1.join)(currentDir, NEW_CONFIG_DIR, NEW_CONFIG_FILE);
|
|
105
|
+
if ((0, fs_1.existsSync)(newConfigPath)) {
|
|
106
|
+
const config = loadJSONFile(newConfigPath);
|
|
107
|
+
if (isConfigV1(config)) {
|
|
108
|
+
return configV1ToLegacy(config, currentDir);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Legacy format: .mementorc
|
|
112
|
+
const legacyConfigPath = (0, path_1.join)(currentDir, LEGACY_CONFIG_FILE);
|
|
113
|
+
if ((0, fs_1.existsSync)(legacyConfigPath)) {
|
|
114
|
+
const config = loadJSONFile(legacyConfigPath);
|
|
38
115
|
if (config) {
|
|
39
116
|
return config;
|
|
40
117
|
}
|
|
@@ -48,6 +125,47 @@ function findProjectConfig(startDir = process.cwd()) {
|
|
|
48
125
|
}
|
|
49
126
|
return null;
|
|
50
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Find the raw config path (new or legacy format).
|
|
130
|
+
* Returns the absolute path to the config file found.
|
|
131
|
+
*/
|
|
132
|
+
function findConfigPath(startDir = process.cwd()) {
|
|
133
|
+
let currentDir = startDir;
|
|
134
|
+
const maxDepth = 10;
|
|
135
|
+
let depth = 0;
|
|
136
|
+
while (depth < maxDepth) {
|
|
137
|
+
const newConfigPath = (0, path_1.join)(currentDir, NEW_CONFIG_DIR, NEW_CONFIG_FILE);
|
|
138
|
+
if ((0, fs_1.existsSync)(newConfigPath))
|
|
139
|
+
return newConfigPath;
|
|
140
|
+
const legacyConfigPath = (0, path_1.join)(currentDir, LEGACY_CONFIG_FILE);
|
|
141
|
+
if ((0, fs_1.existsSync)(legacyConfigPath))
|
|
142
|
+
return legacyConfigPath;
|
|
143
|
+
const parentDir = (0, path_1.dirname)(currentDir);
|
|
144
|
+
if (parentDir === currentDir)
|
|
145
|
+
break;
|
|
146
|
+
currentDir = parentDir;
|
|
147
|
+
depth++;
|
|
148
|
+
}
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
// ─── Config Loading ─────────────────────────────────────────
|
|
152
|
+
/**
|
|
153
|
+
* Read the stale session threshold from V1 config.
|
|
154
|
+
* Returns DEFAULT_STALE_THRESHOLD_MS (24h) if not configured.
|
|
155
|
+
*/
|
|
156
|
+
function getStaleThresholdMs() {
|
|
157
|
+
const configPath = findConfigPath();
|
|
158
|
+
if (!configPath)
|
|
159
|
+
return exports.DEFAULT_STALE_THRESHOLD_MS;
|
|
160
|
+
// Only V1 config supports this setting
|
|
161
|
+
if (configPath.endsWith('config.json')) {
|
|
162
|
+
const v1 = loadJSONFile(configPath);
|
|
163
|
+
if (v1?.defaults?.session?.staleThresholdMs) {
|
|
164
|
+
return v1.defaults.session.staleThresholdMs;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return exports.DEFAULT_STALE_THRESHOLD_MS;
|
|
168
|
+
}
|
|
51
169
|
function loadConfig() {
|
|
52
170
|
let config = { ...DEFAULT_CONFIG };
|
|
53
171
|
const projectConfig = findProjectConfig();
|
|
@@ -58,6 +176,7 @@ function loadConfig() {
|
|
|
58
176
|
if (globalConfig) {
|
|
59
177
|
config = { ...config, ...globalConfig };
|
|
60
178
|
}
|
|
179
|
+
// Environment variable overrides
|
|
61
180
|
if (process.env.MEMENTO_STORAGE_METHOD) {
|
|
62
181
|
config.storageMethod = process.env.MEMENTO_STORAGE_METHOD;
|
|
63
182
|
}
|
|
@@ -72,6 +191,7 @@ function loadConfig() {
|
|
|
72
191
|
}
|
|
73
192
|
return config;
|
|
74
193
|
}
|
|
194
|
+
// ─── Path Resolution ────────────────────────────────────────
|
|
75
195
|
function resolveStoragePath(config) {
|
|
76
196
|
const storagePath = config.storagePath || DEFAULT_CONFIG.storagePath;
|
|
77
197
|
if (storagePath.startsWith('/')) {
|
|
@@ -94,10 +214,146 @@ function resolveDbPath(config) {
|
|
|
94
214
|
}
|
|
95
215
|
function getProjectId(config) {
|
|
96
216
|
if (config.projectId) {
|
|
97
|
-
return config.projectId;
|
|
217
|
+
return normalizeProjectId(config.projectId);
|
|
98
218
|
}
|
|
99
219
|
const packageJsonPath = (0, path_1.join)(process.cwd(), 'package.json');
|
|
100
220
|
const packageJson = loadJSONFile(packageJsonPath);
|
|
101
|
-
|
|
221
|
+
const rawName = packageJson?.name || 'default';
|
|
222
|
+
// Strip @scope/ prefix before normalizing (consistent with deriveProjectName)
|
|
223
|
+
return normalizeProjectId(rawName.replace(/^@[^/]+\//, ''));
|
|
224
|
+
}
|
|
225
|
+
// ─── Config V1 ↔ Legacy Conversion ─────────────────────────
|
|
226
|
+
function configV1ToLegacy(v1, _configDir) {
|
|
227
|
+
return {
|
|
228
|
+
storageMethod: 'database',
|
|
229
|
+
dbPath: v1.database.path,
|
|
230
|
+
projectId: v1.project,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function legacyToConfigV1(legacy, projectDir) {
|
|
234
|
+
return {
|
|
235
|
+
version: 1,
|
|
236
|
+
project: legacy.projectId || deriveProjectName(projectDir),
|
|
237
|
+
database: {
|
|
238
|
+
path: legacy.dbPath || (0, path_1.join)('.memento', 'memento.db'),
|
|
239
|
+
wal: true,
|
|
240
|
+
},
|
|
241
|
+
defaults: {
|
|
242
|
+
autoSeed: true,
|
|
243
|
+
scope: 'project',
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
// ─── Config Creation ────────────────────────────────────────
|
|
248
|
+
/**
|
|
249
|
+
* Create a new config file (.memento/config.json or global).
|
|
250
|
+
* Returns the result with paths and whether migration occurred.
|
|
251
|
+
*/
|
|
252
|
+
function createConfig(options = {}) {
|
|
253
|
+
const { project, dbPath, targetDir, force = false, global = false, } = options;
|
|
254
|
+
const resolvedDir = global
|
|
255
|
+
? GLOBAL_CONFIG_DIR
|
|
256
|
+
: (targetDir || process.cwd());
|
|
257
|
+
const configDir = global
|
|
258
|
+
? GLOBAL_CONFIG_DIR
|
|
259
|
+
: (0, path_1.join)(resolvedDir, NEW_CONFIG_DIR);
|
|
260
|
+
const configPath = (0, path_1.join)(configDir, NEW_CONFIG_FILE);
|
|
261
|
+
// Check existing config
|
|
262
|
+
if (!force && (0, fs_1.existsSync)(configPath)) {
|
|
263
|
+
throw new Error(`Config already exists at ${configPath}. Use --force to overwrite.`);
|
|
264
|
+
}
|
|
265
|
+
// Check for legacy config to migrate
|
|
266
|
+
let migrated = false;
|
|
267
|
+
let backupPath;
|
|
268
|
+
const legacyPath = (0, path_1.join)(resolvedDir, LEGACY_CONFIG_FILE);
|
|
269
|
+
let projectName = project || deriveProjectName(resolvedDir);
|
|
270
|
+
let resolvedDbPath = dbPath || (0, path_1.join)(NEW_CONFIG_DIR, 'memento.db');
|
|
271
|
+
// If migrating from legacy config
|
|
272
|
+
if (!global && (0, fs_1.existsSync)(legacyPath)) {
|
|
273
|
+
const legacyConfig = loadJSONFile(legacyPath);
|
|
274
|
+
if (legacyConfig) {
|
|
275
|
+
if (!project)
|
|
276
|
+
projectName = legacyConfig.projectId || projectName;
|
|
277
|
+
if (!dbPath && legacyConfig.dbPath) {
|
|
278
|
+
// Keep existing DB path from legacy config
|
|
279
|
+
resolvedDbPath = legacyConfig.dbPath;
|
|
280
|
+
}
|
|
281
|
+
migrated = true;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// Build V1 config
|
|
285
|
+
const config = {
|
|
286
|
+
version: 1,
|
|
287
|
+
project: projectName,
|
|
288
|
+
database: {
|
|
289
|
+
path: resolvedDbPath,
|
|
290
|
+
wal: true,
|
|
291
|
+
},
|
|
292
|
+
defaults: {
|
|
293
|
+
autoSeed: true,
|
|
294
|
+
scope: global ? 'personal' : 'project',
|
|
295
|
+
},
|
|
296
|
+
};
|
|
297
|
+
// Write config
|
|
298
|
+
(0, fs_1.mkdirSync)(configDir, { recursive: true });
|
|
299
|
+
(0, fs_1.writeFileSync)(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
300
|
+
return {
|
|
301
|
+
configPath,
|
|
302
|
+
dbPath: global
|
|
303
|
+
? (0, path_1.join)(GLOBAL_CONFIG_DIR, resolvedDbPath)
|
|
304
|
+
: (0, path_1.join)(resolvedDir, resolvedDbPath),
|
|
305
|
+
projectDir: resolvedDir,
|
|
306
|
+
migrated,
|
|
307
|
+
backupPath,
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
// ─── Config Migration ──────────────────────────────────────
|
|
311
|
+
/**
|
|
312
|
+
* Migrate a legacy .mementorc to the new .memento/config.json format.
|
|
313
|
+
* Backs up the original file as .mementorc.bak.
|
|
314
|
+
*/
|
|
315
|
+
function migrateConfig(sourceDir = process.cwd()) {
|
|
316
|
+
const sourcePath = (0, path_1.join)(sourceDir, LEGACY_CONFIG_FILE);
|
|
317
|
+
const targetDir = (0, path_1.join)(sourceDir, NEW_CONFIG_DIR);
|
|
318
|
+
const targetPath = (0, path_1.join)(targetDir, NEW_CONFIG_FILE);
|
|
319
|
+
const backupPath = sourcePath + '.bak';
|
|
320
|
+
// Validate source exists
|
|
321
|
+
if (!(0, fs_1.existsSync)(sourcePath)) {
|
|
322
|
+
return {
|
|
323
|
+
success: false,
|
|
324
|
+
sourcePath,
|
|
325
|
+
targetPath,
|
|
326
|
+
backupPath,
|
|
327
|
+
config: {},
|
|
328
|
+
error: `No .mementorc found at ${sourcePath}`,
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
// Load and validate legacy config
|
|
332
|
+
const legacyConfig = loadJSONFile(sourcePath);
|
|
333
|
+
if (!legacyConfig) {
|
|
334
|
+
return {
|
|
335
|
+
success: false,
|
|
336
|
+
sourcePath,
|
|
337
|
+
targetPath,
|
|
338
|
+
backupPath,
|
|
339
|
+
config: {},
|
|
340
|
+
error: `Failed to parse ${sourcePath}`,
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
// Convert to V1
|
|
344
|
+
const v1Config = legacyToConfigV1(legacyConfig, sourceDir);
|
|
345
|
+
// Create target directory
|
|
346
|
+
(0, fs_1.mkdirSync)(targetDir, { recursive: true });
|
|
347
|
+
// Write new config
|
|
348
|
+
(0, fs_1.writeFileSync)(targetPath, JSON.stringify(v1Config, null, 2) + '\n', 'utf-8');
|
|
349
|
+
// Backup original
|
|
350
|
+
(0, fs_1.renameSync)(sourcePath, backupPath);
|
|
351
|
+
return {
|
|
352
|
+
success: true,
|
|
353
|
+
sourcePath,
|
|
354
|
+
targetPath,
|
|
355
|
+
backupPath,
|
|
356
|
+
config: v1Config,
|
|
357
|
+
};
|
|
102
358
|
}
|
|
103
359
|
//# sourceMappingURL=ConfigManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfigManager.js","sourceRoot":"","sources":["../src/ConfigManager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ConfigManager.js","sourceRoot":"","sources":["../src/ConfigManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EmbeddingService.ts — Local embedding generation with graceful degradation.
|
|
3
|
+
*
|
|
4
|
+
* Uses @huggingface/transformers (optional peer dependency) to generate
|
|
5
|
+
* 384-dim embeddings via Xenova/all-MiniLM-L6-v2.
|
|
6
|
+
*
|
|
7
|
+
* If the library is not installed, all operations return null/empty
|
|
8
|
+
* and the system falls back to FTS5 keyword search.
|
|
9
|
+
*
|
|
10
|
+
* Privacy: Zero network requests after initial model download (cached).
|
|
11
|
+
*/
|
|
12
|
+
export interface EmbeddingResult {
|
|
13
|
+
embedding: Float32Array;
|
|
14
|
+
dimensions: number;
|
|
15
|
+
model: string;
|
|
16
|
+
}
|
|
17
|
+
export interface EmbeddingStatus {
|
|
18
|
+
available: boolean;
|
|
19
|
+
model: string | null;
|
|
20
|
+
error: string | null;
|
|
21
|
+
}
|
|
22
|
+
export declare class EmbeddingService {
|
|
23
|
+
private embedFn;
|
|
24
|
+
private initPromise;
|
|
25
|
+
private modelName;
|
|
26
|
+
private dimensions;
|
|
27
|
+
private _status;
|
|
28
|
+
get status(): EmbeddingStatus;
|
|
29
|
+
/**
|
|
30
|
+
* Initialize the embedding model lazily.
|
|
31
|
+
* Safe to call multiple times — only initializes once.
|
|
32
|
+
*/
|
|
33
|
+
initialize(): Promise<void>;
|
|
34
|
+
private _initialize;
|
|
35
|
+
/**
|
|
36
|
+
* Generate embedding for a text string.
|
|
37
|
+
* Returns null if embedding service is unavailable.
|
|
38
|
+
*/
|
|
39
|
+
generate(text: string): Promise<EmbeddingResult | null>;
|
|
40
|
+
/**
|
|
41
|
+
* Serialize Float32Array to Buffer for SQLite BLOB storage.
|
|
42
|
+
*/
|
|
43
|
+
static serializeEmbedding(embedding: Float32Array): Buffer;
|
|
44
|
+
/**
|
|
45
|
+
* Deserialize SQLite BLOB to Float32Array.
|
|
46
|
+
*/
|
|
47
|
+
static deserializeEmbedding(blob: Buffer | Uint8Array, dimensions: number): Float32Array;
|
|
48
|
+
/**
|
|
49
|
+
* Calculate cosine similarity between two embeddings.
|
|
50
|
+
* Returns value in [-1, 1] range.
|
|
51
|
+
*/
|
|
52
|
+
static cosineSimilarity(a: Float32Array, b: Float32Array): number;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=EmbeddingService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmbeddingService.d.ts","sourceRoot":"","sources":["../src/EmbeddingService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,YAAY,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAID,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,UAAU,CAAO;IACzB,OAAO,CAAC,OAAO,CAIb;IAEF,IAAI,MAAM,IAAI,eAAe,CAE5B;IAED;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAOnB,WAAW;IA8CzB;;;OAGG;IACG,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAoB7D;;OAEG;IACH,MAAM,CAAC,kBAAkB,CAAC,SAAS,EAAE,YAAY,GAAG,MAAM;IAI1D;;OAEG;IACH,MAAM,CAAC,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,YAAY;IAQxF;;;OAGG;IACH,MAAM,CAAC,gBAAgB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,GAAG,MAAM;CAkBlE"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* EmbeddingService.ts — Local embedding generation with graceful degradation.
|
|
4
|
+
*
|
|
5
|
+
* Uses @huggingface/transformers (optional peer dependency) to generate
|
|
6
|
+
* 384-dim embeddings via Xenova/all-MiniLM-L6-v2.
|
|
7
|
+
*
|
|
8
|
+
* If the library is not installed, all operations return null/empty
|
|
9
|
+
* and the system falls back to FTS5 keyword search.
|
|
10
|
+
*
|
|
11
|
+
* Privacy: Zero network requests after initial model download (cached).
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.EmbeddingService = void 0;
|
|
15
|
+
class EmbeddingService {
|
|
16
|
+
embedFn = null;
|
|
17
|
+
initPromise = null;
|
|
18
|
+
modelName = 'Xenova/all-MiniLM-L6-v2';
|
|
19
|
+
dimensions = 384;
|
|
20
|
+
_status = {
|
|
21
|
+
available: false,
|
|
22
|
+
model: null,
|
|
23
|
+
error: null,
|
|
24
|
+
};
|
|
25
|
+
get status() {
|
|
26
|
+
return this._status;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Initialize the embedding model lazily.
|
|
30
|
+
* Safe to call multiple times — only initializes once.
|
|
31
|
+
*/
|
|
32
|
+
async initialize() {
|
|
33
|
+
if (this.initPromise)
|
|
34
|
+
return this.initPromise;
|
|
35
|
+
this.initPromise = this._initialize();
|
|
36
|
+
return this.initPromise;
|
|
37
|
+
}
|
|
38
|
+
async _initialize() {
|
|
39
|
+
try {
|
|
40
|
+
// Dynamic import — if @huggingface/transformers is not installed,
|
|
41
|
+
// this will fail gracefully
|
|
42
|
+
const transformers = await import('@huggingface/transformers');
|
|
43
|
+
const pipeline = transformers.pipeline ||
|
|
44
|
+
transformers.default?.pipeline;
|
|
45
|
+
if (!pipeline) {
|
|
46
|
+
throw new Error('pipeline function not found in @huggingface/transformers');
|
|
47
|
+
}
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
49
|
+
const extractor = await pipeline('feature-extraction', this.modelName, { quantized: true });
|
|
50
|
+
this.embedFn = async (text) => {
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
52
|
+
const output = await extractor(text, { pooling: 'mean', normalize: true });
|
|
53
|
+
// Extract the tensor data as Float32Array
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
55
|
+
const data = output.data || output.tolist?.() || output;
|
|
56
|
+
if (data instanceof Float32Array)
|
|
57
|
+
return data;
|
|
58
|
+
// Fallback: convert from regular array
|
|
59
|
+
return new Float32Array(Array.isArray(data) ? data : Array.from(data));
|
|
60
|
+
};
|
|
61
|
+
this._status = {
|
|
62
|
+
available: true,
|
|
63
|
+
model: this.modelName,
|
|
64
|
+
error: null,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
69
|
+
this._status = {
|
|
70
|
+
available: false,
|
|
71
|
+
model: null,
|
|
72
|
+
error: message,
|
|
73
|
+
};
|
|
74
|
+
// Don't throw — graceful degradation
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Generate embedding for a text string.
|
|
79
|
+
* Returns null if embedding service is unavailable.
|
|
80
|
+
*/
|
|
81
|
+
async generate(text) {
|
|
82
|
+
if (!this.embedFn) {
|
|
83
|
+
await this.initialize();
|
|
84
|
+
if (!this.embedFn)
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
// Truncate to 512 tokens worth of text (~2000 chars)
|
|
89
|
+
const truncated = text.length > 2000 ? text.slice(0, 2000) : text;
|
|
90
|
+
const embedding = await this.embedFn(truncated);
|
|
91
|
+
return {
|
|
92
|
+
embedding,
|
|
93
|
+
dimensions: this.dimensions,
|
|
94
|
+
model: this.modelName,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Serialize Float32Array to Buffer for SQLite BLOB storage.
|
|
103
|
+
*/
|
|
104
|
+
static serializeEmbedding(embedding) {
|
|
105
|
+
return Buffer.from(embedding.buffer, embedding.byteOffset, embedding.byteLength);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Deserialize SQLite BLOB to Float32Array.
|
|
109
|
+
*/
|
|
110
|
+
static deserializeEmbedding(blob, dimensions) {
|
|
111
|
+
return new Float32Array((blob instanceof Buffer ? blob : Buffer.from(blob)).buffer, (blob instanceof Buffer ? blob : Buffer.from(blob)).byteOffset, dimensions);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Calculate cosine similarity between two embeddings.
|
|
115
|
+
* Returns value in [-1, 1] range.
|
|
116
|
+
*/
|
|
117
|
+
static cosineSimilarity(a, b) {
|
|
118
|
+
if (a.length !== b.length)
|
|
119
|
+
return 0;
|
|
120
|
+
let dotProduct = 0;
|
|
121
|
+
let normA = 0;
|
|
122
|
+
let normB = 0;
|
|
123
|
+
for (let i = 0; i < a.length; i++) {
|
|
124
|
+
dotProduct += a[i] * b[i];
|
|
125
|
+
normA += a[i] * a[i];
|
|
126
|
+
normB += b[i] * b[i];
|
|
127
|
+
}
|
|
128
|
+
const denominator = Math.sqrt(normA) * Math.sqrt(normB);
|
|
129
|
+
if (denominator === 0)
|
|
130
|
+
return 0;
|
|
131
|
+
return dotProduct / denominator;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
exports.EmbeddingService = EmbeddingService;
|
|
135
|
+
//# sourceMappingURL=EmbeddingService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmbeddingService.js","sourceRoot":"","sources":["../src/EmbeddingService.ts"],"names":[],"mappings":"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"}
|