@ppdocs/mcp 2.6.26 → 2.6.28
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/vector/index.d.ts +1 -1
- package/dist/vector/index.js +35 -10
- package/package.json +1 -1
package/dist/vector/index.d.ts
CHANGED
package/dist/vector/index.js
CHANGED
|
@@ -1,13 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 向量检索服务 - 基于 transformers.js 的语义搜索
|
|
3
|
-
* @version 0.
|
|
3
|
+
* @version 0.2
|
|
4
4
|
*/
|
|
5
5
|
import { pipeline } from '@xenova/transformers';
|
|
6
6
|
import * as fs from 'fs';
|
|
7
7
|
import * as path from 'path';
|
|
8
|
-
//
|
|
9
|
-
const
|
|
8
|
+
// 默认模型配置
|
|
9
|
+
const DEFAULT_MODEL = 'Xenova/multilingual-e5-small';
|
|
10
10
|
const VECTOR_DIM = 384;
|
|
11
|
+
// 当前加载的模型名
|
|
12
|
+
let currentModel = null;
|
|
13
|
+
/**
|
|
14
|
+
* 获取向量配置 (从 ~/.ppdocs/config/vector.json 读取)
|
|
15
|
+
*/
|
|
16
|
+
function getVectorConfig() {
|
|
17
|
+
const baseDir = process.env.PPDOCS_DATA_DIR || path.join(process.env.HOME || process.env.USERPROFILE || '', '.ppdocs');
|
|
18
|
+
const configPath = path.join(baseDir, 'config', 'vector.json');
|
|
19
|
+
try {
|
|
20
|
+
if (fs.existsSync(configPath)) {
|
|
21
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
22
|
+
return JSON.parse(content);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
console.warn('[Vector] Failed to load config:', e);
|
|
27
|
+
}
|
|
28
|
+
return { model: DEFAULT_MODEL, quantized: true };
|
|
29
|
+
}
|
|
11
30
|
// 单例模式
|
|
12
31
|
let extractor = null;
|
|
13
32
|
let isLoading = false;
|
|
@@ -18,15 +37,19 @@ const vectorIndex = new Map();
|
|
|
18
37
|
* 加载嵌入模型 (懒加载, 首次调用时下载)
|
|
19
38
|
*/
|
|
20
39
|
async function getExtractor() {
|
|
21
|
-
|
|
40
|
+
const config = getVectorConfig();
|
|
41
|
+
// 如果模型变更,重新加载
|
|
42
|
+
if (extractor && currentModel === config.model) {
|
|
22
43
|
return extractor;
|
|
23
|
-
|
|
44
|
+
}
|
|
45
|
+
if (isLoading && loadPromise && currentModel === config.model) {
|
|
24
46
|
return loadPromise;
|
|
25
47
|
}
|
|
26
48
|
isLoading = true;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
49
|
+
currentModel = config.model;
|
|
50
|
+
console.log(`[Vector] Loading embedding model: ${config.model}...`);
|
|
51
|
+
loadPromise = pipeline('feature-extraction', config.model, {
|
|
52
|
+
quantized: config.quantized,
|
|
30
53
|
});
|
|
31
54
|
extractor = await loadPromise;
|
|
32
55
|
isLoading = false;
|
|
@@ -100,9 +123,10 @@ async function saveIndex(projectId) {
|
|
|
100
123
|
if (!fs.existsSync(dir)) {
|
|
101
124
|
fs.mkdirSync(dir, { recursive: true });
|
|
102
125
|
}
|
|
126
|
+
const config = getVectorConfig();
|
|
103
127
|
fs.writeFileSync(indexPath, JSON.stringify({
|
|
104
128
|
version: 1,
|
|
105
|
-
model:
|
|
129
|
+
model: config.model,
|
|
106
130
|
dimension: VECTOR_DIM,
|
|
107
131
|
updatedAt: new Date().toISOString(),
|
|
108
132
|
entries
|
|
@@ -188,9 +212,10 @@ export async function buildIndex(projectId, nodes) {
|
|
|
188
212
|
*/
|
|
189
213
|
export async function getIndexStats(projectId) {
|
|
190
214
|
const entries = await loadIndex(projectId);
|
|
215
|
+
const config = getVectorConfig();
|
|
191
216
|
return {
|
|
192
217
|
count: entries.length,
|
|
193
|
-
model:
|
|
218
|
+
model: config.model,
|
|
194
219
|
dimension: VECTOR_DIM,
|
|
195
220
|
loaded: extractor !== null
|
|
196
221
|
};
|