@robthepcguy/rag-vault 1.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/LICENSE +24 -0
- package/README.md +421 -0
- package/dist/bin/install-skills.d.ts +20 -0
- package/dist/bin/install-skills.d.ts.map +1 -0
- package/dist/bin/install-skills.js +196 -0
- package/dist/bin/install-skills.js.map +1 -0
- package/dist/chunker/index.d.ts +11 -0
- package/dist/chunker/index.d.ts.map +1 -0
- package/dist/chunker/index.js +6 -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 +267 -0
- package/dist/chunker/semantic-chunker.js.map +1 -0
- package/dist/chunker/sentence-splitter.d.ts +16 -0
- package/dist/chunker/sentence-splitter.d.ts.map +1 -0
- package/dist/chunker/sentence-splitter.js +114 -0
- package/dist/chunker/sentence-splitter.js.map +1 -0
- package/dist/embedder/index.d.ts +55 -0
- package/dist/embedder/index.d.ts.map +1 -0
- package/dist/embedder/index.js +146 -0
- package/dist/embedder/index.js.map +1 -0
- package/dist/errors/index.d.ts +73 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +170 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/html-parser.d.ts +14 -0
- package/dist/parser/html-parser.d.ts.map +1 -0
- package/dist/parser/html-parser.js +99 -0
- package/dist/parser/html-parser.js.map +1 -0
- package/dist/parser/index.d.ts +144 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +446 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/pdf-filter.d.ts +89 -0
- package/dist/parser/pdf-filter.d.ts.map +1 -0
- package/dist/parser/pdf-filter.js +304 -0
- package/dist/parser/pdf-filter.js.map +1 -0
- package/dist/server/index.d.ts +144 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +518 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/raw-data-utils.d.ts +81 -0
- package/dist/server/raw-data-utils.d.ts.map +1 -0
- package/dist/server/raw-data-utils.js +196 -0
- package/dist/server/raw-data-utils.js.map +1 -0
- package/dist/server/schemas.d.ts +186 -0
- package/dist/server/schemas.d.ts.map +1 -0
- package/dist/server/schemas.js +99 -0
- package/dist/server/schemas.js.map +1 -0
- package/dist/utils/config-parsers.d.ts +14 -0
- package/dist/utils/config-parsers.d.ts.map +1 -0
- package/dist/utils/config-parsers.js +47 -0
- package/dist/utils/config-parsers.js.map +1 -0
- package/dist/utils/config.d.ts +37 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +52 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/logger.d.ts +36 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +64 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/math.d.ts +34 -0
- package/dist/utils/math.d.ts.map +1 -0
- package/dist/utils/math.js +73 -0
- package/dist/utils/math.js.map +1 -0
- package/dist/utils/process-handlers.d.ts +26 -0
- package/dist/utils/process-handlers.d.ts.map +1 -0
- package/dist/utils/process-handlers.js +69 -0
- package/dist/utils/process-handlers.js.map +1 -0
- package/dist/vectordb/index.d.ts +210 -0
- package/dist/vectordb/index.d.ts.map +1 -0
- package/dist/vectordb/index.js +613 -0
- package/dist/vectordb/index.js.map +1 -0
- package/dist/web/api-routes.d.ts +9 -0
- package/dist/web/api-routes.d.ts.map +1 -0
- package/dist/web/api-routes.js +127 -0
- package/dist/web/api-routes.js.map +1 -0
- package/dist/web/config-routes.d.ts +7 -0
- package/dist/web/config-routes.d.ts.map +1 -0
- package/dist/web/config-routes.js +54 -0
- package/dist/web/config-routes.js.map +1 -0
- package/dist/web/database-manager.d.ts +130 -0
- package/dist/web/database-manager.d.ts.map +1 -0
- package/dist/web/database-manager.js +382 -0
- package/dist/web/database-manager.js.map +1 -0
- package/dist/web/http-server.d.ts +28 -0
- package/dist/web/http-server.d.ts.map +1 -0
- package/dist/web/http-server.js +311 -0
- package/dist/web/http-server.js.map +1 -0
- package/dist/web/index.d.ts +3 -0
- package/dist/web/index.d.ts.map +1 -0
- package/dist/web/index.js +114 -0
- package/dist/web/index.js.map +1 -0
- package/dist/web/middleware/async-handler.d.ts +17 -0
- package/dist/web/middleware/async-handler.d.ts.map +1 -0
- package/dist/web/middleware/async-handler.js +26 -0
- package/dist/web/middleware/async-handler.js.map +1 -0
- package/dist/web/middleware/auth.d.ts +22 -0
- package/dist/web/middleware/auth.d.ts.map +1 -0
- package/dist/web/middleware/auth.js +81 -0
- package/dist/web/middleware/auth.js.map +1 -0
- package/dist/web/middleware/error-handler.d.ts +36 -0
- package/dist/web/middleware/error-handler.d.ts.map +1 -0
- package/dist/web/middleware/error-handler.js +68 -0
- package/dist/web/middleware/error-handler.js.map +1 -0
- package/dist/web/middleware/index.d.ts +6 -0
- package/dist/web/middleware/index.d.ts.map +1 -0
- package/dist/web/middleware/index.js +19 -0
- package/dist/web/middleware/index.js.map +1 -0
- package/dist/web/middleware/rate-limit.d.ts +38 -0
- package/dist/web/middleware/rate-limit.d.ts.map +1 -0
- package/dist/web/middleware/rate-limit.js +116 -0
- package/dist/web/middleware/rate-limit.js.map +1 -0
- package/dist/web/middleware/request-logger.d.ts +52 -0
- package/dist/web/middleware/request-logger.d.ts.map +1 -0
- package/dist/web/middleware/request-logger.js +74 -0
- package/dist/web/middleware/request-logger.js.map +1 -0
- package/dist/web/types.d.ts +6 -0
- package/dist/web/types.d.ts.map +1 -0
- package/dist/web/types.js +4 -0
- package/dist/web/types.js.map +1 -0
- package/package.json +135 -0
- package/skills/rag-vault/SKILL.md +111 -0
- package/skills/rag-vault/references/html-ingestion.md +73 -0
- package/skills/rag-vault/references/query-optimization.md +57 -0
- package/skills/rag-vault/references/result-refinement.md +54 -0
|
@@ -0,0 +1,613 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// VectorStore implementation with LanceDB integration
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.VectorStore = exports.DatabaseError = void 0;
|
|
5
|
+
const lancedb_1 = require("@lancedb/lancedb");
|
|
6
|
+
const index_js_1 = require("../errors/index.js");
|
|
7
|
+
// Re-export error class for backwards compatibility
|
|
8
|
+
var index_js_2 = require("../errors/index.js");
|
|
9
|
+
Object.defineProperty(exports, "DatabaseError", { enumerable: true, get: function () { return index_js_2.DatabaseError; } });
|
|
10
|
+
// ============================================
|
|
11
|
+
// Constants
|
|
12
|
+
// ============================================
|
|
13
|
+
/**
|
|
14
|
+
* Standard deviation multiplier for detecting group boundaries.
|
|
15
|
+
* A gap is considered a "boundary" if it exceeds mean + k*std.
|
|
16
|
+
* Value of 1.5 means gaps > 1.5 standard deviations above mean are boundaries.
|
|
17
|
+
*/
|
|
18
|
+
const GROUPING_BOUNDARY_STD_MULTIPLIER = 1.5;
|
|
19
|
+
/** Multiplier for candidate count in hybrid search (to allow reranking) */
|
|
20
|
+
const HYBRID_SEARCH_CANDIDATE_MULTIPLIER = 2;
|
|
21
|
+
/** FTS index name (bump version when changing tokenizer settings) */
|
|
22
|
+
const FTS_INDEX_NAME = 'fts_index_v2';
|
|
23
|
+
/** Threshold for cleaning up old index versions (1 minute) */
|
|
24
|
+
const FTS_CLEANUP_THRESHOLD_MS = 60 * 1000;
|
|
25
|
+
/** FTS circuit breaker: max failures before disabling FTS */
|
|
26
|
+
const FTS_MAX_FAILURES = 3;
|
|
27
|
+
/** FTS circuit breaker: cooldown period before retry (5 minutes) */
|
|
28
|
+
const FTS_COOLDOWN_MS = 5 * 60 * 1000;
|
|
29
|
+
// ============================================
|
|
30
|
+
// Error Codes (for robust error handling)
|
|
31
|
+
// ============================================
|
|
32
|
+
/**
|
|
33
|
+
* Known LanceDB error patterns for delete operations
|
|
34
|
+
* Used instead of fragile string matching
|
|
35
|
+
*/
|
|
36
|
+
const DELETE_IGNORABLE_PATTERNS = [
|
|
37
|
+
'not found',
|
|
38
|
+
'does not exist',
|
|
39
|
+
'no matching',
|
|
40
|
+
'no rows',
|
|
41
|
+
'empty result',
|
|
42
|
+
];
|
|
43
|
+
/**
|
|
44
|
+
* Regex for validating file paths before use in queries.
|
|
45
|
+
* Allows alphanumeric characters, slashes, dots, underscores, hyphens, colons (Windows), and spaces.
|
|
46
|
+
* Rejects paths with SQL injection attempts or path traversal.
|
|
47
|
+
*/
|
|
48
|
+
const SAFE_PATH_REGEX = /^[a-zA-Z0-9\\/_.:\- ]+$/;
|
|
49
|
+
/**
|
|
50
|
+
* Validate file path to prevent SQL injection and path traversal attacks.
|
|
51
|
+
* @param filePath - The file path to validate
|
|
52
|
+
* @returns true if path is safe for use in queries
|
|
53
|
+
*/
|
|
54
|
+
function isValidFilePath(filePath) {
|
|
55
|
+
if (!filePath || typeof filePath !== 'string')
|
|
56
|
+
return false;
|
|
57
|
+
if (filePath.includes('..'))
|
|
58
|
+
return false; // Path traversal
|
|
59
|
+
if (filePath.includes("'") || filePath.includes('"'))
|
|
60
|
+
return false; // Quote injection
|
|
61
|
+
if (filePath.includes(';'))
|
|
62
|
+
return false; // SQL terminator
|
|
63
|
+
if (filePath.includes('--'))
|
|
64
|
+
return false; // SQL comment
|
|
65
|
+
return SAFE_PATH_REGEX.test(filePath);
|
|
66
|
+
}
|
|
67
|
+
// ============================================
|
|
68
|
+
// Type Guards
|
|
69
|
+
// ============================================
|
|
70
|
+
/**
|
|
71
|
+
* Type guard for DocumentMetadata
|
|
72
|
+
*/
|
|
73
|
+
function isDocumentMetadata(value) {
|
|
74
|
+
if (typeof value !== 'object' || value === null)
|
|
75
|
+
return false;
|
|
76
|
+
const obj = value;
|
|
77
|
+
return (typeof obj['fileName'] === 'string' &&
|
|
78
|
+
typeof obj['fileSize'] === 'number' &&
|
|
79
|
+
typeof obj['fileType'] === 'string');
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Type guard for LanceDB raw search result
|
|
83
|
+
*/
|
|
84
|
+
function isLanceDBRawResult(value) {
|
|
85
|
+
if (typeof value !== 'object' || value === null)
|
|
86
|
+
return false;
|
|
87
|
+
const obj = value;
|
|
88
|
+
return (typeof obj['filePath'] === 'string' &&
|
|
89
|
+
typeof obj['chunkIndex'] === 'number' &&
|
|
90
|
+
typeof obj['text'] === 'string' &&
|
|
91
|
+
isDocumentMetadata(obj['metadata']));
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Convert LanceDB raw result to SearchResult with type validation
|
|
95
|
+
* @throws DatabaseError if the result is invalid
|
|
96
|
+
*/
|
|
97
|
+
function toSearchResult(raw) {
|
|
98
|
+
if (!isLanceDBRawResult(raw)) {
|
|
99
|
+
throw new index_js_1.DatabaseError('Invalid search result format from LanceDB');
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
filePath: raw.filePath,
|
|
103
|
+
chunkIndex: raw.chunkIndex,
|
|
104
|
+
text: raw.text,
|
|
105
|
+
score: raw._distance ?? raw._score ?? 0,
|
|
106
|
+
metadata: raw.metadata,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// ============================================
|
|
110
|
+
// VectorStore Class
|
|
111
|
+
// ============================================
|
|
112
|
+
/**
|
|
113
|
+
* Vector storage class using LanceDB
|
|
114
|
+
*
|
|
115
|
+
* Responsibilities:
|
|
116
|
+
* - LanceDB operations (insert, delete, search)
|
|
117
|
+
* - Transaction handling (atomicity of delete→insert)
|
|
118
|
+
* - Metadata management
|
|
119
|
+
*
|
|
120
|
+
* FTS Circuit Breaker:
|
|
121
|
+
* - Tracks FTS failures (max 3 before disabling)
|
|
122
|
+
* - Auto-recovers after 5-minute cooldown
|
|
123
|
+
* - Prevents permanent FTS disable from transient errors
|
|
124
|
+
*/
|
|
125
|
+
class VectorStore {
|
|
126
|
+
constructor(config) {
|
|
127
|
+
this.db = null;
|
|
128
|
+
this.table = null;
|
|
129
|
+
this.ftsEnabled = false;
|
|
130
|
+
this.ftsFailureCount = 0;
|
|
131
|
+
this.ftsLastFailure = null;
|
|
132
|
+
/** Mutex to prevent race conditions in circuit breaker state transitions */
|
|
133
|
+
this.circuitBreakerResetting = false;
|
|
134
|
+
this.config = config;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Check if FTS should be attempted (circuit breaker logic)
|
|
138
|
+
* - Returns false if max failures reached and cooldown not elapsed
|
|
139
|
+
* - Resets failure count after successful cooldown period
|
|
140
|
+
* - Uses mutex to prevent race conditions during reset
|
|
141
|
+
*/
|
|
142
|
+
shouldAttemptFts() {
|
|
143
|
+
if (!this.ftsEnabled)
|
|
144
|
+
return false;
|
|
145
|
+
// If under failure threshold, allow FTS
|
|
146
|
+
if (this.ftsFailureCount < FTS_MAX_FAILURES)
|
|
147
|
+
return true;
|
|
148
|
+
// Check if cooldown period has elapsed
|
|
149
|
+
if (this.ftsLastFailure && Date.now() - this.ftsLastFailure > FTS_COOLDOWN_MS) {
|
|
150
|
+
// Use mutex to prevent multiple concurrent resets (race condition protection)
|
|
151
|
+
if (this.circuitBreakerResetting) {
|
|
152
|
+
// Another call is already resetting, don't allow FTS yet
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
// Acquire mutex and reset circuit breaker (half-open state)
|
|
156
|
+
this.circuitBreakerResetting = true;
|
|
157
|
+
this.ftsFailureCount = 0;
|
|
158
|
+
this.ftsLastFailure = null;
|
|
159
|
+
this.circuitBreakerResetting = false;
|
|
160
|
+
console.error('VectorStore: FTS circuit breaker reset - attempting recovery');
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Record FTS failure (circuit breaker)
|
|
167
|
+
*/
|
|
168
|
+
recordFtsFailure(error) {
|
|
169
|
+
this.ftsFailureCount++;
|
|
170
|
+
this.ftsLastFailure = Date.now();
|
|
171
|
+
console.error(`VectorStore: FTS failure ${this.ftsFailureCount}/${FTS_MAX_FAILURES}: ${error.message}`);
|
|
172
|
+
if (this.ftsFailureCount >= FTS_MAX_FAILURES) {
|
|
173
|
+
console.error(`VectorStore: FTS circuit breaker OPEN - will retry after ${FTS_COOLDOWN_MS / 1000}s cooldown`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Record FTS success (resets circuit breaker)
|
|
178
|
+
*/
|
|
179
|
+
recordFtsSuccess() {
|
|
180
|
+
if (this.ftsFailureCount > 0) {
|
|
181
|
+
console.error('VectorStore: FTS recovered successfully - circuit breaker reset');
|
|
182
|
+
this.ftsFailureCount = 0;
|
|
183
|
+
this.ftsLastFailure = null;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Initialize LanceDB and create table
|
|
188
|
+
*/
|
|
189
|
+
async initialize() {
|
|
190
|
+
try {
|
|
191
|
+
// Connect to LanceDB
|
|
192
|
+
this.db = await (0, lancedb_1.connect)(this.config.dbPath);
|
|
193
|
+
// Check table existence and create if needed
|
|
194
|
+
const tableNames = await this.db.tableNames();
|
|
195
|
+
if (tableNames.includes(this.config.tableName)) {
|
|
196
|
+
// Open existing table
|
|
197
|
+
this.table = await this.db.openTable(this.config.tableName);
|
|
198
|
+
console.error(`VectorStore: Opened existing table "${this.config.tableName}"`);
|
|
199
|
+
// Ensure FTS index exists (migration for existing databases)
|
|
200
|
+
await this.ensureFtsIndex();
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
// Create new table (schema auto-defined on first data insertion)
|
|
204
|
+
console.error(`VectorStore: Table "${this.config.tableName}" will be created on first data insertion`);
|
|
205
|
+
}
|
|
206
|
+
console.error(`VectorStore initialized: ${this.config.dbPath}`);
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
throw new index_js_1.DatabaseError('Failed to initialize VectorStore', error);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Delete all chunks for specified file path
|
|
214
|
+
*
|
|
215
|
+
* @param filePath - File path (absolute)
|
|
216
|
+
*/
|
|
217
|
+
async deleteChunks(filePath) {
|
|
218
|
+
if (!this.table) {
|
|
219
|
+
// If table doesn't exist, no deletion targets, return normally
|
|
220
|
+
console.error('VectorStore: Skipping deletion as table does not exist');
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
// Validate file path before use in query to prevent SQL injection
|
|
224
|
+
if (!isValidFilePath(filePath)) {
|
|
225
|
+
throw new index_js_1.DatabaseError(`Invalid file path: contains disallowed characters or patterns`);
|
|
226
|
+
}
|
|
227
|
+
// Escape path before try block so it's available in catch for logging
|
|
228
|
+
const escapedFilePath = filePath.replace(/'/g, "''");
|
|
229
|
+
try {
|
|
230
|
+
// Use LanceDB delete API to remove records matching filePath
|
|
231
|
+
// Path is pre-validated, escaping is belt-and-suspenders defense
|
|
232
|
+
// LanceDB's delete method doesn't throw errors if targets don't exist,
|
|
233
|
+
// so call delete directly
|
|
234
|
+
// Note: Field names are case-sensitive, use backticks for camelCase fields
|
|
235
|
+
await this.table.delete(`\`filePath\` = '${escapedFilePath}'`);
|
|
236
|
+
console.error(`VectorStore: Deleted chunks for file "${filePath}"`);
|
|
237
|
+
// Rebuild FTS index after deleting data
|
|
238
|
+
await this.rebuildFtsIndex();
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
// Build error context for debugging
|
|
242
|
+
const errorContext = {
|
|
243
|
+
operation: 'deleteChunks',
|
|
244
|
+
filePath,
|
|
245
|
+
query: `\`filePath\` = '${escapedFilePath}'`,
|
|
246
|
+
errorMessage: error.message,
|
|
247
|
+
};
|
|
248
|
+
console.warn('VectorStore delete error:', errorContext);
|
|
249
|
+
// Check if this is a known ignorable error (no matching records)
|
|
250
|
+
const errorMessage = error.message.toLowerCase();
|
|
251
|
+
const isIgnorable = DELETE_IGNORABLE_PATTERNS.some((pattern) => errorMessage.includes(pattern));
|
|
252
|
+
if (!isIgnorable) {
|
|
253
|
+
throw new index_js_1.DatabaseError(`Failed to delete chunks for file: ${filePath}`, error);
|
|
254
|
+
}
|
|
255
|
+
// Ignorable errors (no matching records) are logged but not thrown
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Batch insert vector chunks
|
|
260
|
+
*
|
|
261
|
+
* @param chunks - Array of vector chunks
|
|
262
|
+
*/
|
|
263
|
+
async insertChunks(chunks) {
|
|
264
|
+
if (chunks.length === 0) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
try {
|
|
268
|
+
if (!this.table) {
|
|
269
|
+
// Create table on first insertion
|
|
270
|
+
if (!this.db) {
|
|
271
|
+
throw new index_js_1.DatabaseError('VectorStore is not initialized. Call initialize() first.');
|
|
272
|
+
}
|
|
273
|
+
// LanceDB's createTable API accepts data as Record<string, unknown>[]
|
|
274
|
+
const records = chunks.map((chunk) => chunk);
|
|
275
|
+
this.table = await this.db.createTable(this.config.tableName, records);
|
|
276
|
+
console.error(`VectorStore: Created table "${this.config.tableName}"`);
|
|
277
|
+
// Create FTS index for hybrid search
|
|
278
|
+
await this.ensureFtsIndex();
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
// Add data to existing table
|
|
282
|
+
const records = chunks.map((chunk) => chunk);
|
|
283
|
+
await this.table.add(records);
|
|
284
|
+
// Rebuild FTS index after adding new data
|
|
285
|
+
await this.rebuildFtsIndex();
|
|
286
|
+
}
|
|
287
|
+
console.error(`VectorStore: Inserted ${chunks.length} chunks`);
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
throw new index_js_1.DatabaseError('Failed to insert chunks', error);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Ensure FTS index exists for hybrid search
|
|
295
|
+
* Creates ngram-based index if it doesn't exist, drops old versions
|
|
296
|
+
* @throws DatabaseError if index creation fails (Fail-Fast principle)
|
|
297
|
+
*/
|
|
298
|
+
async ensureFtsIndex() {
|
|
299
|
+
if (!this.table) {
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
// Check existing indices
|
|
303
|
+
const indices = await this.table.listIndices();
|
|
304
|
+
const existingFtsIndices = indices.filter((idx) => idx.indexType === 'FTS');
|
|
305
|
+
const hasExpectedIndex = existingFtsIndices.some((idx) => idx.name === FTS_INDEX_NAME);
|
|
306
|
+
if (hasExpectedIndex) {
|
|
307
|
+
this.ftsEnabled = true;
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
// Create new FTS index with ngram tokenizer for multilingual support
|
|
311
|
+
// - min=2: Capture Japanese bi-grams (e.g., "東京", "設計")
|
|
312
|
+
// - max=3: Balance between precision and index size
|
|
313
|
+
// - prefixOnly=false: Generate ngrams from all positions for proper CJK support
|
|
314
|
+
await this.table.createIndex('text', {
|
|
315
|
+
config: lancedb_1.Index.fts({
|
|
316
|
+
baseTokenizer: 'ngram',
|
|
317
|
+
ngramMinLength: 2,
|
|
318
|
+
ngramMaxLength: 3,
|
|
319
|
+
prefixOnly: false,
|
|
320
|
+
stem: false,
|
|
321
|
+
}),
|
|
322
|
+
name: FTS_INDEX_NAME,
|
|
323
|
+
});
|
|
324
|
+
this.ftsEnabled = true;
|
|
325
|
+
console.error(`VectorStore: FTS index "${FTS_INDEX_NAME}" created successfully`);
|
|
326
|
+
// Drop old FTS indices
|
|
327
|
+
for (const idx of existingFtsIndices) {
|
|
328
|
+
if (idx.name !== FTS_INDEX_NAME) {
|
|
329
|
+
await this.table.dropIndex(idx.name);
|
|
330
|
+
console.error(`VectorStore: Dropped old FTS index "${idx.name}"`);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Rebuild FTS index after data changes (insert/delete)
|
|
336
|
+
* LanceDB OSS requires explicit optimize() call to update FTS index
|
|
337
|
+
* Also cleans up old index versions to prevent storage bloat
|
|
338
|
+
*/
|
|
339
|
+
async rebuildFtsIndex() {
|
|
340
|
+
if (!this.table || !this.ftsEnabled) {
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
// TODO(perf): optimize() after every write keeps FTS correct, but can be expensive at scale.
|
|
344
|
+
// If ingestion throughput becomes an issue, consider debouncing or batching optimize calls.
|
|
345
|
+
// Optimize table and clean up old versions
|
|
346
|
+
const cleanupThreshold = new Date(Date.now() - FTS_CLEANUP_THRESHOLD_MS);
|
|
347
|
+
await this.table.optimize({ cleanupOlderThan: cleanupThreshold });
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Apply grouping algorithm to filter results by detecting group boundaries.
|
|
351
|
+
*
|
|
352
|
+
* Uses statistical threshold (mean + k*std) to identify significant gaps (group boundaries).
|
|
353
|
+
* - 'similar': Returns only the first group (cuts at first boundary)
|
|
354
|
+
* - 'related': Returns up to 2 groups (cuts at second boundary)
|
|
355
|
+
*
|
|
356
|
+
* @param results - Search results sorted by distance (ascending)
|
|
357
|
+
* @param mode - Grouping mode ('similar' = 1 group, 'related' = 2 groups)
|
|
358
|
+
* @returns Filtered results
|
|
359
|
+
*/
|
|
360
|
+
applyGrouping(results, mode) {
|
|
361
|
+
if (results.length <= 1)
|
|
362
|
+
return results;
|
|
363
|
+
// Calculate gaps between consecutive results with their indices
|
|
364
|
+
const gaps = [];
|
|
365
|
+
for (let i = 0; i < results.length - 1; i++) {
|
|
366
|
+
const current = results[i];
|
|
367
|
+
const next = results[i + 1];
|
|
368
|
+
if (current !== undefined && next !== undefined) {
|
|
369
|
+
gaps.push({ index: i + 1, gap: next.score - current.score });
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
if (gaps.length === 0)
|
|
373
|
+
return results;
|
|
374
|
+
// Calculate statistical threshold to identify significant gaps (group boundaries)
|
|
375
|
+
const gapValues = gaps.map((g) => g.gap);
|
|
376
|
+
const mean = gapValues.reduce((a, b) => a + b, 0) / gapValues.length;
|
|
377
|
+
const variance = gapValues.reduce((a, b) => a + (b - mean) ** 2, 0) / gapValues.length;
|
|
378
|
+
const std = Math.sqrt(variance);
|
|
379
|
+
const threshold = mean + GROUPING_BOUNDARY_STD_MULTIPLIER * std;
|
|
380
|
+
// Find all significant gaps (group boundaries)
|
|
381
|
+
const boundaries = gaps.filter((g) => g.gap > threshold).map((g) => g.index);
|
|
382
|
+
// If no boundaries found, return all results
|
|
383
|
+
if (boundaries.length === 0)
|
|
384
|
+
return results;
|
|
385
|
+
// Determine how many groups to include based on mode
|
|
386
|
+
// 'similar': 1 group (cut at first boundary)
|
|
387
|
+
// 'related': 2 groups (cut at second boundary, or return all if only 1 boundary)
|
|
388
|
+
const groupsToInclude = mode === 'similar' ? 1 : 2;
|
|
389
|
+
const boundaryIndex = groupsToInclude - 1;
|
|
390
|
+
// If we don't have enough boundaries, return all results for 'related' mode
|
|
391
|
+
if (boundaryIndex >= boundaries.length) {
|
|
392
|
+
return mode === 'related' ? results : results.slice(0, boundaries[0]);
|
|
393
|
+
}
|
|
394
|
+
// Cut at the appropriate boundary
|
|
395
|
+
return results.slice(0, boundaries[boundaryIndex]);
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Execute vector search with quality filtering
|
|
399
|
+
* Architecture: Semantic search → Filter (maxDistance, grouping) → Keyword boost
|
|
400
|
+
*
|
|
401
|
+
* This "prefetch then rerank" approach ensures:
|
|
402
|
+
* - maxDistance and grouping work on meaningful vector distances
|
|
403
|
+
* - Keyword matching acts as a boost, not a replacement for semantic similarity
|
|
404
|
+
*
|
|
405
|
+
* @param queryVector - Query vector (dimension depends on model)
|
|
406
|
+
* @param queryText - Optional query text for keyword boost (BM25)
|
|
407
|
+
* @param limit - Number of results to retrieve (default 10)
|
|
408
|
+
* @returns Array of search results (sorted by distance ascending, filtered by quality settings)
|
|
409
|
+
*/
|
|
410
|
+
async search(queryVector, queryText, limit = 10) {
|
|
411
|
+
if (!this.table) {
|
|
412
|
+
console.error('VectorStore: Returning empty results as table does not exist');
|
|
413
|
+
return [];
|
|
414
|
+
}
|
|
415
|
+
if (limit < 1 || limit > 20) {
|
|
416
|
+
throw new index_js_1.DatabaseError(`Invalid limit: expected 1-20, got ${limit}`);
|
|
417
|
+
}
|
|
418
|
+
try {
|
|
419
|
+
// Step 1: Semantic (vector) search - always the primary search
|
|
420
|
+
const candidateLimit = limit * HYBRID_SEARCH_CANDIDATE_MULTIPLIER;
|
|
421
|
+
// Assumes normalized embeddings so dot behaves like cosine distance (lower is better, [0,2]).
|
|
422
|
+
let query = this.table.vectorSearch(queryVector).distanceType('dot').limit(candidateLimit);
|
|
423
|
+
// Apply distance threshold at query level
|
|
424
|
+
if (this.config.maxDistance !== undefined) {
|
|
425
|
+
query = query.distanceRange(undefined, this.config.maxDistance);
|
|
426
|
+
}
|
|
427
|
+
const vectorResults = await query.toArray();
|
|
428
|
+
// Convert to SearchResult format with type validation
|
|
429
|
+
let results = vectorResults.map((result) => toSearchResult(result));
|
|
430
|
+
// Step 2: Apply grouping filter on vector distances (before keyword boost)
|
|
431
|
+
// Grouping is meaningful only on semantic distances, not after keyword boost
|
|
432
|
+
if (this.config.grouping && results.length > 1) {
|
|
433
|
+
results = this.applyGrouping(results, this.config.grouping);
|
|
434
|
+
}
|
|
435
|
+
// Step 3: Apply keyword boost if enabled (with circuit breaker)
|
|
436
|
+
const hybridWeight = this.config.hybridWeight ?? 0.6;
|
|
437
|
+
if (this.shouldAttemptFts() && queryText && queryText.trim().length > 0 && hybridWeight > 0) {
|
|
438
|
+
try {
|
|
439
|
+
// Get unique filePaths from vector results to filter FTS search
|
|
440
|
+
const uniqueFilePaths = [...new Set(results.map((r) => r.filePath))];
|
|
441
|
+
// Build WHERE clause with IN for targeted FTS search
|
|
442
|
+
// Use backticks for column name (required for camelCase in LanceDB)
|
|
443
|
+
const escapedPaths = uniqueFilePaths.map((p) => `'${p.replace(/'/g, "''")}'`);
|
|
444
|
+
const whereClause = `\`filePath\` IN (${escapedPaths.join(', ')})`;
|
|
445
|
+
const ftsResults = await this.table
|
|
446
|
+
.search(queryText, 'fts', 'text')
|
|
447
|
+
.where(whereClause)
|
|
448
|
+
.select(['filePath', 'chunkIndex', 'text', 'metadata', '_score'])
|
|
449
|
+
.limit(results.length * 2) // Enough to cover all vector results
|
|
450
|
+
.toArray();
|
|
451
|
+
results = this.applyKeywordBoost(results, ftsResults, hybridWeight);
|
|
452
|
+
// FTS succeeded - reset circuit breaker
|
|
453
|
+
this.recordFtsSuccess();
|
|
454
|
+
}
|
|
455
|
+
catch (ftsError) {
|
|
456
|
+
// Record failure for circuit breaker (will auto-recover after cooldown)
|
|
457
|
+
this.recordFtsFailure(ftsError);
|
|
458
|
+
// Continue with vector-only results
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
// Return top results after all filtering and boosting
|
|
462
|
+
return results.slice(0, limit);
|
|
463
|
+
}
|
|
464
|
+
catch (error) {
|
|
465
|
+
throw new index_js_1.DatabaseError('Failed to search vectors', error);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Apply keyword boost to rerank vector search results
|
|
470
|
+
* Uses multiplicative formula: final_distance = distance / (1 + keyword_normalized * weight)
|
|
471
|
+
*
|
|
472
|
+
* This proportional boost ensures:
|
|
473
|
+
* - Keyword matches improve ranking without dominating semantic similarity
|
|
474
|
+
* - Documents without keyword matches keep their original vector distance
|
|
475
|
+
* - Higher weight = stronger influence of keyword matching
|
|
476
|
+
*
|
|
477
|
+
* @param vectorResults - Results from vector search (already filtered by maxDistance/grouping)
|
|
478
|
+
* @param ftsResults - Raw FTS results with BM25 scores
|
|
479
|
+
* @param weight - Boost weight (0-1, from hybridWeight config)
|
|
480
|
+
*/
|
|
481
|
+
applyKeywordBoost(vectorResults, ftsResults, weight) {
|
|
482
|
+
// Build FTS score map with normalized scores (0-1)
|
|
483
|
+
let maxBm25Score = 0;
|
|
484
|
+
for (const result of ftsResults) {
|
|
485
|
+
if (!result)
|
|
486
|
+
continue;
|
|
487
|
+
const score = result['_score'] ?? 0;
|
|
488
|
+
if (score > maxBm25Score)
|
|
489
|
+
maxBm25Score = score;
|
|
490
|
+
}
|
|
491
|
+
const ftsScoreMap = new Map();
|
|
492
|
+
for (const result of ftsResults) {
|
|
493
|
+
if (!result)
|
|
494
|
+
continue;
|
|
495
|
+
const key = `${result['filePath']}:${result['chunkIndex']}`;
|
|
496
|
+
const rawScore = result['_score'] ?? 0;
|
|
497
|
+
const normalized = maxBm25Score > 0 ? rawScore / maxBm25Score : 0;
|
|
498
|
+
ftsScoreMap.set(key, normalized);
|
|
499
|
+
}
|
|
500
|
+
// Apply multiplicative boost to vector results
|
|
501
|
+
const boostedResults = vectorResults.map((result) => {
|
|
502
|
+
const key = `${result.filePath}:${result.chunkIndex}`;
|
|
503
|
+
const keywordScore = ftsScoreMap.get(key) ?? 0;
|
|
504
|
+
// Multiplicative boost: distance / (1 + keyword * weight)
|
|
505
|
+
// - If keyword matches (score=1) and weight=1: distance halved
|
|
506
|
+
// - If no keyword match (score=0): distance unchanged
|
|
507
|
+
const boostedDistance = result.score / (1 + keywordScore * weight);
|
|
508
|
+
return {
|
|
509
|
+
...result,
|
|
510
|
+
score: boostedDistance,
|
|
511
|
+
};
|
|
512
|
+
});
|
|
513
|
+
// Re-sort by boosted distance (ascending = better)
|
|
514
|
+
return boostedResults.sort((a, b) => a.score - b.score);
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Get list of ingested files
|
|
518
|
+
*
|
|
519
|
+
* @returns Array of file information
|
|
520
|
+
*/
|
|
521
|
+
async listFiles() {
|
|
522
|
+
if (!this.table) {
|
|
523
|
+
return []; // Return empty array if table doesn't exist
|
|
524
|
+
}
|
|
525
|
+
try {
|
|
526
|
+
// Retrieve all records
|
|
527
|
+
const allRecords = await this.table.query().toArray();
|
|
528
|
+
// Group by file path
|
|
529
|
+
const fileMap = new Map();
|
|
530
|
+
for (const record of allRecords) {
|
|
531
|
+
const filePath = record.filePath;
|
|
532
|
+
const timestamp = record.timestamp;
|
|
533
|
+
if (fileMap.has(filePath)) {
|
|
534
|
+
const fileInfo = fileMap.get(filePath);
|
|
535
|
+
if (fileInfo) {
|
|
536
|
+
fileInfo.chunkCount += 1;
|
|
537
|
+
// Keep most recent timestamp
|
|
538
|
+
if (timestamp > fileInfo.timestamp) {
|
|
539
|
+
fileInfo.timestamp = timestamp;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
else {
|
|
544
|
+
fileMap.set(filePath, { chunkCount: 1, timestamp });
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
// Convert Map to array of objects
|
|
548
|
+
return Array.from(fileMap.entries()).map(([filePath, info]) => ({
|
|
549
|
+
filePath,
|
|
550
|
+
chunkCount: info.chunkCount,
|
|
551
|
+
timestamp: info.timestamp,
|
|
552
|
+
}));
|
|
553
|
+
}
|
|
554
|
+
catch (error) {
|
|
555
|
+
throw new index_js_1.DatabaseError('Failed to list files', error);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Close the database connection and release resources
|
|
560
|
+
*/
|
|
561
|
+
async close() {
|
|
562
|
+
this.db = null;
|
|
563
|
+
this.table = null;
|
|
564
|
+
this.ftsEnabled = false;
|
|
565
|
+
this.ftsFailureCount = 0;
|
|
566
|
+
this.ftsLastFailure = null;
|
|
567
|
+
console.error('VectorStore: Connection closed');
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Get system status
|
|
571
|
+
*
|
|
572
|
+
* @returns System status information
|
|
573
|
+
*/
|
|
574
|
+
async getStatus() {
|
|
575
|
+
if (!this.table) {
|
|
576
|
+
return {
|
|
577
|
+
documentCount: 0,
|
|
578
|
+
chunkCount: 0,
|
|
579
|
+
memoryUsage: 0,
|
|
580
|
+
uptime: process.uptime(),
|
|
581
|
+
ftsIndexEnabled: false,
|
|
582
|
+
searchMode: 'vector-only',
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
try {
|
|
586
|
+
// Retrieve all records
|
|
587
|
+
const allRecords = await this.table.query().toArray();
|
|
588
|
+
const chunkCount = allRecords.length;
|
|
589
|
+
// Count unique file paths
|
|
590
|
+
const uniqueFilePaths = new Set(allRecords.map((record) => record.filePath));
|
|
591
|
+
const documentCount = uniqueFilePaths.size;
|
|
592
|
+
// Get memory usage (in MB)
|
|
593
|
+
const memoryUsage = process.memoryUsage().heapUsed / 1024 / 1024;
|
|
594
|
+
// Get uptime (in seconds)
|
|
595
|
+
const uptime = process.uptime();
|
|
596
|
+
// Determine effective FTS state (considering circuit breaker)
|
|
597
|
+
const ftsEffectivelyEnabled = this.shouldAttemptFts();
|
|
598
|
+
return {
|
|
599
|
+
documentCount,
|
|
600
|
+
chunkCount,
|
|
601
|
+
memoryUsage,
|
|
602
|
+
uptime,
|
|
603
|
+
ftsIndexEnabled: this.ftsEnabled,
|
|
604
|
+
searchMode: ftsEffectivelyEnabled && (this.config.hybridWeight ?? 0.6) > 0 ? 'hybrid' : 'vector-only',
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
catch (error) {
|
|
608
|
+
throw new index_js_1.DatabaseError('Failed to get status', error);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
exports.VectorStore = VectorStore;
|
|
613
|
+
//# 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,9 @@
|
|
|
1
|
+
import type { Router } from 'express';
|
|
2
|
+
import type { RAGServer } from '../server/index.js';
|
|
3
|
+
import type { ServerAccessor } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Create API router with all endpoints
|
|
6
|
+
* @param serverOrAccessor - RAGServer instance or accessor function
|
|
7
|
+
*/
|
|
8
|
+
export declare function createApiRouter(serverOrAccessor: RAGServer | ServerAccessor): Router;
|
|
9
|
+
//# sourceMappingURL=api-routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-routes.d.ts","sourceRoot":"","sources":["../../src/web/api-routes.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAqB,MAAM,EAAE,MAAM,SAAS,CAAA;AAGxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAEnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAgDhD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,gBAAgB,EAAE,SAAS,GAAG,cAAc,GAAG,MAAM,CA+HpF"}
|