@vibgrate/cli 2026.803.3 → 2026.803.5
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/agent-PQEODATY.js +26 -0
- package/dist/{agent-JTA4YWMQ.js.map → agent-PQEODATY.js.map} +1 -1
- package/dist/baseline-SU2PCQV2.js +9 -0
- package/dist/{baseline-2V7PKA7Q.js.map → baseline-SU2PCQV2.js.map} +1 -1
- package/dist/chunk-2A7XCANX.js +375 -0
- package/dist/chunk-2A7XCANX.js.map +1 -0
- package/dist/{chunk-SJFBXCII.js → chunk-2U4SXS5U.js} +77 -9
- package/dist/chunk-2U4SXS5U.js.map +1 -0
- package/dist/{chunk-QMME6TB4.js → chunk-4LGDQBYK.js} +3 -102
- package/dist/chunk-4LGDQBYK.js.map +1 -0
- package/dist/{chunk-XK5LKOBF.js → chunk-5WMFX7TY.js} +4 -4
- package/dist/{chunk-XK5LKOBF.js.map → chunk-5WMFX7TY.js.map} +1 -1
- package/dist/{chunk-KYX2YCXT.js → chunk-72XI4MTL.js} +9 -9
- package/dist/{chunk-KYX2YCXT.js.map → chunk-72XI4MTL.js.map} +1 -1
- package/dist/{chunk-WGPS3NZQ.js → chunk-COZEHQTK.js} +33 -11
- package/dist/chunk-COZEHQTK.js.map +1 -0
- package/dist/{chunk-6DFV4WCQ.js → chunk-CPGTEDFD.js} +3 -3
- package/dist/{chunk-6DFV4WCQ.js.map → chunk-CPGTEDFD.js.map} +1 -1
- package/dist/{chunk-M452MRWI.js → chunk-H4XQQ4N2.js} +9 -8
- package/dist/chunk-H4XQQ4N2.js.map +1 -0
- package/dist/{chunk-PXM3VZYR.js → chunk-HE2TEFWY.js} +4 -4
- package/dist/{chunk-PXM3VZYR.js.map → chunk-HE2TEFWY.js.map} +1 -1
- package/dist/{chunk-NJFQCDGA.js → chunk-INIULQEP.js} +3 -3
- package/dist/{chunk-NJFQCDGA.js.map → chunk-INIULQEP.js.map} +1 -1
- package/dist/{chunk-K6Q6HTFD.js → chunk-JZGVUH57.js} +4 -4
- package/dist/{chunk-K6Q6HTFD.js.map → chunk-JZGVUH57.js.map} +1 -1
- package/dist/{chunk-TM5XQY3L.js → chunk-KFK7KCAH.js} +3 -3
- package/dist/{chunk-TM5XQY3L.js.map → chunk-KFK7KCAH.js.map} +1 -1
- package/dist/{chunk-L5PUNO3T.js → chunk-LOV44ROX.js} +451 -22
- package/dist/chunk-LOV44ROX.js.map +1 -0
- package/dist/{chunk-NSWEJPLV.js → chunk-MKDM2KLO.js} +9 -9
- package/dist/{chunk-NSWEJPLV.js.map → chunk-MKDM2KLO.js.map} +1 -1
- package/dist/{chunk-3Q3ZXJZP.js → chunk-OCINHIPN.js} +5 -4
- package/dist/chunk-OCINHIPN.js.map +1 -0
- package/dist/chunk-RBMKBYGV.js +102 -0
- package/dist/chunk-RBMKBYGV.js.map +1 -0
- package/dist/{chunk-NUZM7UOR.js → chunk-SJC3VKQ2.js} +59 -9
- package/dist/chunk-SJC3VKQ2.js.map +1 -0
- package/dist/{chunk-M7773OUN.js → chunk-TKV3GAKX.js} +5 -5
- package/dist/{chunk-M7773OUN.js.map → chunk-TKV3GAKX.js.map} +1 -1
- package/dist/{chunk-HC44772H.js → chunk-TVRM57CE.js} +5 -373
- package/dist/chunk-TVRM57CE.js.map +1 -0
- package/dist/{chunk-TNADGCOX.js → chunk-UH2WHRKJ.js} +8 -8
- package/dist/{chunk-TNADGCOX.js.map → chunk-UH2WHRKJ.js.map} +1 -1
- package/dist/{chunk-CPLG4GFB.js → chunk-UJGWQ6YA.js} +4 -4
- package/dist/{chunk-CPLG4GFB.js.map → chunk-UJGWQ6YA.js.map} +1 -1
- package/dist/chunk-USO67ZEE.js +6 -0
- package/dist/{chunk-7KNFG44U.js.map → chunk-USO67ZEE.js.map} +1 -1
- package/dist/{chunk-4ACXDVON.js → chunk-UXWN5YQW.js} +4 -4
- package/dist/{chunk-4ACXDVON.js.map → chunk-UXWN5YQW.js.map} +1 -1
- package/dist/{chunk-UXR7FBE3.js → chunk-VJHNGNCT.js} +6 -6
- package/dist/{chunk-UXR7FBE3.js.map → chunk-VJHNGNCT.js.map} +1 -1
- package/dist/{chunk-6JP7HGIF.js → chunk-Y4JO6LYP.js} +3 -3
- package/dist/{chunk-6JP7HGIF.js.map → chunk-Y4JO6LYP.js.map} +1 -1
- package/dist/cli.js +498 -340
- package/dist/cli.js.map +1 -1
- package/dist/embed-worker-main.d.ts +2 -0
- package/dist/embed-worker-main.js +64 -0
- package/dist/embed-worker-main.js.map +1 -0
- package/dist/ensure-map-Z6UXBPI7.js +31 -0
- package/dist/{ensure-map-TAVYMPEG.js.map → ensure-map-Z6UXBPI7.js.map} +1 -1
- package/dist/graph-backend-3A2M22QN.js +13 -0
- package/dist/{graph-backend-WF4LGBGD.js.map → graph-backend-3A2M22QN.js.map} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +16 -14
- package/dist/index.js.map +1 -1
- package/dist/{interactive-6PN237LX.js → interactive-6TCXGIMA.js} +31 -29
- package/dist/interactive-6TCXGIMA.js.map +1 -0
- package/dist/load-QHU4WMUN.js +11 -0
- package/dist/{load-T2FOJUPI.js.map → load-QHU4WMUN.js.map} +1 -1
- package/dist/{run-outcome-AMIKAASL.js → run-outcome-NHD3NXTL.js} +7 -6
- package/dist/run-outcome-NHD3NXTL.js.map +1 -0
- package/dist/runtime-session-W65P4OXR.js +22 -0
- package/dist/{runtime-session-QAVOPSSH.js.map → runtime-session-W65P4OXR.js.map} +1 -1
- package/dist/session-NZKZXBX4.js +17 -0
- package/dist/{session-SCHQQTHN.js.map → session-NZKZXBX4.js.map} +1 -1
- package/dist/{stream-json-A6K2MONY.js → stream-json-MLWEIQNK.js} +13 -11
- package/dist/stream-json-MLWEIQNK.js.map +1 -0
- package/dist/{vg-mcp-bridge-3TSFOL4V.js → vg-mcp-bridge-2DEZF3JM.js} +12 -10
- package/dist/vg-mcp-bridge-2DEZF3JM.js.map +1 -0
- package/dist/{vgd-B67JCNJP.js → vgd-W7IHKGNU.js} +12 -10
- package/dist/vgd-W7IHKGNU.js.map +1 -0
- package/package.json +1 -1
- package/scripts/postinstall.mjs +22 -1
- package/dist/agent-JTA4YWMQ.js +0 -24
- package/dist/baseline-2V7PKA7Q.js +0 -9
- package/dist/chunk-3Q3ZXJZP.js.map +0 -1
- package/dist/chunk-7KNFG44U.js +0 -6
- package/dist/chunk-HC44772H.js.map +0 -1
- package/dist/chunk-L5PUNO3T.js.map +0 -1
- package/dist/chunk-M452MRWI.js.map +0 -1
- package/dist/chunk-NUZM7UOR.js.map +0 -1
- package/dist/chunk-QMME6TB4.js.map +0 -1
- package/dist/chunk-SJFBXCII.js.map +0 -1
- package/dist/chunk-WGPS3NZQ.js.map +0 -1
- package/dist/ensure-map-TAVYMPEG.js +0 -29
- package/dist/graph-backend-WF4LGBGD.js +0 -11
- package/dist/interactive-6PN237LX.js.map +0 -1
- package/dist/load-T2FOJUPI.js +0 -10
- package/dist/run-outcome-AMIKAASL.js.map +0 -1
- package/dist/runtime-session-QAVOPSSH.js +0 -20
- package/dist/session-SCHQQTHN.js +0 -15
- package/dist/stream-json-A6K2MONY.js.map +0 -1
- package/dist/vg-mcp-bridge-3TSFOL4V.js.map +0 -1
- package/dist/vgd-B67JCNJP.js.map +0 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export { CONTEXT_POLICY_VERSION, DISCOVERY_TOOLS, MUTATION_TOOLS, compact, compactWithModel, runAgent } from './chunk-COZEHQTK.js';
|
|
2
|
+
import './chunk-543E6WDJ.js';
|
|
3
|
+
import './chunk-2U4SXS5U.js';
|
|
4
|
+
import './chunk-REIGWTTH.js';
|
|
5
|
+
import './chunk-KFK7KCAH.js';
|
|
6
|
+
import './chunk-RBIRXQR6.js';
|
|
7
|
+
import './chunk-5HYCB55P.js';
|
|
8
|
+
export { summarizeCapsule } from './chunk-JZGVUH57.js';
|
|
9
|
+
import './chunk-VIWZ4QT7.js';
|
|
10
|
+
import './chunk-5WMFX7TY.js';
|
|
11
|
+
import './chunk-3LSG7Z4I.js';
|
|
12
|
+
import './chunk-J7LKEB2R.js';
|
|
13
|
+
import './chunk-TVRM57CE.js';
|
|
14
|
+
import './chunk-UTNNGKKX.js';
|
|
15
|
+
import './chunk-RXP66R2E.js';
|
|
16
|
+
import './chunk-2A7XCANX.js';
|
|
17
|
+
import './chunk-OCINHIPN.js';
|
|
18
|
+
import './chunk-USO67ZEE.js';
|
|
19
|
+
import './chunk-4LGDQBYK.js';
|
|
20
|
+
import './chunk-RBMKBYGV.js';
|
|
21
|
+
import './chunk-BWPBB45M.js';
|
|
22
|
+
import './chunk-JFGYT6BI.js';
|
|
23
|
+
import './chunk-BPF3YX2U.js';
|
|
24
|
+
import './chunk-Z6ZWNWWR.js';
|
|
25
|
+
//# sourceMappingURL=agent-PQEODATY.js.map
|
|
26
|
+
//# sourceMappingURL=agent-PQEODATY.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"agent-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"agent-PQEODATY.js"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { baselineCommand, runBaseline } from './chunk-Y4JO6LYP.js';
|
|
2
|
+
import './chunk-INIULQEP.js';
|
|
3
|
+
import './chunk-DT4KIVRI.js';
|
|
4
|
+
import './chunk-CRAMOEBE.js';
|
|
5
|
+
import './chunk-RXP66R2E.js';
|
|
6
|
+
import './chunk-USO67ZEE.js';
|
|
7
|
+
import './chunk-Z6ZWNWWR.js';
|
|
8
|
+
//# sourceMappingURL=baseline-SU2PCQV2.js.map
|
|
9
|
+
//# sourceMappingURL=baseline-SU2PCQV2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"baseline-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"baseline-SU2PCQV2.js"}
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import { cacheDir } from './chunk-RBMKBYGV.js';
|
|
2
|
+
import { hashString } from './chunk-JFGYT6BI.js';
|
|
3
|
+
import * as fs2 from 'fs';
|
|
4
|
+
import { createRequire } from 'module';
|
|
5
|
+
import * as os from 'os';
|
|
6
|
+
import * as path2 from 'path';
|
|
7
|
+
import { pathToFileURL } from 'url';
|
|
8
|
+
|
|
9
|
+
var DEFAULT_LOCK_STALE_MS = 15 * 60 * 1e3;
|
|
10
|
+
function isProcessAlive(pid) {
|
|
11
|
+
try {
|
|
12
|
+
process.kill(pid, 0);
|
|
13
|
+
return true;
|
|
14
|
+
} catch (e) {
|
|
15
|
+
return e.code === "EPERM";
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function lockIsStale(file, staleMs) {
|
|
19
|
+
try {
|
|
20
|
+
const { pid, at } = JSON.parse(fs2.readFileSync(file, "utf8"));
|
|
21
|
+
if (typeof at === "number" && Date.now() - at > staleMs) return true;
|
|
22
|
+
if (typeof pid === "number" && !isProcessAlive(pid)) return true;
|
|
23
|
+
return false;
|
|
24
|
+
} catch {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function acquireLock(file, staleMs = DEFAULT_LOCK_STALE_MS) {
|
|
29
|
+
const write = () => {
|
|
30
|
+
try {
|
|
31
|
+
fs2.mkdirSync(path2.dirname(file), { recursive: true });
|
|
32
|
+
const fd = fs2.openSync(file, "wx");
|
|
33
|
+
fs2.writeFileSync(fd, JSON.stringify({ pid: process.pid, at: Date.now() }));
|
|
34
|
+
fs2.closeSync(fd);
|
|
35
|
+
return true;
|
|
36
|
+
} catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
if (write()) return true;
|
|
41
|
+
if (lockIsStale(file, staleMs)) {
|
|
42
|
+
try {
|
|
43
|
+
fs2.rmSync(file, { force: true });
|
|
44
|
+
} catch {
|
|
45
|
+
}
|
|
46
|
+
return write();
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
function releaseLock(file) {
|
|
51
|
+
try {
|
|
52
|
+
fs2.rmSync(file, { force: true });
|
|
53
|
+
} catch {
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// src/engine/embeddings.ts
|
|
58
|
+
function resolveEmbedModel(model) {
|
|
59
|
+
return model ?? "bge-small-en-v1.5";
|
|
60
|
+
}
|
|
61
|
+
function modelCacheDir() {
|
|
62
|
+
const base = process.env.XDG_CACHE_HOME || path2.join(os.homedir(), ".cache");
|
|
63
|
+
return path2.join(base, "vibgrate", "models");
|
|
64
|
+
}
|
|
65
|
+
function modelReadyMarker(modelId) {
|
|
66
|
+
return path2.join(modelCacheDir(), `.ready-${safe(modelId)}`);
|
|
67
|
+
}
|
|
68
|
+
function isModelReady(modelId = resolveEmbedModel()) {
|
|
69
|
+
return fs2.existsSync(modelReadyMarker(modelId));
|
|
70
|
+
}
|
|
71
|
+
function unavailableMessage(reason) {
|
|
72
|
+
switch (reason) {
|
|
73
|
+
case "no-permission":
|
|
74
|
+
return `semantic search couldn't write its model cache at ${modelCacheDir()} \u2014 using fast lexical search instead. Relocate it with the standard XDG_CACHE_HOME, or run with --local to stay lexical quietly. (No admin/sudo is ever needed \u2014 the cache lives in your home folder.)`;
|
|
75
|
+
case "download-failed":
|
|
76
|
+
return `the semantic model isn't downloaded yet and couldn't be fetched (offline?) \u2014 using fast lexical search. It'll try again next time; run with --local to keep lexical without retrying.`;
|
|
77
|
+
case "not-installed":
|
|
78
|
+
return `the optional semantic backend isn't available here \u2014 using fast lexical search.`;
|
|
79
|
+
case "init-failed":
|
|
80
|
+
default:
|
|
81
|
+
return `the semantic model couldn't load \u2014 using fast lexical search.`;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function modelCacheInfo(modelId = resolveEmbedModel()) {
|
|
85
|
+
const dir = modelCacheDir();
|
|
86
|
+
return { dir, present: isModelReady(modelId) || fs2.existsSync(dir), bytes: dirSize(dir) };
|
|
87
|
+
}
|
|
88
|
+
function clearModelCache() {
|
|
89
|
+
const dir = modelCacheDir();
|
|
90
|
+
const bytes = dirSize(dir);
|
|
91
|
+
try {
|
|
92
|
+
fs2.rmSync(dir, { recursive: true, force: true });
|
|
93
|
+
} catch {
|
|
94
|
+
}
|
|
95
|
+
return bytes;
|
|
96
|
+
}
|
|
97
|
+
function dirSize(dir) {
|
|
98
|
+
let total = 0;
|
|
99
|
+
let entries;
|
|
100
|
+
try {
|
|
101
|
+
entries = fs2.readdirSync(dir, { withFileTypes: true });
|
|
102
|
+
} catch {
|
|
103
|
+
return 0;
|
|
104
|
+
}
|
|
105
|
+
for (const e of entries) {
|
|
106
|
+
const p = path2.join(dir, e.name);
|
|
107
|
+
if (e.isDirectory()) total += dirSize(p);
|
|
108
|
+
else {
|
|
109
|
+
try {
|
|
110
|
+
total += fs2.statSync(p).size;
|
|
111
|
+
} catch {
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return total;
|
|
116
|
+
}
|
|
117
|
+
function isPermissionError(e) {
|
|
118
|
+
const code = e?.code;
|
|
119
|
+
return code === "EACCES" || code === "EPERM" || code === "EROFS";
|
|
120
|
+
}
|
|
121
|
+
function embeddingsCached(root, modelId) {
|
|
122
|
+
return fs2.existsSync(path2.join(cacheDir(root), `embeddings-${safe(modelId)}.json`));
|
|
123
|
+
}
|
|
124
|
+
async function loadEmbedder(options = {}) {
|
|
125
|
+
if (options.local) return null;
|
|
126
|
+
const modelId = resolveEmbedModel(options.model);
|
|
127
|
+
if (options.noDownload && !isModelReady(modelId)) return null;
|
|
128
|
+
const fail = (reason) => {
|
|
129
|
+
options.onUnavailable?.(reason);
|
|
130
|
+
return null;
|
|
131
|
+
};
|
|
132
|
+
const mod = await importEmbedBackend();
|
|
133
|
+
if (!mod?.FlagEmbedding) return fail("not-installed");
|
|
134
|
+
const cache = modelCacheDir();
|
|
135
|
+
try {
|
|
136
|
+
fs2.mkdirSync(cache, { recursive: true });
|
|
137
|
+
} catch (e) {
|
|
138
|
+
return fail(isPermissionError(e) ? "no-permission" : "init-failed");
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
const model = await withTimeout(
|
|
142
|
+
mod.FlagEmbedding.init({
|
|
143
|
+
model: mapModel(mod, modelId),
|
|
144
|
+
cacheDir: cache,
|
|
145
|
+
showDownloadProgress: options.showDownloadProgress ?? false
|
|
146
|
+
}),
|
|
147
|
+
embedInitTimeoutMs(),
|
|
148
|
+
"embedding model init timed out"
|
|
149
|
+
);
|
|
150
|
+
try {
|
|
151
|
+
fs2.writeFileSync(modelReadyMarker(modelId), (/* @__PURE__ */ new Date(0)).toISOString());
|
|
152
|
+
} catch {
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
id: modelId,
|
|
156
|
+
async embed(texts) {
|
|
157
|
+
const out = [];
|
|
158
|
+
for await (const batch of model.embed(texts, 64)) {
|
|
159
|
+
for (const v of batch) out.push(Array.from(v));
|
|
160
|
+
}
|
|
161
|
+
return out;
|
|
162
|
+
},
|
|
163
|
+
async embedQuery(text) {
|
|
164
|
+
const v = await model.queryEmbed(text);
|
|
165
|
+
return Array.from(v);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
} catch (e) {
|
|
169
|
+
return fail(isPermissionError(e) ? "no-permission" : "download-failed");
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async function importEmbedBackend() {
|
|
173
|
+
const hostDir = process.env.VIBGRATE_EMBEDDER_PATH;
|
|
174
|
+
if (hostDir) {
|
|
175
|
+
try {
|
|
176
|
+
const req = createRequire(path2.join(hostDir, "package.json"));
|
|
177
|
+
const mod = await import(pathToFileURL(req.resolve("fastembed")).href);
|
|
178
|
+
const resolved = mod?.FlagEmbedding ? mod : mod?.default;
|
|
179
|
+
if (resolved?.FlagEmbedding) return resolved;
|
|
180
|
+
} catch {
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return await import('fastembed').catch(() => null);
|
|
184
|
+
}
|
|
185
|
+
function embedInitTimeoutMs() {
|
|
186
|
+
const n = Number(process.env.VG_EMBED_TIMEOUT_MS);
|
|
187
|
+
return Number.isFinite(n) && n > 0 ? n : 6e4;
|
|
188
|
+
}
|
|
189
|
+
async function withTimeout(promise, ms, message) {
|
|
190
|
+
let timer;
|
|
191
|
+
try {
|
|
192
|
+
return await Promise.race([
|
|
193
|
+
promise,
|
|
194
|
+
new Promise((_, reject) => {
|
|
195
|
+
timer = setTimeout(() => reject(new Error(message)), ms);
|
|
196
|
+
timer.unref?.();
|
|
197
|
+
})
|
|
198
|
+
]);
|
|
199
|
+
} finally {
|
|
200
|
+
clearTimeout(timer);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
function mapModel(mod, id) {
|
|
204
|
+
const m = mod.EmbeddingModel ?? {};
|
|
205
|
+
if (/bge-small/i.test(id)) return m.BGESmallENV15 ?? m.BGESmallEN ?? id;
|
|
206
|
+
if (/bge-base/i.test(id)) return m.BGEBaseENV15 ?? id;
|
|
207
|
+
if (/all-minilm/i.test(id)) return m.AllMiniLML6V2 ?? id;
|
|
208
|
+
return id;
|
|
209
|
+
}
|
|
210
|
+
var PATH_NOISE = /* @__PURE__ */ new Set([
|
|
211
|
+
"src",
|
|
212
|
+
"app",
|
|
213
|
+
"apps",
|
|
214
|
+
"lib",
|
|
215
|
+
"libs",
|
|
216
|
+
"dist",
|
|
217
|
+
"build",
|
|
218
|
+
"out",
|
|
219
|
+
"index",
|
|
220
|
+
"main",
|
|
221
|
+
"packages",
|
|
222
|
+
"pkg",
|
|
223
|
+
"test",
|
|
224
|
+
"tests",
|
|
225
|
+
"__tests__",
|
|
226
|
+
"spec",
|
|
227
|
+
"node_modules",
|
|
228
|
+
"internal",
|
|
229
|
+
"com",
|
|
230
|
+
"example",
|
|
231
|
+
"demo",
|
|
232
|
+
"java",
|
|
233
|
+
"net",
|
|
234
|
+
"org",
|
|
235
|
+
"www"
|
|
236
|
+
]);
|
|
237
|
+
function pathContext(file) {
|
|
238
|
+
const parts = file.split("/");
|
|
239
|
+
const stem = (parts.pop() ?? "").replace(/\.[^.]+$/, "");
|
|
240
|
+
const dirs = parts.filter((p) => p && !PATH_NOISE.has(p.toLowerCase()));
|
|
241
|
+
return [...dirs.slice(-2), stem].filter(Boolean).join(" ");
|
|
242
|
+
}
|
|
243
|
+
function nodeEmbedText(node, areaLabel) {
|
|
244
|
+
if (node.kind === "document") {
|
|
245
|
+
const category = (node.signature ?? "document").replace(/^document:/, "");
|
|
246
|
+
const categoryHints = {
|
|
247
|
+
manifest: "package dependencies scripts install dependencies versions",
|
|
248
|
+
docker: "dockerfile container image build runtime",
|
|
249
|
+
compose: "docker-compose services containers networking volumes",
|
|
250
|
+
ci: "continuous integration github actions workflow pipeline test build deploy",
|
|
251
|
+
"build-config": "typescript tsconfig bundler vite webpack eslint prettier test",
|
|
252
|
+
"api-contract": "openapi swagger graphql protobuf api schema endpoints",
|
|
253
|
+
"task-runner": "makefile justfile tasks build test run commands",
|
|
254
|
+
workspace: "monorepo workspace packages pnpm turbo nx",
|
|
255
|
+
infra: "deploy infrastructure kubernetes kubernetes terraform helm kubernetes",
|
|
256
|
+
"env-example": "environment variables configuration secrets template",
|
|
257
|
+
markdown: "documentation readme guide"
|
|
258
|
+
};
|
|
259
|
+
const hint = categoryHints[category] ?? category;
|
|
260
|
+
return [
|
|
261
|
+
node.qualifiedName,
|
|
262
|
+
"document",
|
|
263
|
+
category,
|
|
264
|
+
hint,
|
|
265
|
+
pathContext(node.file),
|
|
266
|
+
(node.doc ?? "").slice(0, 5e3)
|
|
267
|
+
].filter(Boolean).join("\n");
|
|
268
|
+
}
|
|
269
|
+
return [node.qualifiedName, node.kind, node.signature ?? "", node.doc ?? "", pathContext(node.file), areaLabel ?? ""].filter(Boolean).join(" ");
|
|
270
|
+
}
|
|
271
|
+
function cosine(a, b) {
|
|
272
|
+
let dot = 0;
|
|
273
|
+
let na = 0;
|
|
274
|
+
let nb = 0;
|
|
275
|
+
const n = Math.min(a.length, b.length);
|
|
276
|
+
for (let i = 0; i < n; i++) {
|
|
277
|
+
dot += a[i] * b[i];
|
|
278
|
+
na += a[i] * a[i];
|
|
279
|
+
nb += b[i] * b[i];
|
|
280
|
+
}
|
|
281
|
+
if (na === 0 || nb === 0) return 0;
|
|
282
|
+
return dot / (Math.sqrt(na) * Math.sqrt(nb));
|
|
283
|
+
}
|
|
284
|
+
var EMBED_CHUNK = 256;
|
|
285
|
+
var CACHE_WRITE_INTERVAL_MS = 1500;
|
|
286
|
+
function vectorCachePath(root, modelId) {
|
|
287
|
+
return path2.join(cacheDir(root), `embeddings-${safe(modelId)}.json`);
|
|
288
|
+
}
|
|
289
|
+
function countPending(graph, root, modelId) {
|
|
290
|
+
const entries = readCacheEntries(vectorCachePath(root, modelId), modelId);
|
|
291
|
+
const areaLabel = new Map(graph.areas.map((a) => [a.id, a.label]));
|
|
292
|
+
let pending = 0;
|
|
293
|
+
for (const n of graph.nodes) {
|
|
294
|
+
if (n.kind === "file" || n.kind === "external") continue;
|
|
295
|
+
const h = hashString(nodeEmbedText(n, areaLabel.get(n.area)));
|
|
296
|
+
const cached = entries[n.id];
|
|
297
|
+
if (!cached || cached.hash !== h) pending++;
|
|
298
|
+
}
|
|
299
|
+
return pending;
|
|
300
|
+
}
|
|
301
|
+
function readCacheEntries(file, modelId) {
|
|
302
|
+
if (!fs2.existsSync(file)) return {};
|
|
303
|
+
try {
|
|
304
|
+
const loaded = JSON.parse(fs2.readFileSync(file, "utf8"));
|
|
305
|
+
if (loaded.model === modelId && loaded.entries) return loaded.entries;
|
|
306
|
+
} catch {
|
|
307
|
+
}
|
|
308
|
+
return {};
|
|
309
|
+
}
|
|
310
|
+
async function getNodeEmbeddings(graph, embedder, root, onProgress) {
|
|
311
|
+
const file = vectorCachePath(root, embedder.id);
|
|
312
|
+
let cache = { model: embedder.id, entries: {} };
|
|
313
|
+
if (fs2.existsSync(file)) {
|
|
314
|
+
try {
|
|
315
|
+
const loaded = JSON.parse(fs2.readFileSync(file, "utf8"));
|
|
316
|
+
if (loaded.model === embedder.id && loaded.entries) cache = loaded;
|
|
317
|
+
} catch {
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
const areaLabel = new Map(graph.areas.map((a) => [a.id, a.label]));
|
|
321
|
+
const targets = graph.nodes.filter((n) => n.kind !== "file" && n.kind !== "external");
|
|
322
|
+
const toEmbed = [];
|
|
323
|
+
const vectors = /* @__PURE__ */ new Map();
|
|
324
|
+
for (const n of targets) {
|
|
325
|
+
const text = nodeEmbedText(n, areaLabel.get(n.area));
|
|
326
|
+
const h = hashString(text);
|
|
327
|
+
const cached = cache.entries[n.id];
|
|
328
|
+
if (cached && cached.hash === h) vectors.set(n.id, cached.vec);
|
|
329
|
+
else toEmbed.push({ id: n.id, text, hash: h });
|
|
330
|
+
}
|
|
331
|
+
const persist = () => {
|
|
332
|
+
try {
|
|
333
|
+
fs2.mkdirSync(cacheDir(root), { recursive: true });
|
|
334
|
+
const tmp = `${file}.tmp.${process.pid}`;
|
|
335
|
+
fs2.writeFileSync(tmp, JSON.stringify(cache));
|
|
336
|
+
fs2.renameSync(tmp, file);
|
|
337
|
+
} catch {
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
if (toEmbed.length) {
|
|
341
|
+
const lock = `${file}.lock`;
|
|
342
|
+
if (!acquireLock(lock)) return vectors;
|
|
343
|
+
try {
|
|
344
|
+
onProgress?.(0, toEmbed.length);
|
|
345
|
+
let lastWrite = Date.now();
|
|
346
|
+
for (let i = 0; i < toEmbed.length; i += EMBED_CHUNK) {
|
|
347
|
+
const slice = toEmbed.slice(i, i + EMBED_CHUNK);
|
|
348
|
+
const vecs = await embedder.embed(slice.map((t) => t.text));
|
|
349
|
+
slice.forEach((t, j) => {
|
|
350
|
+
const vec = vecs[j] ?? [];
|
|
351
|
+
vectors.set(t.id, vec);
|
|
352
|
+
cache.entries[t.id] = { hash: t.hash, vec };
|
|
353
|
+
});
|
|
354
|
+
onProgress?.(Math.min(i + EMBED_CHUNK, toEmbed.length), toEmbed.length);
|
|
355
|
+
if (Date.now() - lastWrite >= CACHE_WRITE_INTERVAL_MS) {
|
|
356
|
+
persist();
|
|
357
|
+
lastWrite = Date.now();
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
const live = new Set(targets.map((n) => n.id));
|
|
361
|
+
for (const id of Object.keys(cache.entries)) if (!live.has(id)) delete cache.entries[id];
|
|
362
|
+
persist();
|
|
363
|
+
} finally {
|
|
364
|
+
releaseLock(lock);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return vectors;
|
|
368
|
+
}
|
|
369
|
+
function safe(id) {
|
|
370
|
+
return id.replace(/[^a-z0-9.-]+/gi, "_");
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
export { acquireLock, clearModelCache, cosine, countPending, embeddingsCached, getNodeEmbeddings, isModelReady, loadEmbedder, modelCacheInfo, nodeEmbedText, releaseLock, resolveEmbedModel, unavailableMessage, withTimeout };
|
|
374
|
+
//# sourceMappingURL=chunk-2A7XCANX.js.map
|
|
375
|
+
//# sourceMappingURL=chunk-2A7XCANX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/engine/lock.ts","../src/engine/embeddings.ts"],"names":["fs","path"],"mappings":"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","file":"chunk-2A7XCANX.js","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\n/**\n * Cross-process single-writer lock (O_EXCL create), shared by the embedding\n * cache writer and the auto-refresh rebuild so two vg processes never write\n * the same repo-local artifact at once. A lock whose owning process is dead,\n * or that is older than `staleMs`, is presumed abandoned and reclaimed.\n */\n\n/** A lock older than this is presumed dead (crashed process). */\nexport const DEFAULT_LOCK_STALE_MS = 15 * 60 * 1000;\n\nfunction isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (e) {\n return (e as NodeJS.ErrnoException).code === 'EPERM'; // exists, just not ours to signal\n }\n}\n\nfunction lockIsStale(file: string, staleMs: number): boolean {\n try {\n const { pid, at } = JSON.parse(fs.readFileSync(file, 'utf8')) as { pid?: number; at?: number };\n if (typeof at === 'number' && Date.now() - at > staleMs) return true;\n if (typeof pid === 'number' && !isProcessAlive(pid)) return true;\n return false;\n } catch {\n return true; // unreadable/corrupt → reclaim it\n }\n}\n\n/** Take the lock (O_EXCL), reclaiming a stale/dead one. Returns success. */\nexport function acquireLock(file: string, staleMs = DEFAULT_LOCK_STALE_MS): boolean {\n const write = (): boolean => {\n try {\n fs.mkdirSync(path.dirname(file), { recursive: true });\n const fd = fs.openSync(file, 'wx');\n fs.writeFileSync(fd, JSON.stringify({ pid: process.pid, at: Date.now() }));\n fs.closeSync(fd);\n return true;\n } catch {\n return false;\n }\n };\n if (write()) return true;\n if (lockIsStale(file, staleMs)) {\n try {\n fs.rmSync(file, { force: true });\n } catch {\n /* another process may have reclaimed it */\n }\n return write();\n }\n return false;\n}\n\nexport function releaseLock(file: string): void {\n try {\n fs.rmSync(file, { force: true });\n } catch {\n /* best-effort */\n }\n}\n","import * as fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { hashString } from './hash.js';\nimport { cacheDir } from './cache.js';\nimport { acquireLock, releaseLock } from './lock.js';\nimport type { GraphNode, VgGraph } from '../schema.js';\n\n/**\n * Local-embedding semantic search for `vg ask --semantic`/`--deep` (no API key).\n *\n * The embedding backend is an OPTIONAL, lazily-loaded dependency (`fastembed`,\n * Apache-2.0, local ONNX) so the core install stays lean and `ask` never breaks:\n * if the backend or model isn't available it degrades to (prefix-fuzzy) lexical\n * search with a clear note. Embeddings are query-time + cached under\n * `.vibgrate/cache/` (keyed by node-text hash); they are NEVER written into the\n * committed `graph.json`, so the artifact stays byte-deterministic.\n *\n * `--local` disables the model download (semantic is skipped unless already\n * cached via an injected backend), keeping the air-gapped guarantee.\n */\n\nexport interface Embedder {\n /** Stable model id (recorded with cached vectors so a model change invalidates them). */\n id: string;\n /** Embed documents → unit-or-raw vectors (cosine handles normalization). */\n embed(texts: string[]): Promise<number[][]>;\n /** Embed a single query string. */\n embedQuery(text: string): Promise<number[]>;\n}\n\n/** Why semantic fell back to lexical — for calm, specific messaging. */\nexport type EmbedUnavailable = 'not-installed' | 'no-permission' | 'download-failed' | 'init-failed';\n\nexport interface LoadEmbedderOptions {\n local?: boolean; // --local: do not download a model\n model?: string; // override the embedding model id\n noDownload?: boolean; // only load if the model is already cached (never fetch)\n showDownloadProgress?: boolean; // let fastembed print its one-time download progress\n onUnavailable?: (reason: EmbedUnavailable) => void; // called (not thrown) when it can't load\n}\n\n/** The embedding model id in effect (explicit override → default). */\nexport function resolveEmbedModel(model?: string): string {\n return model ?? 'bge-small-en-v1.5';\n}\n\n/**\n * The **central, per-user** model cache — downloaded once per machine and shared\n * across every repo/folder (devs have many repos; the ~tens-of-MB model should\n * not re-download per project). Uses the XDG standard:\n * `$XDG_CACHE_HOME/vibgrate/models` (or `~/.cache/vibgrate/models`); relocate via\n * the standard `XDG_CACHE_HOME`. NB: fastembed's own default is the relative\n * `./local_cache`, i.e. per-CWD — which we override.\n */\nexport function modelCacheDir(): string {\n const base = process.env.XDG_CACHE_HOME || path.join(os.homedir(), '.cache');\n return path.join(base, 'vibgrate', 'models');\n}\n\n/** A machine-global marker written once the model has loaded successfully. */\nfunction modelReadyMarker(modelId: string): string {\n return path.join(modelCacheDir(), `.ready-${safe(modelId)}`);\n}\n\n/**\n * Whether the embedding model is already present on this machine (loaded at least\n * once), so it can be used with **no network**. Lets the background warm-up\n * trigger only when it won't surprise-download.\n */\nexport function isModelReady(modelId = resolveEmbedModel()): boolean {\n return fs.existsSync(modelReadyMarker(modelId));\n}\n\n/**\n * A calm, specific, actionable one-liner for why semantic isn't available right\n * now — built to reassure (lexical still works) and inform, never to alarm. No\n * stack traces, no scary words; always names the off switch and the fix.\n */\nexport function unavailableMessage(reason: EmbedUnavailable): string {\n switch (reason) {\n case 'no-permission':\n return `semantic search couldn't write its model cache at ${modelCacheDir()} — using fast lexical search instead. Relocate it with the standard XDG_CACHE_HOME, or run with --local to stay lexical quietly. (No admin/sudo is ever needed — the cache lives in your home folder.)`;\n case 'download-failed':\n return `the semantic model isn't downloaded yet and couldn't be fetched (offline?) — using fast lexical search. It'll try again next time; run with --local to keep lexical without retrying.`;\n case 'not-installed':\n return `the optional semantic backend isn't available here — using fast lexical search.`;\n case 'init-failed':\n default:\n return `the semantic model couldn't load — using fast lexical search.`;\n }\n}\n\nexport interface ModelCacheInfo {\n dir: string;\n present: boolean;\n bytes: number;\n}\n\n/** Where the shared model lives, whether it's present, and how big it is. */\nexport function modelCacheInfo(modelId = resolveEmbedModel()): ModelCacheInfo {\n const dir = modelCacheDir();\n return { dir, present: isModelReady(modelId) || fs.existsSync(dir), bytes: dirSize(dir) };\n}\n\n/** Remove the shared, re-downloadable model from the central cache. Returns bytes freed. */\nexport function clearModelCache(): number {\n const dir = modelCacheDir();\n const bytes = dirSize(dir);\n try {\n fs.rmSync(dir, { recursive: true, force: true });\n } catch {\n /* best-effort */\n }\n return bytes;\n}\n\nfunction dirSize(dir: string): number {\n let total = 0;\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return 0;\n }\n for (const e of entries) {\n const p = path.join(dir, e.name);\n if (e.isDirectory()) total += dirSize(p);\n else {\n try {\n total += fs.statSync(p).size;\n } catch {\n /* skip unreadable */\n }\n }\n }\n return total;\n}\n\nfunction isPermissionError(e: unknown): boolean {\n const code = (e as NodeJS.ErrnoException | undefined)?.code;\n return code === 'EACCES' || code === 'EPERM' || code === 'EROFS';\n}\n\n/**\n * Whether this repo already has a cached vector set for `modelId` — i.e. semantic\n * search has run here before, so the next run is fast (no first-use download/embed).\n * Lets `ask` show the one-time setup note only when it's actually warranted.\n */\nexport function embeddingsCached(root: string, modelId: string): boolean {\n return fs.existsSync(path.join(cacheDir(root), `embeddings-${safe(modelId)}.json`));\n}\n\n/**\n * Try to load the optional local embedding backend. Returns null (→ caller falls\n * back to lexical) when running `--local`, when the dependency isn't installed,\n * or when the model can't initialize.\n */\nexport async function loadEmbedder(options: LoadEmbedderOptions = {}): Promise<Embedder | null> {\n // `--local` forces the deterministic lexical floor with no model load/download\n // (air-gapped guarantee; also how tests stay offline).\n if (options.local) return null;\n const modelId = resolveEmbedModel(options.model);\n // noDownload (used by the background warm-up): never fetch — bail if not cached.\n if (options.noDownload && !isModelReady(modelId)) return null;\n const fail = (reason: EmbedUnavailable): null => {\n options.onUnavailable?.(reason);\n return null;\n };\n\n // Lazy, optional dependency (native ONNX): loaded only for `vg ask`/`embed`,\n // never by build/verify, so the graph artifact stays deterministic.\n const mod: any = await importEmbedBackend();\n if (!mod?.FlagEmbedding) return fail('not-installed');\n\n const cache = modelCacheDir(); // central, shared across all repos\n try {\n fs.mkdirSync(cache, { recursive: true });\n } catch (e) {\n return fail(isPermissionError(e) ? 'no-permission' : 'init-failed');\n }\n\n try {\n // First use fetches the model. A refused connection fails fast, but a\n // black-holing proxy (common on corporate networks) would hang the first\n // `vg ask` / MCP query_graph forever — bound the wait and fall back to\n // lexical instead. Cached loads are local disk and get the same generous\n // ceiling without ever hitting it.\n const model: any = await withTimeout(\n mod.FlagEmbedding.init({\n model: mapModel(mod, modelId),\n cacheDir: cache,\n showDownloadProgress: options.showDownloadProgress ?? false,\n }) as Promise<unknown>,\n embedInitTimeoutMs(),\n 'embedding model init timed out',\n );\n // Record machine-global readiness so future builds can warm up offline.\n try {\n fs.writeFileSync(modelReadyMarker(modelId), new Date(0).toISOString());\n } catch {\n /* marker is best-effort */\n }\n return {\n id: modelId,\n async embed(texts) {\n const out: number[][] = [];\n for await (const batch of model.embed(texts, 64)) {\n for (const v of batch) out.push(Array.from(v as ArrayLike<number>));\n }\n return out;\n },\n async embedQuery(text) {\n const v = await model.queryEmbed(text);\n return Array.from(v as ArrayLike<number>);\n },\n };\n } catch (e) {\n return fail(isPermissionError(e) ? 'no-permission' : 'download-failed');\n }\n}\n\n/**\n * Import the optional native backend. A host can supply it out-of-tree via\n * `VIBGRATE_EMBEDDER_PATH` — a directory whose `node_modules` contains\n * `fastembed`. Editor integrations use this when their bundled engine ships\n * without the native optional dependency (the VS Code extension installs it\n * into its own storage on consent); the host dir wins over this package's own\n * dependency tree so the copy the user consented to is the one that loads.\n * Any resolution failure falls through — never throws.\n */\nasync function importEmbedBackend(): Promise<any> {\n const hostDir = process.env.VIBGRATE_EMBEDDER_PATH;\n if (hostDir) {\n try {\n const req = createRequire(path.join(hostDir, 'package.json'));\n const mod: any = await import(pathToFileURL(req.resolve('fastembed')).href);\n // A CJS entry imported over ESM may nest its exports under `default`.\n const resolved = mod?.FlagEmbedding ? mod : mod?.default;\n if (resolved?.FlagEmbedding) return resolved;\n } catch {\n /* fall through to normal resolution */\n }\n }\n return await import('fastembed' as string).catch(() => null);\n}\n\n/** Ceiling for the one-time model fetch/init; override via VG_EMBED_TIMEOUT_MS. */\nfunction embedInitTimeoutMs(): number {\n const n = Number(process.env.VG_EMBED_TIMEOUT_MS);\n return Number.isFinite(n) && n > 0 ? n : 60_000;\n}\n\n/** Reject `promise` if it hasn't settled within `ms` (the work itself is not cancelled). */\nexport async function withTimeout<T>(promise: Promise<T>, ms: number, message: string): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(message)), ms);\n timer.unref?.();\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n}\n\nfunction mapModel(mod: any, id: string): unknown {\n const m = mod.EmbeddingModel ?? {};\n if (/bge-small/i.test(id)) return m.BGESmallENV15 ?? m.BGESmallEN ?? id;\n if (/bge-base/i.test(id)) return m.BGEBaseENV15 ?? id;\n if (/all-minilm/i.test(id)) return m.AllMiniLML6V2 ?? id;\n return id;\n}\n\n/** Path segments that carry no semantic signal — dropped from embed context. */\nconst PATH_NOISE = new Set([\n 'src', 'app', 'apps', 'lib', 'libs', 'dist', 'build', 'out', 'index', 'main',\n 'packages', 'pkg', 'test', 'tests', '__tests__', 'spec', 'node_modules', 'internal',\n 'com', 'example', 'demo', 'java', 'net', 'org', 'www',\n]);\n\n/** Meaningful path context for a node: a couple of parent dirs + the filename stem. */\nfunction pathContext(file: string): string {\n const parts = file.split('/');\n const stem = (parts.pop() ?? '').replace(/\\.[^.]+$/, '');\n const dirs = parts.filter((p) => p && !PATH_NOISE.has(p.toLowerCase()));\n return [...dirs.slice(-2), stem].filter(Boolean).join(' ');\n}\n\n/**\n * The text we embed for a node. Alongside identity + signature we add the\n * strongest available signal — the node's **doc-comment / docstring** summary —\n * plus lightweight context already on the graph (file-path words, area label), so\n * a tersely-named symbol (`Table`, `NotificationJob`) a concept query can reach.\n *\n * `document` nodes (markdown, manifests, Docker, CI, OpenAPI, …) put the\n * scrubbed body in `doc` — that body is the primary embed signal so `vg ask`\n * can answer project-context questions, not only code symbols.\n */\nexport function nodeEmbedText(node: GraphNode, areaLabel?: string): string {\n if (node.kind === 'document') {\n const category = (node.signature ?? 'document').replace(/^document:/, '');\n // Category keywords help ops/config queries land on the right file type.\n const categoryHints: Record<string, string> = {\n manifest: 'package dependencies scripts install dependencies versions',\n docker: 'dockerfile container image build runtime',\n compose: 'docker-compose services containers networking volumes',\n ci: 'continuous integration github actions workflow pipeline test build deploy',\n 'build-config': 'typescript tsconfig bundler vite webpack eslint prettier test',\n 'api-contract': 'openapi swagger graphql protobuf api schema endpoints',\n 'task-runner': 'makefile justfile tasks build test run commands',\n workspace: 'monorepo workspace packages pnpm turbo nx',\n infra: 'deploy infrastructure kubernetes kubernetes terraform helm kubernetes',\n 'env-example': 'environment variables configuration secrets template',\n markdown: 'documentation readme guide',\n };\n const hint = categoryHints[category] ?? category;\n return [\n node.qualifiedName,\n 'document',\n category,\n hint,\n pathContext(node.file),\n (node.doc ?? '').slice(0, 5000),\n ]\n .filter(Boolean)\n .join('\\n');\n }\n return [node.qualifiedName, node.kind, node.signature ?? '', node.doc ?? '', pathContext(node.file), areaLabel ?? '']\n .filter(Boolean)\n .join(' ');\n}\n\nexport function cosine(a: number[], b: number[]): number {\n let dot = 0;\n let na = 0;\n let nb = 0;\n const n = Math.min(a.length, b.length);\n for (let i = 0; i < n; i++) {\n dot += a[i] * b[i];\n na += a[i] * a[i];\n nb += b[i] * b[i];\n }\n if (na === 0 || nb === 0) return 0;\n return dot / (Math.sqrt(na) * Math.sqrt(nb));\n}\n\ninterface EmbedCache {\n model: string;\n entries: Record<string, { hash: string; vec: number[] }>;\n}\n\n/** Reports embedding progress: how many of `total` nodes are done so far. */\nexport type EmbedProgress = (done: number, total: number) => void;\n\n/** Nodes embedded per chunk — bounds memory and gives progress granularity. */\nconst EMBED_CHUNK = 256;\n/** Min gap between incremental cache writes (ms) — caps IO on big repos. */\nconst CACHE_WRITE_INTERVAL_MS = 1500;\n\nfunction vectorCachePath(root: string, modelId: string): string {\n return path.join(cacheDir(root), `embeddings-${safe(modelId)}.json`);\n}\n\n/**\n * How many searchable nodes still need embedding for `modelId` — cheap (hashes\n * the embed-text, reads only the cache; never loads the model). Lets the embed\n * command / background warm-up exit instantly when nothing changed.\n */\nexport function countPending(graph: VgGraph, root: string, modelId: string): number {\n const entries = readCacheEntries(vectorCachePath(root, modelId), modelId);\n const areaLabel = new Map(graph.areas.map((a) => [a.id, a.label] as const));\n let pending = 0;\n for (const n of graph.nodes) {\n // file/external stay out of the index; document (docs/env examples) are in.\n if (n.kind === 'file' || n.kind === 'external') continue;\n const h = hashString(nodeEmbedText(n, areaLabel.get(n.area)));\n const cached = entries[n.id];\n if (!cached || cached.hash !== h) pending++;\n }\n return pending;\n}\n\nfunction readCacheEntries(file: string, modelId: string): EmbedCache['entries'] {\n if (!fs.existsSync(file)) return {};\n try {\n const loaded = JSON.parse(fs.readFileSync(file, 'utf8')) as EmbedCache;\n if (loaded.model === modelId && loaded.entries) return loaded.entries;\n } catch {\n /* treat as empty */\n }\n return {};\n}\n\n// Single-writer lock (shared helper — see ./lock.ts) so a foreground `ask`\n// and a background `embed` never both embed the same repo at once (which\n// would race on the cache file).\n\n/**\n * Node embeddings for the searchable (non-file/external) nodes, cache-backed:\n * only nodes whose embed-text changed are re-embedded. The first run embeds in\n * chunks, **persists the cache incrementally** (so an interrupted/timed-out run\n * resumes instead of wasting the work), and reports progress via `onProgress`.\n */\nexport async function getNodeEmbeddings(\n graph: VgGraph,\n embedder: Embedder,\n root: string,\n onProgress?: EmbedProgress,\n): Promise<Map<string, number[]>> {\n const file = vectorCachePath(root, embedder.id);\n let cache: EmbedCache = { model: embedder.id, entries: {} };\n if (fs.existsSync(file)) {\n try {\n const loaded = JSON.parse(fs.readFileSync(file, 'utf8')) as EmbedCache;\n if (loaded.model === embedder.id && loaded.entries) cache = loaded;\n } catch {\n /* rebuild */\n }\n }\n\n const areaLabel = new Map(graph.areas.map((a) => [a.id, a.label] as const));\n // Include document nodes (markdown/txt/env examples) so ask can retrieve docs.\n const targets = graph.nodes.filter((n) => n.kind !== 'file' && n.kind !== 'external');\n const toEmbed: { id: string; text: string; hash: string }[] = [];\n const vectors = new Map<string, number[]>();\n for (const n of targets) {\n const text = nodeEmbedText(n, areaLabel.get(n.area));\n const h = hashString(text);\n const cached = cache.entries[n.id];\n if (cached && cached.hash === h) vectors.set(n.id, cached.vec);\n else toEmbed.push({ id: n.id, text, hash: h });\n }\n\n // Atomic write (temp + rename) so a reader never sees a half-written cache.\n const persist = (): void => {\n try {\n fs.mkdirSync(cacheDir(root), { recursive: true });\n const tmp = `${file}.tmp.${process.pid}`;\n fs.writeFileSync(tmp, JSON.stringify(cache));\n fs.renameSync(tmp, file);\n } catch {\n /* cache write best-effort */\n }\n };\n\n if (toEmbed.length) {\n // Single-writer: if another process (e.g. a background warm-up) is already\n // embedding this repo, don't double-work or race the cache — return what's\n // cached so far (lexical floor still applies). It will be complete next run.\n const lock = `${file}.lock`;\n if (!acquireLock(lock)) return vectors;\n try {\n onProgress?.(0, toEmbed.length);\n let lastWrite = Date.now();\n for (let i = 0; i < toEmbed.length; i += EMBED_CHUNK) {\n const slice = toEmbed.slice(i, i + EMBED_CHUNK);\n const vecs = await embedder.embed(slice.map((t) => t.text));\n slice.forEach((t, j) => {\n const vec = vecs[j] ?? [];\n vectors.set(t.id, vec);\n cache.entries[t.id] = { hash: t.hash, vec };\n });\n onProgress?.(Math.min(i + EMBED_CHUNK, toEmbed.length), toEmbed.length);\n // Persist periodically so a crash/timeout resumes from here next run.\n if (Date.now() - lastWrite >= CACHE_WRITE_INTERVAL_MS) {\n persist();\n lastWrite = Date.now();\n }\n }\n // prune entries for nodes no longer present, then a final authoritative write\n const live = new Set(targets.map((n) => n.id));\n for (const id of Object.keys(cache.entries)) if (!live.has(id)) delete cache.entries[id];\n persist();\n } finally {\n releaseLock(lock);\n }\n }\n\n return vectors;\n}\n\nfunction safe(id: string): string {\n return id.replace(/[^a-z0-9.-]+/gi, '_');\n}\n"]}
|
|
@@ -479,6 +479,67 @@ function redactSecrets(s) {
|
|
|
479
479
|
function httpError(label, status, hint) {
|
|
480
480
|
return new Error(`${label} returned HTTP ${status} \u2014 ${hint}`);
|
|
481
481
|
}
|
|
482
|
+
function unwrapNestedErrorJson(text) {
|
|
483
|
+
const trimmed = (text ?? "").trim();
|
|
484
|
+
if (!trimmed.startsWith("{")) return trimmed;
|
|
485
|
+
let parsed;
|
|
486
|
+
try {
|
|
487
|
+
parsed = JSON.parse(trimmed);
|
|
488
|
+
} catch {
|
|
489
|
+
return trimmed;
|
|
490
|
+
}
|
|
491
|
+
const obj = parsed ?? {};
|
|
492
|
+
const err = obj.error;
|
|
493
|
+
const errObj = typeof err === "object" && err ? err : {};
|
|
494
|
+
const message = typeof err === "string" ? err : typeof errObj.message === "string" ? errObj.message : typeof obj.message === "string" ? obj.message : null;
|
|
495
|
+
if (!message?.trim()) return trimmed;
|
|
496
|
+
const metadata = typeof errObj.metadata === "object" && errObj.metadata ? errObj.metadata : {};
|
|
497
|
+
const names = (value) => Array.isArray(value) ? value.filter((v) => typeof v === "string" && !!v.trim()) : [];
|
|
498
|
+
const requested = names(metadata.requested_providers);
|
|
499
|
+
const available = names(metadata.available_providers);
|
|
500
|
+
const parts = [message.trim()];
|
|
501
|
+
if (requested.length) parts.push(`requested provider(s): ${requested.join(", ")}`);
|
|
502
|
+
if (available.length) parts.push(`permitted provider(s): ${available.join(", ")}`);
|
|
503
|
+
return parts.join(" \u2014 ");
|
|
504
|
+
}
|
|
505
|
+
function relayErrorDetail(body) {
|
|
506
|
+
if (!body) return null;
|
|
507
|
+
let parsed;
|
|
508
|
+
try {
|
|
509
|
+
parsed = JSON.parse(body);
|
|
510
|
+
} catch {
|
|
511
|
+
return nonJsonErrorDetail(body);
|
|
512
|
+
}
|
|
513
|
+
const obj = parsed;
|
|
514
|
+
const err = obj?.error;
|
|
515
|
+
const errObj = typeof err === "object" && err ? err : {};
|
|
516
|
+
const message = typeof err === "string" ? err : typeof errObj.message === "string" ? errObj.message : typeof obj?.message === "string" ? obj.message : null;
|
|
517
|
+
const detailValue = typeof obj?.detail === "string" ? obj.detail : typeof errObj.detail === "string" ? errObj.detail : null;
|
|
518
|
+
const detail = detailValue && detailValue.trim() ? unwrapNestedErrorJson(detailValue) : null;
|
|
519
|
+
const parts = [message, detail].filter((p) => !!p && p.trim().length > 0);
|
|
520
|
+
if (!parts.length) return null;
|
|
521
|
+
const correlationId = typeof obj?.correlation_id === "string" && obj.correlation_id ? obj.correlation_id : typeof errObj.correlation_id === "string" && errObj.correlation_id ? errObj.correlation_id : null;
|
|
522
|
+
const id = correlationId ? ` (correlation id ${correlationId})` : "";
|
|
523
|
+
return `${[...new Set(parts)].join(" \u2014 ").slice(0, 400)}${id}`;
|
|
524
|
+
}
|
|
525
|
+
function nonJsonErrorDetail(body) {
|
|
526
|
+
const text = body.trim();
|
|
527
|
+
if (!text) return null;
|
|
528
|
+
if (text.length <= 200) return text;
|
|
529
|
+
const title = /<title[^>]*>([\s\S]*?)<\/title>/i.exec(text)?.[1]?.replace(/\s+/g, " ").trim();
|
|
530
|
+
if (title) return title.slice(0, 200);
|
|
531
|
+
const code = /\bError\s+\d{3,4}\b/.exec(text)?.[0];
|
|
532
|
+
return code ?? null;
|
|
533
|
+
}
|
|
534
|
+
function statusHint(status, model, apiKeyEnv) {
|
|
535
|
+
if (status === 401 || status === 403) return `the key in ${apiKeyEnv ?? "(none)"} was rejected \u2014 check it has access to "${model}"`;
|
|
536
|
+
if (status === 402) return "the account behind this endpoint is out of credit \u2014 top it up, or switch backend with --provider / --local";
|
|
537
|
+
if (status === 404) return `this endpoint has no model "${model}" \u2014 check the id (\`vg models catalog\`) and the base URL`;
|
|
538
|
+
if (status === 408 || status === 504) return "the request timed out before the model replied \u2014 retry, shorten the task, or use --local";
|
|
539
|
+
if (status === 429) return "rate limited \u2014 wait and retry, or switch backend with --provider / --local";
|
|
540
|
+
if (status >= 500) return `the endpoint failed to serve the request \u2014 this is an upstream/gateway failure, not the model id "${model}"; retry, or use --provider / --local if it persists`;
|
|
541
|
+
return `check the model id "${model}" and the endpoint`;
|
|
542
|
+
}
|
|
482
543
|
async function* streamLines(res) {
|
|
483
544
|
const reader = res.body?.getReader();
|
|
484
545
|
if (!reader) return;
|
|
@@ -499,6 +560,8 @@ async function* streamLines(res) {
|
|
|
499
560
|
}
|
|
500
561
|
function accumulateOpenAiDelta(acc, chunk, onToken) {
|
|
501
562
|
const c = chunk;
|
|
563
|
+
const reason = c.choices?.[0]?.finish_reason;
|
|
564
|
+
if (typeof reason === "string" && reason) acc.finishReason = reason;
|
|
502
565
|
const delta = c.choices?.[0]?.delta;
|
|
503
566
|
if (delta?.content) {
|
|
504
567
|
acc.text += delta.content;
|
|
@@ -570,6 +633,7 @@ var OllamaProvider = class {
|
|
|
570
633
|
if (streaming) {
|
|
571
634
|
let text = "";
|
|
572
635
|
let toolCallsRaw;
|
|
636
|
+
let truncated = false;
|
|
573
637
|
const usage = {};
|
|
574
638
|
for await (const line of streamLines(res)) {
|
|
575
639
|
try {
|
|
@@ -582,10 +646,11 @@ var OllamaProvider = class {
|
|
|
582
646
|
if (obj.message?.tool_calls) toolCallsRaw = obj.message.tool_calls;
|
|
583
647
|
if (typeof obj.prompt_eval_count === "number") usage.promptTokens = obj.prompt_eval_count;
|
|
584
648
|
if (typeof obj.eval_count === "number") usage.completionTokens = obj.eval_count;
|
|
649
|
+
if (obj.done_reason === "length") truncated = true;
|
|
585
650
|
} catch {
|
|
586
651
|
}
|
|
587
652
|
}
|
|
588
|
-
return { text, model: this.model, provider: this.id, toolCalls: parseToolCalls(toolCallsRaw), usage };
|
|
653
|
+
return { text, model: this.model, provider: this.id, toolCalls: parseToolCalls(toolCallsRaw), usage, truncated };
|
|
589
654
|
}
|
|
590
655
|
const data = await res.json();
|
|
591
656
|
return {
|
|
@@ -593,7 +658,8 @@ var OllamaProvider = class {
|
|
|
593
658
|
model: this.model,
|
|
594
659
|
provider: this.id,
|
|
595
660
|
toolCalls: parseToolCalls(data.message?.tool_calls),
|
|
596
|
-
usage: { promptTokens: data.prompt_eval_count, completionTokens: data.eval_count }
|
|
661
|
+
usage: { promptTokens: data.prompt_eval_count, completionTokens: data.eval_count },
|
|
662
|
+
truncated: data.done_reason === "length"
|
|
597
663
|
};
|
|
598
664
|
}
|
|
599
665
|
};
|
|
@@ -637,11 +703,12 @@ var OpenAiCompatibleProvider = class {
|
|
|
637
703
|
throw new Error(`couldn't reach ${this.label} at ${this.config.baseUrl} \u2014 check the endpoint is up (or use --local).`);
|
|
638
704
|
}
|
|
639
705
|
if (!res.ok) {
|
|
640
|
-
const
|
|
706
|
+
const detail = relayErrorDetail(await res.text().catch(() => ""));
|
|
707
|
+
const hint = detail ?? statusHint(res.status, this.model, this.config.apiKeyEnv);
|
|
641
708
|
throw httpError(this.label, res.status, hint);
|
|
642
709
|
}
|
|
643
710
|
if (streaming) {
|
|
644
|
-
const acc = { text: "", tools: /* @__PURE__ */ new Map(), usage: {} };
|
|
711
|
+
const acc = { text: "", tools: /* @__PURE__ */ new Map(), usage: {}, finishReason: void 0 };
|
|
645
712
|
for await (const line of streamLines(res)) {
|
|
646
713
|
if (!line.startsWith("data:")) continue;
|
|
647
714
|
const payload = line.slice(5).trim();
|
|
@@ -652,7 +719,7 @@ var OpenAiCompatibleProvider = class {
|
|
|
652
719
|
}
|
|
653
720
|
}
|
|
654
721
|
const tools = finalizeTools(acc.tools);
|
|
655
|
-
return { text: acc.text, model: this.model, provider: this.id, toolCalls: tools.length ? tools : void 0, usage: acc.usage };
|
|
722
|
+
return { text: acc.text, model: this.model, provider: this.id, toolCalls: tools.length ? tools : void 0, usage: acc.usage, truncated: acc.finishReason === "length" };
|
|
656
723
|
}
|
|
657
724
|
const data = await res.json();
|
|
658
725
|
const message = data.choices?.[0]?.message;
|
|
@@ -661,7 +728,8 @@ var OpenAiCompatibleProvider = class {
|
|
|
661
728
|
model: this.model,
|
|
662
729
|
provider: this.id,
|
|
663
730
|
toolCalls: parseToolCalls(message?.tool_calls),
|
|
664
|
-
usage: { promptTokens: data.usage?.prompt_tokens, completionTokens: data.usage?.completion_tokens }
|
|
731
|
+
usage: { promptTokens: data.usage?.prompt_tokens, completionTokens: data.usage?.completion_tokens },
|
|
732
|
+
truncated: data.choices?.[0]?.finish_reason === "length"
|
|
665
733
|
};
|
|
666
734
|
}
|
|
667
735
|
};
|
|
@@ -680,7 +748,7 @@ var ScriptedProvider = class {
|
|
|
680
748
|
async chat(_messages, _opts) {
|
|
681
749
|
const step = this.steps[Math.min(this.turn, this.steps.length - 1)];
|
|
682
750
|
this.turn++;
|
|
683
|
-
return { text: step.text ?? "", model: this.model, provider: this.id, toolCalls: step.toolCalls };
|
|
751
|
+
return { text: step.text ?? "", model: this.model, provider: this.id, toolCalls: step.toolCalls, truncated: step.truncated };
|
|
684
752
|
}
|
|
685
753
|
};
|
|
686
754
|
var OPENAI_COMPATIBLE = {
|
|
@@ -835,5 +903,5 @@ var LocalLlamaProvider = class _LocalLlamaProvider {
|
|
|
835
903
|
};
|
|
836
904
|
|
|
837
905
|
export { LocalLlamaProvider, MockProvider, OPENAI_COMPATIBLE, OllamaProvider, OpenAiCompatibleProvider, ScriptedProvider, applyEdit, applyEdits, buildAgentMessages, buildMessages, parseEdits, redactSecrets, summarizeDiffs, unifiedDiff };
|
|
838
|
-
//# sourceMappingURL=chunk-
|
|
839
|
-
//# sourceMappingURL=chunk-
|
|
906
|
+
//# sourceMappingURL=chunk-2U4SXS5U.js.map
|
|
907
|
+
//# sourceMappingURL=chunk-2U4SXS5U.js.map
|