@zabaca/lattice 1.0.20 → 1.0.22
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/main.js +42 -137
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -989,29 +989,6 @@ class GraphService {
|
|
|
989
989
|
return [];
|
|
990
990
|
}
|
|
991
991
|
}
|
|
992
|
-
async findNodesWithMissingEmbeddings(labels) {
|
|
993
|
-
try {
|
|
994
|
-
const conn = await this.ensureConnected();
|
|
995
|
-
const labelFilter = labels.map((l) => `'${this.escape(l)}'`).join(", ");
|
|
996
|
-
const reader = await conn.runAndReadAll(`
|
|
997
|
-
SELECT label, name, properties->>'description' as description
|
|
998
|
-
FROM nodes
|
|
999
|
-
WHERE label IN (${labelFilter})
|
|
1000
|
-
AND embedding IS NULL
|
|
1001
|
-
`);
|
|
1002
|
-
return reader.getRows().map((row) => {
|
|
1003
|
-
const [label, name, description] = row;
|
|
1004
|
-
return {
|
|
1005
|
-
label,
|
|
1006
|
-
name,
|
|
1007
|
-
description: description || undefined
|
|
1008
|
-
};
|
|
1009
|
-
});
|
|
1010
|
-
} catch (error) {
|
|
1011
|
-
this.logger.error(`Failed to find nodes with missing embeddings: ${error instanceof Error ? error.message : String(error)}`);
|
|
1012
|
-
return [];
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
992
|
}
|
|
1016
993
|
GraphService = __legacyDecorateClassTS([
|
|
1017
994
|
Injectable4(),
|
|
@@ -1312,13 +1289,18 @@ class VoyageEmbeddingProvider {
|
|
|
1312
1289
|
class EmbeddingService {
|
|
1313
1290
|
configService;
|
|
1314
1291
|
logger = new Logger3(EmbeddingService.name);
|
|
1315
|
-
provider;
|
|
1292
|
+
provider = null;
|
|
1316
1293
|
config;
|
|
1317
1294
|
constructor(configService) {
|
|
1318
1295
|
this.configService = configService;
|
|
1319
1296
|
this.config = this.loadConfig();
|
|
1320
|
-
|
|
1321
|
-
|
|
1297
|
+
}
|
|
1298
|
+
getProvider() {
|
|
1299
|
+
if (!this.provider) {
|
|
1300
|
+
this.provider = this.createProvider();
|
|
1301
|
+
this.logger.log(`Initialized embedding provider: ${this.provider.name}`);
|
|
1302
|
+
}
|
|
1303
|
+
return this.provider;
|
|
1322
1304
|
}
|
|
1323
1305
|
loadConfig() {
|
|
1324
1306
|
const providerEnv = this.configService.get("EMBEDDING_PROVIDER");
|
|
@@ -1365,35 +1347,36 @@ class EmbeddingService {
|
|
|
1365
1347
|
}
|
|
1366
1348
|
}
|
|
1367
1349
|
getProviderName() {
|
|
1368
|
-
return this.
|
|
1350
|
+
return this.getProvider().name;
|
|
1369
1351
|
}
|
|
1370
1352
|
getDimensions() {
|
|
1371
|
-
return this.
|
|
1353
|
+
return this.getProvider().dimensions;
|
|
1372
1354
|
}
|
|
1373
1355
|
async generateEmbedding(text) {
|
|
1374
1356
|
if (!text || text.trim().length === 0) {
|
|
1375
1357
|
throw new Error("Cannot generate embedding for empty text");
|
|
1376
1358
|
}
|
|
1377
|
-
return this.
|
|
1359
|
+
return this.getProvider().generateEmbedding(text);
|
|
1378
1360
|
}
|
|
1379
1361
|
async generateQueryEmbedding(text) {
|
|
1380
1362
|
if (!text || text.trim().length === 0) {
|
|
1381
1363
|
throw new Error("Cannot generate embedding for empty text");
|
|
1382
1364
|
}
|
|
1383
|
-
|
|
1384
|
-
|
|
1365
|
+
const provider = this.getProvider();
|
|
1366
|
+
if (provider.generateQueryEmbedding) {
|
|
1367
|
+
return provider.generateQueryEmbedding(text);
|
|
1385
1368
|
}
|
|
1386
|
-
return
|
|
1369
|
+
return provider.generateEmbedding(text);
|
|
1387
1370
|
}
|
|
1388
1371
|
async generateEmbeddings(texts) {
|
|
1389
1372
|
const validTexts = texts.filter((t) => t && t.trim().length > 0);
|
|
1390
1373
|
if (validTexts.length === 0) {
|
|
1391
1374
|
return [];
|
|
1392
1375
|
}
|
|
1393
|
-
return this.
|
|
1376
|
+
return this.getProvider().generateEmbeddings(validTexts);
|
|
1394
1377
|
}
|
|
1395
1378
|
isRealProvider() {
|
|
1396
|
-
return this.
|
|
1379
|
+
return this.getProvider().name !== "mock";
|
|
1397
1380
|
}
|
|
1398
1381
|
}
|
|
1399
1382
|
EmbeddingService = __legacyDecorateClassTS([
|
|
@@ -2059,6 +2042,11 @@ class DatabaseChangeDetectorService {
|
|
|
2059
2042
|
this.hashCache.clear();
|
|
2060
2043
|
this.loaded = false;
|
|
2061
2044
|
}
|
|
2045
|
+
clearEntries(paths) {
|
|
2046
|
+
for (const path2 of paths) {
|
|
2047
|
+
this.hashCache.delete(path2);
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2062
2050
|
getContentHash(content) {
|
|
2063
2051
|
return createHash3("sha256").update(content).digest("hex");
|
|
2064
2052
|
}
|
|
@@ -2236,30 +2224,30 @@ class SyncService {
|
|
|
2236
2224
|
embeddingsGenerated: 0,
|
|
2237
2225
|
entityEmbeddingsGenerated: 0
|
|
2238
2226
|
};
|
|
2239
|
-
const
|
|
2240
|
-
const useAiExtraction = options.legacy ? false : options.aiExtraction ?? true;
|
|
2227
|
+
const useAiExtraction = options.aiExtraction ?? true;
|
|
2241
2228
|
try {
|
|
2242
2229
|
await this.manifest.load();
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
this.logger.log(`v2 mode: Loaded ${this.dbChangeDetector.getCacheSize()} document hashes from database`);
|
|
2247
|
-
}
|
|
2230
|
+
await this.dbChangeDetector.loadHashes();
|
|
2231
|
+
if (options.verbose) {
|
|
2232
|
+
this.logger.log(`Loaded ${this.dbChangeDetector.getCacheSize()} document hashes from database`);
|
|
2248
2233
|
}
|
|
2249
2234
|
if (options.force) {
|
|
2250
2235
|
if (options.paths && options.paths.length > 0) {
|
|
2236
|
+
const normalizedPaths = this.pathResolver.resolveDocPaths(options.paths, { requireExists: true, requireInDocs: true });
|
|
2251
2237
|
if (options.verbose) {
|
|
2252
|
-
this.logger.log(`Force mode: marking ${
|
|
2238
|
+
this.logger.log(`Force mode: marking ${normalizedPaths.length} document(s) for re-sync`);
|
|
2253
2239
|
}
|
|
2254
2240
|
await this.clearManifestEntries(options.paths);
|
|
2241
|
+
this.dbChangeDetector.clearEntries(normalizedPaths);
|
|
2255
2242
|
} else {
|
|
2256
2243
|
if (options.verbose) {
|
|
2257
|
-
this.logger.log("Force mode: clearing
|
|
2244
|
+
this.logger.log("Force mode: clearing tracking data to force full re-sync");
|
|
2258
2245
|
}
|
|
2259
2246
|
await this.clearManifest();
|
|
2247
|
+
this.dbChangeDetector.reset();
|
|
2260
2248
|
}
|
|
2261
2249
|
}
|
|
2262
|
-
const changes = await this.detectChanges(options.paths
|
|
2250
|
+
const changes = await this.detectChanges(options.paths);
|
|
2263
2251
|
result.changes = changes;
|
|
2264
2252
|
const docsToSync = [];
|
|
2265
2253
|
const docsByPath = new Map;
|
|
@@ -2328,10 +2316,6 @@ class SyncService {
|
|
|
2328
2316
|
}
|
|
2329
2317
|
if (!options.dryRun) {
|
|
2330
2318
|
result.entityEmbeddingsGenerated = await this.syncEntities(uniqueEntities, options);
|
|
2331
|
-
if (options.embeddings && !options.skipEmbeddings && this.embeddingService) {
|
|
2332
|
-
const repairedCount = await this.repairMissingEntityEmbeddings(options);
|
|
2333
|
-
result.entityEmbeddingsGenerated += repairedCount;
|
|
2334
|
-
}
|
|
2335
2319
|
await this.graph.checkpoint();
|
|
2336
2320
|
if (options.verbose) {
|
|
2337
2321
|
this.logger.log(`Synced ${uniqueEntities.size} entities, generated ${result.entityEmbeddingsGenerated} embeddings`);
|
|
@@ -2379,7 +2363,7 @@ class SyncService {
|
|
|
2379
2363
|
result.duration = Date.now() - startTime;
|
|
2380
2364
|
return result;
|
|
2381
2365
|
}
|
|
2382
|
-
async detectChanges(paths
|
|
2366
|
+
async detectChanges(paths) {
|
|
2383
2367
|
const changes = [];
|
|
2384
2368
|
let allDocPaths = await this.parser.discoverDocuments();
|
|
2385
2369
|
if (paths && paths.length > 0) {
|
|
@@ -2390,11 +2374,11 @@ class SyncService {
|
|
|
2390
2374
|
const pathSet = new Set(normalizedPaths);
|
|
2391
2375
|
allDocPaths = allDocPaths.filter((p) => pathSet.has(p));
|
|
2392
2376
|
}
|
|
2393
|
-
const trackedPaths = new Set(
|
|
2377
|
+
const trackedPaths = new Set(this.dbChangeDetector.getTrackedPaths());
|
|
2394
2378
|
for (const docPath of allDocPaths) {
|
|
2395
2379
|
try {
|
|
2396
2380
|
const doc = await this.parser.parseDocument(docPath);
|
|
2397
|
-
const changeType =
|
|
2381
|
+
const changeType = this.dbChangeDetector.detectChange(docPath, doc.contentHash);
|
|
2398
2382
|
changes.push({
|
|
2399
2383
|
path: docPath,
|
|
2400
2384
|
changeType,
|
|
@@ -2551,11 +2535,8 @@ class SyncService {
|
|
|
2551
2535
|
change.embeddingGenerated = embeddingGenerated;
|
|
2552
2536
|
const currentDoc = await this.parser.parseDocument(change.path);
|
|
2553
2537
|
this.manifest.updateEntry(currentDoc.path, currentDoc.contentHash, currentDoc.frontmatterHash, currentDoc.entities.length, currentDoc.relationships.length);
|
|
2554
|
-
const
|
|
2555
|
-
|
|
2556
|
-
const embeddingSourceHash = embeddingGenerated ? currentDoc.contentHash : undefined;
|
|
2557
|
-
await this.graph.updateDocumentHashes(currentDoc.path, currentDoc.contentHash, embeddingSourceHash);
|
|
2558
|
-
}
|
|
2538
|
+
const embeddingSourceHash = embeddingGenerated ? currentDoc.contentHash : undefined;
|
|
2539
|
+
await this.graph.updateDocumentHashes(currentDoc.path, currentDoc.contentHash, embeddingSourceHash);
|
|
2559
2540
|
break;
|
|
2560
2541
|
}
|
|
2561
2542
|
case "deleted": {
|
|
@@ -2640,43 +2621,6 @@ class SyncService {
|
|
|
2640
2621
|
}
|
|
2641
2622
|
}
|
|
2642
2623
|
}
|
|
2643
|
-
async repairMissingEntityEmbeddings(options) {
|
|
2644
|
-
if (!this.embeddingService) {
|
|
2645
|
-
return 0;
|
|
2646
|
-
}
|
|
2647
|
-
const labelsToCheck = [...ENTITY_TYPES, "Document"];
|
|
2648
|
-
const nodesWithMissingEmbeddings = await this.graph.findNodesWithMissingEmbeddings(labelsToCheck);
|
|
2649
|
-
if (nodesWithMissingEmbeddings.length === 0) {
|
|
2650
|
-
return 0;
|
|
2651
|
-
}
|
|
2652
|
-
if (options.verbose) {
|
|
2653
|
-
this.logger.log(`Found ${nodesWithMissingEmbeddings.length} nodes with missing embeddings, repairing...`);
|
|
2654
|
-
}
|
|
2655
|
-
let repairedCount = 0;
|
|
2656
|
-
for (const node of nodesWithMissingEmbeddings) {
|
|
2657
|
-
try {
|
|
2658
|
-
const text = node.label === "Document" ? node.name : composeEntityEmbeddingText({
|
|
2659
|
-
type: node.label,
|
|
2660
|
-
name: node.name,
|
|
2661
|
-
description: node.description,
|
|
2662
|
-
documentPaths: []
|
|
2663
|
-
});
|
|
2664
|
-
if (text.trim()) {
|
|
2665
|
-
const embedding = await this.embeddingService.generateEmbedding(text);
|
|
2666
|
-
await this.graph.updateNodeEmbedding(node.label, node.name, embedding);
|
|
2667
|
-
repairedCount++;
|
|
2668
|
-
this.logger.debug(`Repaired embedding for ${node.label}:${node.name}`);
|
|
2669
|
-
}
|
|
2670
|
-
} catch (error) {
|
|
2671
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2672
|
-
this.logger.warn(`Failed to repair embedding for ${node.label}:${node.name}: ${errorMessage}`);
|
|
2673
|
-
}
|
|
2674
|
-
}
|
|
2675
|
-
if (options.verbose && repairedCount > 0) {
|
|
2676
|
-
this.logger.log(`Repaired ${repairedCount} missing embeddings`);
|
|
2677
|
-
}
|
|
2678
|
-
return repairedCount;
|
|
2679
|
-
}
|
|
2680
2624
|
}
|
|
2681
2625
|
SyncService = __legacyDecorateClassTS([
|
|
2682
2626
|
Injectable11(),
|
|
@@ -2743,7 +2687,6 @@ class MigrateCommand extends CommandRunner3 {
|
|
|
2743
2687
|
if (!options.dryRun) {
|
|
2744
2688
|
const result = await this.syncService.sync({
|
|
2745
2689
|
force: false,
|
|
2746
|
-
useDbChangeDetection: true,
|
|
2747
2690
|
aiExtraction: true,
|
|
2748
2691
|
verbose: options.verbose,
|
|
2749
2692
|
embeddings: true
|
|
@@ -3182,23 +3125,16 @@ import { Injectable as Injectable16 } from "@nestjs/common";
|
|
|
3182
3125
|
import { Command as Command6, CommandRunner as CommandRunner6, Option as Option4 } from "nest-commander";
|
|
3183
3126
|
class StatusCommand extends CommandRunner6 {
|
|
3184
3127
|
syncService;
|
|
3185
|
-
manifestService;
|
|
3186
3128
|
dbChangeDetector;
|
|
3187
|
-
constructor(syncService,
|
|
3129
|
+
constructor(syncService, dbChangeDetector) {
|
|
3188
3130
|
super();
|
|
3189
3131
|
this.syncService = syncService;
|
|
3190
|
-
this.manifestService = manifestService;
|
|
3191
3132
|
this.dbChangeDetector = dbChangeDetector;
|
|
3192
3133
|
}
|
|
3193
3134
|
async run(_inputs, options) {
|
|
3194
3135
|
try {
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
await this.dbChangeDetector.loadHashes();
|
|
3198
|
-
} else {
|
|
3199
|
-
await this.manifestService.load();
|
|
3200
|
-
}
|
|
3201
|
-
const changes = await this.syncService.detectChanges(undefined, useDbDetection);
|
|
3136
|
+
await this.dbChangeDetector.loadHashes();
|
|
3137
|
+
const changes = await this.syncService.detectChanges();
|
|
3202
3138
|
const newDocs = changes.filter((c) => c.changeType === "new");
|
|
3203
3139
|
const updatedDocs = changes.filter((c) => c.changeType === "updated");
|
|
3204
3140
|
const deletedDocs = changes.filter((c) => c.changeType === "deleted");
|
|
@@ -3251,9 +3187,6 @@ class StatusCommand extends CommandRunner6 {
|
|
|
3251
3187
|
parseVerbose() {
|
|
3252
3188
|
return true;
|
|
3253
3189
|
}
|
|
3254
|
-
parseLegacy() {
|
|
3255
|
-
return true;
|
|
3256
|
-
}
|
|
3257
3190
|
}
|
|
3258
3191
|
__legacyDecorateClassTS([
|
|
3259
3192
|
Option4({
|
|
@@ -3264,15 +3197,6 @@ __legacyDecorateClassTS([
|
|
|
3264
3197
|
__legacyMetadataTS("design:paramtypes", []),
|
|
3265
3198
|
__legacyMetadataTS("design:returntype", Boolean)
|
|
3266
3199
|
], StatusCommand.prototype, "parseVerbose", null);
|
|
3267
|
-
__legacyDecorateClassTS([
|
|
3268
|
-
Option4({
|
|
3269
|
-
flags: "--legacy",
|
|
3270
|
-
description: "Use legacy v1 mode: manifest-based change detection"
|
|
3271
|
-
}),
|
|
3272
|
-
__legacyMetadataTS("design:type", Function),
|
|
3273
|
-
__legacyMetadataTS("design:paramtypes", []),
|
|
3274
|
-
__legacyMetadataTS("design:returntype", Boolean)
|
|
3275
|
-
], StatusCommand.prototype, "parseLegacy", null);
|
|
3276
3200
|
StatusCommand = __legacyDecorateClassTS([
|
|
3277
3201
|
Injectable16(),
|
|
3278
3202
|
Command6({
|
|
@@ -3281,7 +3205,6 @@ StatusCommand = __legacyDecorateClassTS([
|
|
|
3281
3205
|
}),
|
|
3282
3206
|
__legacyMetadataTS("design:paramtypes", [
|
|
3283
3207
|
typeof SyncService === "undefined" ? Object : SyncService,
|
|
3284
|
-
typeof ManifestService === "undefined" ? Object : ManifestService,
|
|
3285
3208
|
typeof DatabaseChangeDetectorService === "undefined" ? Object : DatabaseChangeDetectorService
|
|
3286
3209
|
])
|
|
3287
3210
|
], StatusCommand);
|
|
@@ -3486,7 +3409,6 @@ class SyncCommand extends CommandRunner7 {
|
|
|
3486
3409
|
paths: paths.length > 0 ? paths : undefined,
|
|
3487
3410
|
skipCascade: options.skipCascade,
|
|
3488
3411
|
embeddings: options.embeddings !== false,
|
|
3489
|
-
legacy: options.legacy,
|
|
3490
3412
|
aiExtraction: !options.skipExtraction
|
|
3491
3413
|
};
|
|
3492
3414
|
console.log(`
|
|
@@ -3508,14 +3430,9 @@ class SyncCommand extends CommandRunner7 {
|
|
|
3508
3430
|
console.log(`\uD83D\uDEAB Embedding generation disabled
|
|
3509
3431
|
`);
|
|
3510
3432
|
}
|
|
3511
|
-
if (syncOptions.
|
|
3512
|
-
console.log(`\
|
|
3433
|
+
if (!syncOptions.aiExtraction) {
|
|
3434
|
+
console.log(`\u23ED\uFE0F AI entity extraction skipped (--skip-extraction)
|
|
3513
3435
|
`);
|
|
3514
|
-
} else {
|
|
3515
|
-
if (!syncOptions.aiExtraction) {
|
|
3516
|
-
console.log(`\u23ED\uFE0F AI entity extraction skipped (--skip-extraction)
|
|
3517
|
-
`);
|
|
3518
|
-
}
|
|
3519
3436
|
}
|
|
3520
3437
|
if (syncOptions.paths) {
|
|
3521
3438
|
console.log(`\uD83D\uDCC1 Syncing specific paths: ${syncOptions.paths.join(", ")}
|
|
@@ -3713,9 +3630,6 @@ class SyncCommand extends CommandRunner7 {
|
|
|
3713
3630
|
parseSkipExtraction() {
|
|
3714
3631
|
return true;
|
|
3715
3632
|
}
|
|
3716
|
-
parseLegacy() {
|
|
3717
|
-
return true;
|
|
3718
|
-
}
|
|
3719
3633
|
}
|
|
3720
3634
|
__legacyDecorateClassTS([
|
|
3721
3635
|
Option5({
|
|
@@ -3789,15 +3703,6 @@ __legacyDecorateClassTS([
|
|
|
3789
3703
|
__legacyMetadataTS("design:paramtypes", []),
|
|
3790
3704
|
__legacyMetadataTS("design:returntype", Boolean)
|
|
3791
3705
|
], SyncCommand.prototype, "parseSkipExtraction", null);
|
|
3792
|
-
__legacyDecorateClassTS([
|
|
3793
|
-
Option5({
|
|
3794
|
-
flags: "--legacy",
|
|
3795
|
-
description: "Use legacy v1 mode: manifest-based change detection, no AI extraction"
|
|
3796
|
-
}),
|
|
3797
|
-
__legacyMetadataTS("design:type", Function),
|
|
3798
|
-
__legacyMetadataTS("design:paramtypes", []),
|
|
3799
|
-
__legacyMetadataTS("design:returntype", Boolean)
|
|
3800
|
-
], SyncCommand.prototype, "parseLegacy", null);
|
|
3801
3706
|
SyncCommand = __legacyDecorateClassTS([
|
|
3802
3707
|
Injectable18(),
|
|
3803
3708
|
Command7({
|