@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.
@@ -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 GLOBAL_CONFIG_PATH = (0, path_1.join)((0, os_1.homedir)(), '.memento', 'config');
17
- const LOCAL_CONFIG_FILE = '.mementorc';
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
- const configPath = (0, path_1.join)(currentDir, LOCAL_CONFIG_FILE);
36
- if ((0, fs_1.existsSync)(configPath)) {
37
- const config = loadJSONFile(configPath);
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
- return packageJson?.name || 'default';
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":"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"}
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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"}