@ssmeo/mcp-local-rag 0.18.6
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/LICENSE +21 -0
- package/README.de.md +441 -0
- package/README.es.md +441 -0
- package/README.fr.md +441 -0
- package/README.md +530 -0
- package/README.pt-BR.md +441 -0
- package/README.zh-CN.md +441 -0
- package/dist/bin/install-skills.d.ts +19 -0
- package/dist/bin/install-skills.d.ts.map +1 -0
- package/dist/bin/install-skills.js +218 -0
- package/dist/bin/install-skills.js.map +1 -0
- package/dist/chunker/index.d.ts +24 -0
- package/dist/chunker/index.d.ts.map +1 -0
- package/dist/chunker/index.js +2 -0
- package/dist/chunker/index.js.map +1 -0
- package/dist/chunker/semantic-chunker.d.ts +96 -0
- package/dist/chunker/semantic-chunker.d.ts.map +1 -0
- package/dist/chunker/semantic-chunker.js +362 -0
- package/dist/chunker/semantic-chunker.js.map +1 -0
- package/dist/chunker/sentence-splitter.d.ts +32 -0
- package/dist/chunker/sentence-splitter.d.ts.map +1 -0
- package/dist/chunker/sentence-splitter.js +231 -0
- package/dist/chunker/sentence-splitter.js.map +1 -0
- package/dist/chunker/token-containment.d.ts +39 -0
- package/dist/chunker/token-containment.d.ts.map +1 -0
- package/dist/chunker/token-containment.js +83 -0
- package/dist/chunker/token-containment.js.map +1 -0
- package/dist/cli/common.d.ts +34 -0
- package/dist/cli/common.d.ts.map +1 -0
- package/dist/cli/common.js +121 -0
- package/dist/cli/common.js.map +1 -0
- package/dist/cli/delete.d.ts +3 -0
- package/dist/cli/delete.d.ts.map +1 -0
- package/dist/cli/delete.js +169 -0
- package/dist/cli/delete.js.map +1 -0
- package/dist/cli/file-collection.d.ts +2 -0
- package/dist/cli/file-collection.d.ts.map +1 -0
- package/dist/cli/file-collection.js +53 -0
- package/dist/cli/file-collection.js.map +1 -0
- package/dist/cli/ingest.d.ts +69 -0
- package/dist/cli/ingest.d.ts.map +1 -0
- package/dist/cli/ingest.js +323 -0
- package/dist/cli/ingest.js.map +1 -0
- package/dist/cli/list.d.ts +27 -0
- package/dist/cli/list.d.ts.map +1 -0
- package/dist/cli/list.js +207 -0
- package/dist/cli/list.js.map +1 -0
- package/dist/cli/options.d.ts +89 -0
- package/dist/cli/options.d.ts.map +1 -0
- package/dist/cli/options.js +244 -0
- package/dist/cli/options.js.map +1 -0
- package/dist/cli/query.d.ts +17 -0
- package/dist/cli/query.d.ts.map +1 -0
- package/dist/cli/query.js +194 -0
- package/dist/cli/query.js.map +1 -0
- package/dist/cli/read-neighbors.d.ts +3 -0
- package/dist/cli/read-neighbors.d.ts.map +1 -0
- package/dist/cli/read-neighbors.js +192 -0
- package/dist/cli/read-neighbors.js.map +1 -0
- package/dist/cli/status.d.ts +6 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +78 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/sync.d.ts +6 -0
- package/dist/cli/sync.d.ts.map +1 -0
- package/dist/cli/sync.js +271 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/cli-main.d.ts +9 -0
- package/dist/cli-main.d.ts.map +1 -0
- package/dist/cli-main.js +60 -0
- package/dist/cli-main.js.map +1 -0
- package/dist/embedder/index.d.ts +143 -0
- package/dist/embedder/index.d.ts.map +1 -0
- package/dist/embedder/index.js +429 -0
- package/dist/embedder/index.js.map +1 -0
- package/dist/embedder/remote.d.ts +51 -0
- package/dist/embedder/remote.d.ts.map +1 -0
- package/dist/embedder/remote.js +182 -0
- package/dist/embedder/remote.js.map +1 -0
- package/dist/features/list.d.ts +37 -0
- package/dist/features/list.d.ts.map +1 -0
- package/dist/features/list.js +41 -0
- package/dist/features/list.js.map +1 -0
- package/dist/features/sync.d.ts +219 -0
- package/dist/features/sync.d.ts.map +1 -0
- package/dist/features/sync.js +461 -0
- package/dist/features/sync.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/ingest/compute.d.ts +63 -0
- package/dist/ingest/compute.d.ts.map +1 -0
- package/dist/ingest/compute.js +161 -0
- package/dist/ingest/compute.js.map +1 -0
- package/dist/ingest/file.d.ts +40 -0
- package/dist/ingest/file.d.ts.map +1 -0
- package/dist/ingest/file.js +74 -0
- package/dist/ingest/file.js.map +1 -0
- package/dist/ingest/visual.d.ts +52 -0
- package/dist/ingest/visual.d.ts.map +1 -0
- package/dist/ingest/visual.js +294 -0
- package/dist/ingest/visual.js.map +1 -0
- package/dist/parser/docx-parser.d.ts +12 -0
- package/dist/parser/docx-parser.d.ts.map +1 -0
- package/dist/parser/docx-parser.js +375 -0
- package/dist/parser/docx-parser.js.map +1 -0
- package/dist/parser/html-parser.d.ts +16 -0
- package/dist/parser/html-parser.d.ts.map +1 -0
- package/dist/parser/html-parser.js +119 -0
- package/dist/parser/html-parser.js.map +1 -0
- package/dist/parser/index.d.ts +125 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +364 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/pdf-extract.d.ts +49 -0
- package/dist/parser/pdf-extract.d.ts.map +1 -0
- package/dist/parser/pdf-extract.js +114 -0
- package/dist/parser/pdf-extract.js.map +1 -0
- package/dist/parser/pdf-filter.d.ts +91 -0
- package/dist/parser/pdf-filter.d.ts.map +1 -0
- package/dist/parser/pdf-filter.js +522 -0
- package/dist/parser/pdf-filter.js.map +1 -0
- package/dist/parser/title-extractor.d.ts +28 -0
- package/dist/parser/title-extractor.d.ts.map +1 -0
- package/dist/parser/title-extractor.js +105 -0
- package/dist/parser/title-extractor.js.map +1 -0
- package/dist/pdf-visual/captioner.d.ts +11 -0
- package/dist/pdf-visual/captioner.d.ts.map +1 -0
- package/dist/pdf-visual/captioner.js +48 -0
- package/dist/pdf-visual/captioner.js.map +1 -0
- package/dist/pdf-visual/captioners/fast.d.ts +7 -0
- package/dist/pdf-visual/captioners/fast.d.ts.map +1 -0
- package/dist/pdf-visual/captioners/fast.js +108 -0
- package/dist/pdf-visual/captioners/fast.js.map +1 -0
- package/dist/pdf-visual/captioners/quality.d.ts +7 -0
- package/dist/pdf-visual/captioners/quality.d.ts.map +1 -0
- package/dist/pdf-visual/captioners/quality.js +101 -0
- package/dist/pdf-visual/captioners/quality.js.map +1 -0
- package/dist/pdf-visual/captioners/shared.d.ts +81 -0
- package/dist/pdf-visual/captioners/shared.d.ts.map +1 -0
- package/dist/pdf-visual/captioners/shared.js +156 -0
- package/dist/pdf-visual/captioners/shared.js.map +1 -0
- package/dist/pdf-visual/detector.d.ts +9 -0
- package/dist/pdf-visual/detector.d.ts.map +1 -0
- package/dist/pdf-visual/detector.js +269 -0
- package/dist/pdf-visual/detector.js.map +1 -0
- package/dist/pdf-visual/index.d.ts +13 -0
- package/dist/pdf-visual/index.d.ts.map +1 -0
- package/dist/pdf-visual/index.js +53 -0
- package/dist/pdf-visual/index.js.map +1 -0
- package/dist/pdf-visual/renderer.d.ts +9 -0
- package/dist/pdf-visual/renderer.d.ts.map +1 -0
- package/dist/pdf-visual/renderer.js +186 -0
- package/dist/pdf-visual/renderer.js.map +1 -0
- package/dist/pdf-visual/types.d.ts +53 -0
- package/dist/pdf-visual/types.d.ts.map +1 -0
- package/dist/pdf-visual/types.js +17 -0
- package/dist/pdf-visual/types.js.map +1 -0
- package/dist/server/error-utils.d.ts +63 -0
- package/dist/server/error-utils.d.ts.map +1 -0
- package/dist/server/error-utils.js +124 -0
- package/dist/server/error-utils.js.map +1 -0
- package/dist/server/index.d.ts +216 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +1068 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/list-scanner.d.ts +30 -0
- package/dist/server/list-scanner.d.ts.map +1 -0
- package/dist/server/list-scanner.js +50 -0
- package/dist/server/list-scanner.js.map +1 -0
- package/dist/server/tool-definitions.d.ts +8 -0
- package/dist/server/tool-definitions.d.ts.map +1 -0
- package/dist/server/tool-definitions.js +181 -0
- package/dist/server/tool-definitions.js.map +1 -0
- package/dist/server/tool-input.d.ts +37 -0
- package/dist/server/tool-input.d.ts.map +1 -0
- package/dist/server/tool-input.js +211 -0
- package/dist/server/tool-input.js.map +1 -0
- package/dist/server/types.d.ts +307 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +3 -0
- package/dist/server/types.js.map +1 -0
- package/dist/server-main.d.ts +40 -0
- package/dist/server-main.d.ts.map +1 -0
- package/dist/server-main.js +254 -0
- package/dist/server-main.js.map +1 -0
- package/dist/utils/base-dirs.d.ts +145 -0
- package/dist/utils/base-dirs.d.ts.map +1 -0
- package/dist/utils/base-dirs.js +344 -0
- package/dist/utils/base-dirs.js.map +1 -0
- package/dist/utils/errors.d.ts +32 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +61 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/limits.d.ts +26 -0
- package/dist/utils/limits.d.ts.map +1 -0
- package/dist/utils/limits.js +28 -0
- package/dist/utils/limits.js.map +1 -0
- package/dist/utils/list-sources.d.ts +38 -0
- package/dist/utils/list-sources.d.ts.map +1 -0
- package/dist/utils/list-sources.js +40 -0
- package/dist/utils/list-sources.js.map +1 -0
- package/dist/utils/raw-data-utils.d.ts +76 -0
- package/dist/utils/raw-data-utils.d.ts.map +1 -0
- package/dist/utils/raw-data-utils.js +202 -0
- package/dist/utils/raw-data-utils.js.map +1 -0
- package/dist/utils/scan.d.ts +114 -0
- package/dist/utils/scan.d.ts.map +1 -0
- package/dist/utils/scan.js +209 -0
- package/dist/utils/scan.js.map +1 -0
- package/dist/utils/scope-match.d.ts +38 -0
- package/dist/utils/scope-match.d.ts.map +1 -0
- package/dist/utils/scope-match.js +86 -0
- package/dist/utils/scope-match.js.map +1 -0
- package/dist/utils/sensitive-path.d.ts +9 -0
- package/dist/utils/sensitive-path.d.ts.map +1 -0
- package/dist/utils/sensitive-path.js +78 -0
- package/dist/utils/sensitive-path.js.map +1 -0
- package/dist/utils/sync-path-key.d.ts +14 -0
- package/dist/utils/sync-path-key.d.ts.map +1 -0
- package/dist/utils/sync-path-key.js +27 -0
- package/dist/utils/sync-path-key.js.map +1 -0
- package/dist/utils/type-guards.d.ts +18 -0
- package/dist/utils/type-guards.d.ts.map +1 -0
- package/dist/utils/type-guards.js +34 -0
- package/dist/utils/type-guards.js.map +1 -0
- package/dist/utils/visual-profile.d.ts +10 -0
- package/dist/utils/visual-profile.d.ts.map +1 -0
- package/dist/utils/visual-profile.js +15 -0
- package/dist/utils/visual-profile.js.map +1 -0
- package/dist/vectordb/index.d.ts +132 -0
- package/dist/vectordb/index.d.ts.map +1 -0
- package/dist/vectordb/index.js +617 -0
- package/dist/vectordb/index.js.map +1 -0
- package/dist/vectordb/search-filters.d.ts +15 -0
- package/dist/vectordb/search-filters.d.ts.map +1 -0
- package/dist/vectordb/search-filters.js +129 -0
- package/dist/vectordb/search-filters.js.map +1 -0
- package/dist/vectordb/types.d.ts +194 -0
- package/dist/vectordb/types.d.ts.map +1 -0
- package/dist/vectordb/types.js +237 -0
- package/dist/vectordb/types.js.map +1 -0
- package/package.json +108 -0
- package/skills/mcp-local-rag/SKILL.md +234 -0
- package/skills/mcp-local-rag/references/cli-reference.md +190 -0
- package/skills/mcp-local-rag/references/html-ingestion.md +78 -0
|
@@ -0,0 +1,617 @@
|
|
|
1
|
+
// VectorStore implementation with LanceDB integration
|
|
2
|
+
import { connect, Index } from '@lancedb/lancedb';
|
|
3
|
+
import { toError } from '../utils/errors.js';
|
|
4
|
+
import { MAX_QUERY_LIMIT, MIN_QUERY_LIMIT } from '../utils/limits.js';
|
|
5
|
+
import { normalizeScopePrefix } from '../utils/scope-match.js';
|
|
6
|
+
import { applyFileFilter, applyGrouping, applyKeywordBoost } from './search-filters.js';
|
|
7
|
+
import { DatabaseError, DEFAULT_HYBRID_WEIGHT, FTS_CLEANUP_THRESHOLD_MS, FTS_INDEX_NAME, HYBRID_SEARCH_CANDIDATE_MULTIPLIER, normalizeVisualAttachments, parseHydratedVisualAttachments, toChunkRow, toSearchResult, toVectorChunk, } from './types.js';
|
|
8
|
+
// ============================================
|
|
9
|
+
// VectorStore Class
|
|
10
|
+
// ============================================
|
|
11
|
+
/** Vector storage over LanceDB, including the delete-then-insert atomicity. */
|
|
12
|
+
export class VectorStore {
|
|
13
|
+
db = null;
|
|
14
|
+
table = null;
|
|
15
|
+
openingTable = null;
|
|
16
|
+
config;
|
|
17
|
+
ftsEnabled = false;
|
|
18
|
+
constructor(config) {
|
|
19
|
+
this.config = config;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Initialize LanceDB and create table
|
|
23
|
+
*/
|
|
24
|
+
async initialize() {
|
|
25
|
+
try {
|
|
26
|
+
// Connect to LanceDB
|
|
27
|
+
// readConsistencyInterval: 0 ensures every read checks for external changes.
|
|
28
|
+
// Without this, a cached Table object becomes stale when another process
|
|
29
|
+
// (e.g., CLI ingestion from a different terminal) modifies the database,
|
|
30
|
+
// causing "Failed to search vectors" errors until restart.
|
|
31
|
+
this.db = await connect(this.config.dbPath, { readConsistencyInterval: 0 });
|
|
32
|
+
await this.openExistingTable();
|
|
33
|
+
console.error(`VectorStore initialized: ${this.config.dbPath}`);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
throw new DatabaseError('Failed to initialize VectorStore', { cause: toError(error) });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** Discover a table created after this connection was initialized. */
|
|
40
|
+
async openExistingTable() {
|
|
41
|
+
if (this.openingTable !== null) {
|
|
42
|
+
return this.openingTable;
|
|
43
|
+
}
|
|
44
|
+
if (this.table || !this.db) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const db = this.db;
|
|
48
|
+
this.openingTable = (async () => {
|
|
49
|
+
try {
|
|
50
|
+
if (!(await db.tableNames()).includes(this.config.tableName)) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
this.table = await db.openTable(this.config.tableName);
|
|
54
|
+
await this.ensureFtsIndex();
|
|
55
|
+
await this.ensureSchemaVersion();
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
this.table = null;
|
|
59
|
+
this.ftsEnabled = false;
|
|
60
|
+
throw new DatabaseError('Failed to open existing table', { cause: toError(error) });
|
|
61
|
+
}
|
|
62
|
+
})();
|
|
63
|
+
try {
|
|
64
|
+
await this.openingTable;
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
this.openingTable = null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** @returns the number of chunks removed; 0 when nothing matched. */
|
|
71
|
+
async deleteChunks(filePath) {
|
|
72
|
+
await this.openExistingTable();
|
|
73
|
+
if (!this.table) {
|
|
74
|
+
// If table doesn't exist, no deletion targets, return normally
|
|
75
|
+
console.error('VectorStore: Skipping deletion as table does not exist');
|
|
76
|
+
return 0;
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
// Use LanceDB delete API to remove records matching filePath.
|
|
80
|
+
// Escape single quotes to prevent SQL injection.
|
|
81
|
+
// Note: Field names are case-sensitive, use backticks for camelCase fields.
|
|
82
|
+
const escapedFilePath = filePath.replace(/'/g, "''");
|
|
83
|
+
// delete() reports the authoritative removed count (numDeletedRows) from
|
|
84
|
+
// the same operation, so the total stays correct under concurrent deletes
|
|
85
|
+
// and we avoid a second pre-count query that materializes matching rows.
|
|
86
|
+
const { numDeletedRows } = await this.table.delete(`\`filePath\` = '${escapedFilePath}'`);
|
|
87
|
+
console.error(`VectorStore: Deleted ${numDeletedRows} chunks for file "${filePath}"`);
|
|
88
|
+
return numDeletedRows;
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
// LanceDB's delete resolves normally when nothing matched, so reaching
|
|
92
|
+
// this catch means a genuine failure. Propagate rather than swallowing by
|
|
93
|
+
// error-message matching, which broke silently across LanceDB versions.
|
|
94
|
+
console.warn(`VectorStore: Error occurred while deleting file "${filePath}":`, error);
|
|
95
|
+
throw new DatabaseError(`Failed to delete chunks for file: ${filePath}`, {
|
|
96
|
+
cause: toError(error),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Chunk rows for one file with chunkIndex in the inclusive [minIdx, maxIdx]
|
|
102
|
+
* range. The ascending sort is a contract, not incidental storage order.
|
|
103
|
+
*
|
|
104
|
+
* Feature-agnostic: before/after/isTarget semantics live in the handler.
|
|
105
|
+
*/
|
|
106
|
+
async getChunksByRange(filePath, minIdx, maxIdx) {
|
|
107
|
+
await this.openExistingTable();
|
|
108
|
+
if (!this.table) {
|
|
109
|
+
console.error('VectorStore: Skipping range read as table does not exist');
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
if (!Number.isInteger(minIdx) || !Number.isInteger(maxIdx) || minIdx < 0 || maxIdx < minIdx) {
|
|
113
|
+
throw new DatabaseError('getChunksByRange requires non-negative integer range bounds with minIdx <= maxIdx');
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
// Escape single quotes to prevent SQL injection (mirrors deleteChunks)
|
|
117
|
+
const escapedFilePath = filePath.replace(/'/g, "''");
|
|
118
|
+
// Backtick-quoted camelCase columns; numeric literals unquoted
|
|
119
|
+
const predicate = `\`filePath\` = '${escapedFilePath}' AND \`chunkIndex\` >= ${minIdx} AND \`chunkIndex\` <= ${maxIdx}`;
|
|
120
|
+
const raw = await this.table
|
|
121
|
+
.query()
|
|
122
|
+
.where(predicate)
|
|
123
|
+
.select(['filePath', 'chunkIndex', 'text', 'fileTitle'])
|
|
124
|
+
.toArray();
|
|
125
|
+
const rows = raw.map((row) => toChunkRow(row));
|
|
126
|
+
// Contractual ascending sort; do not rely on storage order.
|
|
127
|
+
rows.sort((a, b) => a.chunkIndex - b.chunkIndex);
|
|
128
|
+
return rows;
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
throw new DatabaseError('Failed to read chunks by range', { cause: toError(error) });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Every stored chunk for a file as a full {@link VectorChunk}, embedding
|
|
136
|
+
* included, so it can be re-inserted verbatim. The ingest handler backs data
|
|
137
|
+
* up with this before a destructive re-ingest, so a failure rolls back
|
|
138
|
+
* without corrupting vectors.
|
|
139
|
+
*/
|
|
140
|
+
async getChunksByFilePath(filePath) {
|
|
141
|
+
await this.openExistingTable();
|
|
142
|
+
if (!this.table) {
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
// Escape single quotes to prevent SQL injection (mirrors deleteChunks)
|
|
147
|
+
const escapedFilePath = filePath.replace(/'/g, "''");
|
|
148
|
+
const raw = await this.table.query().where(`\`filePath\` = '${escapedFilePath}'`).toArray();
|
|
149
|
+
return raw.map((row) => toVectorChunk(row));
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
throw new DatabaseError(`Failed to read chunks for file: ${filePath}`, {
|
|
153
|
+
cause: toError(error),
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Batch insert vector chunks
|
|
159
|
+
*/
|
|
160
|
+
async insertChunks(chunks) {
|
|
161
|
+
if (chunks.length === 0) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
await this.openExistingTable();
|
|
166
|
+
if (!this.table) {
|
|
167
|
+
// Create table on first insertion
|
|
168
|
+
if (!this.db) {
|
|
169
|
+
throw new DatabaseError('VectorStore is not initialized. Call initialize() first.');
|
|
170
|
+
}
|
|
171
|
+
// LanceDB's createTable API accepts data as Record<string, unknown>[]
|
|
172
|
+
// Note: LanceDB cannot infer Arrow type from null/absent values, so the
|
|
173
|
+
// nullable string columns need a non-null sample value for schema
|
|
174
|
+
// inference. The read converters normalize each placeholder back to
|
|
175
|
+
// its logical no-value state, matching what migration produces.
|
|
176
|
+
const records = chunks.map((chunk) => ({
|
|
177
|
+
...chunk,
|
|
178
|
+
fileTitle: chunk.fileTitle ?? '',
|
|
179
|
+
contentHash: chunk.contentHash ?? '',
|
|
180
|
+
visualProfile: chunk.visualProfile ?? '',
|
|
181
|
+
visualAttachments: normalizeVisualAttachments(chunk.visualAttachments),
|
|
182
|
+
}));
|
|
183
|
+
this.table = await this.db.createTable(this.config.tableName, records);
|
|
184
|
+
console.error(`VectorStore: Created table "${this.config.tableName}"`);
|
|
185
|
+
// Create FTS index for hybrid search
|
|
186
|
+
await this.ensureFtsIndex();
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
// Add data to existing table
|
|
190
|
+
// An explicit `null` rather than an omitted key: `add` builds its batch
|
|
191
|
+
// from the supplied properties, so omission on an optional column is not
|
|
192
|
+
// a reliable way to write "no value".
|
|
193
|
+
const records = chunks.map((chunk) => ({
|
|
194
|
+
...chunk,
|
|
195
|
+
visualProfile: chunk.visualProfile ?? null,
|
|
196
|
+
visualAttachments: normalizeVisualAttachments(chunk.visualAttachments),
|
|
197
|
+
}));
|
|
198
|
+
await this.table.add(records);
|
|
199
|
+
}
|
|
200
|
+
console.error(`VectorStore: Inserted ${chunks.length} chunks`);
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
throw new DatabaseError('Failed to insert chunks', { cause: toError(error) });
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Ensure FTS index exists for hybrid search
|
|
208
|
+
* Creates ngram-based index if it doesn't exist, drops old versions
|
|
209
|
+
* @throws DatabaseError if index creation fails (Fail-Fast principle)
|
|
210
|
+
*/
|
|
211
|
+
async ensureFtsIndex() {
|
|
212
|
+
if (!this.table) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
// Check existing indices
|
|
216
|
+
const indices = await this.table.listIndices();
|
|
217
|
+
const existingFtsIndices = indices.filter((idx) => idx.indexType === 'FTS');
|
|
218
|
+
const hasExpectedIndex = existingFtsIndices.some((idx) => idx.name === FTS_INDEX_NAME);
|
|
219
|
+
if (hasExpectedIndex) {
|
|
220
|
+
this.ftsEnabled = true;
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
// Create new FTS index with ngram tokenizer for multilingual support
|
|
224
|
+
// - min=2: Capture Japanese bi-grams (e.g., "東京", "設計")
|
|
225
|
+
// - max=3: Balance between precision and index size
|
|
226
|
+
// - prefixOnly=false: Generate ngrams from all positions for proper CJK support
|
|
227
|
+
await this.table.createIndex('text', {
|
|
228
|
+
config: Index.fts({
|
|
229
|
+
baseTokenizer: 'ngram',
|
|
230
|
+
ngramMinLength: 2,
|
|
231
|
+
ngramMaxLength: 3,
|
|
232
|
+
prefixOnly: false,
|
|
233
|
+
stem: false,
|
|
234
|
+
}),
|
|
235
|
+
name: FTS_INDEX_NAME,
|
|
236
|
+
});
|
|
237
|
+
this.ftsEnabled = true;
|
|
238
|
+
console.error(`VectorStore: FTS index "${FTS_INDEX_NAME}" created successfully`);
|
|
239
|
+
// Drop old FTS indices
|
|
240
|
+
for (const idx of existingFtsIndices) {
|
|
241
|
+
if (idx.name !== FTS_INDEX_NAME) {
|
|
242
|
+
await this.table.dropIndex(idx.name);
|
|
243
|
+
console.error(`VectorStore: Dropped old FTS index "${idx.name}"`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Ensure schema is up to date by adding missing columns.
|
|
249
|
+
* Uses table.addColumns() API for top-level column additions.
|
|
250
|
+
* Idempotent: checks for column existence before adding.
|
|
251
|
+
*/
|
|
252
|
+
async ensureSchemaVersion() {
|
|
253
|
+
if (!this.table) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const schema = await this.table.schema();
|
|
257
|
+
const hasField = (name) => schema.fields.some((f) => f.name === name);
|
|
258
|
+
if (!hasField('fileTitle')) {
|
|
259
|
+
await this.table.addColumns([{ name: 'fileTitle', valueSql: 'cast(NULL as string)' }]);
|
|
260
|
+
console.error('VectorStore: Migrated schema - added fileTitle column');
|
|
261
|
+
}
|
|
262
|
+
if (!hasField('contentHash')) {
|
|
263
|
+
await this.table.addColumns([{ name: 'contentHash', valueSql: 'cast(NULL as string)' }]);
|
|
264
|
+
console.error('VectorStore: Migrated schema - added contentHash column');
|
|
265
|
+
}
|
|
266
|
+
if (!hasField('visualAttachments')) {
|
|
267
|
+
await this.table.addColumns([{ name: 'visualAttachments', valueSql: 'cast(NULL as string)' }]);
|
|
268
|
+
console.error('VectorStore: Migrated schema - added visualAttachments column');
|
|
269
|
+
}
|
|
270
|
+
if (!hasField('visualProfile')) {
|
|
271
|
+
await this.table.addColumns([{ name: 'visualProfile', valueSql: 'cast(NULL as string)' }]);
|
|
272
|
+
console.error('VectorStore: Migrated schema - added visualProfile column');
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Compact fragments, update the FTS index, and drop old versions. LanceDB OSS
|
|
277
|
+
* only updates the FTS index on an explicit call.
|
|
278
|
+
*
|
|
279
|
+
* The caller decides when — once per ingest rather than per insert, to avoid
|
|
280
|
+
* O(n^2) during bulk work.
|
|
281
|
+
*/
|
|
282
|
+
async optimize() {
|
|
283
|
+
await this.openExistingTable();
|
|
284
|
+
if (!this.table || !this.ftsEnabled) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
const cleanupThreshold = new Date(Date.now() - FTS_CLEANUP_THRESHOLD_MS);
|
|
288
|
+
await this.table.optimize({ cleanupOlderThan: cleanupThreshold });
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Semantic search → maxDistance/grouping filter → keyword boost → maxFiles.
|
|
292
|
+
*
|
|
293
|
+
* Prefetch-then-rerank, so the distance filters see real vector distances and
|
|
294
|
+
* keyword matching boosts rather than replaces semantic similarity.
|
|
295
|
+
*/
|
|
296
|
+
/**
|
|
297
|
+
* Rerank vector hits with BM25 scores for the same files. A failure degrades
|
|
298
|
+
* this request only — FTS stays enabled, so the next query retries hybrid.
|
|
299
|
+
*/
|
|
300
|
+
async boostWithKeywords(results, queryText, hybridWeight) {
|
|
301
|
+
const table = this.table;
|
|
302
|
+
if (!table) {
|
|
303
|
+
return results;
|
|
304
|
+
}
|
|
305
|
+
try {
|
|
306
|
+
// Restrict FTS to the files the vector step already selected. Backticks
|
|
307
|
+
// are required for a camelCase column name in LanceDB.
|
|
308
|
+
const uniqueFilePaths = [...new Set(results.map((result) => result.filePath))];
|
|
309
|
+
const escapedPaths = uniqueFilePaths.map((path) => `'${path.replace(/'/g, "''")}'`);
|
|
310
|
+
const whereClause = `\`filePath\` IN (${escapedPaths.join(', ')})`;
|
|
311
|
+
const ftsResults = await table
|
|
312
|
+
.search(queryText, 'fts', 'text')
|
|
313
|
+
.where(whereClause)
|
|
314
|
+
.select(['filePath', 'chunkIndex', 'text', 'metadata', '_score'])
|
|
315
|
+
.limit(results.length * 2) // Enough to cover all vector results
|
|
316
|
+
.toArray();
|
|
317
|
+
return applyKeywordBoost(results, ftsResults, hybridWeight);
|
|
318
|
+
}
|
|
319
|
+
catch (ftsError) {
|
|
320
|
+
console.error('VectorStore: FTS search failed, using vector-only results:', ftsError);
|
|
321
|
+
return results;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
async search(queryVector, options = {}) {
|
|
325
|
+
const { queryText, limit = 10, scope } = options;
|
|
326
|
+
await this.openExistingTable();
|
|
327
|
+
if (!this.table) {
|
|
328
|
+
console.error('VectorStore: Returning empty results as table does not exist');
|
|
329
|
+
return [];
|
|
330
|
+
}
|
|
331
|
+
if (limit < MIN_QUERY_LIMIT || limit > MAX_QUERY_LIMIT) {
|
|
332
|
+
throw new DatabaseError(`Invalid limit: expected ${MIN_QUERY_LIMIT}-${MAX_QUERY_LIMIT}, got ${limit}`);
|
|
333
|
+
}
|
|
334
|
+
try {
|
|
335
|
+
// Step 1: Semantic (vector) search - always the primary search
|
|
336
|
+
const candidateLimit = limit * HYBRID_SEARCH_CANDIDATE_MULTIPLIER;
|
|
337
|
+
let query = this.table
|
|
338
|
+
.vectorSearch(queryVector)
|
|
339
|
+
.distanceType('dot')
|
|
340
|
+
.select(['id', 'filePath', 'chunkIndex', 'text', 'metadata', 'fileTitle', '_distance'])
|
|
341
|
+
.limit(candidateLimit);
|
|
342
|
+
// Restrict to chunks under the given prefixes (exact-or-descendant)
|
|
343
|
+
// before ranking, and only when a scope was given.
|
|
344
|
+
if (scope && scope.length > 0) {
|
|
345
|
+
query = query.where(this.buildScopePredicate(scope));
|
|
346
|
+
}
|
|
347
|
+
// Apply distance threshold at query level
|
|
348
|
+
if (this.config.maxDistance !== undefined) {
|
|
349
|
+
query = query.distanceRange(undefined, this.config.maxDistance);
|
|
350
|
+
}
|
|
351
|
+
const vectorResults = await query.toArray();
|
|
352
|
+
// Convert to SearchResult format with type validation
|
|
353
|
+
let results = vectorResults.map((result) => toSearchResult(result));
|
|
354
|
+
// Step 2: Apply grouping filter on vector distances (before keyword boost)
|
|
355
|
+
// Grouping is meaningful only on semantic distances, not after keyword boost
|
|
356
|
+
if (this.config.grouping && results.length > 1) {
|
|
357
|
+
results = applyGrouping(results, this.config.grouping);
|
|
358
|
+
}
|
|
359
|
+
// `results.length > 0` guards the FTS branch: with zero vector hits the
|
|
360
|
+
// IN clause would degrade to a malformed `filePath IN ()`, and there is
|
|
361
|
+
// nothing to rerank anyway. FTS inherits scope through those hits.
|
|
362
|
+
const hybridWeight = this.config.hybridWeight ?? DEFAULT_HYBRID_WEIGHT;
|
|
363
|
+
if (this.ftsEnabled &&
|
|
364
|
+
queryText &&
|
|
365
|
+
queryText.trim().length > 0 &&
|
|
366
|
+
hybridWeight > 0 &&
|
|
367
|
+
results.length > 0) {
|
|
368
|
+
results = await this.boostWithKeywords(results, queryText, hybridWeight);
|
|
369
|
+
}
|
|
370
|
+
// Step 4: Apply file filter after keyword boost
|
|
371
|
+
// Unlike grouping (which depends on raw semantic distance gaps), maxFiles selects
|
|
372
|
+
// the "most relevant files" — this should respect the final ranking including keyword boost
|
|
373
|
+
if (this.config.maxFiles !== undefined && results.length > 0) {
|
|
374
|
+
results = applyFileFilter(results, this.config.maxFiles);
|
|
375
|
+
}
|
|
376
|
+
// Return top results after all filtering and boosting
|
|
377
|
+
return results.slice(0, limit);
|
|
378
|
+
}
|
|
379
|
+
catch (error) {
|
|
380
|
+
throw new DatabaseError('Failed to search vectors', { cause: toError(error) });
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Load and validate attachments for the ordered unique final search identities.
|
|
385
|
+
* Candidate retrieval and ranking are deliberately complete before this one
|
|
386
|
+
* projected batch query runs.
|
|
387
|
+
*/
|
|
388
|
+
async hydrateVisualAttachments(results) {
|
|
389
|
+
const ids = [];
|
|
390
|
+
const seen = new Set();
|
|
391
|
+
for (const result of results) {
|
|
392
|
+
if (typeof result.id !== 'string' || result.id.length === 0) {
|
|
393
|
+
throw new DatabaseError('Invalid final attachment hydration identity');
|
|
394
|
+
}
|
|
395
|
+
if (!seen.has(result.id)) {
|
|
396
|
+
seen.add(result.id);
|
|
397
|
+
ids.push(result.id);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
await this.openExistingTable();
|
|
401
|
+
if (!this.table || ids.length === 0) {
|
|
402
|
+
return {
|
|
403
|
+
rows: ids.map((id) => ({ id, attachments: [] })),
|
|
404
|
+
omittedCount: 0,
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
try {
|
|
408
|
+
const predicate = ids.map((id) => `\`id\` = '${this.escapeQuotes(id)}'`).join(' OR ');
|
|
409
|
+
const records = await this.table
|
|
410
|
+
.query()
|
|
411
|
+
.where(predicate)
|
|
412
|
+
.select(['id', 'visualAttachments'])
|
|
413
|
+
.toArray();
|
|
414
|
+
const recordsByIdentity = new Map();
|
|
415
|
+
for (const record of records) {
|
|
416
|
+
if (typeof record.id !== 'string') {
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
419
|
+
recordsByIdentity.set(record.id, record.visualAttachments);
|
|
420
|
+
}
|
|
421
|
+
let omittedCount = 0;
|
|
422
|
+
const rows = ids.map((id) => {
|
|
423
|
+
if (!recordsByIdentity.has(id)) {
|
|
424
|
+
omittedCount += 1;
|
|
425
|
+
return { id, attachments: [] };
|
|
426
|
+
}
|
|
427
|
+
const parsed = parseHydratedVisualAttachments(recordsByIdentity.get(id));
|
|
428
|
+
omittedCount += parsed.omittedCount;
|
|
429
|
+
return { id, attachments: parsed.attachments };
|
|
430
|
+
});
|
|
431
|
+
return { rows, omittedCount };
|
|
432
|
+
}
|
|
433
|
+
catch (error) {
|
|
434
|
+
throw new DatabaseError('Failed to hydrate visual attachments', { cause: toError(error) });
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* `.where()` predicate restricting `filePath` to the exact-or-descendant set
|
|
439
|
+
* of the given prefixes. The separator boundary stops `/a/b` from matching
|
|
440
|
+
* `/a/bc`. Vector branch only — FTS inherits scope via its own `IN (...)`.
|
|
441
|
+
*/
|
|
442
|
+
buildScopePredicate(prefixes) {
|
|
443
|
+
return prefixes.map((prefix) => this.buildPrefixPredicate(prefix)).join(' OR ');
|
|
444
|
+
}
|
|
445
|
+
/** Build the exact-or-descendant predicate for a single prefix. */
|
|
446
|
+
buildPrefixPredicate(prefix) {
|
|
447
|
+
const { exact, descendant } = normalizeScopePrefix(prefix);
|
|
448
|
+
const exactTerm = `\`filePath\` = '${this.escapeQuotes(exact)}'`;
|
|
449
|
+
const descendantTerm = `\`filePath\` LIKE '${this.escapeLike(descendant)}%' ESCAPE '\\'`;
|
|
450
|
+
return `(${exactTerm} OR ${descendantTerm})`;
|
|
451
|
+
}
|
|
452
|
+
/** Escape single quotes for a SQL string literal (mirrors deleteChunks). */
|
|
453
|
+
escapeQuotes(value) {
|
|
454
|
+
return value.replace(/'/g, "''");
|
|
455
|
+
}
|
|
456
|
+
/** Escape for a LIKE term with `ESCAPE '\'`: backslash first (else it double-escapes), then `%`, `_`, then quotes. */
|
|
457
|
+
escapeLike(value) {
|
|
458
|
+
return value
|
|
459
|
+
.replace(/\\/g, '\\\\')
|
|
460
|
+
.replace(/%/g, '\\%')
|
|
461
|
+
.replace(/_/g, '\\_')
|
|
462
|
+
.replace(/'/g, "''");
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Per-chunk `(filePath, contentHash, visualProfile)` projection used by
|
|
466
|
+
* incremental sync.
|
|
467
|
+
*
|
|
468
|
+
* One entry per row rather than per file, so a file whose rows disagree on the
|
|
469
|
+
* hash or the recorded profile is detectable as dirty. `filePath` is the
|
|
470
|
+
* verbatim stored spelling, since that is what {@link deleteChunks} matches.
|
|
471
|
+
* The empty-string placeholder the create path seeds for Arrow inference
|
|
472
|
+
* normalizes to `null`, while any other stored profile string reaches the
|
|
473
|
+
* planner unchanged so it can validate the vocabulary itself.
|
|
474
|
+
*
|
|
475
|
+
* Projects only those three columns, so a manifest load does not materialize
|
|
476
|
+
* embedding vectors or attachment payloads.
|
|
477
|
+
*/
|
|
478
|
+
async listSyncManifest() {
|
|
479
|
+
await this.openExistingTable();
|
|
480
|
+
if (!this.table) {
|
|
481
|
+
return [];
|
|
482
|
+
}
|
|
483
|
+
try {
|
|
484
|
+
const records = await this.table
|
|
485
|
+
.query()
|
|
486
|
+
.select(['filePath', 'contentHash', 'visualProfile'])
|
|
487
|
+
.toArray();
|
|
488
|
+
const entries = [];
|
|
489
|
+
for (const record of records) {
|
|
490
|
+
const filePath = record.filePath;
|
|
491
|
+
const contentHash = record.contentHash;
|
|
492
|
+
const visualProfile = record.visualProfile;
|
|
493
|
+
// Type-guard parity with listFiles: skip rows missing the expected
|
|
494
|
+
// string column rather than coercing via `as string`.
|
|
495
|
+
if (typeof filePath !== 'string') {
|
|
496
|
+
continue;
|
|
497
|
+
}
|
|
498
|
+
entries.push({
|
|
499
|
+
filePath,
|
|
500
|
+
contentHash: typeof contentHash === 'string' && contentHash.length > 0 ? contentHash : null,
|
|
501
|
+
visualProfile: typeof visualProfile === 'string' && visualProfile.length > 0 ? visualProfile : null,
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
return entries;
|
|
505
|
+
}
|
|
506
|
+
catch (error) {
|
|
507
|
+
throw new DatabaseError('Failed to list the sync manifest', { cause: toError(error) });
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Get list of ingested files
|
|
512
|
+
*/
|
|
513
|
+
async listFiles() {
|
|
514
|
+
await this.openExistingTable();
|
|
515
|
+
if (!this.table) {
|
|
516
|
+
return []; // Return empty array if table doesn't exist
|
|
517
|
+
}
|
|
518
|
+
try {
|
|
519
|
+
// Project to only the columns needed for aggregation, excluding the
|
|
520
|
+
// embedding vector payload. LanceDB JS has no group-by, so the per-file
|
|
521
|
+
// count + latest-timestamp aggregation still runs here — but over a much
|
|
522
|
+
// smaller row payload than a full `query().toArray()`.
|
|
523
|
+
const allRecords = await this.table.query().select(['filePath', 'timestamp']).toArray();
|
|
524
|
+
// Group by file path
|
|
525
|
+
const fileMap = new Map();
|
|
526
|
+
for (const record of allRecords) {
|
|
527
|
+
const filePath = record.filePath;
|
|
528
|
+
const timestamp = record.timestamp;
|
|
529
|
+
// Type-guard parity with toSearchResult/toChunkRow: skip rows missing
|
|
530
|
+
// the expected string columns rather than coercing via `as string`.
|
|
531
|
+
if (typeof filePath !== 'string' || typeof timestamp !== 'string') {
|
|
532
|
+
continue;
|
|
533
|
+
}
|
|
534
|
+
const fileInfo = fileMap.get(filePath);
|
|
535
|
+
if (fileInfo === undefined) {
|
|
536
|
+
fileMap.set(filePath, { chunkCount: 1, timestamp });
|
|
537
|
+
continue;
|
|
538
|
+
}
|
|
539
|
+
fileInfo.chunkCount += 1;
|
|
540
|
+
// Keep most recent timestamp
|
|
541
|
+
fileInfo.timestamp = timestamp > fileInfo.timestamp ? timestamp : fileInfo.timestamp;
|
|
542
|
+
}
|
|
543
|
+
// Convert Map to array of objects
|
|
544
|
+
return Array.from(fileMap.entries()).map(([filePath, info]) => ({
|
|
545
|
+
filePath,
|
|
546
|
+
chunkCount: info.chunkCount,
|
|
547
|
+
timestamp: info.timestamp,
|
|
548
|
+
}));
|
|
549
|
+
}
|
|
550
|
+
catch (error) {
|
|
551
|
+
throw new DatabaseError('Failed to list files', { cause: toError(error) });
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Get system status
|
|
556
|
+
*/
|
|
557
|
+
async getStatus() {
|
|
558
|
+
await this.openExistingTable();
|
|
559
|
+
if (!this.table) {
|
|
560
|
+
return {
|
|
561
|
+
documentCount: 0,
|
|
562
|
+
chunkCount: 0,
|
|
563
|
+
memoryUsage: 0,
|
|
564
|
+
uptime: process.uptime(),
|
|
565
|
+
ftsIndexEnabled: false,
|
|
566
|
+
searchMode: 'vector-only',
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
try {
|
|
570
|
+
// Total chunk count comes straight from LanceDB's row count — no need to
|
|
571
|
+
// materialize every row just to read `.length`.
|
|
572
|
+
const chunkCount = await this.table.countRows();
|
|
573
|
+
// Distinct document count: LanceDB JS has no DISTINCT, so project to just
|
|
574
|
+
// the filePath column (excludes the vector payload) and dedupe here.
|
|
575
|
+
const records = await this.table.query().select(['filePath']).toArray();
|
|
576
|
+
const uniqueFilePaths = new Set();
|
|
577
|
+
for (const record of records) {
|
|
578
|
+
const filePath = record.filePath;
|
|
579
|
+
if (typeof filePath === 'string') {
|
|
580
|
+
uniqueFilePaths.add(filePath);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
const documentCount = uniqueFilePaths.size;
|
|
584
|
+
// Get memory usage (in MB)
|
|
585
|
+
const memoryUsage = process.memoryUsage().heapUsed / 1024 / 1024;
|
|
586
|
+
// Get uptime (in seconds)
|
|
587
|
+
const uptime = process.uptime();
|
|
588
|
+
return {
|
|
589
|
+
documentCount,
|
|
590
|
+
chunkCount,
|
|
591
|
+
memoryUsage,
|
|
592
|
+
uptime,
|
|
593
|
+
ftsIndexEnabled: this.ftsEnabled,
|
|
594
|
+
searchMode: this.ftsEnabled && (this.config.hybridWeight ?? DEFAULT_HYBRID_WEIGHT) > 0
|
|
595
|
+
? 'hybrid'
|
|
596
|
+
: 'vector-only',
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
catch (error) {
|
|
600
|
+
throw new DatabaseError('Failed to get status', { cause: toError(error) });
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* Close the database connection
|
|
605
|
+
*/
|
|
606
|
+
async close() {
|
|
607
|
+
if (this.db) {
|
|
608
|
+
// LanceDB Connections should be closed to release file handles
|
|
609
|
+
this.db.close();
|
|
610
|
+
this.db = null;
|
|
611
|
+
this.table = null;
|
|
612
|
+
this.ftsEnabled = false;
|
|
613
|
+
console.error('VectorStore connection closed');
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vectordb/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { GroupingMode, SearchResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Cut the distance-sorted results at gaps wider than `mean + k*std`:
|
|
4
|
+
* `similar` keeps the first group, `related` up to two.
|
|
5
|
+
*/
|
|
6
|
+
export declare function applyGrouping(results: SearchResult[], mode: GroupingMode): SearchResult[];
|
|
7
|
+
/**
|
|
8
|
+
* Rank files by their best (lowest-distance) chunk and keep only the top
|
|
9
|
+
* `maxFiles` files' chunks.
|
|
10
|
+
*/
|
|
11
|
+
export declare function applyFileFilter(results: SearchResult[], maxFiles: number): SearchResult[];
|
|
12
|
+
/** One raw row from a LanceDB full-text search; entries can be missing. */
|
|
13
|
+
export type FtsRow = Record<string, unknown> | null | undefined;
|
|
14
|
+
export declare function applyKeywordBoost(vectorResults: SearchResult[], ftsResults: readonly FtsRow[], weight: number): SearchResult[];
|
|
15
|
+
//# sourceMappingURL=search-filters.d.ts.map
|