ultracode 5.4.0 → 5.6.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/dist/chunks/analysis-tool-handlers-GH5FDEWW.js +817 -0
- package/dist/chunks/analysis-tool-handlers-IXP4MWZX.js +817 -0
- package/dist/chunks/analysis-tool-handlers-LC2BTQYK.js +13 -0
- package/dist/chunks/analysis-tool-handlers-QYFKQPFL.js +817 -0
- package/dist/chunks/autodoc-tool-handlers-2HF6ERYN.js +1112 -0
- package/dist/chunks/autodoc-tool-handlers-4OGQJ7C3.js +1112 -0
- package/dist/chunks/autodoc-tool-handlers-N736CB56.js +138 -0
- package/dist/chunks/autodoc-tool-handlers-NQYBY6U4.js +1112 -0
- package/dist/chunks/branch-tool-handlers-KW3H4FJK.js +276 -0
- package/dist/chunks/branch-tool-handlers-QOUDZKJ2.js +276 -0
- package/dist/chunks/branch-tool-handlers-RB2U36KI.js +2 -0
- package/dist/chunks/branch-tool-handlers-ZHJM6PDK.js +276 -0
- package/dist/chunks/chunk-2Z6OQPYC.js +656 -0
- package/dist/chunks/chunk-3MQ7LRPN.js +322 -0
- package/dist/chunks/chunk-4W6QYGXZ.js +10 -0
- package/dist/chunks/chunk-533NFGUG.js +1 -0
- package/dist/chunks/chunk-5NUPOPWM.js +1 -0
- package/dist/chunks/chunk-AK4HIPA2.js +322 -0
- package/dist/chunks/chunk-B3H5NS3I.js +656 -0
- package/dist/chunks/chunk-DPTZHDST.js +4 -0
- package/dist/chunks/chunk-E5HQWLU5.js +322 -0
- package/dist/chunks/chunk-EOH25B5P.js +572 -0
- package/dist/chunks/chunk-ESV6F6E3.js +3179 -0
- package/dist/chunks/chunk-FPELPFER.js +924 -0
- package/dist/chunks/chunk-G6J42I55.js +161 -0
- package/dist/chunks/chunk-GCQE7ZYW.js +1 -0
- package/dist/chunks/chunk-GTIF6MOX.js +1 -0
- package/dist/chunks/chunk-I6STSSAK.js +2 -0
- package/dist/chunks/chunk-J2WBGTK2.js +4697 -0
- package/dist/chunks/chunk-KAYOX5EB.js +4697 -0
- package/dist/chunks/chunk-KPMTACOT.js +656 -0
- package/dist/chunks/chunk-L376GZ44.js +3179 -0
- package/dist/chunks/chunk-LCTOTHDA.js +15 -0
- package/dist/chunks/chunk-LEDJ7GVQ.js +316 -0
- package/dist/chunks/chunk-LH4OUKNZ.js +277 -0
- package/dist/chunks/chunk-O6IE2MEZ.js +161 -0
- package/dist/chunks/chunk-OEXPCY3F.js +316 -0
- package/dist/chunks/chunk-OMXOLFDN.js +924 -0
- package/dist/chunks/chunk-PLPBXWOU.js +3179 -0
- package/dist/chunks/chunk-PWLE5DN2.js +572 -0
- package/dist/chunks/chunk-PY43JPWL.js +447 -0
- package/dist/chunks/chunk-Q3B4EB7A.js +15 -0
- package/dist/chunks/chunk-Q5LPVLXA.js +337 -0
- package/dist/chunks/chunk-QIRZHZK2.js +5 -0
- package/dist/chunks/chunk-ROQ27LSL.js +924 -0
- package/dist/chunks/chunk-S5Q7BD6J.js +572 -0
- package/dist/chunks/chunk-SAMX3HJQ.js +337 -0
- package/dist/chunks/chunk-SV3WKUNV.js +1 -0
- package/dist/chunks/chunk-TCHCDCDO.js +167 -0
- package/dist/chunks/chunk-TR3HS7U6.js +316 -0
- package/dist/chunks/chunk-TUWE6FCW.js +167 -0
- package/dist/chunks/chunk-TVOTA7EE.js +277 -0
- package/dist/chunks/chunk-VS44D772.js +337 -0
- package/dist/chunks/chunk-WIE3G5ES.js +167 -0
- package/dist/chunks/chunk-XG3ACLWR.js +5 -0
- package/dist/chunks/chunk-XJ2Z5QQO.js +1 -0
- package/dist/chunks/chunk-XK2NY7RB.js +277 -0
- package/dist/chunks/chunk-Y4F7NZFZ.js +4700 -0
- package/dist/chunks/chunk-YS75L3ZS.js +161 -0
- package/dist/chunks/chunk-ZVG5HHI3.js +15 -0
- package/dist/chunks/dev-agent-DDDIVWOF.js +1 -0
- package/dist/chunks/dev-agent-E2VCFKXN.js +1624 -0
- package/dist/chunks/dev-agent-KJNSU5KQ.js +1624 -0
- package/dist/chunks/dev-agent-NDERYIPV.js +1624 -0
- package/dist/chunks/faiss-provider-7R4BQDIV.js +12 -0
- package/dist/chunks/faiss-provider-7ZFRSDN5.js +12 -0
- package/dist/chunks/faiss-provider-SXB7FTLB.js +1 -0
- package/dist/chunks/faiss-provider-TKLBEUSH.js +12 -0
- package/dist/chunks/file-tool-handlers-5DODQXGF.js +1027 -0
- package/dist/chunks/file-tool-handlers-KGHLE4KR.js +1027 -0
- package/dist/chunks/file-tool-handlers-KTOQ4NFS.js +12 -0
- package/dist/chunks/file-tool-handlers-V4SFUDQB.js +1027 -0
- package/dist/chunks/graph-metrics-tool-handlers-3AV4X4ZY.js +65 -0
- package/dist/chunks/graph-metrics-tool-handlers-3VMDQHJ6.js +65 -0
- package/dist/chunks/graph-metrics-tool-handlers-BZ6E6YHF.js +1 -0
- package/dist/chunks/graph-metrics-tool-handlers-IYBGSXL7.js +65 -0
- package/dist/chunks/graph-storage-factory-2CQ2RPDV.js +13 -0
- package/dist/chunks/graph-storage-factory-C5SMMYL6.js +13 -0
- package/dist/chunks/graph-storage-factory-EEO2V3GJ.js +1 -0
- package/dist/chunks/graph-storage-factory-WBCTXP34.js +13 -0
- package/dist/chunks/history-tool-handlers-AS7OQFZI.js +1 -0
- package/dist/chunks/history-tool-handlers-FSNJYXV2.js +208 -0
- package/dist/chunks/history-tool-handlers-JZAH4EIQ.js +208 -0
- package/dist/chunks/history-tool-handlers-KCSCXZ7T.js +208 -0
- package/dist/chunks/incremental-updater-A2EL4QXU.js +14 -0
- package/dist/chunks/incremental-updater-EQIKBVY2.js +14 -0
- package/dist/chunks/incremental-updater-JFGRPH3B.js +14 -0
- package/dist/chunks/incremental-updater-S5BAAGHP.js +1 -0
- package/dist/chunks/indexer-agent-ASKY7JPG.js +1 -0
- package/dist/chunks/indexer-agent-NKAOF323.js +21 -0
- package/dist/chunks/indexer-agent-PJN5IOKQ.js +21 -0
- package/dist/chunks/indexer-agent-WRJFWKZX.js +21 -0
- package/dist/chunks/indexing-pipeline-D4P2O72Z.js +249 -0
- package/dist/chunks/indexing-pipeline-L7C543N4.js +1 -0
- package/dist/chunks/indexing-pipeline-NHPRN3AB.js +249 -0
- package/dist/chunks/indexing-pipeline-ZAXCZU22.js +249 -0
- package/dist/chunks/layered-faiss-provider-62CNW54X.js +1 -0
- package/dist/chunks/layered-faiss-provider-O7L77GFX.js +12 -0
- package/dist/chunks/layered-faiss-provider-RVHLHLPK.js +12 -0
- package/dist/chunks/layered-faiss-provider-YT7EDIJI.js +12 -0
- package/dist/chunks/merge-agent-3RF7VFF5.js +2481 -0
- package/dist/chunks/merge-agent-JCKTCBCE.js +2481 -0
- package/dist/chunks/merge-agent-VCL7OXPN.js +2481 -0
- package/dist/chunks/merge-agent-ZGK24WVF.js +11 -0
- package/dist/chunks/merge-tool-handlers-GV2LOIKU.js +277 -0
- package/dist/chunks/merge-tool-handlers-TYDWU5X2.js +277 -0
- package/dist/chunks/merge-tool-handlers-U7X2ZO2M.js +1 -0
- package/dist/chunks/merge-tool-handlers-YH62ZLPJ.js +277 -0
- package/dist/chunks/pattern-tool-handlers-76NF5JDS.js +13 -0
- package/dist/chunks/pattern-tool-handlers-IJAGEIVD.js +1549 -0
- package/dist/chunks/pattern-tool-handlers-VA5WYA62.js +1549 -0
- package/dist/chunks/pattern-tool-handlers-WQ6UBMJS.js +1549 -0
- package/dist/chunks/query-agent-36ADGCFZ.js +1 -0
- package/dist/chunks/query-agent-H22CR5N5.js +191 -0
- package/dist/chunks/query-agent-K2UGZS4M.js +191 -0
- package/dist/chunks/query-agent-YJCEHOXD.js +191 -0
- package/dist/chunks/semantic-agent-AC7CBEDE.js +6381 -0
- package/dist/chunks/semantic-agent-HK5X6CKU.js +6381 -0
- package/dist/chunks/semantic-agent-KONIKEGW.js +6381 -0
- package/dist/chunks/semantic-agent-LH6IZ2L7.js +137 -0
- package/dist/chunks/semantic-tool-handlers-5LMSH2U7.js +3 -0
- package/dist/chunks/semantic-tool-handlers-735UMO7Y.js +817 -0
- package/dist/chunks/semantic-tool-handlers-BNUYPP7X.js +817 -0
- package/dist/chunks/semantic-tool-handlers-MYZPEUD2.js +817 -0
- package/dist/chunks/snapshot-tool-handlers-6SIHZT2F.js +201 -0
- package/dist/chunks/snapshot-tool-handlers-DS4P3KOT.js +201 -0
- package/dist/chunks/snapshot-tool-handlers-JYHRFPC7.js +201 -0
- package/dist/chunks/snapshot-tool-handlers-YEHMAT3L.js +1 -0
- package/dist/chunks/storage-paths-A3C7WHHG.js +8 -0
- package/dist/chunks/storage-paths-HDYH7WPM.js +1 -0
- package/dist/chunks/storage-paths-IMFRHBWF.js +8 -0
- package/dist/chunks/storage-paths-P3PUSMUD.js +8 -0
- package/dist/chunks/taint-tool-handlers-CWESOOMQ.js +68 -0
- package/dist/chunks/taint-tool-handlers-OG3NVVP3.js +1 -0
- package/dist/chunks/taint-tool-handlers-ON3G3FA7.js +68 -0
- package/dist/chunks/taint-tool-handlers-P4P5J6DB.js +68 -0
- package/dist/chunks/tracing-tool-handlers-4BDCXTZZ.js +3935 -0
- package/dist/chunks/tracing-tool-handlers-6FPNM7HX.js +3935 -0
- package/dist/chunks/tracing-tool-handlers-LQTQ5SKK.js +89 -0
- package/dist/chunks/tracing-tool-handlers-XRQX2DTS.js +3935 -0
- package/dist/chunks/validation-tool-handlers-DZUG7KYY.js +2 -0
- package/dist/chunks/validation-tool-handlers-O6TGFSH5.js +555 -0
- package/dist/chunks/validation-tool-handlers-RREUYKIR.js +555 -0
- package/dist/chunks/validation-tool-handlers-XPWSMS37.js +555 -0
- package/dist/index.js +13 -13
- package/dist/roslyn-addon/.build-hash +1 -1
- package/dist/roslyn-addon/ILGPU.Algorithms.dll +0 -0
- package/dist/roslyn-addon/ILGPU.dll +0 -0
- package/dist/roslyn-addon/UltraCode.CSharp.deps.json +35 -0
- package/dist/roslyn-addon/UltraCode.CSharp.dll +0 -0
- package/package.json +1 -1
|
@@ -0,0 +1,656 @@
|
|
|
1
|
+
import { getGpuClient } from './chunk-FPELPFER.js';
|
|
2
|
+
import { simdL2Normalize } from './chunk-QN237S7C.js';
|
|
3
|
+
import { detectBaseBranch, loadBaseMetadata, createInitialBaseMetadata, updateBaseMetadata } from './chunk-G6J42I55.js';
|
|
4
|
+
import { init_storage_paths, normalizeBranchName, getProjectDir } from './chunk-TVOTA7EE.js';
|
|
5
|
+
import { tryGarbageCollect } from './chunk-IMQ6WSJV.js';
|
|
6
|
+
import { init_logging, log, logMemory } from './chunk-VCCBEJQ5.js';
|
|
7
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
8
|
+
import { dirname, join } from 'path';
|
|
9
|
+
|
|
10
|
+
// src/semantic/faiss/layered-faiss-provider.ts
|
|
11
|
+
init_logging();
|
|
12
|
+
init_storage_paths();
|
|
13
|
+
var DEFAULT_CONFIG = {
|
|
14
|
+
dimensions: 384,
|
|
15
|
+
indexType: "hnsw",
|
|
16
|
+
hnswM: 32,
|
|
17
|
+
hnswEfConstruction: 200,
|
|
18
|
+
hnswEfSearch: 64,
|
|
19
|
+
autoSaveThreshold: 5e4
|
|
20
|
+
// Increased to reduce blocking during indexing
|
|
21
|
+
};
|
|
22
|
+
function getLayeredPaths(projectDir, branchName, baseBranch) {
|
|
23
|
+
const safeBranch = normalizeBranchName(branchName);
|
|
24
|
+
const safeBase = baseBranch ? normalizeBranchName(baseBranch) : safeBranch;
|
|
25
|
+
return {
|
|
26
|
+
// Base layer - uses base branch name (e.g., faiss-dev.bin for base branch "dev")
|
|
27
|
+
baseIndex: join(projectDir, `faiss-${safeBase}.bin`),
|
|
28
|
+
baseIds: join(projectDir, `faiss-${safeBase}.bin.ids.json`),
|
|
29
|
+
baseMeta: join(projectDir, "faiss-base.meta.json"),
|
|
30
|
+
// Delta layer (per feature branch)
|
|
31
|
+
deltaIndex: join(projectDir, `faiss-${safeBranch}.delta.bin`),
|
|
32
|
+
deltaIds: join(projectDir, `faiss-${safeBranch}.delta.ids.json`),
|
|
33
|
+
deltaMeta: join(projectDir, `faiss-${safeBranch}.delta.meta.json`),
|
|
34
|
+
tombstones: join(projectDir, `faiss-${safeBranch}.tombstones.json`)
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
var LayeredFaissProvider = class _LayeredFaissProvider {
|
|
38
|
+
config;
|
|
39
|
+
client = null;
|
|
40
|
+
isInitialized = false;
|
|
41
|
+
// Project context
|
|
42
|
+
projectPath = "";
|
|
43
|
+
projectHash = "";
|
|
44
|
+
currentBranch = null;
|
|
45
|
+
baseBranch = null;
|
|
46
|
+
// Layer state
|
|
47
|
+
isOnBaseBranch = false;
|
|
48
|
+
baseIdSet = /* @__PURE__ */ new Set();
|
|
49
|
+
deltaIdSet = /* @__PURE__ */ new Set();
|
|
50
|
+
tombstones = /* @__PURE__ */ new Set();
|
|
51
|
+
// Change tracking
|
|
52
|
+
baseUnsavedCount = 0;
|
|
53
|
+
deltaUnsavedCount = 0;
|
|
54
|
+
/** Maximum delta size before auto-merge to prevent memory leaks */
|
|
55
|
+
static MAX_DELTA_SIZE = 5e3;
|
|
56
|
+
// Initialization mutex
|
|
57
|
+
initializePromise = null;
|
|
58
|
+
constructor(config = {}) {
|
|
59
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
60
|
+
}
|
|
61
|
+
// ===========================================================================
|
|
62
|
+
// Public API
|
|
63
|
+
// ===========================================================================
|
|
64
|
+
/**
|
|
65
|
+
* Check if the provider is initialized
|
|
66
|
+
*/
|
|
67
|
+
get initialized() {
|
|
68
|
+
return this.isInitialized;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get current configured dimensions
|
|
72
|
+
*/
|
|
73
|
+
getDimensions() {
|
|
74
|
+
return this.config.dimensions;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Update dimensions (e.g. when embedding model changes)
|
|
78
|
+
* Only effective before initialize() creates the FAISS index.
|
|
79
|
+
*/
|
|
80
|
+
setDimensions(dimensions) {
|
|
81
|
+
if (this.config.dimensions !== dimensions) {
|
|
82
|
+
log.i("LAYERED_FAISS", "dimensions_updated", { from: this.config.dimensions, to: dimensions });
|
|
83
|
+
this.config.dimensions = dimensions;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// ===========================================================================
|
|
87
|
+
// Lifecycle
|
|
88
|
+
// ===========================================================================
|
|
89
|
+
/**
|
|
90
|
+
* Initialize the provider for a specific project and branch
|
|
91
|
+
* v6: CRITICAL FIX - Check if projectHash changed and reinitialize if needed!
|
|
92
|
+
* Without this, switching projects would continue using the first project's index.
|
|
93
|
+
*/
|
|
94
|
+
async initialize(projectPath, projectHash, branchName) {
|
|
95
|
+
if (this.initializePromise && this.projectHash === projectHash) {
|
|
96
|
+
return this.initializePromise;
|
|
97
|
+
}
|
|
98
|
+
if (this.projectHash && this.projectHash !== projectHash) {
|
|
99
|
+
log.i("LAYERED_FAISS", "project_switch", {
|
|
100
|
+
from: this.projectHash,
|
|
101
|
+
to: projectHash
|
|
102
|
+
});
|
|
103
|
+
if (this.isInitialized) {
|
|
104
|
+
log.i("LAYERED_FAISS", "saving_before_switch", {
|
|
105
|
+
project: this.projectHash,
|
|
106
|
+
baseUnsaved: this.baseUnsavedCount,
|
|
107
|
+
deltaUnsaved: this.deltaUnsavedCount
|
|
108
|
+
});
|
|
109
|
+
await this.save();
|
|
110
|
+
}
|
|
111
|
+
this.isInitialized = false;
|
|
112
|
+
this.initializePromise = null;
|
|
113
|
+
}
|
|
114
|
+
this.initializePromise = this.initializeInternal(projectPath, projectHash, branchName);
|
|
115
|
+
return this.initializePromise;
|
|
116
|
+
}
|
|
117
|
+
async initializeInternal(projectPath, projectHash, branchName) {
|
|
118
|
+
try {
|
|
119
|
+
this.projectPath = projectPath;
|
|
120
|
+
this.projectHash = projectHash;
|
|
121
|
+
this.currentBranch = normalizeBranchName(branchName);
|
|
122
|
+
this.baseIdSet.clear();
|
|
123
|
+
this.deltaIdSet.clear();
|
|
124
|
+
this.tombstones.clear();
|
|
125
|
+
this.baseUnsavedCount = 0;
|
|
126
|
+
this.deltaUnsavedCount = 0;
|
|
127
|
+
const projectDir = getProjectDir(projectPath);
|
|
128
|
+
if (!existsSync(projectDir)) {
|
|
129
|
+
mkdirSync(projectDir, { recursive: true });
|
|
130
|
+
}
|
|
131
|
+
this.client = getGpuClient();
|
|
132
|
+
const started = await this.client.start();
|
|
133
|
+
if (!started) {
|
|
134
|
+
log.e("LAYERED_FAISS", "client_start_fail");
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
this.baseBranch = detectBaseBranch(projectPath);
|
|
138
|
+
this.isOnBaseBranch = this.baseBranch === this.currentBranch;
|
|
139
|
+
log.i("LAYERED_FAISS", "init", {
|
|
140
|
+
project: projectHash,
|
|
141
|
+
current: this.currentBranch,
|
|
142
|
+
base: this.baseBranch,
|
|
143
|
+
isOnBase: this.isOnBaseBranch
|
|
144
|
+
});
|
|
145
|
+
await this.loadLayers();
|
|
146
|
+
this.isInitialized = true;
|
|
147
|
+
return true;
|
|
148
|
+
} catch (error) {
|
|
149
|
+
log.e("LAYERED_FAISS", "init_fail", { err: String(error) });
|
|
150
|
+
this.initializePromise = null;
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Load the appropriate layers based on current branch
|
|
156
|
+
*/
|
|
157
|
+
async loadLayers() {
|
|
158
|
+
const projectDir = getProjectDir(this.projectPath);
|
|
159
|
+
const paths = getLayeredPaths(projectDir, this.currentBranch, this.baseBranch);
|
|
160
|
+
log.d("LAYERED_FAISS", "load_layers", {
|
|
161
|
+
projectDir,
|
|
162
|
+
projectPath: this.projectPath,
|
|
163
|
+
currentBranch: this.currentBranch,
|
|
164
|
+
baseBranch: this.baseBranch,
|
|
165
|
+
baseIndexPath: paths.baseIndex,
|
|
166
|
+
baseIndexExists: existsSync(paths.baseIndex),
|
|
167
|
+
baseIdsPath: paths.baseIds,
|
|
168
|
+
baseIdsExists: existsSync(paths.baseIds)
|
|
169
|
+
});
|
|
170
|
+
await this.loadBaseLayer(paths);
|
|
171
|
+
if (!this.isOnBaseBranch) {
|
|
172
|
+
await this.loadDeltaLayer(paths);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Load base layer index
|
|
177
|
+
*/
|
|
178
|
+
async loadBaseLayer(paths) {
|
|
179
|
+
const indexConfig = {
|
|
180
|
+
dimensions: this.config.dimensions,
|
|
181
|
+
indexType: this.config.indexType,
|
|
182
|
+
metric: "l2",
|
|
183
|
+
hnswM: this.config.hnswM,
|
|
184
|
+
hnswEfConstruction: this.config.hnswEfConstruction,
|
|
185
|
+
hnswEfSearch: this.config.hnswEfSearch
|
|
186
|
+
};
|
|
187
|
+
const baseIndexExists = existsSync(paths.baseIndex);
|
|
188
|
+
const loadPath = baseIndexExists ? paths.baseIndex : void 0;
|
|
189
|
+
await this.client.faissInitialize(indexConfig, loadPath);
|
|
190
|
+
if (baseIndexExists && existsSync(paths.baseIds)) {
|
|
191
|
+
try {
|
|
192
|
+
const data = readFileSync(paths.baseIds, "utf-8");
|
|
193
|
+
const ids = JSON.parse(data);
|
|
194
|
+
this.baseIdSet = new Set(ids);
|
|
195
|
+
log.d("LAYERED_FAISS", "base_ids_loaded", { count: this.baseIdSet.size });
|
|
196
|
+
} catch (error) {
|
|
197
|
+
log.w("LAYERED_FAISS", "base_ids_load_fail", { err: String(error) });
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
const stats = await this.client.faissGetStats();
|
|
201
|
+
log.i("LAYERED_FAISS", "base_loaded", {
|
|
202
|
+
vectors: stats.totalVectors,
|
|
203
|
+
ids: this.baseIdSet.size,
|
|
204
|
+
fromFile: baseIndexExists
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Load delta layer for feature branch
|
|
209
|
+
*/
|
|
210
|
+
async loadDeltaLayer(paths) {
|
|
211
|
+
if (existsSync(paths.tombstones)) {
|
|
212
|
+
try {
|
|
213
|
+
const data = readFileSync(paths.tombstones, "utf-8");
|
|
214
|
+
const tombstoneList = JSON.parse(data);
|
|
215
|
+
this.tombstones = new Set(tombstoneList);
|
|
216
|
+
log.d("LAYERED_FAISS", "tombstones_loaded", { count: this.tombstones.size });
|
|
217
|
+
} catch (error) {
|
|
218
|
+
log.w("LAYERED_FAISS", "tombstones_load_fail", { err: String(error) });
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (existsSync(paths.deltaIds)) {
|
|
222
|
+
try {
|
|
223
|
+
const data = readFileSync(paths.deltaIds, "utf-8");
|
|
224
|
+
const ids = JSON.parse(data);
|
|
225
|
+
this.deltaIdSet = new Set(ids);
|
|
226
|
+
log.d("LAYERED_FAISS", "delta_ids_loaded", { count: this.deltaIdSet.size });
|
|
227
|
+
} catch (error) {
|
|
228
|
+
log.w("LAYERED_FAISS", "delta_ids_load_fail", { err: String(error) });
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// ===========================================================================
|
|
233
|
+
// Branch switching
|
|
234
|
+
// ===========================================================================
|
|
235
|
+
/**
|
|
236
|
+
* Switch to a different branch
|
|
237
|
+
*/
|
|
238
|
+
async switchBranch(branchName) {
|
|
239
|
+
const normalizedBranch = normalizeBranchName(branchName);
|
|
240
|
+
if (this.currentBranch === normalizedBranch) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
log.i("LAYERED_FAISS", "branch_switch", {
|
|
244
|
+
from: this.currentBranch,
|
|
245
|
+
to: normalizedBranch
|
|
246
|
+
});
|
|
247
|
+
await this.save();
|
|
248
|
+
this.currentBranch = normalizedBranch;
|
|
249
|
+
this.isOnBaseBranch = this.baseBranch === normalizedBranch;
|
|
250
|
+
this.deltaIdSet.clear();
|
|
251
|
+
this.tombstones.clear();
|
|
252
|
+
this.deltaUnsavedCount = 0;
|
|
253
|
+
if (!this.isOnBaseBranch) {
|
|
254
|
+
const projectDir = getProjectDir(this.projectPath);
|
|
255
|
+
const paths = getLayeredPaths(projectDir, normalizedBranch, this.baseBranch);
|
|
256
|
+
await this.loadDeltaLayer(paths);
|
|
257
|
+
}
|
|
258
|
+
log.i("LAYERED_FAISS", "branch_switched", {
|
|
259
|
+
branch: normalizedBranch,
|
|
260
|
+
isOnBase: this.isOnBaseBranch,
|
|
261
|
+
deltaIds: this.deltaIdSet.size,
|
|
262
|
+
tombstones: this.tombstones.size
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
// ===========================================================================
|
|
266
|
+
// Search
|
|
267
|
+
// ===========================================================================
|
|
268
|
+
/**
|
|
269
|
+
* Search across all layers
|
|
270
|
+
*
|
|
271
|
+
* Algorithm:
|
|
272
|
+
* 1. Search base index for top K*2 results
|
|
273
|
+
* 2. Filter out tombstones
|
|
274
|
+
* 3. If on feature branch, search delta for top K*2
|
|
275
|
+
* 4. Merge and deduplicate (delta takes precedence)
|
|
276
|
+
* 5. Sort by similarity and return top K
|
|
277
|
+
*/
|
|
278
|
+
async search(queryVector, limit) {
|
|
279
|
+
if (!this.isInitialized || !this.client) {
|
|
280
|
+
log.w("LAYERED_FAISS", "search called but not initialized", {
|
|
281
|
+
isInit: this.isInitialized,
|
|
282
|
+
hasClient: !!this.client
|
|
283
|
+
});
|
|
284
|
+
return [];
|
|
285
|
+
}
|
|
286
|
+
const normalizedQuery = simdL2Normalize(queryVector);
|
|
287
|
+
log.d("LAYERED_FAISS", "search", {
|
|
288
|
+
inputLen: queryVector.length,
|
|
289
|
+
normalizedLen: normalizedQuery.length,
|
|
290
|
+
limit,
|
|
291
|
+
normalizedSample: Array.from(normalizedQuery.slice(0, 3))
|
|
292
|
+
});
|
|
293
|
+
const searchLimit = Math.min(limit * 2, 200);
|
|
294
|
+
const results = [];
|
|
295
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
296
|
+
if (!this.isOnBaseBranch && this.deltaIdSet.size > 0) ;
|
|
297
|
+
log.d("LAYERED_FAISS", "calling faissSearch", {
|
|
298
|
+
vectorLen: normalizedQuery.length,
|
|
299
|
+
vectorType: normalizedQuery.constructor.name,
|
|
300
|
+
searchLimit
|
|
301
|
+
});
|
|
302
|
+
const baseResults = await this.client.faissSearch(normalizedQuery, searchLimit);
|
|
303
|
+
for (const result of baseResults) {
|
|
304
|
+
if (seenIds.has(result.id)) continue;
|
|
305
|
+
if (this.tombstones.has(result.id)) continue;
|
|
306
|
+
if (this.deltaIdSet.has(result.id)) {
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
results.push({
|
|
310
|
+
id: result.id,
|
|
311
|
+
similarity: 1 - result.distance,
|
|
312
|
+
// Convert L2 distance to similarity
|
|
313
|
+
source: "base"
|
|
314
|
+
});
|
|
315
|
+
seenIds.add(result.id);
|
|
316
|
+
}
|
|
317
|
+
for (const id of this.deltaIdSet) {
|
|
318
|
+
if (!seenIds.has(id) && results.length < limit) {
|
|
319
|
+
const baseResult = baseResults.find((r) => r.id === id);
|
|
320
|
+
if (baseResult) {
|
|
321
|
+
results.push({
|
|
322
|
+
id: baseResult.id,
|
|
323
|
+
similarity: 1 - baseResult.distance,
|
|
324
|
+
source: "delta"
|
|
325
|
+
});
|
|
326
|
+
seenIds.add(id);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return results.sort((a, b) => b.similarity - a.similarity).slice(0, limit);
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Search and return in VectorStore-compatible format
|
|
334
|
+
*/
|
|
335
|
+
async searchForVectorStore(queryVector, limit) {
|
|
336
|
+
const results = await this.search(queryVector, limit);
|
|
337
|
+
return results.map((r) => ({
|
|
338
|
+
id: r.id,
|
|
339
|
+
content: "",
|
|
340
|
+
// Content is not stored in FAISS, retrieved separately
|
|
341
|
+
similarity: r.similarity,
|
|
342
|
+
metadata: { source: r.source }
|
|
343
|
+
}));
|
|
344
|
+
}
|
|
345
|
+
// ===========================================================================
|
|
346
|
+
// Add / Remove
|
|
347
|
+
// ===========================================================================
|
|
348
|
+
/**
|
|
349
|
+
* Add a vector embedding
|
|
350
|
+
*/
|
|
351
|
+
async add(embedding) {
|
|
352
|
+
if (!this.isInitialized || !this.client) {
|
|
353
|
+
return { success: false, target: "base", error: "Not initialized" };
|
|
354
|
+
}
|
|
355
|
+
const normalizedVector = simdL2Normalize(embedding.vector);
|
|
356
|
+
if (this.isOnBaseBranch) {
|
|
357
|
+
await this.client.faissAdd([embedding.id], normalizedVector);
|
|
358
|
+
this.baseIdSet.add(embedding.id);
|
|
359
|
+
this.baseUnsavedCount++;
|
|
360
|
+
if (this.baseUnsavedCount >= this.config.autoSaveThreshold) {
|
|
361
|
+
await this.saveBase();
|
|
362
|
+
}
|
|
363
|
+
return { success: true, target: "base" };
|
|
364
|
+
} else {
|
|
365
|
+
this.tombstones.delete(embedding.id);
|
|
366
|
+
this.deltaIdSet.add(embedding.id);
|
|
367
|
+
this.deltaUnsavedCount++;
|
|
368
|
+
log.i("LAYERED_FAISS", "add_to_delta", {
|
|
369
|
+
id: embedding.id.slice(0, 50),
|
|
370
|
+
branch: this.currentBranch,
|
|
371
|
+
deltaUnsaved: this.deltaUnsavedCount
|
|
372
|
+
});
|
|
373
|
+
await this.client.faissAdd([embedding.id], normalizedVector);
|
|
374
|
+
if (this.deltaUnsavedCount >= this.config.autoSaveThreshold) {
|
|
375
|
+
await this.saveDelta();
|
|
376
|
+
}
|
|
377
|
+
return { success: true, target: "delta" };
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Add multiple embeddings in batch (optimized - single Named Pipe call)
|
|
382
|
+
*/
|
|
383
|
+
async addBatch(embeddings) {
|
|
384
|
+
if (embeddings.length === 0) {
|
|
385
|
+
return [];
|
|
386
|
+
}
|
|
387
|
+
if (!this.isInitialized || !this.client) {
|
|
388
|
+
return embeddings.map(() => ({ success: false, target: "base", error: "Not initialized" }));
|
|
389
|
+
}
|
|
390
|
+
log.d("LAYERED_FAISS", "addBatch_called", {
|
|
391
|
+
count: embeddings.length,
|
|
392
|
+
branch: this.currentBranch,
|
|
393
|
+
isOnBase: this.isOnBaseBranch
|
|
394
|
+
});
|
|
395
|
+
const startTime = performance.now();
|
|
396
|
+
const allIds = [];
|
|
397
|
+
const dimensions = this.config.dimensions;
|
|
398
|
+
const allVectors = new Float32Array(embeddings.length * dimensions);
|
|
399
|
+
for (let i = 0; i < embeddings.length; i++) {
|
|
400
|
+
const embedding = embeddings[i];
|
|
401
|
+
const normalized = simdL2Normalize(embedding.vector);
|
|
402
|
+
allIds.push(embedding.id);
|
|
403
|
+
allVectors.set(normalized, i * dimensions);
|
|
404
|
+
if (this.isOnBaseBranch) {
|
|
405
|
+
this.baseIdSet.add(embedding.id);
|
|
406
|
+
} else {
|
|
407
|
+
this.tombstones.delete(embedding.id);
|
|
408
|
+
this.deltaIdSet.add(embedding.id);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
await this.client.faissAdd(allIds, allVectors);
|
|
412
|
+
if (this.isOnBaseBranch) {
|
|
413
|
+
this.baseUnsavedCount += embeddings.length;
|
|
414
|
+
if (this.baseUnsavedCount >= this.config.autoSaveThreshold) {
|
|
415
|
+
await this.saveBase();
|
|
416
|
+
}
|
|
417
|
+
} else {
|
|
418
|
+
this.deltaUnsavedCount += embeddings.length;
|
|
419
|
+
if (this.deltaUnsavedCount >= this.config.autoSaveThreshold) {
|
|
420
|
+
await this.saveDelta();
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
const elapsed = performance.now() - startTime;
|
|
424
|
+
log.i("LAYERED_FAISS", "addBatch_complete", {
|
|
425
|
+
count: embeddings.length,
|
|
426
|
+
elapsed: `${elapsed.toFixed(1)}ms`,
|
|
427
|
+
speed: `${Math.round(embeddings.length / (elapsed / 1e3))}/s`,
|
|
428
|
+
target: this.isOnBaseBranch ? "base" : "delta",
|
|
429
|
+
deltaIdSetSize: this.deltaIdSet.size,
|
|
430
|
+
tombstonesSize: this.tombstones.size
|
|
431
|
+
});
|
|
432
|
+
if (!this.isOnBaseBranch && this.deltaIdSet.size > _LayeredFaissProvider.MAX_DELTA_SIZE) {
|
|
433
|
+
log.i("LAYERED_FAISS", "auto_merge_delta", {
|
|
434
|
+
deltaSize: this.deltaIdSet.size,
|
|
435
|
+
tombstones: this.tombstones.size,
|
|
436
|
+
threshold: _LayeredFaissProvider.MAX_DELTA_SIZE
|
|
437
|
+
});
|
|
438
|
+
logMemory("LAYERED_FAISS", { deltaSize: this.deltaIdSet.size, tombstones: this.tombstones.size });
|
|
439
|
+
await this.saveBase();
|
|
440
|
+
if (tryGarbageCollect(true)) {
|
|
441
|
+
log.d("LAYERED_FAISS", "gc_after_merge");
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
const target = this.isOnBaseBranch ? "base" : "delta";
|
|
445
|
+
return embeddings.map(() => ({ success: true, target }));
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Remove vectors by IDs (IVectorProvider interface)
|
|
449
|
+
*/
|
|
450
|
+
async remove(ids) {
|
|
451
|
+
for (const id of ids) {
|
|
452
|
+
await this.removeOne(id);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Remove a single vector by ID
|
|
457
|
+
*/
|
|
458
|
+
async removeOne(id) {
|
|
459
|
+
if (!this.isInitialized || !this.client) {
|
|
460
|
+
return { success: false, action: "not_found" };
|
|
461
|
+
}
|
|
462
|
+
if (this.isOnBaseBranch) {
|
|
463
|
+
const existed = this.baseIdSet.has(id);
|
|
464
|
+
if (existed) {
|
|
465
|
+
await this.client.faissRemove([id]);
|
|
466
|
+
this.baseIdSet.delete(id);
|
|
467
|
+
this.baseUnsavedCount++;
|
|
468
|
+
return { success: true, action: "removed_from_base" };
|
|
469
|
+
}
|
|
470
|
+
return { success: false, action: "not_found" };
|
|
471
|
+
} else {
|
|
472
|
+
if (this.deltaIdSet.has(id)) {
|
|
473
|
+
this.deltaIdSet.delete(id);
|
|
474
|
+
this.deltaUnsavedCount++;
|
|
475
|
+
return { success: true, action: "removed_from_delta" };
|
|
476
|
+
} else if (this.baseIdSet.has(id)) {
|
|
477
|
+
this.tombstones.add(id);
|
|
478
|
+
this.deltaUnsavedCount++;
|
|
479
|
+
return { success: true, action: "added_tombstone" };
|
|
480
|
+
}
|
|
481
|
+
return { success: false, action: "not_found" };
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Check if ID exists (considering tombstones)
|
|
486
|
+
*/
|
|
487
|
+
has(id) {
|
|
488
|
+
if (this.tombstones.has(id)) {
|
|
489
|
+
return false;
|
|
490
|
+
}
|
|
491
|
+
return this.deltaIdSet.has(id) || this.baseIdSet.has(id);
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Get existing IDs from a list (considering tombstones)
|
|
495
|
+
* Required by IVectorProvider interface
|
|
496
|
+
*/
|
|
497
|
+
getExistingIds(ids) {
|
|
498
|
+
const existing = /* @__PURE__ */ new Set();
|
|
499
|
+
for (const id of ids) {
|
|
500
|
+
if (this.has(id)) {
|
|
501
|
+
existing.add(id);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
return existing;
|
|
505
|
+
}
|
|
506
|
+
// ===========================================================================
|
|
507
|
+
// Persistence
|
|
508
|
+
// ===========================================================================
|
|
509
|
+
/**
|
|
510
|
+
* Save all layers
|
|
511
|
+
*/
|
|
512
|
+
async save() {
|
|
513
|
+
log.i("LAYERED_FAISS", "save_called", {
|
|
514
|
+
branch: this.currentBranch,
|
|
515
|
+
isOnBase: this.isOnBaseBranch,
|
|
516
|
+
baseUnsaved: this.baseUnsavedCount,
|
|
517
|
+
deltaUnsaved: this.deltaUnsavedCount
|
|
518
|
+
});
|
|
519
|
+
if (this.baseUnsavedCount > 0) {
|
|
520
|
+
await this.saveBase();
|
|
521
|
+
}
|
|
522
|
+
if (this.deltaUnsavedCount > 0) {
|
|
523
|
+
await this.saveDelta();
|
|
524
|
+
} else if (!this.isOnBaseBranch) {
|
|
525
|
+
log.w("LAYERED_FAISS", "delta_not_saved_zero_unsaved", {
|
|
526
|
+
branch: this.currentBranch,
|
|
527
|
+
deltaIdSetSize: this.deltaIdSet.size
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Save base layer
|
|
533
|
+
*/
|
|
534
|
+
async saveBase() {
|
|
535
|
+
if (!this.client || !this.isInitialized) return;
|
|
536
|
+
const projectDir = getProjectDir(this.projectPath);
|
|
537
|
+
const paths = getLayeredPaths(projectDir, this.currentBranch, this.baseBranch);
|
|
538
|
+
try {
|
|
539
|
+
const dir = dirname(paths.baseIndex);
|
|
540
|
+
if (!existsSync(dir)) {
|
|
541
|
+
mkdirSync(dir, { recursive: true });
|
|
542
|
+
}
|
|
543
|
+
await this.client.faissSave(paths.baseIndex);
|
|
544
|
+
writeFileSync(paths.baseIds, JSON.stringify([...this.baseIdSet]), "utf-8");
|
|
545
|
+
const existingMeta = loadBaseMetadata(this.projectPath);
|
|
546
|
+
if (!existingMeta) {
|
|
547
|
+
createInitialBaseMetadata(this.projectPath, this.currentBranch, this.config.dimensions, this.baseIdSet.size);
|
|
548
|
+
this.baseBranch = this.currentBranch;
|
|
549
|
+
log.i("LAYERED_FAISS", "base_meta_created", { branch: this.currentBranch });
|
|
550
|
+
} else {
|
|
551
|
+
updateBaseMetadata(this.projectPath, this.baseIdSet.size);
|
|
552
|
+
}
|
|
553
|
+
this.baseUnsavedCount = 0;
|
|
554
|
+
log.i("LAYERED_FAISS", "base_saved", { vectors: this.baseIdSet.size });
|
|
555
|
+
} catch (error) {
|
|
556
|
+
log.e("LAYERED_FAISS", "base_save_fail", { err: String(error) });
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Save delta layer
|
|
561
|
+
*/
|
|
562
|
+
async saveDelta() {
|
|
563
|
+
if (!this.isInitialized || this.isOnBaseBranch || !this.client) return;
|
|
564
|
+
const projectDir = getProjectDir(this.projectPath);
|
|
565
|
+
const paths = getLayeredPaths(projectDir, this.currentBranch, this.baseBranch);
|
|
566
|
+
try {
|
|
567
|
+
const dir = dirname(paths.deltaIds);
|
|
568
|
+
if (!existsSync(dir)) {
|
|
569
|
+
mkdirSync(dir, { recursive: true });
|
|
570
|
+
}
|
|
571
|
+
await this.client.faissSave(paths.deltaIndex || paths.baseIndex);
|
|
572
|
+
writeFileSync(paths.deltaIds, JSON.stringify([...this.deltaIdSet]), "utf-8");
|
|
573
|
+
writeFileSync(paths.tombstones, JSON.stringify([...this.tombstones]), "utf-8");
|
|
574
|
+
const deltaMeta = {
|
|
575
|
+
branchName: this.currentBranch,
|
|
576
|
+
baseBranch: this.baseBranch,
|
|
577
|
+
deltaVectorCount: this.deltaIdSet.size,
|
|
578
|
+
tombstoneCount: this.tombstones.size,
|
|
579
|
+
createdAt: Date.now(),
|
|
580
|
+
updatedAt: Date.now()
|
|
581
|
+
};
|
|
582
|
+
writeFileSync(paths.deltaMeta, JSON.stringify(deltaMeta, null, 2), "utf-8");
|
|
583
|
+
this.deltaUnsavedCount = 0;
|
|
584
|
+
log.i("LAYERED_FAISS", "delta_saved", {
|
|
585
|
+
branch: this.currentBranch,
|
|
586
|
+
deltaIds: this.deltaIdSet.size,
|
|
587
|
+
tombstones: this.tombstones.size
|
|
588
|
+
});
|
|
589
|
+
} catch (error) {
|
|
590
|
+
log.e("LAYERED_FAISS", "delta_save_fail", { err: String(error) });
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
// ===========================================================================
|
|
594
|
+
// Statistics
|
|
595
|
+
// ===========================================================================
|
|
596
|
+
/**
|
|
597
|
+
* Get statistics about the layered index
|
|
598
|
+
*/
|
|
599
|
+
async getStats() {
|
|
600
|
+
const baseVectors = this.baseIdSet.size;
|
|
601
|
+
const deltaVectors = this.deltaIdSet.size;
|
|
602
|
+
const tombstoneCount = this.tombstones.size;
|
|
603
|
+
const totalVectors = baseVectors + deltaVectors - tombstoneCount;
|
|
604
|
+
return {
|
|
605
|
+
totalVectors: Math.max(0, totalVectors),
|
|
606
|
+
baseVectors,
|
|
607
|
+
deltaVectors,
|
|
608
|
+
tombstones: tombstoneCount,
|
|
609
|
+
currentBranch: this.currentBranch,
|
|
610
|
+
baseBranch: this.baseBranch,
|
|
611
|
+
isOnBaseBranch: this.isOnBaseBranch
|
|
612
|
+
};
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Get count of searchable vectors
|
|
616
|
+
*/
|
|
617
|
+
async count() {
|
|
618
|
+
const stats = await this.getStats();
|
|
619
|
+
return stats.totalVectors;
|
|
620
|
+
}
|
|
621
|
+
// ===========================================================================
|
|
622
|
+
// Cleanup
|
|
623
|
+
// ===========================================================================
|
|
624
|
+
/**
|
|
625
|
+
* Close and save all state
|
|
626
|
+
*/
|
|
627
|
+
async close() {
|
|
628
|
+
if (!this.isInitialized) return;
|
|
629
|
+
await this.save();
|
|
630
|
+
this.isInitialized = false;
|
|
631
|
+
this.initializePromise = null;
|
|
632
|
+
log.i("LAYERED_FAISS", "closed", {
|
|
633
|
+
project: this.projectHash,
|
|
634
|
+
branch: this.currentBranch
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
};
|
|
638
|
+
var layeredProviderInstance = null;
|
|
639
|
+
function getLayeredFaissProvider(config) {
|
|
640
|
+
if (!layeredProviderInstance) {
|
|
641
|
+
layeredProviderInstance = new LayeredFaissProvider(config);
|
|
642
|
+
} else if (config?.dimensions && config.dimensions !== layeredProviderInstance.getDimensions()) {
|
|
643
|
+
layeredProviderInstance.setDimensions(config.dimensions);
|
|
644
|
+
}
|
|
645
|
+
return layeredProviderInstance;
|
|
646
|
+
}
|
|
647
|
+
async function shutdownLayeredFaissProvider() {
|
|
648
|
+
if (layeredProviderInstance) {
|
|
649
|
+
await layeredProviderInstance.close();
|
|
650
|
+
layeredProviderInstance = null;
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
export { LayeredFaissProvider, getLayeredFaissProvider, shutdownLayeredFaissProvider };
|
|
655
|
+
//# sourceMappingURL=chunk-2Z6OQPYC.js.map
|
|
656
|
+
//# sourceMappingURL=chunk-2Z6OQPYC.js.map
|