maestro-flow 0.5.34 → 0.5.35
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/.agents/agents/workflow-collab-planner.md +1 -0
- package/.agents/agents/workflow-planner.md +2 -0
- package/.agents/skills/maestro-help/SKILL.md +1 -1
- package/.agents/skills/maestro-help/index/catalog.json +0 -1
- package/.agents/skills/maestro-help/phases/01-parse-intent.md +1 -1
- package/.agents/skills/maestro-plan/SKILL.md +3 -1
- package/.agents/skills/maestro-ralph/SKILL.md +46 -17
- package/.agents/skills/maestro-ralph-execute/SKILL.md +51 -10
- package/.agents/skills/quality-test/SKILL.md +27 -1
- package/.agy/agents/workflow-collab-planner.md +1 -0
- package/.agy/agents/workflow-planner.md +2 -0
- package/.agy/skills/maestro-help/SKILL.md +1 -1
- package/.agy/skills/maestro-help/index/catalog.json +0 -1
- package/.agy/skills/maestro-help/phases/01-parse-intent.md +1 -1
- package/.agy/skills/maestro-plan/SKILL.md +3 -1
- package/.agy/skills/maestro-ralph/SKILL.md +46 -17
- package/.agy/skills/maestro-ralph-execute/SKILL.md +51 -10
- package/.agy/skills/quality-test/SKILL.md +27 -1
- package/.claude/agents/workflow-collab-planner.md +1 -0
- package/.claude/agents/workflow-planner.md +2 -0
- package/.claude/commands/maestro-plan.md +3 -1
- package/.claude/commands/maestro-ralph-execute.md +51 -10
- package/.claude/commands/maestro-ralph.md +46 -17
- package/.claude/commands/quality-test.md +27 -1
- package/.claude/skills/maestro-help/SKILL.md +1 -1
- package/.claude/skills/maestro-help/index/catalog.json +0 -1
- package/.claude/skills/maestro-help/phases/01-parse-intent.md +1 -1
- package/.codex/skills/maestro/SKILL.md +17 -2
- package/.codex/skills/maestro-analyze/SKILL.md +20 -3
- package/.codex/skills/maestro-brainstorm/SKILL.md +30 -4
- package/.codex/skills/maestro-execute/SKILL.md +25 -3
- package/.codex/skills/maestro-grill/SKILL.md +9 -0
- package/.codex/skills/maestro-plan/SKILL.md +26 -3
- package/.codex/skills/maestro-ralph/SKILL.md +6 -0
- package/.codex/skills/maestro-ralph-execute/SKILL.md +51 -10
- package/.codex/skills/maestro-roadmap/SKILL.md +30 -1
- package/.codex/skills/quality-review/SKILL.md +9 -0
- package/README.md +28 -5
- package/README.zh-CN.md +28 -5
- package/dashboard/dist-server/dashboard/src/server/wiki/embedding.d.ts +82 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/embedding.js +444 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/embedding.js.map +1 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/search.d.ts +46 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/search.js +413 -19
- package/dashboard/dist-server/dashboard/src/server/wiki/search.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/stress.test.js +16 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/stress.test.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.d.ts +13 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js +102 -7
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.test.js +42 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.test.js.map +1 -1
- package/dashboard/dist-server/src/commands/hooks.d.ts +3 -0
- package/dashboard/dist-server/src/commands/hooks.js +11 -8
- package/dashboard/dist-server/src/commands/hooks.js.map +1 -1
- package/dashboard/dist-server/src/graph/kg/extraction/code/code-extractor.js +1 -1
- package/dashboard/dist-server/src/graph/kg/extraction/code/code-extractor.js.map +1 -1
- package/dashboard/dist-server/src/graph/kg/extraction/orchestrator.js +2 -6
- package/dashboard/dist-server/src/graph/kg/extraction/orchestrator.js.map +1 -1
- package/dist/src/cli.js +1 -0
- package/dist/src/cli.js.map +1 -1
- package/dist/src/commands/hooks.d.ts +3 -0
- package/dist/src/commands/hooks.d.ts.map +1 -1
- package/dist/src/commands/hooks.js +11 -8
- package/dist/src/commands/hooks.js.map +1 -1
- package/dist/src/commands/install.d.ts.map +1 -1
- package/dist/src/commands/install.js +42 -9
- package/dist/src/commands/install.js.map +1 -1
- package/dist/src/commands/search.d.ts +5 -0
- package/dist/src/commands/search.d.ts.map +1 -1
- package/dist/src/commands/search.js +81 -11
- package/dist/src/commands/search.js.map +1 -1
- package/dist/src/commands/update.d.ts.map +1 -1
- package/dist/src/commands/update.js +37 -21
- package/dist/src/commands/update.js.map +1 -1
- package/dist/src/core/install-executor.d.ts.map +1 -1
- package/dist/src/core/install-executor.js +6 -3
- package/dist/src/core/install-executor.js.map +1 -1
- package/dist/src/graph/kg/extraction/code/code-extractor.js +1 -1
- package/dist/src/graph/kg/extraction/code/code-extractor.js.map +1 -1
- package/dist/src/graph/kg/extraction/orchestrator.d.ts.map +1 -1
- package/dist/src/graph/kg/extraction/orchestrator.js +2 -6
- package/dist/src/graph/kg/extraction/orchestrator.js.map +1 -1
- package/dist/src/ralph/cmd-next.d.ts.map +1 -1
- package/dist/src/ralph/cmd-next.js +2 -3
- package/dist/src/ralph/cmd-next.js.map +1 -1
- package/package.json +4 -2
- package/workflows/claude-instructions.md +17 -2
- package/workflows/codex-instructions.md +85 -14
- package/workflows/command-authoring.md +1 -1
- package/workflows/plan.md +2 -1
- package/.agents/skills/maestro-ralph-beta/SKILL.md +0 -882
- package/.agy/skills/maestro-ralph-beta/SKILL.md +0 -878
- package/.claude/commands/maestro-ralph-beta.md +0 -880
- package/.codex/skills/maestro-ralph-beta/SKILL.md +0 -883
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedding-based semantic search using @huggingface/transformers (ONNX backend).
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - Smart device detection: auto-benchmarks CPU vs GPU (DirectML), picks fastest
|
|
6
|
+
* - Batch inference: processes documents in configurable batch sizes (4-5x faster)
|
|
7
|
+
* - Incremental indexing: only re-embeds new or changed documents
|
|
8
|
+
* - Graceful degradation: falls back to pure BM25 when transformers is unavailable
|
|
9
|
+
*/
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
import { createHash } from 'node:crypto';
|
|
12
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync } from 'node:fs';
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Cosine similarity (flat search — fast enough for <10K docs)
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
function cosineSimilarity(a, b) {
|
|
17
|
+
let dot = 0, normA = 0, normB = 0;
|
|
18
|
+
for (let i = 0; i < a.length; i++) {
|
|
19
|
+
dot += a[i] * b[i];
|
|
20
|
+
normA += a[i] * a[i];
|
|
21
|
+
normB += b[i] * b[i];
|
|
22
|
+
}
|
|
23
|
+
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
24
|
+
return denom === 0 ? 0 : dot / denom;
|
|
25
|
+
}
|
|
26
|
+
export function mergeRRFSignals(signals, limit, k = 60) {
|
|
27
|
+
const scores = new Map();
|
|
28
|
+
for (const { weight, results } of signals) {
|
|
29
|
+
for (let i = 0; i < results.length; i++) {
|
|
30
|
+
const rrf = weight / (k + i + 1);
|
|
31
|
+
scores.set(results[i].docId, (scores.get(results[i].docId) ?? 0) + rrf);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const merged = [];
|
|
35
|
+
for (const [docId, score] of scores)
|
|
36
|
+
merged.push({ docId, score });
|
|
37
|
+
merged.sort((a, b) => b.score - a.score);
|
|
38
|
+
return merged.slice(0, limit);
|
|
39
|
+
}
|
|
40
|
+
export function mergeRRF(bm25Results, vectorResults, limit, k = 60, bm25Weight = 0.6, vectorWeight = 0.4) {
|
|
41
|
+
return mergeRRFSignals([
|
|
42
|
+
{ name: 'bm25', weight: bm25Weight, results: bm25Results },
|
|
43
|
+
{ name: 'vector', weight: vectorWeight, results: vectorResults },
|
|
44
|
+
], limit, k);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Hybrid fusion: RRF for ordering stability + BM25 magnitude for score discrimination.
|
|
48
|
+
* finalScore = alpha * rrfNorm + (1-alpha) * bm25Norm
|
|
49
|
+
*/
|
|
50
|
+
export function mergeHybrid(bm25Results, vectorResults, limit, options) {
|
|
51
|
+
const k = options?.k ?? 10;
|
|
52
|
+
const alpha = options?.alpha ?? 0.4;
|
|
53
|
+
const bm25W = options?.bm25Weight ?? 0.6;
|
|
54
|
+
const vectorW = options?.vectorWeight ?? 0.4;
|
|
55
|
+
const rrfResults = mergeRRFSignals([
|
|
56
|
+
{ name: 'bm25', weight: bm25W, results: bm25Results },
|
|
57
|
+
{ name: 'vector', weight: vectorW, results: vectorResults },
|
|
58
|
+
], limit * 3, k);
|
|
59
|
+
const maxRrf = rrfResults.length > 0 ? rrfResults[0].score : 1;
|
|
60
|
+
const rrfNorm = new Map(rrfResults.map(r => [r.docId, maxRrf > 0 ? r.score / maxRrf : 0]));
|
|
61
|
+
const maxBm25 = bm25Results.length > 0 ? bm25Results[0].score : 1;
|
|
62
|
+
const bm25Norm = new Map(bm25Results.map(r => [r.docId, maxBm25 > 0 ? r.score / maxBm25 : 0]));
|
|
63
|
+
const merged = [];
|
|
64
|
+
const seen = new Set();
|
|
65
|
+
for (const r of rrfResults) {
|
|
66
|
+
if (seen.has(r.docId))
|
|
67
|
+
continue;
|
|
68
|
+
seen.add(r.docId);
|
|
69
|
+
const rn = rrfNorm.get(r.docId) ?? 0;
|
|
70
|
+
const bn = bm25Norm.get(r.docId) ?? 0;
|
|
71
|
+
merged.push({ docId: r.docId, score: alpha * rn + (1 - alpha) * bn });
|
|
72
|
+
}
|
|
73
|
+
merged.sort((a, b) => b.score - a.score);
|
|
74
|
+
return merged.slice(0, limit);
|
|
75
|
+
}
|
|
76
|
+
let _detectedConfig = null;
|
|
77
|
+
async function listBackends() {
|
|
78
|
+
try {
|
|
79
|
+
const ort = await import('onnxruntime-node');
|
|
80
|
+
if (typeof ort.listSupportedBackends === 'function') {
|
|
81
|
+
return ort.listSupportedBackends();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch { /* onnxruntime-node not available */ }
|
|
85
|
+
return [{ name: 'cpu', bundled: true }];
|
|
86
|
+
}
|
|
87
|
+
export async function detectDevice() {
|
|
88
|
+
if (_detectedConfig)
|
|
89
|
+
return _detectedConfig;
|
|
90
|
+
const backends = await listBackends();
|
|
91
|
+
const hasGpu = backends.some(b => b.name === 'dml' || b.name === 'cuda');
|
|
92
|
+
// For small models (all-MiniLM-L6-v2, 22M params), CPU is consistently faster
|
|
93
|
+
// due to CPU↔GPU data transfer overhead exceeding compute savings.
|
|
94
|
+
// GPU only wins for models >100M params or batch sizes >500.
|
|
95
|
+
_detectedConfig = {
|
|
96
|
+
device: 'cpu',
|
|
97
|
+
dtype: 'fp32',
|
|
98
|
+
batchSize: 32,
|
|
99
|
+
};
|
|
100
|
+
if (hasGpu) {
|
|
101
|
+
// Store GPU availability for future large-model support
|
|
102
|
+
_detectedConfig.batchSize = 64;
|
|
103
|
+
}
|
|
104
|
+
return _detectedConfig;
|
|
105
|
+
}
|
|
106
|
+
export function getDeviceSummary() {
|
|
107
|
+
if (!_detectedConfig)
|
|
108
|
+
return 'not initialized';
|
|
109
|
+
return `${_detectedConfig.device}/${_detectedConfig.dtype} batch=${_detectedConfig.batchSize}`;
|
|
110
|
+
}
|
|
111
|
+
export async function getHardwareInfo() {
|
|
112
|
+
const backends = await listBackends();
|
|
113
|
+
const hasGpu = backends.some(b => b.name === 'dml' || b.name === 'cuda');
|
|
114
|
+
const config = await detectDevice();
|
|
115
|
+
return {
|
|
116
|
+
backends,
|
|
117
|
+
gpuAvailable: hasGpu,
|
|
118
|
+
selectedDevice: config,
|
|
119
|
+
reason: hasGpu
|
|
120
|
+
? 'GPU available (DML/CUDA) but CPU selected — small model (22M params) runs faster on CPU due to transfer overhead'
|
|
121
|
+
: 'CPU only — no GPU backend detected',
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
// Pipeline management — lazy-loads model with detected device
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
const DEFAULT_MODEL = 'Xenova/multilingual-e5-small';
|
|
128
|
+
export const DEFAULT_MODEL_ID = DEFAULT_MODEL;
|
|
129
|
+
const CACHE_FILE = 'embedding-index.json';
|
|
130
|
+
let _pipeline = null;
|
|
131
|
+
let _available = null;
|
|
132
|
+
async function configureProxy() {
|
|
133
|
+
const proxy = process.env.HTTPS_PROXY || process.env.HTTP_PROXY || process.env.ALL_PROXY;
|
|
134
|
+
if (!proxy)
|
|
135
|
+
return;
|
|
136
|
+
try {
|
|
137
|
+
const { ProxyAgent, setGlobalDispatcher } = await import('undici');
|
|
138
|
+
setGlobalDispatcher(new ProxyAgent(proxy));
|
|
139
|
+
}
|
|
140
|
+
catch { /* undici not available */ }
|
|
141
|
+
}
|
|
142
|
+
async function loadTransformers() {
|
|
143
|
+
return await import('@huggingface/transformers');
|
|
144
|
+
}
|
|
145
|
+
async function getPipeline() {
|
|
146
|
+
if (_pipeline)
|
|
147
|
+
return _pipeline;
|
|
148
|
+
await configureProxy();
|
|
149
|
+
const config = await detectDevice();
|
|
150
|
+
const { pipeline } = await loadTransformers();
|
|
151
|
+
_pipeline = await pipeline('feature-extraction', DEFAULT_MODEL, {
|
|
152
|
+
dtype: config.dtype,
|
|
153
|
+
device: config.device,
|
|
154
|
+
});
|
|
155
|
+
return _pipeline;
|
|
156
|
+
}
|
|
157
|
+
let _unavailableReason = null;
|
|
158
|
+
export async function isAvailable() {
|
|
159
|
+
if (_available !== null)
|
|
160
|
+
return _available;
|
|
161
|
+
try {
|
|
162
|
+
await loadTransformers();
|
|
163
|
+
_available = true;
|
|
164
|
+
}
|
|
165
|
+
catch (e) {
|
|
166
|
+
_available = false;
|
|
167
|
+
_unavailableReason = e instanceof Error ? e.message : String(e);
|
|
168
|
+
}
|
|
169
|
+
return _available;
|
|
170
|
+
}
|
|
171
|
+
export function getUnavailableReason() {
|
|
172
|
+
return _unavailableReason;
|
|
173
|
+
}
|
|
174
|
+
// ---------------------------------------------------------------------------
|
|
175
|
+
// Batch embedding — processes texts in configurable batch sizes
|
|
176
|
+
// ---------------------------------------------------------------------------
|
|
177
|
+
export async function embedTexts(texts) {
|
|
178
|
+
if (texts.length === 0)
|
|
179
|
+
return [];
|
|
180
|
+
const pipe = await getPipeline();
|
|
181
|
+
const config = await detectDevice();
|
|
182
|
+
const batchSize = config.batchSize;
|
|
183
|
+
const results = [];
|
|
184
|
+
const truncated = texts.map(t => t.slice(0, 512));
|
|
185
|
+
for (let i = 0; i < truncated.length; i += batchSize) {
|
|
186
|
+
const batch = truncated.slice(i, i + batchSize);
|
|
187
|
+
const output = await pipe(batch, { pooling: 'mean', normalize: true });
|
|
188
|
+
if (batch.length === 1) {
|
|
189
|
+
results.push(new Float32Array(output.data));
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
const dim = output.dims[1];
|
|
193
|
+
for (let j = 0; j < batch.length; j++) {
|
|
194
|
+
const start = j * dim;
|
|
195
|
+
results.push(new Float32Array(output.data.slice(start, start + dim)));
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return results;
|
|
200
|
+
}
|
|
201
|
+
export async function embedQuery(query) {
|
|
202
|
+
const pipe = await getPipeline();
|
|
203
|
+
// E5 models require "query: " prefix for search queries
|
|
204
|
+
const output = await pipe(('query: ' + query).slice(0, 512), { pooling: 'mean', normalize: true });
|
|
205
|
+
return new Float32Array(output.data);
|
|
206
|
+
}
|
|
207
|
+
// ---------------------------------------------------------------------------
|
|
208
|
+
// Vector search (flat cosine — no index structure needed for <10K docs)
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
export function vectorSearch(queryVector, index, limit) {
|
|
211
|
+
const scored = [];
|
|
212
|
+
for (let i = 0; i < index.docIds.length; i++) {
|
|
213
|
+
const sim = cosineSimilarity(queryVector, index.vectors[i]);
|
|
214
|
+
if (sim > 0)
|
|
215
|
+
scored.push({ docId: index.docIds[i], score: sim });
|
|
216
|
+
}
|
|
217
|
+
scored.sort((a, b) => b.score - a.score);
|
|
218
|
+
return scored.slice(0, limit);
|
|
219
|
+
}
|
|
220
|
+
// ---------------------------------------------------------------------------
|
|
221
|
+
// Persistence — SQLite binary BLOB (primary) with JSON fallback for migration
|
|
222
|
+
// ---------------------------------------------------------------------------
|
|
223
|
+
const SQLITE_FILE = 'embedding-index.db';
|
|
224
|
+
import { createRequire } from 'node:module';
|
|
225
|
+
const _require = createRequire(import.meta.url);
|
|
226
|
+
const BINARY_FILE = 'embedding-index.bin';
|
|
227
|
+
export function saveEmbeddingIndex(index, dir) {
|
|
228
|
+
mkdirSync(dir, { recursive: true });
|
|
229
|
+
const dim = index.dimension;
|
|
230
|
+
const n = index.docIds.length;
|
|
231
|
+
const docIdsJson = JSON.stringify(index.docIds);
|
|
232
|
+
const docIdsBytes = Buffer.from(docIdsJson, 'utf-8');
|
|
233
|
+
const metaJson = JSON.stringify({
|
|
234
|
+
modelId: index.modelId,
|
|
235
|
+
dimension: dim,
|
|
236
|
+
count: n,
|
|
237
|
+
builtAt: index.builtAt,
|
|
238
|
+
deviceUsed: index.deviceUsed,
|
|
239
|
+
buildTimeMs: index.buildTimeMs,
|
|
240
|
+
contentHashes: index.contentHashes,
|
|
241
|
+
});
|
|
242
|
+
const metaBytes = Buffer.from(metaJson, 'utf-8');
|
|
243
|
+
// Format: [metaLen:4][meta][docIdsLen:4][docIds][packedVectors:n*dim*4]
|
|
244
|
+
const vectorBytes = n * dim * 4;
|
|
245
|
+
const totalSize = 4 + metaBytes.length + 4 + docIdsBytes.length + vectorBytes;
|
|
246
|
+
const buf = Buffer.alloc(totalSize);
|
|
247
|
+
let offset = 0;
|
|
248
|
+
buf.writeUInt32LE(metaBytes.length, offset);
|
|
249
|
+
offset += 4;
|
|
250
|
+
metaBytes.copy(buf, offset);
|
|
251
|
+
offset += metaBytes.length;
|
|
252
|
+
buf.writeUInt32LE(docIdsBytes.length, offset);
|
|
253
|
+
offset += 4;
|
|
254
|
+
docIdsBytes.copy(buf, offset);
|
|
255
|
+
offset += docIdsBytes.length;
|
|
256
|
+
for (let i = 0; i < n; i++) {
|
|
257
|
+
const v = index.vectors[i];
|
|
258
|
+
const vBuf = Buffer.from(v.buffer, v.byteOffset, v.byteLength);
|
|
259
|
+
vBuf.copy(buf, offset);
|
|
260
|
+
offset += dim * 4;
|
|
261
|
+
}
|
|
262
|
+
writeFileSync(join(dir, BINARY_FILE), buf);
|
|
263
|
+
// Remove legacy files
|
|
264
|
+
for (const f of [CACHE_FILE, SQLITE_FILE, SQLITE_FILE + '-shm', SQLITE_FILE + '-wal', SQLITE_FILE + '-journal']) {
|
|
265
|
+
try {
|
|
266
|
+
if (existsSync(join(dir, f)))
|
|
267
|
+
unlinkSync(join(dir, f));
|
|
268
|
+
}
|
|
269
|
+
catch { /* ignore */ }
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
export function loadEmbeddingIndex(dir) {
|
|
273
|
+
// Primary: packed binary
|
|
274
|
+
const binPath = join(dir, BINARY_FILE);
|
|
275
|
+
if (existsSync(binPath)) {
|
|
276
|
+
try {
|
|
277
|
+
return loadFromBinary(binPath);
|
|
278
|
+
}
|
|
279
|
+
catch {
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// Legacy: SQLite → migrate to binary
|
|
284
|
+
const dbPath = join(dir, SQLITE_FILE);
|
|
285
|
+
if (existsSync(dbPath)) {
|
|
286
|
+
try {
|
|
287
|
+
const idx = loadFromSqlite(dir);
|
|
288
|
+
saveEmbeddingIndex(idx, dir);
|
|
289
|
+
return idx;
|
|
290
|
+
}
|
|
291
|
+
catch { /* fall through */ }
|
|
292
|
+
}
|
|
293
|
+
// Legacy: JSON → migrate to binary
|
|
294
|
+
const jsonPath = join(dir, CACHE_FILE);
|
|
295
|
+
if (existsSync(jsonPath)) {
|
|
296
|
+
try {
|
|
297
|
+
const idx = loadFromLegacyJson(jsonPath);
|
|
298
|
+
saveEmbeddingIndex(idx, dir);
|
|
299
|
+
return idx;
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
function loadFromBinary(filePath) {
|
|
308
|
+
const raw = readFileSync(filePath);
|
|
309
|
+
let offset = 0;
|
|
310
|
+
const metaLen = raw.readUInt32LE(offset);
|
|
311
|
+
offset += 4;
|
|
312
|
+
const meta = JSON.parse(raw.subarray(offset, offset + metaLen).toString('utf-8'));
|
|
313
|
+
offset += metaLen;
|
|
314
|
+
const docIdsLen = raw.readUInt32LE(offset);
|
|
315
|
+
offset += 4;
|
|
316
|
+
const docIds = JSON.parse(raw.subarray(offset, offset + docIdsLen).toString('utf-8'));
|
|
317
|
+
offset += docIdsLen;
|
|
318
|
+
const dim = meta.dimension;
|
|
319
|
+
const n = meta.count;
|
|
320
|
+
const vectors = new Array(n);
|
|
321
|
+
for (let i = 0; i < n; i++) {
|
|
322
|
+
const ab = raw.buffer.slice(raw.byteOffset + offset, raw.byteOffset + offset + dim * 4);
|
|
323
|
+
vectors[i] = new Float32Array(ab);
|
|
324
|
+
offset += dim * 4;
|
|
325
|
+
}
|
|
326
|
+
return {
|
|
327
|
+
modelId: meta.modelId,
|
|
328
|
+
dimension: dim,
|
|
329
|
+
docIds,
|
|
330
|
+
vectors,
|
|
331
|
+
contentHashes: meta.contentHashes,
|
|
332
|
+
builtAt: meta.builtAt,
|
|
333
|
+
deviceUsed: meta.deviceUsed,
|
|
334
|
+
buildTimeMs: meta.buildTimeMs,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
function loadFromSqlite(dir) {
|
|
338
|
+
const Database = _require('better-sqlite3');
|
|
339
|
+
const dbPath = join(dir, SQLITE_FILE);
|
|
340
|
+
const db = new Database(dbPath, { readonly: true });
|
|
341
|
+
try {
|
|
342
|
+
const getMeta = db.prepare('SELECT value FROM meta WHERE key = ?');
|
|
343
|
+
const modelId = getMeta.get('modelId')?.value ?? 'unknown';
|
|
344
|
+
const dimension = parseInt(getMeta.get('dimension')?.value ?? '384', 10);
|
|
345
|
+
const builtAt = parseInt(getMeta.get('builtAt')?.value ?? '0', 10);
|
|
346
|
+
const deviceUsed = getMeta.get('deviceUsed')?.value;
|
|
347
|
+
const buildTimeMs = parseInt(getMeta.get('buildTimeMs')?.value ?? '0', 10) || undefined;
|
|
348
|
+
const rows = db.prepare('SELECT doc_id, vector FROM vectors ORDER BY rowid').all();
|
|
349
|
+
const docIds = [];
|
|
350
|
+
const vectors = [];
|
|
351
|
+
for (const row of rows) {
|
|
352
|
+
docIds.push(row.doc_id);
|
|
353
|
+
const ab = row.vector.buffer.slice(row.vector.byteOffset, row.vector.byteOffset + row.vector.byteLength);
|
|
354
|
+
vectors.push(new Float32Array(ab));
|
|
355
|
+
}
|
|
356
|
+
return { modelId, dimension, docIds, vectors, builtAt, deviceUsed, buildTimeMs };
|
|
357
|
+
}
|
|
358
|
+
finally {
|
|
359
|
+
db.close();
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
function loadFromLegacyJson(filePath) {
|
|
363
|
+
const raw = JSON.parse(readFileSync(filePath, 'utf-8'));
|
|
364
|
+
return {
|
|
365
|
+
modelId: raw.modelId,
|
|
366
|
+
dimension: raw.dimension,
|
|
367
|
+
docIds: raw.docIds,
|
|
368
|
+
vectors: raw.vectors.map((b64) => {
|
|
369
|
+
const buf = Buffer.from(b64, 'base64');
|
|
370
|
+
const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
|
|
371
|
+
return new Float32Array(ab);
|
|
372
|
+
}),
|
|
373
|
+
builtAt: raw.builtAt,
|
|
374
|
+
deviceUsed: raw.deviceUsed,
|
|
375
|
+
buildTimeMs: raw.buildTimeMs,
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
export function hashDocContent(d) {
|
|
379
|
+
const text = [d.title, d.summary, d.tags.join(','), d.body?.slice(0, 500) ?? ''].join('|');
|
|
380
|
+
return createHash('md5').update(text).digest('hex');
|
|
381
|
+
}
|
|
382
|
+
function docToText(d) {
|
|
383
|
+
const parts = [d.title];
|
|
384
|
+
if (d.summary)
|
|
385
|
+
parts.push(d.summary);
|
|
386
|
+
if (d.tags.length > 0)
|
|
387
|
+
parts.push(d.tags.join(' '));
|
|
388
|
+
if (d.body)
|
|
389
|
+
parts.push(d.body.slice(0, 500));
|
|
390
|
+
// E5 models require "passage: " prefix for documents
|
|
391
|
+
return 'passage: ' + parts.join('. ');
|
|
392
|
+
}
|
|
393
|
+
export async function buildEmbeddingIndex(docs, existingIndex) {
|
|
394
|
+
const config = await detectDevice();
|
|
395
|
+
const t0 = Date.now();
|
|
396
|
+
const currentHashes = docs.map(hashDocContent);
|
|
397
|
+
let vectors;
|
|
398
|
+
// Model changed → discard all cached vectors, force full rebuild
|
|
399
|
+
const modelMatch = existingIndex && existingIndex.modelId === DEFAULT_MODEL;
|
|
400
|
+
if (modelMatch && existingIndex.docIds.length > 0) {
|
|
401
|
+
// Incremental: reuse vectors only for docs with matching content hash
|
|
402
|
+
const existingMap = new Map();
|
|
403
|
+
for (let i = 0; i < existingIndex.docIds.length; i++) {
|
|
404
|
+
existingMap.set(existingIndex.docIds[i], {
|
|
405
|
+
vector: existingIndex.vectors[i],
|
|
406
|
+
hash: existingIndex.contentHashes?.[i] ?? '',
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
const changedDocs = [];
|
|
410
|
+
vectors = new Array(docs.length);
|
|
411
|
+
for (let i = 0; i < docs.length; i++) {
|
|
412
|
+
const cached = existingMap.get(docs[i].id);
|
|
413
|
+
if (cached && cached.hash && cached.hash === currentHashes[i]) {
|
|
414
|
+
vectors[i] = cached.vector;
|
|
415
|
+
}
|
|
416
|
+
else {
|
|
417
|
+
changedDocs.push({ index: i, doc: docs[i] });
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
if (changedDocs.length > 0) {
|
|
421
|
+
const texts = changedDocs.map(nd => docToText(nd.doc));
|
|
422
|
+
const newVectors = await embedTexts(texts);
|
|
423
|
+
for (let j = 0; j < changedDocs.length; j++) {
|
|
424
|
+
vectors[changedDocs[j].index] = newVectors[j];
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
// Full rebuild
|
|
430
|
+
const texts = docs.map(docToText);
|
|
431
|
+
vectors = await embedTexts(texts);
|
|
432
|
+
}
|
|
433
|
+
return {
|
|
434
|
+
modelId: DEFAULT_MODEL,
|
|
435
|
+
dimension: vectors[0]?.length ?? 384,
|
|
436
|
+
docIds: docs.map(d => d.id),
|
|
437
|
+
vectors,
|
|
438
|
+
contentHashes: currentHashes,
|
|
439
|
+
builtAt: Date.now(),
|
|
440
|
+
deviceUsed: `${config.device}/${config.dtype}`,
|
|
441
|
+
buildTimeMs: Date.now() - t0,
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
//# sourceMappingURL=embedding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedding.js","sourceRoot":"","sources":["../../../../../src/server/wiki/embedding.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,37 @@
|
|
|
1
1
|
import type { WikiEntry } from './wiki-types.js';
|
|
2
|
+
interface WeightedTerm {
|
|
3
|
+
term: string;
|
|
4
|
+
weight: number;
|
|
5
|
+
coverageKey?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface CoverageTerm {
|
|
8
|
+
key: string;
|
|
9
|
+
terms: string[];
|
|
10
|
+
weight: number;
|
|
11
|
+
}
|
|
12
|
+
export interface CoveragePenaltyOptions {
|
|
13
|
+
coreTerms: readonly CoverageTerm[];
|
|
14
|
+
baseFactor?: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function applyCoveragePenalty(score: number, matchedCoreWeight: number, totalCoreWeight: number, baseFactor?: number): number;
|
|
17
|
+
export type QueryTermRole = 'anchor' | 'core' | 'context';
|
|
18
|
+
export interface QueryTokenClassification {
|
|
19
|
+
raw: string;
|
|
20
|
+
normalized: string;
|
|
21
|
+
role: QueryTermRole;
|
|
22
|
+
weight: number;
|
|
23
|
+
}
|
|
24
|
+
export interface QueryPlanGroup {
|
|
25
|
+
role: QueryTermRole;
|
|
26
|
+
weightedTerms: WeightedTerm[];
|
|
27
|
+
rrfWeight: number;
|
|
28
|
+
}
|
|
29
|
+
export interface QueryPlan {
|
|
30
|
+
rawQuery: string;
|
|
31
|
+
tokens: QueryTokenClassification[];
|
|
32
|
+
groups: QueryPlanGroup[];
|
|
33
|
+
coreCoverageTerms: CoverageTerm[];
|
|
34
|
+
}
|
|
2
35
|
type FieldName = 'title' | 'summary' | 'tags' | 'body';
|
|
3
36
|
/** @deprecated Legacy flat posting — kept for test backward compat only. */
|
|
4
37
|
export interface Posting {
|
|
@@ -31,4 +64,17 @@ interface FieldPosting {
|
|
|
31
64
|
export declare function tokenize(text: string): string[];
|
|
32
65
|
export declare function buildInvertedIndex(entries: WikiEntry[]): InvertedIndex;
|
|
33
66
|
export declare function searchBM25(index: InvertedIndex, query: string, limit?: number, credibilityFactors?: Map<string, number>): SearchResult[];
|
|
67
|
+
export declare function buildQueryPlan(query: string, index?: InvertedIndex): QueryPlan;
|
|
68
|
+
export declare function searchBM25Planned(index: InvertedIndex, query: string, limit?: number, credibilityFactors?: Map<string, number>): SearchResult[];
|
|
69
|
+
export interface ProximityRerankOptions {
|
|
70
|
+
windowSize?: number;
|
|
71
|
+
maxBoost?: number;
|
|
72
|
+
}
|
|
73
|
+
export declare function rerankByPhraseProximity(results: Array<{
|
|
74
|
+
entry: WikiEntry;
|
|
75
|
+
score: number;
|
|
76
|
+
}>, query: string, options?: ProximityRerankOptions): Array<{
|
|
77
|
+
entry: WikiEntry;
|
|
78
|
+
score: number;
|
|
79
|
+
}>;
|
|
34
80
|
export {};
|