opencode-rag-plugin 1.21.1 → 1.21.2
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/vectorstore/lancedb.d.ts +19 -1
- package/dist/vectorstore/lancedb.js +89 -10
- package/package.json +1 -1
|
@@ -7,10 +7,28 @@ export type StoreWarn = (message: string) => void;
|
|
|
7
7
|
* store holds one per built index, while a store whose index commits fail
|
|
8
8
|
* accumulates one per attempt (and eventually degrades / corrupts).
|
|
9
9
|
*
|
|
10
|
+
* Empty directories are the husks of pruned versions (Lance removes the files
|
|
11
|
+
* but leaves the directory behind) and are harmless — they must not count
|
|
12
|
+
* toward the corruption threshold.
|
|
13
|
+
*
|
|
10
14
|
* @param tablePath - Filesystem path of the table directory (e.g. `.../chunks.lance`).
|
|
15
|
+
* @param options - `withFiles: true` counts only directories that still contain index files.
|
|
11
16
|
* @returns The number of index-version directories, or 0 when unavailable.
|
|
12
17
|
*/
|
|
13
|
-
export declare function countIndexVersionDirs(tablePath: string
|
|
18
|
+
export declare function countIndexVersionDirs(tablePath: string, options?: {
|
|
19
|
+
withFiles?: boolean;
|
|
20
|
+
}): number;
|
|
21
|
+
/**
|
|
22
|
+
* Remove stale empty index-version directories (husks of versions whose files
|
|
23
|
+
* Lance already pruned). Empty directories are never referenced by the index,
|
|
24
|
+
* so removing them is safe; only husks older than `MIN_HUSK_AGE_MS` are swept
|
|
25
|
+
* so a concurrent createIndex from another process can never lose its
|
|
26
|
+
* freshly-created (and momentarily empty) version directory.
|
|
27
|
+
*
|
|
28
|
+
* @param tablePath - Filesystem path of the table directory (e.g. `.../chunks.lance`).
|
|
29
|
+
* @returns The number of removed directories.
|
|
30
|
+
*/
|
|
31
|
+
export declare function sweepEmptyIndexVersionDirs(tablePath: string): number;
|
|
14
32
|
/**
|
|
15
33
|
* L2-normalize a vector to unit length. Cosine models require unit vectors
|
|
16
34
|
* for the dot product to equal cosine similarity.
|
|
@@ -30,18 +30,75 @@ const MAX_STALE_INDEX_VERSIONS = 40;
|
|
|
30
30
|
* store holds one per built index, while a store whose index commits fail
|
|
31
31
|
* accumulates one per attempt (and eventually degrades / corrupts).
|
|
32
32
|
*
|
|
33
|
+
* Empty directories are the husks of pruned versions (Lance removes the files
|
|
34
|
+
* but leaves the directory behind) and are harmless — they must not count
|
|
35
|
+
* toward the corruption threshold.
|
|
36
|
+
*
|
|
33
37
|
* @param tablePath - Filesystem path of the table directory (e.g. `.../chunks.lance`).
|
|
38
|
+
* @param options - `withFiles: true` counts only directories that still contain index files.
|
|
34
39
|
* @returns The number of index-version directories, or 0 when unavailable.
|
|
35
40
|
*/
|
|
36
|
-
export function countIndexVersionDirs(tablePath) {
|
|
41
|
+
export function countIndexVersionDirs(tablePath, options) {
|
|
37
42
|
try {
|
|
38
43
|
const entries = fsSync.readdirSync(path.join(tablePath, "_indices"), { withFileTypes: true });
|
|
39
|
-
|
|
44
|
+
const dirs = entries.filter((e) => e.isDirectory());
|
|
45
|
+
if (!options?.withFiles)
|
|
46
|
+
return dirs.length;
|
|
47
|
+
let count = 0;
|
|
48
|
+
for (const dir of dirs) {
|
|
49
|
+
try {
|
|
50
|
+
if (fsSync.readdirSync(path.join(tablePath, "_indices", dir.name)).length > 0)
|
|
51
|
+
count++;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// unreadable dir — count it conservatively
|
|
55
|
+
count++;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return count;
|
|
40
59
|
}
|
|
41
60
|
catch {
|
|
42
61
|
return 0;
|
|
43
62
|
}
|
|
44
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Remove stale empty index-version directories (husks of versions whose files
|
|
66
|
+
* Lance already pruned). Empty directories are never referenced by the index,
|
|
67
|
+
* so removing them is safe; only husks older than `MIN_HUSK_AGE_MS` are swept
|
|
68
|
+
* so a concurrent createIndex from another process can never lose its
|
|
69
|
+
* freshly-created (and momentarily empty) version directory.
|
|
70
|
+
*
|
|
71
|
+
* @param tablePath - Filesystem path of the table directory (e.g. `.../chunks.lance`).
|
|
72
|
+
* @returns The number of removed directories.
|
|
73
|
+
*/
|
|
74
|
+
export function sweepEmptyIndexVersionDirs(tablePath) {
|
|
75
|
+
const MIN_HUSK_AGE_MS = 10 * 60 * 1000;
|
|
76
|
+
let removed = 0;
|
|
77
|
+
try {
|
|
78
|
+
const indicesDir = path.join(tablePath, "_indices");
|
|
79
|
+
for (const name of fsSync.readdirSync(indicesDir)) {
|
|
80
|
+
const full = path.join(indicesDir, name);
|
|
81
|
+
try {
|
|
82
|
+
const stat = fsSync.statSync(full);
|
|
83
|
+
if (!stat.isDirectory())
|
|
84
|
+
continue;
|
|
85
|
+
if (Date.now() - stat.mtimeMs < MIN_HUSK_AGE_MS)
|
|
86
|
+
continue;
|
|
87
|
+
if (fsSync.readdirSync(full).length > 0)
|
|
88
|
+
continue;
|
|
89
|
+
fsSync.rmdirSync(full);
|
|
90
|
+
removed++;
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// best-effort — skip unreadable/racing entries
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// best-effort
|
|
99
|
+
}
|
|
100
|
+
return removed;
|
|
101
|
+
}
|
|
45
102
|
/**
|
|
46
103
|
* L2-normalize a vector to unit length. Cosine models require unit vectors
|
|
47
104
|
* for the dot product to equal cosine similarity.
|
|
@@ -873,15 +930,16 @@ export class LanceDbStore {
|
|
|
873
930
|
};
|
|
874
931
|
try {
|
|
875
932
|
// Guard against a store that never converges: each failed createIndex
|
|
876
|
-
// leaves a new index-version directory behind.
|
|
877
|
-
//
|
|
878
|
-
//
|
|
879
|
-
const
|
|
933
|
+
// leaves a new index-version directory behind. Empty directories are
|
|
934
|
+
// the husks of already-pruned versions and are harmless — only
|
|
935
|
+
// versions that still carry index files count (see countIndexVersionDirs).
|
|
936
|
+
const activeVersions = this.dbPath.startsWith("memory://")
|
|
880
937
|
? 0
|
|
881
|
-
: countIndexVersionDirs(path.join(this.dbPath, TABLE_NAME + ".lance"));
|
|
882
|
-
if (
|
|
883
|
-
report(`[lancedb] ${
|
|
884
|
-
`
|
|
938
|
+
: countIndexVersionDirs(path.join(this.dbPath, TABLE_NAME + ".lance"), { withFiles: true });
|
|
939
|
+
if (activeVersions > MAX_STALE_INDEX_VERSIONS) {
|
|
940
|
+
report(`[lancedb] ${activeVersions} active index versions detected in ${this.dbPath} — ` +
|
|
941
|
+
`index rebuild skipped to avoid retrain churn. The store cannot converge; ` +
|
|
942
|
+
`delete the rag_db directory and re-index.`);
|
|
885
943
|
// Resolve the memo so no further attempts run this process.
|
|
886
944
|
return;
|
|
887
945
|
}
|
|
@@ -906,6 +964,16 @@ export class LanceDbStore {
|
|
|
906
964
|
// race a background index-creation from another process.
|
|
907
965
|
waitTimeoutSeconds: 120,
|
|
908
966
|
});
|
|
967
|
+
// Verify the index actually registered. On a store whose index
|
|
968
|
+
// commits never register, createIndex can return successfully
|
|
969
|
+
// while leaving the table without a visible index — the failure
|
|
970
|
+
// mode that caused constant retraining and "partition N is empty,
|
|
971
|
+
// skipping" warning spam. Detect it and stop retraining.
|
|
972
|
+
const verify = await table.indexStats(idxName).catch(() => undefined);
|
|
973
|
+
if (!verify || verify.distanceType !== "cosine") {
|
|
974
|
+
throw new Error(`index build did not register (store cannot converge) — ` +
|
|
975
|
+
`delete the rag_db directory and re-index`);
|
|
976
|
+
}
|
|
909
977
|
this.indexRepairFailures = 0;
|
|
910
978
|
return;
|
|
911
979
|
}
|
|
@@ -957,6 +1025,17 @@ export class LanceDbStore {
|
|
|
957
1025
|
const threshold = new Date(Date.now() - 60 * 60 * 1000);
|
|
958
1026
|
await table.optimize({ cleanupOlderThan: threshold, deleteUnverified: false });
|
|
959
1027
|
}
|
|
1028
|
+
// Remove stale empty index-version directories (husks Lance leaves
|
|
1029
|
+
// behind after pruning a version's files). Keeps the directory count
|
|
1030
|
+
// from growing unboundedly and prevents false positives in the
|
|
1031
|
+
// index-repair stale-version guard.
|
|
1032
|
+
if (!this.dbPath.startsWith("memory://")) {
|
|
1033
|
+
const swept = sweepEmptyIndexVersionDirs(path.join(this.dbPath, TABLE_NAME + ".lance"));
|
|
1034
|
+
if (swept > 0) {
|
|
1035
|
+
const message = `[lancedb] swept ${swept} stale index-version directories`;
|
|
1036
|
+
(options?.logger ?? console.warn)(message);
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
960
1039
|
// Build the ANN vector index — without it every vectorSearch() is a
|
|
961
1040
|
// brute-force O(N) flat scan (slow at 50k+ chunks). Skips early when
|
|
962
1041
|
// an index with the correct cosine metric already exists, and can be
|