@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.
Files changed (247) hide show
  1. package/LICENSE +21 -0
  2. package/README.de.md +441 -0
  3. package/README.es.md +441 -0
  4. package/README.fr.md +441 -0
  5. package/README.md +530 -0
  6. package/README.pt-BR.md +441 -0
  7. package/README.zh-CN.md +441 -0
  8. package/dist/bin/install-skills.d.ts +19 -0
  9. package/dist/bin/install-skills.d.ts.map +1 -0
  10. package/dist/bin/install-skills.js +218 -0
  11. package/dist/bin/install-skills.js.map +1 -0
  12. package/dist/chunker/index.d.ts +24 -0
  13. package/dist/chunker/index.d.ts.map +1 -0
  14. package/dist/chunker/index.js +2 -0
  15. package/dist/chunker/index.js.map +1 -0
  16. package/dist/chunker/semantic-chunker.d.ts +96 -0
  17. package/dist/chunker/semantic-chunker.d.ts.map +1 -0
  18. package/dist/chunker/semantic-chunker.js +362 -0
  19. package/dist/chunker/semantic-chunker.js.map +1 -0
  20. package/dist/chunker/sentence-splitter.d.ts +32 -0
  21. package/dist/chunker/sentence-splitter.d.ts.map +1 -0
  22. package/dist/chunker/sentence-splitter.js +231 -0
  23. package/dist/chunker/sentence-splitter.js.map +1 -0
  24. package/dist/chunker/token-containment.d.ts +39 -0
  25. package/dist/chunker/token-containment.d.ts.map +1 -0
  26. package/dist/chunker/token-containment.js +83 -0
  27. package/dist/chunker/token-containment.js.map +1 -0
  28. package/dist/cli/common.d.ts +34 -0
  29. package/dist/cli/common.d.ts.map +1 -0
  30. package/dist/cli/common.js +121 -0
  31. package/dist/cli/common.js.map +1 -0
  32. package/dist/cli/delete.d.ts +3 -0
  33. package/dist/cli/delete.d.ts.map +1 -0
  34. package/dist/cli/delete.js +169 -0
  35. package/dist/cli/delete.js.map +1 -0
  36. package/dist/cli/file-collection.d.ts +2 -0
  37. package/dist/cli/file-collection.d.ts.map +1 -0
  38. package/dist/cli/file-collection.js +53 -0
  39. package/dist/cli/file-collection.js.map +1 -0
  40. package/dist/cli/ingest.d.ts +69 -0
  41. package/dist/cli/ingest.d.ts.map +1 -0
  42. package/dist/cli/ingest.js +323 -0
  43. package/dist/cli/ingest.js.map +1 -0
  44. package/dist/cli/list.d.ts +27 -0
  45. package/dist/cli/list.d.ts.map +1 -0
  46. package/dist/cli/list.js +207 -0
  47. package/dist/cli/list.js.map +1 -0
  48. package/dist/cli/options.d.ts +89 -0
  49. package/dist/cli/options.d.ts.map +1 -0
  50. package/dist/cli/options.js +244 -0
  51. package/dist/cli/options.js.map +1 -0
  52. package/dist/cli/query.d.ts +17 -0
  53. package/dist/cli/query.d.ts.map +1 -0
  54. package/dist/cli/query.js +194 -0
  55. package/dist/cli/query.js.map +1 -0
  56. package/dist/cli/read-neighbors.d.ts +3 -0
  57. package/dist/cli/read-neighbors.d.ts.map +1 -0
  58. package/dist/cli/read-neighbors.js +192 -0
  59. package/dist/cli/read-neighbors.js.map +1 -0
  60. package/dist/cli/status.d.ts +6 -0
  61. package/dist/cli/status.d.ts.map +1 -0
  62. package/dist/cli/status.js +78 -0
  63. package/dist/cli/status.js.map +1 -0
  64. package/dist/cli/sync.d.ts +6 -0
  65. package/dist/cli/sync.d.ts.map +1 -0
  66. package/dist/cli/sync.js +271 -0
  67. package/dist/cli/sync.js.map +1 -0
  68. package/dist/cli-main.d.ts +9 -0
  69. package/dist/cli-main.d.ts.map +1 -0
  70. package/dist/cli-main.js +60 -0
  71. package/dist/cli-main.js.map +1 -0
  72. package/dist/embedder/index.d.ts +143 -0
  73. package/dist/embedder/index.d.ts.map +1 -0
  74. package/dist/embedder/index.js +429 -0
  75. package/dist/embedder/index.js.map +1 -0
  76. package/dist/embedder/remote.d.ts +51 -0
  77. package/dist/embedder/remote.d.ts.map +1 -0
  78. package/dist/embedder/remote.js +182 -0
  79. package/dist/embedder/remote.js.map +1 -0
  80. package/dist/features/list.d.ts +37 -0
  81. package/dist/features/list.d.ts.map +1 -0
  82. package/dist/features/list.js +41 -0
  83. package/dist/features/list.js.map +1 -0
  84. package/dist/features/sync.d.ts +219 -0
  85. package/dist/features/sync.d.ts.map +1 -0
  86. package/dist/features/sync.js +461 -0
  87. package/dist/features/sync.js.map +1 -0
  88. package/dist/index.d.ts +3 -0
  89. package/dist/index.d.ts.map +1 -0
  90. package/dist/index.js +56 -0
  91. package/dist/index.js.map +1 -0
  92. package/dist/ingest/compute.d.ts +63 -0
  93. package/dist/ingest/compute.d.ts.map +1 -0
  94. package/dist/ingest/compute.js +161 -0
  95. package/dist/ingest/compute.js.map +1 -0
  96. package/dist/ingest/file.d.ts +40 -0
  97. package/dist/ingest/file.d.ts.map +1 -0
  98. package/dist/ingest/file.js +74 -0
  99. package/dist/ingest/file.js.map +1 -0
  100. package/dist/ingest/visual.d.ts +52 -0
  101. package/dist/ingest/visual.d.ts.map +1 -0
  102. package/dist/ingest/visual.js +294 -0
  103. package/dist/ingest/visual.js.map +1 -0
  104. package/dist/parser/docx-parser.d.ts +12 -0
  105. package/dist/parser/docx-parser.d.ts.map +1 -0
  106. package/dist/parser/docx-parser.js +375 -0
  107. package/dist/parser/docx-parser.js.map +1 -0
  108. package/dist/parser/html-parser.d.ts +16 -0
  109. package/dist/parser/html-parser.d.ts.map +1 -0
  110. package/dist/parser/html-parser.js +119 -0
  111. package/dist/parser/html-parser.js.map +1 -0
  112. package/dist/parser/index.d.ts +125 -0
  113. package/dist/parser/index.d.ts.map +1 -0
  114. package/dist/parser/index.js +364 -0
  115. package/dist/parser/index.js.map +1 -0
  116. package/dist/parser/pdf-extract.d.ts +49 -0
  117. package/dist/parser/pdf-extract.d.ts.map +1 -0
  118. package/dist/parser/pdf-extract.js +114 -0
  119. package/dist/parser/pdf-extract.js.map +1 -0
  120. package/dist/parser/pdf-filter.d.ts +91 -0
  121. package/dist/parser/pdf-filter.d.ts.map +1 -0
  122. package/dist/parser/pdf-filter.js +522 -0
  123. package/dist/parser/pdf-filter.js.map +1 -0
  124. package/dist/parser/title-extractor.d.ts +28 -0
  125. package/dist/parser/title-extractor.d.ts.map +1 -0
  126. package/dist/parser/title-extractor.js +105 -0
  127. package/dist/parser/title-extractor.js.map +1 -0
  128. package/dist/pdf-visual/captioner.d.ts +11 -0
  129. package/dist/pdf-visual/captioner.d.ts.map +1 -0
  130. package/dist/pdf-visual/captioner.js +48 -0
  131. package/dist/pdf-visual/captioner.js.map +1 -0
  132. package/dist/pdf-visual/captioners/fast.d.ts +7 -0
  133. package/dist/pdf-visual/captioners/fast.d.ts.map +1 -0
  134. package/dist/pdf-visual/captioners/fast.js +108 -0
  135. package/dist/pdf-visual/captioners/fast.js.map +1 -0
  136. package/dist/pdf-visual/captioners/quality.d.ts +7 -0
  137. package/dist/pdf-visual/captioners/quality.d.ts.map +1 -0
  138. package/dist/pdf-visual/captioners/quality.js +101 -0
  139. package/dist/pdf-visual/captioners/quality.js.map +1 -0
  140. package/dist/pdf-visual/captioners/shared.d.ts +81 -0
  141. package/dist/pdf-visual/captioners/shared.d.ts.map +1 -0
  142. package/dist/pdf-visual/captioners/shared.js +156 -0
  143. package/dist/pdf-visual/captioners/shared.js.map +1 -0
  144. package/dist/pdf-visual/detector.d.ts +9 -0
  145. package/dist/pdf-visual/detector.d.ts.map +1 -0
  146. package/dist/pdf-visual/detector.js +269 -0
  147. package/dist/pdf-visual/detector.js.map +1 -0
  148. package/dist/pdf-visual/index.d.ts +13 -0
  149. package/dist/pdf-visual/index.d.ts.map +1 -0
  150. package/dist/pdf-visual/index.js +53 -0
  151. package/dist/pdf-visual/index.js.map +1 -0
  152. package/dist/pdf-visual/renderer.d.ts +9 -0
  153. package/dist/pdf-visual/renderer.d.ts.map +1 -0
  154. package/dist/pdf-visual/renderer.js +186 -0
  155. package/dist/pdf-visual/renderer.js.map +1 -0
  156. package/dist/pdf-visual/types.d.ts +53 -0
  157. package/dist/pdf-visual/types.d.ts.map +1 -0
  158. package/dist/pdf-visual/types.js +17 -0
  159. package/dist/pdf-visual/types.js.map +1 -0
  160. package/dist/server/error-utils.d.ts +63 -0
  161. package/dist/server/error-utils.d.ts.map +1 -0
  162. package/dist/server/error-utils.js +124 -0
  163. package/dist/server/error-utils.js.map +1 -0
  164. package/dist/server/index.d.ts +216 -0
  165. package/dist/server/index.d.ts.map +1 -0
  166. package/dist/server/index.js +1068 -0
  167. package/dist/server/index.js.map +1 -0
  168. package/dist/server/list-scanner.d.ts +30 -0
  169. package/dist/server/list-scanner.d.ts.map +1 -0
  170. package/dist/server/list-scanner.js +50 -0
  171. package/dist/server/list-scanner.js.map +1 -0
  172. package/dist/server/tool-definitions.d.ts +8 -0
  173. package/dist/server/tool-definitions.d.ts.map +1 -0
  174. package/dist/server/tool-definitions.js +181 -0
  175. package/dist/server/tool-definitions.js.map +1 -0
  176. package/dist/server/tool-input.d.ts +37 -0
  177. package/dist/server/tool-input.d.ts.map +1 -0
  178. package/dist/server/tool-input.js +211 -0
  179. package/dist/server/tool-input.js.map +1 -0
  180. package/dist/server/types.d.ts +307 -0
  181. package/dist/server/types.d.ts.map +1 -0
  182. package/dist/server/types.js +3 -0
  183. package/dist/server/types.js.map +1 -0
  184. package/dist/server-main.d.ts +40 -0
  185. package/dist/server-main.d.ts.map +1 -0
  186. package/dist/server-main.js +254 -0
  187. package/dist/server-main.js.map +1 -0
  188. package/dist/utils/base-dirs.d.ts +145 -0
  189. package/dist/utils/base-dirs.d.ts.map +1 -0
  190. package/dist/utils/base-dirs.js +344 -0
  191. package/dist/utils/base-dirs.js.map +1 -0
  192. package/dist/utils/errors.d.ts +32 -0
  193. package/dist/utils/errors.d.ts.map +1 -0
  194. package/dist/utils/errors.js +61 -0
  195. package/dist/utils/errors.js.map +1 -0
  196. package/dist/utils/limits.d.ts +26 -0
  197. package/dist/utils/limits.d.ts.map +1 -0
  198. package/dist/utils/limits.js +28 -0
  199. package/dist/utils/limits.js.map +1 -0
  200. package/dist/utils/list-sources.d.ts +38 -0
  201. package/dist/utils/list-sources.d.ts.map +1 -0
  202. package/dist/utils/list-sources.js +40 -0
  203. package/dist/utils/list-sources.js.map +1 -0
  204. package/dist/utils/raw-data-utils.d.ts +76 -0
  205. package/dist/utils/raw-data-utils.d.ts.map +1 -0
  206. package/dist/utils/raw-data-utils.js +202 -0
  207. package/dist/utils/raw-data-utils.js.map +1 -0
  208. package/dist/utils/scan.d.ts +114 -0
  209. package/dist/utils/scan.d.ts.map +1 -0
  210. package/dist/utils/scan.js +209 -0
  211. package/dist/utils/scan.js.map +1 -0
  212. package/dist/utils/scope-match.d.ts +38 -0
  213. package/dist/utils/scope-match.d.ts.map +1 -0
  214. package/dist/utils/scope-match.js +86 -0
  215. package/dist/utils/scope-match.js.map +1 -0
  216. package/dist/utils/sensitive-path.d.ts +9 -0
  217. package/dist/utils/sensitive-path.d.ts.map +1 -0
  218. package/dist/utils/sensitive-path.js +78 -0
  219. package/dist/utils/sensitive-path.js.map +1 -0
  220. package/dist/utils/sync-path-key.d.ts +14 -0
  221. package/dist/utils/sync-path-key.d.ts.map +1 -0
  222. package/dist/utils/sync-path-key.js +27 -0
  223. package/dist/utils/sync-path-key.js.map +1 -0
  224. package/dist/utils/type-guards.d.ts +18 -0
  225. package/dist/utils/type-guards.d.ts.map +1 -0
  226. package/dist/utils/type-guards.js +34 -0
  227. package/dist/utils/type-guards.js.map +1 -0
  228. package/dist/utils/visual-profile.d.ts +10 -0
  229. package/dist/utils/visual-profile.d.ts.map +1 -0
  230. package/dist/utils/visual-profile.js +15 -0
  231. package/dist/utils/visual-profile.js.map +1 -0
  232. package/dist/vectordb/index.d.ts +132 -0
  233. package/dist/vectordb/index.d.ts.map +1 -0
  234. package/dist/vectordb/index.js +617 -0
  235. package/dist/vectordb/index.js.map +1 -0
  236. package/dist/vectordb/search-filters.d.ts +15 -0
  237. package/dist/vectordb/search-filters.d.ts.map +1 -0
  238. package/dist/vectordb/search-filters.js +129 -0
  239. package/dist/vectordb/search-filters.js.map +1 -0
  240. package/dist/vectordb/types.d.ts +194 -0
  241. package/dist/vectordb/types.d.ts.map +1 -0
  242. package/dist/vectordb/types.js +237 -0
  243. package/dist/vectordb/types.js.map +1 -0
  244. package/package.json +108 -0
  245. package/skills/mcp-local-rag/SKILL.md +234 -0
  246. package/skills/mcp-local-rag/references/cli-reference.md +190 -0
  247. 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