@vostride/agent-qa-knowledge-local 0.0.1 → 0.2.2
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/LICENSE.md +105 -0
- package/NOTICE.md +15 -0
- package/assets/potion-retrieval-32m/LICENSE +29 -0
- package/assets/potion-retrieval-32m/golden-vectors.json +4144 -0
- package/assets/potion-retrieval-32m/manifest.json +37 -0
- package/assets/potion-retrieval-32m/potion-retrieval-32m.i8bin +0 -0
- package/assets/potion-retrieval-32m/tokenizer.json +63241 -0
- package/dist/embedder-worker/worker-entry.cjs +1424 -0
- package/dist/embedder-worker/worker-entry.cjs.map +1 -0
- package/dist/embedder-worker/worker-entry.d.cts +18 -0
- package/dist/embedder-worker/worker-entry.d.ts +18 -0
- package/dist/embedder-worker/worker-entry.js +1426 -0
- package/dist/embedder-worker/worker-entry.js.map +1 -0
- package/dist/index.cjs +21491 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +3983 -0
- package/dist/index.d.ts +3983 -0
- package/dist/index.js +21612 -0
- package/dist/index.js.map +1 -0
- package/dist/mark-evidence-plan-BCkYN07i.d.cts +1014 -0
- package/dist/mark-evidence-plan-BCkYN07i.d.ts +1014 -0
- package/dist/reader.cjs +5829 -0
- package/dist/reader.cjs.map +1 -0
- package/dist/reader.d.cts +107 -0
- package/dist/reader.d.ts +107 -0
- package/dist/reader.js +5951 -0
- package/dist/reader.js.map +1 -0
- package/dist/worker-registration-C-9spEsf.d.cts +78 -0
- package/dist/worker-registration-C-9spEsf.d.ts +78 -0
- package/package.json +69 -3
|
@@ -0,0 +1,1424 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/embedder-worker/worker-entry.ts
|
|
31
|
+
var worker_entry_exports = {};
|
|
32
|
+
__export(worker_entry_exports, {
|
|
33
|
+
runEmbedderWorker: () => runEmbedderWorker
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(worker_entry_exports);
|
|
36
|
+
var import_node_crypto3 = require("node:crypto");
|
|
37
|
+
var import_node_fs4 = require("node:fs");
|
|
38
|
+
var import_node_http2 = require("node:http");
|
|
39
|
+
var import_node_net2 = require("node:net");
|
|
40
|
+
var import_node_path7 = require("node:path");
|
|
41
|
+
|
|
42
|
+
// src/embedder-acquire.ts
|
|
43
|
+
var import_node_path5 = require("node:path");
|
|
44
|
+
var import_agent_qa_schema2 = require("@vostride/agent-qa-schema");
|
|
45
|
+
|
|
46
|
+
// src/embedder-floor.ts
|
|
47
|
+
var import_node_crypto = require("node:crypto");
|
|
48
|
+
var import_node_fs = require("node:fs");
|
|
49
|
+
var import_node_path = require("node:path");
|
|
50
|
+
var import_node_url = require("node:url");
|
|
51
|
+
var import_meta = {};
|
|
52
|
+
var PACKAGE_NAME = "@vostride/agent-qa-knowledge-local";
|
|
53
|
+
var ASSET_DIRECTORY = "potion-retrieval-32m";
|
|
54
|
+
var BINARY_FILE = "potion-retrieval-32m.i8bin";
|
|
55
|
+
var TOKENIZER_FILE = "tokenizer.json";
|
|
56
|
+
var GOLDEN_FILE = "golden-vectors.json";
|
|
57
|
+
var MANIFEST_FILE = "manifest.json";
|
|
58
|
+
var MODEL_ID = "minishlab/potion-retrieval-32M";
|
|
59
|
+
var MODEL_REVISION = "6fc8051fab2a1e0ee76689cf08c853792ac285e7";
|
|
60
|
+
var FLOOR_MAGIC = "PTNF";
|
|
61
|
+
var FLOOR_FORMAT_VERSION = 1;
|
|
62
|
+
var FLOOR_VOCABULARY_SIZE = 63091;
|
|
63
|
+
var FLOOR_DIMENSION = 512;
|
|
64
|
+
var FLOOR_HEADER_BYTES = 16;
|
|
65
|
+
var MANIFEST_MAX_BYTES = 1024 * 1024;
|
|
66
|
+
var TOKENIZER_MAX_BYTES = 16 * 1024 * 1024;
|
|
67
|
+
var GOLDEN_MAX_BYTES = 8 * 1024 * 1024;
|
|
68
|
+
var SHA256_RE = /^[0-9a-f]{64}$/u;
|
|
69
|
+
var FloorAssetLoadError = class extends Error {
|
|
70
|
+
code;
|
|
71
|
+
constructor(code, message, options) {
|
|
72
|
+
super(message, options);
|
|
73
|
+
this.name = "FloorAssetLoadError";
|
|
74
|
+
this.code = code;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
var FloorEmbeddingError = class extends Error {
|
|
78
|
+
code;
|
|
79
|
+
constructor(code, message, options) {
|
|
80
|
+
super(message, options);
|
|
81
|
+
this.name = "FloorEmbeddingError";
|
|
82
|
+
this.code = code;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
var memoizedDefaultAssets;
|
|
86
|
+
var tokenizerRuntime;
|
|
87
|
+
function isRecord(value) {
|
|
88
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
89
|
+
}
|
|
90
|
+
function errorMessage(error) {
|
|
91
|
+
return error instanceof Error ? error.message : String(error);
|
|
92
|
+
}
|
|
93
|
+
function packageRootFromImportMeta() {
|
|
94
|
+
let current = (0, import_node_path.dirname)((0, import_node_url.fileURLToPath)(import_meta.url));
|
|
95
|
+
while (true) {
|
|
96
|
+
const packageJsonPath = (0, import_node_path.join)(current, "package.json");
|
|
97
|
+
if ((0, import_node_fs.existsSync)(packageJsonPath)) {
|
|
98
|
+
try {
|
|
99
|
+
const packageJson = JSON.parse((0, import_node_fs.readFileSync)(packageJsonPath, "utf8"));
|
|
100
|
+
if (isRecord(packageJson) && packageJson.name === PACKAGE_NAME) return current;
|
|
101
|
+
} catch {
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const parent = (0, import_node_path.dirname)(current);
|
|
105
|
+
if (parent === current) break;
|
|
106
|
+
current = parent;
|
|
107
|
+
}
|
|
108
|
+
throw new FloorAssetLoadError(
|
|
109
|
+
"package-root-not-found",
|
|
110
|
+
`could not resolve ${PACKAGE_NAME} from ${(0, import_node_url.fileURLToPath)(import_meta.url)}`
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
function manifestEntry(value, file) {
|
|
114
|
+
if (!isRecord(value)) {
|
|
115
|
+
throw new FloorAssetLoadError("manifest-invalid", `manifest files.${file} is invalid`);
|
|
116
|
+
}
|
|
117
|
+
if (!Number.isSafeInteger(value.bytes) || Number(value.bytes) <= 0) {
|
|
118
|
+
throw new FloorAssetLoadError(
|
|
119
|
+
"manifest-invalid",
|
|
120
|
+
`manifest files.${file}.bytes must be a positive safe integer`
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
if (typeof value.sha256 !== "string" || !SHA256_RE.test(value.sha256)) {
|
|
124
|
+
throw new FloorAssetLoadError(
|
|
125
|
+
"manifest-invalid",
|
|
126
|
+
`manifest files.${file}.sha256 must be a lowercase sha256 digest`
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
return { bytes: Number(value.bytes), sha256: value.sha256 };
|
|
130
|
+
}
|
|
131
|
+
function parseManifest(value) {
|
|
132
|
+
if (!isRecord(value) || value.schemaVersion !== 1 || value.format !== "potion-static-int8") {
|
|
133
|
+
throw new FloorAssetLoadError("manifest-invalid", "floor manifest identity is invalid");
|
|
134
|
+
}
|
|
135
|
+
if (value.modelId !== MODEL_ID || value.revision !== MODEL_REVISION) {
|
|
136
|
+
throw new FloorAssetLoadError("manifest-invalid", "floor manifest model pin is invalid");
|
|
137
|
+
}
|
|
138
|
+
if (!isRecord(value.artifact)) {
|
|
139
|
+
throw new FloorAssetLoadError("manifest-invalid", "floor manifest artifact is invalid");
|
|
140
|
+
}
|
|
141
|
+
const artifact = value.artifact;
|
|
142
|
+
if (artifact.magic !== FLOOR_MAGIC || artifact.version !== FLOOR_FORMAT_VERSION || artifact.vocabularySize !== FLOOR_VOCABULARY_SIZE || artifact.dimension !== FLOOR_DIMENSION || artifact.quantization !== "symmetric-per-row-int8") {
|
|
143
|
+
throw new FloorAssetLoadError("manifest-invalid", "floor manifest artifact lock is invalid");
|
|
144
|
+
}
|
|
145
|
+
if (!isRecord(value.files)) {
|
|
146
|
+
throw new FloorAssetLoadError("manifest-invalid", "floor manifest files are invalid");
|
|
147
|
+
}
|
|
148
|
+
const manifestFiles = value.files;
|
|
149
|
+
const requiredFiles = [BINARY_FILE, TOKENIZER_FILE, GOLDEN_FILE];
|
|
150
|
+
const fileNames = Object.keys(manifestFiles).sort();
|
|
151
|
+
if (fileNames.length !== requiredFiles.length || requiredFiles.some((file) => !fileNames.includes(file))) {
|
|
152
|
+
throw new FloorAssetLoadError(
|
|
153
|
+
"manifest-invalid",
|
|
154
|
+
"floor manifest must contain exactly the committed runtime payloads"
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
modelId: MODEL_ID,
|
|
159
|
+
revision: MODEL_REVISION,
|
|
160
|
+
artifact: {
|
|
161
|
+
magic: FLOOR_MAGIC,
|
|
162
|
+
version: FLOOR_FORMAT_VERSION,
|
|
163
|
+
vocabularySize: FLOOR_VOCABULARY_SIZE,
|
|
164
|
+
dimension: FLOOR_DIMENSION,
|
|
165
|
+
quantization: "symmetric-per-row-int8"
|
|
166
|
+
},
|
|
167
|
+
files: Object.fromEntries(
|
|
168
|
+
requiredFiles.map((file) => [file, manifestEntry(manifestFiles[file], file)])
|
|
169
|
+
)
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
function readManifest(assetsDir) {
|
|
173
|
+
const path = (0, import_node_path.join)(assetsDir, MANIFEST_FILE);
|
|
174
|
+
try {
|
|
175
|
+
const size = (0, import_node_fs.statSync)(path).size;
|
|
176
|
+
if (size <= 0 || size > MANIFEST_MAX_BYTES) {
|
|
177
|
+
throw new FloorAssetLoadError(
|
|
178
|
+
"manifest-invalid",
|
|
179
|
+
`floor manifest byte length ${size} is outside the accepted range`
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
return parseManifest(JSON.parse((0, import_node_fs.readFileSync)(path, "utf8")));
|
|
183
|
+
} catch (error) {
|
|
184
|
+
if (error instanceof FloorAssetLoadError) throw error;
|
|
185
|
+
throw new FloorAssetLoadError(
|
|
186
|
+
"manifest-invalid",
|
|
187
|
+
`could not read floor manifest: ${errorMessage(error)}`,
|
|
188
|
+
{ cause: error }
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
function expectedBinaryBytes(vocabularySize, dimension) {
|
|
193
|
+
const scalesBytes = vocabularySize * Float32Array.BYTES_PER_ELEMENT;
|
|
194
|
+
const weightsBytes = vocabularySize * dimension;
|
|
195
|
+
const total = FLOOR_HEADER_BYTES + scalesBytes + weightsBytes;
|
|
196
|
+
if (!Number.isSafeInteger(total)) {
|
|
197
|
+
throw new FloorAssetLoadError("binary-invalid", "floor binary length is not safe");
|
|
198
|
+
}
|
|
199
|
+
return total;
|
|
200
|
+
}
|
|
201
|
+
function assertExpectedFileSize(assetsDir, file, entry, maximumBytes) {
|
|
202
|
+
let actualBytes;
|
|
203
|
+
try {
|
|
204
|
+
actualBytes = (0, import_node_fs.statSync)((0, import_node_path.join)(assetsDir, file)).size;
|
|
205
|
+
} catch (error) {
|
|
206
|
+
throw new FloorAssetLoadError(
|
|
207
|
+
"asset-read-failed",
|
|
208
|
+
`could not stat floor asset ${file}: ${errorMessage(error)}`,
|
|
209
|
+
{ cause: error }
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
if (actualBytes !== entry.bytes || actualBytes <= 0 || actualBytes > maximumBytes) {
|
|
213
|
+
throw new FloorAssetLoadError(
|
|
214
|
+
"asset-size-mismatch",
|
|
215
|
+
`floor asset ${file} has ${actualBytes} bytes; manifest declares ${entry.bytes}`
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function readAndVerifyFile(assetsDir, file, entry) {
|
|
220
|
+
let bytes;
|
|
221
|
+
try {
|
|
222
|
+
bytes = (0, import_node_fs.readFileSync)((0, import_node_path.join)(assetsDir, file));
|
|
223
|
+
} catch (error) {
|
|
224
|
+
throw new FloorAssetLoadError(
|
|
225
|
+
"asset-read-failed",
|
|
226
|
+
`could not read floor asset ${file}: ${errorMessage(error)}`,
|
|
227
|
+
{ cause: error }
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
const actualDigest = (0, import_node_crypto.createHash)("sha256").update(bytes).digest("hex");
|
|
231
|
+
if (actualDigest !== entry.sha256) {
|
|
232
|
+
throw new FloorAssetLoadError(
|
|
233
|
+
"digest-mismatch",
|
|
234
|
+
`floor asset ${file} does not match its committed sha256`
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
return bytes;
|
|
238
|
+
}
|
|
239
|
+
function parseBinary(bytes) {
|
|
240
|
+
if (bytes.byteLength < FLOOR_HEADER_BYTES) {
|
|
241
|
+
throw new FloorAssetLoadError("binary-invalid", "floor binary is shorter than its header");
|
|
242
|
+
}
|
|
243
|
+
const magic = bytes.toString("ascii", 0, 4);
|
|
244
|
+
const version = bytes.readUInt32LE(4);
|
|
245
|
+
const vocabularySize = bytes.readUInt32LE(8);
|
|
246
|
+
const dimension = bytes.readUInt32LE(12);
|
|
247
|
+
if (magic !== FLOOR_MAGIC || version !== FLOOR_FORMAT_VERSION) {
|
|
248
|
+
throw new FloorAssetLoadError("binary-invalid", "floor binary magic or version is invalid");
|
|
249
|
+
}
|
|
250
|
+
if (vocabularySize !== FLOOR_VOCABULARY_SIZE || dimension !== FLOOR_DIMENSION) {
|
|
251
|
+
throw new FloorAssetLoadError("binary-invalid", "floor binary dimensions are invalid");
|
|
252
|
+
}
|
|
253
|
+
if (bytes.byteLength !== expectedBinaryBytes(vocabularySize, dimension)) {
|
|
254
|
+
throw new FloorAssetLoadError("binary-invalid", "floor binary length is invalid");
|
|
255
|
+
}
|
|
256
|
+
const scales = new Float32Array(vocabularySize);
|
|
257
|
+
for (let row = 0; row < vocabularySize; row += 1) {
|
|
258
|
+
const scale = bytes.readFloatLE(FLOOR_HEADER_BYTES + row * Float32Array.BYTES_PER_ELEMENT);
|
|
259
|
+
if (!Number.isFinite(scale) || scale <= 0) {
|
|
260
|
+
throw new FloorAssetLoadError("binary-invalid", `floor binary row ${row} has invalid scale`);
|
|
261
|
+
}
|
|
262
|
+
scales[row] = scale;
|
|
263
|
+
}
|
|
264
|
+
const weightsOffset = FLOOR_HEADER_BYTES + vocabularySize * Float32Array.BYTES_PER_ELEMENT;
|
|
265
|
+
const weights = new Int8Array(
|
|
266
|
+
bytes.buffer,
|
|
267
|
+
bytes.byteOffset + weightsOffset,
|
|
268
|
+
vocabularySize * dimension
|
|
269
|
+
);
|
|
270
|
+
return { vocabularySize, dimension, scales, weights };
|
|
271
|
+
}
|
|
272
|
+
function loadTokenizerRuntime() {
|
|
273
|
+
tokenizerRuntime ??= import("@huggingface/tokenizers").catch((error) => {
|
|
274
|
+
tokenizerRuntime = void 0;
|
|
275
|
+
throw new FloorAssetLoadError(
|
|
276
|
+
"tokenizer-runtime-unavailable",
|
|
277
|
+
`could not load the floor tokenizer runtime: ${errorMessage(error)}`,
|
|
278
|
+
{ cause: error }
|
|
279
|
+
);
|
|
280
|
+
});
|
|
281
|
+
return tokenizerRuntime;
|
|
282
|
+
}
|
|
283
|
+
async function parseTokenizer(bytes) {
|
|
284
|
+
const { Tokenizer } = await loadTokenizerRuntime();
|
|
285
|
+
try {
|
|
286
|
+
const tokenizerJson = JSON.parse(bytes.toString("utf8"));
|
|
287
|
+
if (!isRecord(tokenizerJson)) throw new TypeError("tokenizer.json must contain an object");
|
|
288
|
+
return new Tokenizer(tokenizerJson, {});
|
|
289
|
+
} catch (error) {
|
|
290
|
+
throw new FloorAssetLoadError(
|
|
291
|
+
"tokenizer-invalid",
|
|
292
|
+
`could not construct floor tokenizer: ${errorMessage(error)}`,
|
|
293
|
+
{ cause: error }
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
async function loadFloorAssetsFrom(assetsDir) {
|
|
298
|
+
const manifest = readManifest(assetsDir);
|
|
299
|
+
const binaryEntry = manifest.files[BINARY_FILE];
|
|
300
|
+
const tokenizerEntry = manifest.files[TOKENIZER_FILE];
|
|
301
|
+
const goldenEntry = manifest.files[GOLDEN_FILE];
|
|
302
|
+
const binaryExpectedBytes = expectedBinaryBytes(
|
|
303
|
+
manifest.artifact.vocabularySize,
|
|
304
|
+
manifest.artifact.dimension
|
|
305
|
+
);
|
|
306
|
+
assertExpectedFileSize(assetsDir, BINARY_FILE, binaryEntry, binaryExpectedBytes);
|
|
307
|
+
if (binaryEntry.bytes !== binaryExpectedBytes) {
|
|
308
|
+
throw new FloorAssetLoadError(
|
|
309
|
+
"asset-size-mismatch",
|
|
310
|
+
`floor binary manifest length must be ${binaryExpectedBytes}`
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
assertExpectedFileSize(assetsDir, TOKENIZER_FILE, tokenizerEntry, TOKENIZER_MAX_BYTES);
|
|
314
|
+
assertExpectedFileSize(assetsDir, GOLDEN_FILE, goldenEntry, GOLDEN_MAX_BYTES);
|
|
315
|
+
const binaryBytes = readAndVerifyFile(assetsDir, BINARY_FILE, binaryEntry);
|
|
316
|
+
const tokenizerBytes = readAndVerifyFile(assetsDir, TOKENIZER_FILE, tokenizerEntry);
|
|
317
|
+
readAndVerifyFile(assetsDir, GOLDEN_FILE, goldenEntry);
|
|
318
|
+
const binary = parseBinary(binaryBytes);
|
|
319
|
+
return { ...binary, tokenizer: await parseTokenizer(tokenizerBytes) };
|
|
320
|
+
}
|
|
321
|
+
function loadFloorAssets(options = {}) {
|
|
322
|
+
if (options.assetsDir !== void 0) return loadFloorAssetsFrom(options.assetsDir);
|
|
323
|
+
if (memoizedDefaultAssets !== void 0) return memoizedDefaultAssets;
|
|
324
|
+
const pending = (async () => loadFloorAssetsFrom((0, import_node_path.join)(packageRootFromImportMeta(), "assets", ASSET_DIRECTORY)))();
|
|
325
|
+
memoizedDefaultAssets = pending;
|
|
326
|
+
pending.catch(() => {
|
|
327
|
+
if (memoizedDefaultAssets === pending) memoizedDefaultAssets = void 0;
|
|
328
|
+
});
|
|
329
|
+
return pending;
|
|
330
|
+
}
|
|
331
|
+
function embed(assets, rendering, maxTokens) {
|
|
332
|
+
const encoded = assets.tokenizer.encode(rendering, { add_special_tokens: false }).ids;
|
|
333
|
+
const tokenIds = maxTokens === void 0 ? encoded : encoded.slice(0, maxTokens);
|
|
334
|
+
if (tokenIds.length === 0) {
|
|
335
|
+
throw new FloorEmbeddingError(
|
|
336
|
+
"empty-token-set",
|
|
337
|
+
"floor tokenizer produced no tokens for the rendering"
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
const means = new Float64Array(assets.dimension);
|
|
341
|
+
for (const tokenId of tokenIds) {
|
|
342
|
+
if (!Number.isSafeInteger(tokenId) || tokenId < 0 || tokenId >= assets.vocabularySize) {
|
|
343
|
+
throw new FloorEmbeddingError(
|
|
344
|
+
"token-id-out-of-range",
|
|
345
|
+
`floor tokenizer produced out-of-range token id ${tokenId}`
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
const rowOffset = tokenId * assets.dimension;
|
|
349
|
+
const scale = assets.scales[tokenId];
|
|
350
|
+
for (let column = 0; column < assets.dimension; column += 1) {
|
|
351
|
+
means[column] = means[column] + assets.weights[rowOffset + column] * scale;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
let squaredLength = 0;
|
|
355
|
+
for (let column = 0; column < assets.dimension; column += 1) {
|
|
356
|
+
const mean = means[column] / tokenIds.length;
|
|
357
|
+
means[column] = mean;
|
|
358
|
+
squaredLength += mean * mean;
|
|
359
|
+
}
|
|
360
|
+
const length = Math.sqrt(squaredLength);
|
|
361
|
+
if (!Number.isFinite(length) || length === 0) {
|
|
362
|
+
throw new FloorEmbeddingError("zero-vector", "floor embedder produced a zero-length vector");
|
|
363
|
+
}
|
|
364
|
+
return Float32Array.from(means, (value) => value / length);
|
|
365
|
+
}
|
|
366
|
+
function createFloorEmbedder(options = {}) {
|
|
367
|
+
const maxTokens = options.maxTokens;
|
|
368
|
+
if (maxTokens !== void 0 && (!Number.isSafeInteger(maxTokens) || maxTokens <= 0)) {
|
|
369
|
+
throw new RangeError("maxTokens must be a positive safe integer");
|
|
370
|
+
}
|
|
371
|
+
return {
|
|
372
|
+
async embedDocument(rendering) {
|
|
373
|
+
return embed(await loadFloorAssets(options), rendering, maxTokens);
|
|
374
|
+
},
|
|
375
|
+
async embedQuery(rendering) {
|
|
376
|
+
return embed(await loadFloorAssets(options), rendering, maxTokens);
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// src/embedder-native.ts
|
|
382
|
+
var import_node_path3 = require("node:path");
|
|
383
|
+
|
|
384
|
+
// src/model-cache-dir.ts
|
|
385
|
+
var import_node_os = require("node:os");
|
|
386
|
+
var import_node_path2 = require("node:path");
|
|
387
|
+
var MODEL_CACHE_DIR_ENV_VAR = "AGENT_QA_MODEL_CACHE_DIR";
|
|
388
|
+
function resolveModelCacheDir() {
|
|
389
|
+
const override = process.env[MODEL_CACHE_DIR_ENV_VAR];
|
|
390
|
+
if (override) return override;
|
|
391
|
+
const xdgCacheHome = process.env.XDG_CACHE_HOME;
|
|
392
|
+
if (xdgCacheHome) return (0, import_node_path2.join)(xdgCacheHome, "agent-qa", "models");
|
|
393
|
+
return (0, import_node_path2.join)((0, import_node_os.homedir)(), ".cache", "agent-qa", "models");
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// src/embedder-native.ts
|
|
397
|
+
var nativePipelines = /* @__PURE__ */ new Map();
|
|
398
|
+
var nativePipelineLoadTail = Promise.resolve();
|
|
399
|
+
var NativeEmbeddingModuleLoadError = class extends Error {
|
|
400
|
+
constructor(cause) {
|
|
401
|
+
super("Native embedding module could not be loaded", { cause });
|
|
402
|
+
this.name = "NativeEmbeddingModuleLoadError";
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
var NativeEmbeddingDimensionError = class extends RangeError {
|
|
406
|
+
actualDim;
|
|
407
|
+
expectedDim;
|
|
408
|
+
constructor(actualDim, expectedDim) {
|
|
409
|
+
super(`Native embedding dimension ${actualDim} does not match profile dimension ${expectedDim}`);
|
|
410
|
+
this.name = "NativeEmbeddingDimensionError";
|
|
411
|
+
this.actualDim = actualDim;
|
|
412
|
+
this.expectedDim = expectedDim;
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
function validateMaxTokens(maxTokens) {
|
|
416
|
+
if (maxTokens === void 0) return void 0;
|
|
417
|
+
if (!Number.isSafeInteger(maxTokens) || maxTokens <= 0) {
|
|
418
|
+
throw new RangeError("maxTokens must be a positive safe integer");
|
|
419
|
+
}
|
|
420
|
+
return maxTokens;
|
|
421
|
+
}
|
|
422
|
+
function pipelineKey(profile) {
|
|
423
|
+
return `${profile.model_id}@${profile.revision}:${profile.dtype}`;
|
|
424
|
+
}
|
|
425
|
+
function tokenBudgetLabel(maxTokens) {
|
|
426
|
+
return maxTokens === void 0 ? "uncapped" : String(maxTokens);
|
|
427
|
+
}
|
|
428
|
+
function pinnedModelDirectory(cacheDir, profile) {
|
|
429
|
+
const root = (0, import_node_path3.resolve)(cacheDir);
|
|
430
|
+
const directory = (0, import_node_path3.resolve)(root, profile.model_id, profile.revision);
|
|
431
|
+
if (directory === root || !directory.startsWith(`${root}${import_node_path3.sep}`)) {
|
|
432
|
+
throw new TypeError(`${profile.model_id} cannot be resolved safely inside the model cache`);
|
|
433
|
+
}
|
|
434
|
+
return directory;
|
|
435
|
+
}
|
|
436
|
+
function capTokenizer(extractor, maxTokens) {
|
|
437
|
+
const tokenizer = extractor.tokenizer;
|
|
438
|
+
const tokenizerConfig = tokenizer._tokenizerConfig;
|
|
439
|
+
const modelMaximum = Number(tokenizerConfig?.model_max_length);
|
|
440
|
+
tokenizer._tokenizerConfig = {
|
|
441
|
+
...tokenizerConfig ?? {},
|
|
442
|
+
model_max_length: Number.isSafeInteger(modelMaximum) && modelMaximum > 0 ? Math.min(modelMaximum, maxTokens) : maxTokens
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
async function withNativePipelineLoadLock(operation) {
|
|
446
|
+
const previous = nativePipelineLoadTail;
|
|
447
|
+
let release;
|
|
448
|
+
nativePipelineLoadTail = new Promise((resolvePending) => {
|
|
449
|
+
release = resolvePending;
|
|
450
|
+
});
|
|
451
|
+
await previous;
|
|
452
|
+
try {
|
|
453
|
+
return await operation();
|
|
454
|
+
} finally {
|
|
455
|
+
release();
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
async function loadPinnedPipeline(transformers, profile, allowDownload, maxTokens) {
|
|
459
|
+
return withNativePipelineLoadLock(async () => {
|
|
460
|
+
const cacheDir = resolveModelCacheDir();
|
|
461
|
+
transformers.env.cacheDir = cacheDir;
|
|
462
|
+
const sharedOptions = {
|
|
463
|
+
cache_dir: cacheDir,
|
|
464
|
+
local_files_only: !allowDownload,
|
|
465
|
+
revision: profile.revision
|
|
466
|
+
};
|
|
467
|
+
const modelSource = allowDownload ? profile.model_id : pinnedModelDirectory(cacheDir, profile);
|
|
468
|
+
const originalRemotePathTemplate = transformers.env.remotePathTemplate;
|
|
469
|
+
const originalAllowRemoteModels = transformers.env.allowRemoteModels;
|
|
470
|
+
if (allowDownload) {
|
|
471
|
+
transformers.env.remotePathTemplate = `{model}/resolve/${encodeURIComponent(profile.revision)}/`;
|
|
472
|
+
} else {
|
|
473
|
+
transformers.env.allowRemoteModels = false;
|
|
474
|
+
}
|
|
475
|
+
try {
|
|
476
|
+
const [tokenizerResult, modelResult] = await Promise.allSettled([
|
|
477
|
+
transformers.AutoTokenizer.from_pretrained(modelSource, sharedOptions),
|
|
478
|
+
transformers.AutoModel.from_pretrained(modelSource, {
|
|
479
|
+
...sharedOptions,
|
|
480
|
+
device: "cpu",
|
|
481
|
+
dtype: profile.dtype,
|
|
482
|
+
session_options: profile.session_options
|
|
483
|
+
})
|
|
484
|
+
]);
|
|
485
|
+
if (tokenizerResult.status === "rejected") {
|
|
486
|
+
if (modelResult.status === "rejected") {
|
|
487
|
+
throw modelResult.reason;
|
|
488
|
+
}
|
|
489
|
+
await modelResult.value.dispose().catch(() => void 0);
|
|
490
|
+
throw tokenizerResult.reason;
|
|
491
|
+
}
|
|
492
|
+
if (modelResult.status === "rejected") throw modelResult.reason;
|
|
493
|
+
const tokenizer = tokenizerResult.value;
|
|
494
|
+
const model = modelResult.value;
|
|
495
|
+
try {
|
|
496
|
+
const extractor = new transformers.FeatureExtractionPipeline({
|
|
497
|
+
task: "feature-extraction",
|
|
498
|
+
model,
|
|
499
|
+
tokenizer
|
|
500
|
+
});
|
|
501
|
+
if (maxTokens !== void 0) capTokenizer(extractor, maxTokens);
|
|
502
|
+
return extractor;
|
|
503
|
+
} catch (error) {
|
|
504
|
+
await model.dispose().catch(() => void 0);
|
|
505
|
+
throw error;
|
|
506
|
+
}
|
|
507
|
+
} finally {
|
|
508
|
+
transformers.env.remotePathTemplate = originalRemotePathTemplate;
|
|
509
|
+
transformers.env.allowRemoteModels = originalAllowRemoteModels;
|
|
510
|
+
}
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
function acquirePipeline(profile, allowDownload, maxTokens) {
|
|
514
|
+
const key = pipelineKey(profile);
|
|
515
|
+
const existing = nativePipelines.get(key);
|
|
516
|
+
if (existing) {
|
|
517
|
+
if (existing.maxTokens !== maxTokens) {
|
|
518
|
+
throw new RangeError(
|
|
519
|
+
`Native embedding pipeline budget conflict for ${key}: existing maxTokens=${tokenBudgetLabel(existing.maxTokens)}, requested maxTokens=${tokenBudgetLabel(maxTokens)}; one process-lifetime session per model identity permits only the first budget`
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
return existing.pipelinePromise;
|
|
523
|
+
}
|
|
524
|
+
const pending = (async () => {
|
|
525
|
+
let transformers;
|
|
526
|
+
try {
|
|
527
|
+
transformers = await import("@huggingface/transformers");
|
|
528
|
+
} catch (error) {
|
|
529
|
+
throw new NativeEmbeddingModuleLoadError(error);
|
|
530
|
+
}
|
|
531
|
+
return loadPinnedPipeline(transformers, profile, allowDownload, maxTokens);
|
|
532
|
+
})();
|
|
533
|
+
nativePipelines.set(key, { maxTokens, pipelinePromise: pending });
|
|
534
|
+
return pending;
|
|
535
|
+
}
|
|
536
|
+
function toEmbedding(data, expectedDim) {
|
|
537
|
+
const vector = data instanceof Float32Array ? data : Float32Array.from(data);
|
|
538
|
+
if (vector.length !== expectedDim) {
|
|
539
|
+
throw new NativeEmbeddingDimensionError(vector.length, expectedDim);
|
|
540
|
+
}
|
|
541
|
+
return vector;
|
|
542
|
+
}
|
|
543
|
+
async function createNativeEmbedder(options) {
|
|
544
|
+
const { profile, allowDownload } = options;
|
|
545
|
+
const maxTokens = validateMaxTokens(options.maxTokens);
|
|
546
|
+
const extractor = await acquirePipeline(profile, allowDownload, maxTokens);
|
|
547
|
+
async function embed2(text, prefix) {
|
|
548
|
+
const output = await extractor(`${prefix}${text}`, {
|
|
549
|
+
pooling: "mean",
|
|
550
|
+
normalize: true
|
|
551
|
+
});
|
|
552
|
+
return toEmbedding(output.data, profile.dim);
|
|
553
|
+
}
|
|
554
|
+
return {
|
|
555
|
+
embedDocument: (rendering) => embed2(rendering, profile.doc_prefix),
|
|
556
|
+
embedQuery: (rendering) => embed2(rendering, profile.query_prefix)
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// src/embedder-worker/worker-registration.ts
|
|
561
|
+
var import_node_crypto2 = require("node:crypto");
|
|
562
|
+
var import_node_fs2 = require("node:fs");
|
|
563
|
+
var import_node_http = require("node:http");
|
|
564
|
+
var import_node_net = require("node:net");
|
|
565
|
+
var import_node_os2 = require("node:os");
|
|
566
|
+
var import_node_path4 = require("node:path");
|
|
567
|
+
var import_zod = require("zod");
|
|
568
|
+
var EMBEDDER_WORKER_REGISTRATION_FILE = "embedder-worker.json";
|
|
569
|
+
var EMBEDDER_WORKER_REGISTRATION_SCHEMA_VERSION = 2;
|
|
570
|
+
var EMBEDDER_WORKER_UNVERIFIABLE_INCARNATION = "unresolved";
|
|
571
|
+
var EMBEDDER_WORKER_PROTOCOL_SCHEMA_VERSION = 2;
|
|
572
|
+
var EMBEDDER_WORKER_SOCKET_PATH_BUDGET_BYTES = 100;
|
|
573
|
+
var MAX_EMBEDDER_WORKER_BODY_BYTES = 4194304;
|
|
574
|
+
var EMBEDDER_WORKER_REQUEST_TIMEOUT_MS = 3e4;
|
|
575
|
+
var EmbedderWorkerTimeoutError = class extends Error {
|
|
576
|
+
phase;
|
|
577
|
+
timeoutMs;
|
|
578
|
+
constructor(phase, timeoutMs) {
|
|
579
|
+
super(`Embedder worker ${phase} timed out after ${timeoutMs} ms`);
|
|
580
|
+
this.name = "EmbedderWorkerTimeoutError";
|
|
581
|
+
this.phase = phase;
|
|
582
|
+
this.timeoutMs = timeoutMs;
|
|
583
|
+
}
|
|
584
|
+
};
|
|
585
|
+
var embeddingProfileSchema = import_zod.z.object({
|
|
586
|
+
model_id: import_zod.z.string().min(1),
|
|
587
|
+
revision: import_zod.z.string().min(1),
|
|
588
|
+
dim: import_zod.z.number().int().positive(),
|
|
589
|
+
dtype: import_zod.z.literal("q8"),
|
|
590
|
+
pooling: import_zod.z.literal("mean"),
|
|
591
|
+
normalize: import_zod.z.literal(true),
|
|
592
|
+
query_prefix: import_zod.z.string(),
|
|
593
|
+
doc_prefix: import_zod.z.string(),
|
|
594
|
+
backend: import_zod.z.enum(["node", "static"]),
|
|
595
|
+
session_options: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()),
|
|
596
|
+
tau_dense: import_zod.z.number().finite()
|
|
597
|
+
}).strict();
|
|
598
|
+
var embedderWorkerRegistrationSchema = import_zod.z.object({
|
|
599
|
+
schemaVersion: import_zod.z.literal(EMBEDDER_WORKER_REGISTRATION_SCHEMA_VERSION),
|
|
600
|
+
instanceId: import_zod.z.string().uuid(),
|
|
601
|
+
pid: import_zod.z.number().int().positive(),
|
|
602
|
+
socketPath: import_zod.z.string().min(1),
|
|
603
|
+
profile: embeddingProfileSchema,
|
|
604
|
+
startedAtMs: import_zod.z.number().int().nonnegative(),
|
|
605
|
+
/** The registering process's own OS-anchored start-time token, or the unverifiable sentinel. */
|
|
606
|
+
incarnation: import_zod.z.string().min(1)
|
|
607
|
+
}).strict();
|
|
608
|
+
var singleEmbeddingRequestSchema = import_zod.z.discriminatedUnion("method", [
|
|
609
|
+
import_zod.z.object({
|
|
610
|
+
schemaVersion: import_zod.z.literal(EMBEDDER_WORKER_PROTOCOL_SCHEMA_VERSION),
|
|
611
|
+
method: import_zod.z.literal("embedDocument"),
|
|
612
|
+
rendering: import_zod.z.string()
|
|
613
|
+
}).strict(),
|
|
614
|
+
import_zod.z.object({
|
|
615
|
+
schemaVersion: import_zod.z.literal(EMBEDDER_WORKER_PROTOCOL_SCHEMA_VERSION),
|
|
616
|
+
method: import_zod.z.literal("embedQuery"),
|
|
617
|
+
rendering: import_zod.z.string()
|
|
618
|
+
}).strict()
|
|
619
|
+
]);
|
|
620
|
+
var embedderWorkerRequestSchema = import_zod.z.discriminatedUnion("method", [
|
|
621
|
+
...singleEmbeddingRequestSchema.options,
|
|
622
|
+
import_zod.z.object({
|
|
623
|
+
schemaVersion: import_zod.z.literal(EMBEDDER_WORKER_PROTOCOL_SCHEMA_VERSION),
|
|
624
|
+
method: import_zod.z.literal("embedBatch"),
|
|
625
|
+
requests: import_zod.z.array(singleEmbeddingRequestSchema).min(1).max(256)
|
|
626
|
+
}).strict()
|
|
627
|
+
]);
|
|
628
|
+
var embedderWorkerResponseSchema = import_zod.z.object({
|
|
629
|
+
schemaVersion: import_zod.z.literal(EMBEDDER_WORKER_PROTOCOL_SCHEMA_VERSION),
|
|
630
|
+
vectors: import_zod.z.array(import_zod.z.array(import_zod.z.number().finite()))
|
|
631
|
+
}).strict();
|
|
632
|
+
function projectHash(projectRoot) {
|
|
633
|
+
return (0, import_node_crypto2.createHash)("sha256").update((0, import_node_fs2.realpathSync)(projectRoot)).digest("hex").slice(0, 12);
|
|
634
|
+
}
|
|
635
|
+
function embedderWorkerAgentQaRoot(projectRoot = process.cwd()) {
|
|
636
|
+
return (0, import_node_path4.join)((0, import_node_fs2.realpathSync)(projectRoot), ".agent-qa");
|
|
637
|
+
}
|
|
638
|
+
function embedderWorkerRegistrationPath(agentQaRoot) {
|
|
639
|
+
return (0, import_node_path4.join)(agentQaRoot, EMBEDDER_WORKER_REGISTRATION_FILE);
|
|
640
|
+
}
|
|
641
|
+
function instanceDiscriminator(instanceId) {
|
|
642
|
+
const validated = import_zod.z.string().uuid().parse(instanceId);
|
|
643
|
+
return (0, import_node_crypto2.createHash)("sha256").update(validated).digest("hex").slice(0, 12);
|
|
644
|
+
}
|
|
645
|
+
function embedderWorkerSocketPath(agentQaRoot, projectRoot, instanceId) {
|
|
646
|
+
const hash = projectHash(projectRoot);
|
|
647
|
+
const instance = instanceDiscriminator(instanceId);
|
|
648
|
+
if (process.platform === "win32") {
|
|
649
|
+
return `\\\\.\\pipe\\agent-qa-embedder-${hash}-${instance}`;
|
|
650
|
+
}
|
|
651
|
+
const canonicalAgentQaRoot = (0, import_node_path4.join)((0, import_node_fs2.realpathSync)((0, import_node_path4.dirname)(agentQaRoot)), (0, import_node_path4.basename)(agentQaRoot));
|
|
652
|
+
const socketFile = `embedder-worker-${instance}.sock`;
|
|
653
|
+
const projectLocal = (0, import_node_path4.join)(canonicalAgentQaRoot, socketFile);
|
|
654
|
+
if (Buffer.byteLength(projectLocal) <= EMBEDDER_WORKER_SOCKET_PATH_BUDGET_BYTES) {
|
|
655
|
+
return projectLocal;
|
|
656
|
+
}
|
|
657
|
+
const fallback = (0, import_node_path4.join)((0, import_node_os2.tmpdir)(), `agent-qa-${hash}`, `${instance}.sock`);
|
|
658
|
+
if (Buffer.byteLength(fallback) > EMBEDDER_WORKER_SOCKET_PATH_BUDGET_BYTES) {
|
|
659
|
+
throw new Error(
|
|
660
|
+
`OS temporary directory is too deep for an agent-qa embedder socket: ${fallback}`
|
|
661
|
+
);
|
|
662
|
+
}
|
|
663
|
+
return fallback;
|
|
664
|
+
}
|
|
665
|
+
function prepareEmbedderWorkerSocketParent(socketPath) {
|
|
666
|
+
if (process.platform === "win32" || socketPath.startsWith("\\\\.\\pipe\\")) return;
|
|
667
|
+
const parent = (0, import_node_path4.dirname)(socketPath);
|
|
668
|
+
(0, import_node_fs2.mkdirSync)(parent, { recursive: true, mode: 448 });
|
|
669
|
+
(0, import_node_fs2.chmodSync)(parent, 448);
|
|
670
|
+
}
|
|
671
|
+
function bestEffortFsyncDirectory(dir) {
|
|
672
|
+
let fd;
|
|
673
|
+
try {
|
|
674
|
+
fd = (0, import_node_fs2.openSync)(dir, "r");
|
|
675
|
+
(0, import_node_fs2.fsyncSync)(fd);
|
|
676
|
+
} catch (error) {
|
|
677
|
+
const code = error.code;
|
|
678
|
+
if (code !== "ENOENT" && code !== "EINVAL" && code !== "EISDIR" && code !== "EPERM" && code !== "ENOTSUP") {
|
|
679
|
+
throw error;
|
|
680
|
+
}
|
|
681
|
+
} finally {
|
|
682
|
+
if (fd !== void 0) (0, import_node_fs2.closeSync)(fd);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
function atomicRewrite(file, text) {
|
|
686
|
+
const parent = (0, import_node_path4.dirname)(file);
|
|
687
|
+
(0, import_node_fs2.mkdirSync)(parent, { recursive: true, mode: 448 });
|
|
688
|
+
(0, import_node_fs2.chmodSync)(parent, 448);
|
|
689
|
+
const temporary = `${file}.tmp-${(0, import_node_crypto2.randomUUID)()}`;
|
|
690
|
+
let fd;
|
|
691
|
+
try {
|
|
692
|
+
fd = (0, import_node_fs2.openSync)(temporary, "wx", 384);
|
|
693
|
+
(0, import_node_fs2.writeFileSync)(fd, text, "utf8");
|
|
694
|
+
(0, import_node_fs2.fsyncSync)(fd);
|
|
695
|
+
(0, import_node_fs2.closeSync)(fd);
|
|
696
|
+
fd = void 0;
|
|
697
|
+
(0, import_node_fs2.renameSync)(temporary, file);
|
|
698
|
+
bestEffortFsyncDirectory(parent);
|
|
699
|
+
} finally {
|
|
700
|
+
if (fd !== void 0) (0, import_node_fs2.closeSync)(fd);
|
|
701
|
+
(0, import_node_fs2.rmSync)(temporary, { force: true });
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
function writeEmbedderWorkerRegistration(agentQaRoot, registration) {
|
|
705
|
+
const validated = embedderWorkerRegistrationSchema.parse(registration);
|
|
706
|
+
atomicRewrite(
|
|
707
|
+
embedderWorkerRegistrationPath(agentQaRoot),
|
|
708
|
+
`${JSON.stringify(validated)}
|
|
709
|
+
`
|
|
710
|
+
);
|
|
711
|
+
}
|
|
712
|
+
function readEmbedderWorkerRegistrationFile(file) {
|
|
713
|
+
let raw;
|
|
714
|
+
try {
|
|
715
|
+
raw = (0, import_node_fs2.readFileSync)(file, "utf8");
|
|
716
|
+
} catch {
|
|
717
|
+
return (0, import_node_fs2.existsSync)(file) ? { kind: "malformed" } : { kind: "absent" };
|
|
718
|
+
}
|
|
719
|
+
try {
|
|
720
|
+
const parsedJson = JSON.parse(raw);
|
|
721
|
+
const parsed = embedderWorkerRegistrationSchema.safeParse(parsedJson);
|
|
722
|
+
return parsed.success ? { kind: "parsed", registration: parsed.data } : { kind: "malformed" };
|
|
723
|
+
} catch {
|
|
724
|
+
return { kind: "malformed" };
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
function readEmbedderWorkerRegistration(agentQaRoot) {
|
|
728
|
+
return readEmbedderWorkerRegistrationFile(embedderWorkerRegistrationPath(agentQaRoot));
|
|
729
|
+
}
|
|
730
|
+
function embedderWorkerProcessIsAlive(pid) {
|
|
731
|
+
try {
|
|
732
|
+
process.kill(pid, 0);
|
|
733
|
+
return true;
|
|
734
|
+
} catch (error) {
|
|
735
|
+
const code = error.code;
|
|
736
|
+
if (code === "ESRCH") return false;
|
|
737
|
+
if (code === "EPERM") return true;
|
|
738
|
+
throw error;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
function sameRegistration(left, right) {
|
|
742
|
+
return left.pid === right.pid && left.startedAtMs === right.startedAtMs && left.socketPath === right.socketPath && left.instanceId === right.instanceId && left.incarnation === right.incarnation;
|
|
743
|
+
}
|
|
744
|
+
function removeEmbedderWorkerRegistration(agentQaRoot, expected, options = {}) {
|
|
745
|
+
const file = embedderWorkerRegistrationPath(agentQaRoot);
|
|
746
|
+
const parent = (0, import_node_path4.dirname)(file);
|
|
747
|
+
const quarantine = `${file}.remove-${expected.instanceId}-${(0, import_node_crypto2.randomUUID)()}`;
|
|
748
|
+
const fsyncDirectory = options.fsyncDirectory ?? bestEffortFsyncDirectory;
|
|
749
|
+
try {
|
|
750
|
+
(0, import_node_fs2.renameSync)(file, quarantine);
|
|
751
|
+
} catch (error) {
|
|
752
|
+
if (error.code === "ENOENT") return false;
|
|
753
|
+
throw error;
|
|
754
|
+
}
|
|
755
|
+
fsyncDirectory(parent);
|
|
756
|
+
options.afterQuarantine?.(quarantine);
|
|
757
|
+
const outcome = readEmbedderWorkerRegistrationFile(quarantine);
|
|
758
|
+
const quarantinedRegistration = outcome.kind === "parsed" ? outcome.registration : void 0;
|
|
759
|
+
if (quarantinedRegistration !== void 0 && sameRegistration(quarantinedRegistration, expected)) {
|
|
760
|
+
(0, import_node_fs2.unlinkSync)(quarantine);
|
|
761
|
+
fsyncDirectory(parent);
|
|
762
|
+
return true;
|
|
763
|
+
}
|
|
764
|
+
try {
|
|
765
|
+
(0, import_node_fs2.linkSync)(quarantine, file);
|
|
766
|
+
fsyncDirectory(parent);
|
|
767
|
+
} catch (error) {
|
|
768
|
+
if (error.code !== "EEXIST") throw error;
|
|
769
|
+
}
|
|
770
|
+
(0, import_node_fs2.unlinkSync)(quarantine);
|
|
771
|
+
fsyncDirectory(parent);
|
|
772
|
+
return false;
|
|
773
|
+
}
|
|
774
|
+
function probeEmbedderWorkerSocket(socketPath) {
|
|
775
|
+
return new Promise((resolveProbe) => {
|
|
776
|
+
const socket = (0, import_node_net.connect)(socketPath);
|
|
777
|
+
socket.once("connect", () => {
|
|
778
|
+
socket.destroy();
|
|
779
|
+
resolveProbe(true);
|
|
780
|
+
});
|
|
781
|
+
socket.once("error", () => {
|
|
782
|
+
socket.destroy();
|
|
783
|
+
resolveProbe(false);
|
|
784
|
+
});
|
|
785
|
+
});
|
|
786
|
+
}
|
|
787
|
+
function requestWorker(socketPath, envelope, options) {
|
|
788
|
+
const body = JSON.stringify(embedderWorkerRequestSchema.parse(envelope));
|
|
789
|
+
return new Promise((resolveRequest, rejectRequest) => {
|
|
790
|
+
const requestTimeoutMs = options.requestTimeoutMs ?? EMBEDDER_WORKER_REQUEST_TIMEOUT_MS;
|
|
791
|
+
const abortController = new AbortController();
|
|
792
|
+
let responseStream;
|
|
793
|
+
let timeout;
|
|
794
|
+
let settled = false;
|
|
795
|
+
const settle = (outcome) => {
|
|
796
|
+
if (settled) return false;
|
|
797
|
+
settled = true;
|
|
798
|
+
if (timeout !== void 0) clearTimeout(timeout);
|
|
799
|
+
if (outcome.kind === "resolved") {
|
|
800
|
+
resolveRequest(outcome.response);
|
|
801
|
+
} else {
|
|
802
|
+
try {
|
|
803
|
+
options.onUnavailable?.(outcome.error);
|
|
804
|
+
} catch {
|
|
805
|
+
}
|
|
806
|
+
rejectRequest(outcome.error);
|
|
807
|
+
}
|
|
808
|
+
return true;
|
|
809
|
+
};
|
|
810
|
+
const workerRequest = (0, import_node_http.request)(
|
|
811
|
+
{
|
|
812
|
+
socketPath,
|
|
813
|
+
path: "/embed",
|
|
814
|
+
method: "POST",
|
|
815
|
+
signal: abortController.signal,
|
|
816
|
+
headers: {
|
|
817
|
+
"content-type": "application/json",
|
|
818
|
+
"content-length": Buffer.byteLength(body)
|
|
819
|
+
}
|
|
820
|
+
},
|
|
821
|
+
(response) => {
|
|
822
|
+
responseStream = response;
|
|
823
|
+
const chunks = [];
|
|
824
|
+
let bytes = 0;
|
|
825
|
+
response.once("aborted", () => {
|
|
826
|
+
settle({ kind: "rejected", error: new Error("Embedder worker response was aborted") });
|
|
827
|
+
});
|
|
828
|
+
response.once("error", (error) => {
|
|
829
|
+
settle({ kind: "rejected", error });
|
|
830
|
+
});
|
|
831
|
+
response.on("data", (chunk) => {
|
|
832
|
+
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
833
|
+
bytes += buffer.byteLength;
|
|
834
|
+
if (bytes <= MAX_EMBEDDER_WORKER_BODY_BYTES) chunks.push(buffer);
|
|
835
|
+
});
|
|
836
|
+
response.on("end", () => {
|
|
837
|
+
try {
|
|
838
|
+
if (bytes > MAX_EMBEDDER_WORKER_BODY_BYTES) {
|
|
839
|
+
throw new Error("Embedder worker response exceeded the body limit");
|
|
840
|
+
}
|
|
841
|
+
const parsedBody = JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
842
|
+
if (response.statusCode !== 200) {
|
|
843
|
+
const message = import_zod.z.object({ error: import_zod.z.string() }).passthrough().safeParse(parsedBody);
|
|
844
|
+
throw new Error(
|
|
845
|
+
message.success ? `Embedder worker rejected the request: ${message.data.error}` : `Embedder worker returned HTTP ${response.statusCode ?? 0}`
|
|
846
|
+
);
|
|
847
|
+
}
|
|
848
|
+
settle({
|
|
849
|
+
kind: "resolved",
|
|
850
|
+
response: embedderWorkerResponseSchema.parse(parsedBody)
|
|
851
|
+
});
|
|
852
|
+
} catch (error) {
|
|
853
|
+
settle({ kind: "rejected", error });
|
|
854
|
+
}
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
);
|
|
858
|
+
workerRequest.once("error", (error) => {
|
|
859
|
+
const refusal = abortController.signal.aborted ? abortController.signal.reason : error;
|
|
860
|
+
settle({ kind: "rejected", error: refusal });
|
|
861
|
+
});
|
|
862
|
+
timeout = setTimeout(() => {
|
|
863
|
+
const error = new EmbedderWorkerTimeoutError("request", requestTimeoutMs);
|
|
864
|
+
if (!settle({ kind: "rejected", error })) return;
|
|
865
|
+
abortController.abort(error);
|
|
866
|
+
responseStream?.destroy(error);
|
|
867
|
+
workerRequest.destroy(error);
|
|
868
|
+
}, requestTimeoutMs);
|
|
869
|
+
workerRequest.end(body);
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
function vectorFromResponse(response, expectedDimension) {
|
|
873
|
+
const [vector] = response.vectors;
|
|
874
|
+
if (vector === void 0 || response.vectors.length !== 1) {
|
|
875
|
+
throw new Error("Embedder worker returned an invalid single-vector response");
|
|
876
|
+
}
|
|
877
|
+
if (vector.length !== expectedDimension) {
|
|
878
|
+
throw new Error(
|
|
879
|
+
`Embedder worker returned dimension ${vector.length}; expected ${expectedDimension}`
|
|
880
|
+
);
|
|
881
|
+
}
|
|
882
|
+
return Float32Array.from(vector);
|
|
883
|
+
}
|
|
884
|
+
function createEmbedderWorkerPort(socketPath, expectedDimension, options = {}) {
|
|
885
|
+
return {
|
|
886
|
+
async embedDocument(rendering) {
|
|
887
|
+
return vectorFromResponse(
|
|
888
|
+
await requestWorker(socketPath, {
|
|
889
|
+
schemaVersion: EMBEDDER_WORKER_PROTOCOL_SCHEMA_VERSION,
|
|
890
|
+
method: "embedDocument",
|
|
891
|
+
rendering
|
|
892
|
+
}, options),
|
|
893
|
+
expectedDimension
|
|
894
|
+
);
|
|
895
|
+
},
|
|
896
|
+
async embedQuery(rendering) {
|
|
897
|
+
return vectorFromResponse(
|
|
898
|
+
await requestWorker(socketPath, {
|
|
899
|
+
schemaVersion: EMBEDDER_WORKER_PROTOCOL_SCHEMA_VERSION,
|
|
900
|
+
method: "embedQuery",
|
|
901
|
+
rendering
|
|
902
|
+
}, options),
|
|
903
|
+
expectedDimension
|
|
904
|
+
);
|
|
905
|
+
}
|
|
906
|
+
};
|
|
907
|
+
}
|
|
908
|
+
function asEmbeddingProfile(profile) {
|
|
909
|
+
return profile;
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
// src/index-open.ts
|
|
913
|
+
var import_node_sqlite = require("node:sqlite");
|
|
914
|
+
var import_agent_qa_schema = require("@vostride/agent-qa-schema");
|
|
915
|
+
|
|
916
|
+
// src/sqlite-vec-loadable.ts
|
|
917
|
+
var import_sqlite_vec = require("sqlite-vec");
|
|
918
|
+
|
|
919
|
+
// src/index-open.ts
|
|
920
|
+
function embeddingProfileKey(profile) {
|
|
921
|
+
return (0, import_agent_qa_schema.canonicalJson)({
|
|
922
|
+
model_id: profile.model_id,
|
|
923
|
+
revision: profile.revision,
|
|
924
|
+
dtype: profile.dtype,
|
|
925
|
+
dim: profile.dim
|
|
926
|
+
});
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
// src/embedder-acquire.ts
|
|
930
|
+
var processCapabilities = /* @__PURE__ */ new Map();
|
|
931
|
+
var injectedCapabilities = /* @__PURE__ */ new WeakMap();
|
|
932
|
+
var injectedCapabilityCaches = /* @__PURE__ */ new Set();
|
|
933
|
+
function resetEmbedderCapability(profile) {
|
|
934
|
+
if (profile === void 0) {
|
|
935
|
+
processCapabilities.clear();
|
|
936
|
+
for (const capabilities of injectedCapabilityCaches) capabilities.clear();
|
|
937
|
+
injectedCapabilityCaches.clear();
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
const prefix = capabilityProfilePrefix(profile);
|
|
941
|
+
for (const key of processCapabilities.keys()) {
|
|
942
|
+
if (key.startsWith(prefix)) processCapabilities.delete(key);
|
|
943
|
+
}
|
|
944
|
+
for (const capabilities of injectedCapabilityCaches) {
|
|
945
|
+
for (const key of capabilities.keys()) {
|
|
946
|
+
if (key.startsWith(prefix)) capabilities.delete(key);
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
function isWorkerBackedDiscovery(result) {
|
|
951
|
+
if (result.kind !== "worker") return false;
|
|
952
|
+
const candidate = result;
|
|
953
|
+
return candidate.profile !== void 0 && candidate.embedder !== void 0;
|
|
954
|
+
}
|
|
955
|
+
async function discoverEmbedderWorker(agentQaRoot, options = {}) {
|
|
956
|
+
const projectRoot = (0, import_node_path5.dirname)(agentQaRoot);
|
|
957
|
+
const outcome = readEmbedderWorkerRegistration(agentQaRoot);
|
|
958
|
+
if (outcome.kind !== "parsed") return { kind: "no-worker" };
|
|
959
|
+
const { registration } = outcome;
|
|
960
|
+
let expectedSocketPath;
|
|
961
|
+
try {
|
|
962
|
+
expectedSocketPath = embedderWorkerSocketPath(
|
|
963
|
+
agentQaRoot,
|
|
964
|
+
projectRoot,
|
|
965
|
+
registration.instanceId
|
|
966
|
+
);
|
|
967
|
+
} catch {
|
|
968
|
+
return { kind: "no-worker" };
|
|
969
|
+
}
|
|
970
|
+
if (registration.socketPath !== expectedSocketPath) return { kind: "no-worker" };
|
|
971
|
+
let pidIsLive;
|
|
972
|
+
try {
|
|
973
|
+
pidIsLive = embedderWorkerProcessIsAlive(registration.pid);
|
|
974
|
+
} catch {
|
|
975
|
+
return { kind: "no-worker" };
|
|
976
|
+
}
|
|
977
|
+
if (!pidIsLive) {
|
|
978
|
+
removeEmbedderWorkerRegistration(agentQaRoot, registration);
|
|
979
|
+
return { kind: "no-worker" };
|
|
980
|
+
}
|
|
981
|
+
if (!await probeEmbedderWorkerSocket(registration.socketPath)) {
|
|
982
|
+
removeEmbedderWorkerRegistration(agentQaRoot, registration);
|
|
983
|
+
return { kind: "no-worker" };
|
|
984
|
+
}
|
|
985
|
+
return {
|
|
986
|
+
kind: "worker",
|
|
987
|
+
profile: asEmbeddingProfile(registration.profile),
|
|
988
|
+
embedder: createEmbedderWorkerPort(
|
|
989
|
+
registration.socketPath,
|
|
990
|
+
registration.profile.dim,
|
|
991
|
+
{
|
|
992
|
+
...options.requestTimeoutMs === void 0 ? {} : { requestTimeoutMs: options.requestTimeoutMs },
|
|
993
|
+
onUnavailable: () => {
|
|
994
|
+
removeEmbedderWorkerRegistration(agentQaRoot, registration);
|
|
995
|
+
resetEmbedderCapability(asEmbeddingProfile(registration.profile));
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
)
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
1001
|
+
function errorRecord(error) {
|
|
1002
|
+
return typeof error === "object" && error !== null ? error : void 0;
|
|
1003
|
+
}
|
|
1004
|
+
function errorText(error) {
|
|
1005
|
+
return error instanceof Error ? error.message : String(error);
|
|
1006
|
+
}
|
|
1007
|
+
function isNativeModuleUnavailable(error) {
|
|
1008
|
+
if (error instanceof NativeEmbeddingModuleLoadError) return true;
|
|
1009
|
+
const code = errorRecord(error)?.code;
|
|
1010
|
+
if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND" || code === "ERR_DLOPEN_FAILED") {
|
|
1011
|
+
return true;
|
|
1012
|
+
}
|
|
1013
|
+
const message = errorText(error).toLowerCase();
|
|
1014
|
+
return message.includes("cannot find package") || message.includes("cannot find module") || message.includes("could not locate the bindings file");
|
|
1015
|
+
}
|
|
1016
|
+
function isColdArtifact(error, allowDownload) {
|
|
1017
|
+
if (allowDownload) return false;
|
|
1018
|
+
const code = errorRecord(error)?.code;
|
|
1019
|
+
if (code === "ENOENT") return true;
|
|
1020
|
+
const message = errorText(error).toLowerCase();
|
|
1021
|
+
return message.includes("local_files_only") || message.includes("not found locally") || message.includes("not present in the local cache") || message.includes("not found in the local cache") || message.includes("could not locate file");
|
|
1022
|
+
}
|
|
1023
|
+
function cacheFor(probes) {
|
|
1024
|
+
if (probes === void 0) return processCapabilities;
|
|
1025
|
+
const existing = injectedCapabilities.get(probes);
|
|
1026
|
+
if (existing !== void 0) {
|
|
1027
|
+
injectedCapabilityCaches.add(existing);
|
|
1028
|
+
return existing;
|
|
1029
|
+
}
|
|
1030
|
+
const created = /* @__PURE__ */ new Map();
|
|
1031
|
+
injectedCapabilities.set(probes, created);
|
|
1032
|
+
injectedCapabilityCaches.add(created);
|
|
1033
|
+
return created;
|
|
1034
|
+
}
|
|
1035
|
+
function capabilityCacheKey(profile, workerPolicy, agentQaRoot) {
|
|
1036
|
+
const profileKey = embeddingProfileKey(profile);
|
|
1037
|
+
return `${profileKey.length}:${profileKey}:${workerPolicy}:${agentQaRoot}`;
|
|
1038
|
+
}
|
|
1039
|
+
function capabilityProfilePrefix(profile) {
|
|
1040
|
+
const profileKey = embeddingProfileKey(profile);
|
|
1041
|
+
return `${profileKey.length}:${profileKey}:`;
|
|
1042
|
+
}
|
|
1043
|
+
async function probeFloor(factory) {
|
|
1044
|
+
try {
|
|
1045
|
+
const embedder = await factory();
|
|
1046
|
+
return {
|
|
1047
|
+
kind: "ready",
|
|
1048
|
+
rung: "floor",
|
|
1049
|
+
profile: import_agent_qa_schema2.STATIC_FLOOR_EMBEDDING_PROFILE,
|
|
1050
|
+
embedder
|
|
1051
|
+
};
|
|
1052
|
+
} catch {
|
|
1053
|
+
return { kind: "lexical-only" };
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
async function probeCapability({
|
|
1057
|
+
preferredProfile,
|
|
1058
|
+
allowDownload,
|
|
1059
|
+
workerPolicy,
|
|
1060
|
+
agentQaRoot,
|
|
1061
|
+
probes
|
|
1062
|
+
}) {
|
|
1063
|
+
const discoverWorker = probes?.discoverWorker ?? discoverEmbedderWorker;
|
|
1064
|
+
const nativeFactory = probes?.createNativeEmbedder ?? createNativeEmbedder;
|
|
1065
|
+
const floorFactory = probes?.createFloorEmbedder ?? (async () => {
|
|
1066
|
+
await loadFloorAssets();
|
|
1067
|
+
return createFloorEmbedder();
|
|
1068
|
+
});
|
|
1069
|
+
try {
|
|
1070
|
+
const worker = await discoverWorker(agentQaRoot);
|
|
1071
|
+
if (isWorkerBackedDiscovery(worker) && embeddingProfileKey(worker.profile) === embeddingProfileKey(preferredProfile)) {
|
|
1072
|
+
return {
|
|
1073
|
+
kind: "ready",
|
|
1074
|
+
rung: worker.profile.backend === "static" ? "floor" : "native",
|
|
1075
|
+
profile: worker.profile,
|
|
1076
|
+
embedder: worker.embedder
|
|
1077
|
+
};
|
|
1078
|
+
}
|
|
1079
|
+
if (workerPolicy === "required") {
|
|
1080
|
+
return { kind: "deferred", reason: "worker-unavailable" };
|
|
1081
|
+
}
|
|
1082
|
+
} catch {
|
|
1083
|
+
return {
|
|
1084
|
+
kind: "deferred",
|
|
1085
|
+
reason: workerPolicy === "required" ? "worker-unavailable" : "load-failure"
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1088
|
+
if (preferredProfile.backend === "static") return probeFloor(floorFactory);
|
|
1089
|
+
try {
|
|
1090
|
+
const embedder = await nativeFactory({ profile: preferredProfile, allowDownload });
|
|
1091
|
+
return { kind: "ready", rung: "native", profile: preferredProfile, embedder };
|
|
1092
|
+
} catch (error) {
|
|
1093
|
+
if (isNativeModuleUnavailable(error)) return probeFloor(floorFactory);
|
|
1094
|
+
if (isColdArtifact(error, allowDownload)) {
|
|
1095
|
+
return { kind: "deferred", reason: "cold-artifact" };
|
|
1096
|
+
}
|
|
1097
|
+
return { kind: "deferred", reason: "load-failure" };
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
function resolveEmbedderCapability(options) {
|
|
1101
|
+
const preferredProfile = options.preferredProfile ?? import_agent_qa_schema2.DEFAULT_EMBEDDING_PROFILE;
|
|
1102
|
+
const workerPolicy = options.workerPolicy ?? "preferred";
|
|
1103
|
+
if (workerPolicy === "required" && options.agentQaRoot === void 0) {
|
|
1104
|
+
throw new TypeError("workerPolicy required needs an explicit agentQaRoot");
|
|
1105
|
+
}
|
|
1106
|
+
const agentQaRoot = options.agentQaRoot ?? embedderWorkerAgentQaRoot(process.cwd());
|
|
1107
|
+
const capabilities = cacheFor(options.probes);
|
|
1108
|
+
const key = capabilityCacheKey(preferredProfile, workerPolicy, agentQaRoot);
|
|
1109
|
+
const existing = capabilities.get(key);
|
|
1110
|
+
if (existing !== void 0) return existing;
|
|
1111
|
+
const pending = probeCapability({
|
|
1112
|
+
preferredProfile,
|
|
1113
|
+
allowDownload: options.allowDownload,
|
|
1114
|
+
workerPolicy,
|
|
1115
|
+
agentQaRoot,
|
|
1116
|
+
probes: options.probes
|
|
1117
|
+
});
|
|
1118
|
+
capabilities.set(key, pending);
|
|
1119
|
+
return pending;
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
// src/lease/writer-lease.ts
|
|
1123
|
+
var import_node_child_process = require("node:child_process");
|
|
1124
|
+
var import_node_fs3 = require("node:fs");
|
|
1125
|
+
var import_node_path6 = require("node:path");
|
|
1126
|
+
var import_node_sqlite2 = require("node:sqlite");
|
|
1127
|
+
var import_zod2 = require("zod");
|
|
1128
|
+
var PROCESS_INCARNATION_PS_PATH = "/bin/ps";
|
|
1129
|
+
var PROCESS_INCARNATION_PS_ENV = Object.freeze({ LC_ALL: "C", LANG: "C", TZ: "UTC0" });
|
|
1130
|
+
var MUTATION_LOCK_TERMINATION_WAIT = new Int32Array(
|
|
1131
|
+
new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT)
|
|
1132
|
+
);
|
|
1133
|
+
var LEASE_GUARD_DIR = "memory/queue/lease-guard";
|
|
1134
|
+
var LEASE_GUARD_STALE_MS = 1e4;
|
|
1135
|
+
var LEASE_GUARD_WAIT_MS = LEASE_GUARD_STALE_MS + 2e3;
|
|
1136
|
+
var LEASE_GUARD_STAGING_STALE_MS = LEASE_GUARD_WAIT_MS + LEASE_GUARD_STALE_MS;
|
|
1137
|
+
var LEASE_GUARD_STAGING_PREFIX = `${(0, import_node_path6.basename)(LEASE_GUARD_DIR)}.tmp-`;
|
|
1138
|
+
var LEASE_GUARD_RESIDUE_PREFIX = `${(0, import_node_path6.basename)(LEASE_GUARD_DIR)}.residue-`;
|
|
1139
|
+
var writerLeaseSchema = import_zod2.z.object({
|
|
1140
|
+
leaseId: import_zod2.z.string().uuid(),
|
|
1141
|
+
pid: import_zod2.z.number().int().positive(),
|
|
1142
|
+
epoch: import_zod2.z.number().int().positive(),
|
|
1143
|
+
heartbeatAtMs: import_zod2.z.number().int().nonnegative()
|
|
1144
|
+
}).strict();
|
|
1145
|
+
function resolveProcessIncarnation(pid, timeoutMs, psExecutable) {
|
|
1146
|
+
if (!Number.isSafeInteger(pid) || pid <= 0) return void 0;
|
|
1147
|
+
try {
|
|
1148
|
+
if (process.platform === "win32") return void 0;
|
|
1149
|
+
return process.platform === "linux" ? resolveLinuxProcessIncarnation(pid) : resolvePosixProcessIncarnation(pid, timeoutMs, psExecutable);
|
|
1150
|
+
} catch {
|
|
1151
|
+
return void 0;
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
function resolveLinuxProcessIncarnation(pid) {
|
|
1155
|
+
let raw;
|
|
1156
|
+
try {
|
|
1157
|
+
raw = (0, import_node_fs3.readFileSync)(`/proc/${pid}/stat`, "utf8");
|
|
1158
|
+
} catch {
|
|
1159
|
+
return void 0;
|
|
1160
|
+
}
|
|
1161
|
+
const commEnd = raw.lastIndexOf(")");
|
|
1162
|
+
if (commEnd < 0) return void 0;
|
|
1163
|
+
const startTime = raw.slice(commEnd + 1).trim().split(/\s+/)[19];
|
|
1164
|
+
return startTime !== void 0 && /^\d+$/.test(startTime) ? `proc-starttime:${startTime}` : void 0;
|
|
1165
|
+
}
|
|
1166
|
+
function resolvePosixProcessIncarnation(pid, timeoutMs, psExecutable = PROCESS_INCARNATION_PS_PATH) {
|
|
1167
|
+
const observed = (0, import_node_child_process.spawnSync)(psExecutable, ["-p", String(pid), "-o", "lstart="], {
|
|
1168
|
+
encoding: "utf8",
|
|
1169
|
+
env: PROCESS_INCARNATION_PS_ENV,
|
|
1170
|
+
windowsHide: true,
|
|
1171
|
+
// `spawnSync` reads 0 as "no timeout", so an exhausted budget must never arrive here as 0.
|
|
1172
|
+
...timeoutMs === void 0 ? {} : { timeout: Math.max(1, Math.ceil(timeoutMs)) }
|
|
1173
|
+
});
|
|
1174
|
+
if (observed.error !== void 0 || observed.status !== 0) return void 0;
|
|
1175
|
+
const lstart = (observed.stdout ?? "").trim();
|
|
1176
|
+
return lstart === "" ? void 0 : `ps-lstart-utc:${lstart}`;
|
|
1177
|
+
}
|
|
1178
|
+
var leaseGuardOwnerSchema = import_zod2.z.object({
|
|
1179
|
+
pid: import_zod2.z.number().int().positive(),
|
|
1180
|
+
threadId: import_zod2.z.number().int().nonnegative(),
|
|
1181
|
+
token: import_zod2.z.string().uuid(),
|
|
1182
|
+
claimedAtNs: import_zod2.z.string().regex(/^[0-9]+$/)
|
|
1183
|
+
}).strict();
|
|
1184
|
+
|
|
1185
|
+
// src/embedder-worker/worker-incarnation.ts
|
|
1186
|
+
function ownEmbedderWorkerIncarnation() {
|
|
1187
|
+
return resolveProcessIncarnation(process.pid) ?? EMBEDDER_WORKER_UNVERIFIABLE_INCARNATION;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
// src/embedder-worker/worker-entry.ts
|
|
1191
|
+
var EmbedderWorkerRequestError = class extends Error {
|
|
1192
|
+
constructor(message) {
|
|
1193
|
+
super(message);
|
|
1194
|
+
this.name = "EmbedderWorkerRequestError";
|
|
1195
|
+
}
|
|
1196
|
+
};
|
|
1197
|
+
async function readRequestBody(request2) {
|
|
1198
|
+
const chunks = [];
|
|
1199
|
+
let bytes = 0;
|
|
1200
|
+
for await (const chunk of request2) {
|
|
1201
|
+
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
1202
|
+
bytes += buffer.byteLength;
|
|
1203
|
+
if (bytes > MAX_EMBEDDER_WORKER_BODY_BYTES) {
|
|
1204
|
+
throw new EmbedderWorkerRequestError(
|
|
1205
|
+
`Embedder request exceeds ${MAX_EMBEDDER_WORKER_BODY_BYTES} bytes`
|
|
1206
|
+
);
|
|
1207
|
+
}
|
|
1208
|
+
chunks.push(buffer);
|
|
1209
|
+
}
|
|
1210
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
1211
|
+
}
|
|
1212
|
+
async function parseRequest(request2) {
|
|
1213
|
+
let parsedJson;
|
|
1214
|
+
try {
|
|
1215
|
+
parsedJson = JSON.parse(await readRequestBody(request2));
|
|
1216
|
+
} catch (error) {
|
|
1217
|
+
if (error instanceof EmbedderWorkerRequestError) throw error;
|
|
1218
|
+
throw new EmbedderWorkerRequestError(
|
|
1219
|
+
`Embedder request body must be valid JSON: ${error instanceof Error ? error.message : String(error)}`
|
|
1220
|
+
);
|
|
1221
|
+
}
|
|
1222
|
+
const parsed = embedderWorkerRequestSchema.safeParse(parsedJson);
|
|
1223
|
+
if (!parsed.success) {
|
|
1224
|
+
throw new EmbedderWorkerRequestError(
|
|
1225
|
+
parsed.error.issues.map((issue) => `${issue.path.map(String).join(".") || "<root>"}: ${issue.message}`).join("; ")
|
|
1226
|
+
);
|
|
1227
|
+
}
|
|
1228
|
+
return parsed.data;
|
|
1229
|
+
}
|
|
1230
|
+
function json(response, statusCode, body) {
|
|
1231
|
+
const payload = JSON.stringify(body);
|
|
1232
|
+
response.writeHead(statusCode, {
|
|
1233
|
+
"content-type": "application/json",
|
|
1234
|
+
"content-length": Buffer.byteLength(payload)
|
|
1235
|
+
});
|
|
1236
|
+
response.end(payload);
|
|
1237
|
+
}
|
|
1238
|
+
async function embedOne(embedder, request2) {
|
|
1239
|
+
return request2.method === "embedDocument" ? embedder.embedDocument(request2.rendering) : embedder.embedQuery(request2.rendering);
|
|
1240
|
+
}
|
|
1241
|
+
async function serveEmbeddingRequest(embedder, request2) {
|
|
1242
|
+
if (request2.method === "embedBatch") {
|
|
1243
|
+
return Promise.all(request2.requests.map((item) => embedOne(embedder, item)));
|
|
1244
|
+
}
|
|
1245
|
+
return [await embedOne(embedder, request2)];
|
|
1246
|
+
}
|
|
1247
|
+
function createEmbedderServer(embedder) {
|
|
1248
|
+
return (0, import_node_http2.createServer)((request2, response) => {
|
|
1249
|
+
void (async () => {
|
|
1250
|
+
if (request2.method !== "POST" || request2.url !== "/embed") {
|
|
1251
|
+
json(response, 404, { error: "not-found" });
|
|
1252
|
+
return;
|
|
1253
|
+
}
|
|
1254
|
+
try {
|
|
1255
|
+
const envelope = await parseRequest(request2);
|
|
1256
|
+
const vectors = await serveEmbeddingRequest(embedder, envelope);
|
|
1257
|
+
json(response, 200, {
|
|
1258
|
+
schemaVersion: EMBEDDER_WORKER_PROTOCOL_SCHEMA_VERSION,
|
|
1259
|
+
vectors: vectors.map((vector) => Array.from(vector))
|
|
1260
|
+
});
|
|
1261
|
+
} catch (error) {
|
|
1262
|
+
const statusCode = error instanceof EmbedderWorkerRequestError ? 400 : 500;
|
|
1263
|
+
json(response, statusCode, {
|
|
1264
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1265
|
+
});
|
|
1266
|
+
}
|
|
1267
|
+
})();
|
|
1268
|
+
});
|
|
1269
|
+
}
|
|
1270
|
+
function listen(server, socketPath) {
|
|
1271
|
+
return new Promise((resolveListen, rejectListen) => {
|
|
1272
|
+
const onError = (error) => {
|
|
1273
|
+
server.off("listening", onListening);
|
|
1274
|
+
rejectListen(error);
|
|
1275
|
+
};
|
|
1276
|
+
const onListening = () => {
|
|
1277
|
+
server.off("error", onError);
|
|
1278
|
+
resolveListen();
|
|
1279
|
+
};
|
|
1280
|
+
server.once("error", onError);
|
|
1281
|
+
server.once("listening", onListening);
|
|
1282
|
+
server.listen(socketPath);
|
|
1283
|
+
});
|
|
1284
|
+
}
|
|
1285
|
+
function probeSocket(socketPath) {
|
|
1286
|
+
return new Promise((resolveProbe) => {
|
|
1287
|
+
const socket = (0, import_node_net2.connect)(socketPath);
|
|
1288
|
+
socket.once("connect", () => {
|
|
1289
|
+
socket.destroy();
|
|
1290
|
+
resolveProbe(true);
|
|
1291
|
+
});
|
|
1292
|
+
socket.once("error", () => {
|
|
1293
|
+
socket.destroy();
|
|
1294
|
+
resolveProbe(false);
|
|
1295
|
+
});
|
|
1296
|
+
});
|
|
1297
|
+
}
|
|
1298
|
+
async function listenWithStaleRecovery(server, socketPath) {
|
|
1299
|
+
try {
|
|
1300
|
+
await listen(server, socketPath);
|
|
1301
|
+
} catch (error) {
|
|
1302
|
+
const code = error.code;
|
|
1303
|
+
if (code !== "EADDRINUSE" && code !== "EINVAL" || process.platform === "win32") {
|
|
1304
|
+
throw error;
|
|
1305
|
+
}
|
|
1306
|
+
if (await probeSocket(socketPath)) {
|
|
1307
|
+
throw new Error(`Embedder worker socket is already live: ${socketPath}`);
|
|
1308
|
+
}
|
|
1309
|
+
(0, import_node_fs4.rmSync)(socketPath);
|
|
1310
|
+
await listen(server, socketPath);
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
function closeServer(server) {
|
|
1314
|
+
return new Promise((resolveClose, rejectClose) => {
|
|
1315
|
+
server.close((error) => {
|
|
1316
|
+
if (error !== void 0) rejectClose(error);
|
|
1317
|
+
else resolveClose();
|
|
1318
|
+
});
|
|
1319
|
+
});
|
|
1320
|
+
}
|
|
1321
|
+
async function acquireProcessLocalEmbedder(profile) {
|
|
1322
|
+
const outcome = await resolveEmbedderCapability({
|
|
1323
|
+
preferredProfile: profile,
|
|
1324
|
+
allowDownload: false,
|
|
1325
|
+
probes: {
|
|
1326
|
+
discoverWorker: () => Promise.resolve({ kind: "no-worker" })
|
|
1327
|
+
}
|
|
1328
|
+
});
|
|
1329
|
+
if (outcome.kind !== "ready") {
|
|
1330
|
+
throw new Error(`Embedder worker could not resolve profile: ${outcome.kind}`);
|
|
1331
|
+
}
|
|
1332
|
+
return outcome.embedder;
|
|
1333
|
+
}
|
|
1334
|
+
async function runEmbedderWorker(options) {
|
|
1335
|
+
const projectRoot = (0, import_node_path7.resolve)(options.projectRoot);
|
|
1336
|
+
const agentQaRoot = embedderWorkerAgentQaRoot(projectRoot);
|
|
1337
|
+
const instanceId = options.instanceId ?? (0, import_node_crypto3.randomUUID)();
|
|
1338
|
+
const socketPath = embedderWorkerSocketPath(agentQaRoot, projectRoot, instanceId);
|
|
1339
|
+
const embedder = await acquireProcessLocalEmbedder(options.profile);
|
|
1340
|
+
const server = createEmbedderServer(embedder);
|
|
1341
|
+
prepareEmbedderWorkerSocketParent(socketPath);
|
|
1342
|
+
await listenWithStaleRecovery(server, socketPath);
|
|
1343
|
+
const registration = {
|
|
1344
|
+
schemaVersion: EMBEDDER_WORKER_REGISTRATION_SCHEMA_VERSION,
|
|
1345
|
+
instanceId,
|
|
1346
|
+
pid: process.pid,
|
|
1347
|
+
socketPath,
|
|
1348
|
+
profile: options.profile,
|
|
1349
|
+
startedAtMs: Date.now(),
|
|
1350
|
+
incarnation: ownEmbedderWorkerIncarnation()
|
|
1351
|
+
};
|
|
1352
|
+
try {
|
|
1353
|
+
if (process.platform !== "win32") (0, import_node_fs4.chmodSync)(socketPath, 384);
|
|
1354
|
+
writeEmbedderWorkerRegistration(agentQaRoot, registration);
|
|
1355
|
+
} catch (error) {
|
|
1356
|
+
await closeServer(server).catch(() => void 0);
|
|
1357
|
+
removeEmbedderWorkerRegistration(agentQaRoot, registration);
|
|
1358
|
+
if (process.platform !== "win32") (0, import_node_fs4.rmSync)(socketPath, { force: true });
|
|
1359
|
+
throw error;
|
|
1360
|
+
}
|
|
1361
|
+
let closePromise;
|
|
1362
|
+
return {
|
|
1363
|
+
registration,
|
|
1364
|
+
close() {
|
|
1365
|
+
closePromise ??= (async () => {
|
|
1366
|
+
try {
|
|
1367
|
+
await closeServer(server);
|
|
1368
|
+
} finally {
|
|
1369
|
+
try {
|
|
1370
|
+
removeEmbedderWorkerRegistration(agentQaRoot, registration);
|
|
1371
|
+
} finally {
|
|
1372
|
+
if (process.platform !== "win32") (0, import_node_fs4.rmSync)(socketPath, { force: true });
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
})();
|
|
1376
|
+
return closePromise;
|
|
1377
|
+
}
|
|
1378
|
+
};
|
|
1379
|
+
}
|
|
1380
|
+
function parseProfile(raw) {
|
|
1381
|
+
if (raw === void 0) throw new Error("Embedder worker requires a profile JSON argument");
|
|
1382
|
+
return asEmbeddingProfile(embeddingProfileSchema.parse(JSON.parse(raw)));
|
|
1383
|
+
}
|
|
1384
|
+
async function main() {
|
|
1385
|
+
const projectRoot = process.argv[2];
|
|
1386
|
+
if (projectRoot === void 0) throw new Error("Embedder worker requires a project root argument");
|
|
1387
|
+
const handle = await runEmbedderWorker({
|
|
1388
|
+
projectRoot,
|
|
1389
|
+
profile: parseProfile(process.argv[3]),
|
|
1390
|
+
...process.argv[4] === void 0 ? {} : { instanceId: process.argv[4] }
|
|
1391
|
+
});
|
|
1392
|
+
let stopping = false;
|
|
1393
|
+
const stop = (exitCode) => {
|
|
1394
|
+
if (stopping) return;
|
|
1395
|
+
stopping = true;
|
|
1396
|
+
void handle.close().then(
|
|
1397
|
+
() => process.exit(exitCode),
|
|
1398
|
+
(error) => {
|
|
1399
|
+
process.stderr.write(
|
|
1400
|
+
`Embedder worker cleanup failed: ${error instanceof Error ? error.message : String(error)}
|
|
1401
|
+
`
|
|
1402
|
+
);
|
|
1403
|
+
process.exit(1);
|
|
1404
|
+
}
|
|
1405
|
+
);
|
|
1406
|
+
};
|
|
1407
|
+
process.once("SIGTERM", () => stop(0));
|
|
1408
|
+
process.once("SIGINT", () => stop(0));
|
|
1409
|
+
}
|
|
1410
|
+
var entryBasename = process.argv[1] === void 0 ? void 0 : (0, import_node_path7.basename)(process.argv[1]);
|
|
1411
|
+
if (entryBasename === "worker-entry.js" || entryBasename === "worker-entry.cjs") {
|
|
1412
|
+
void main().catch((error) => {
|
|
1413
|
+
process.stderr.write(
|
|
1414
|
+
`Embedder worker failed: ${error instanceof Error ? error.message : String(error)}
|
|
1415
|
+
`
|
|
1416
|
+
);
|
|
1417
|
+
process.exitCode = 1;
|
|
1418
|
+
});
|
|
1419
|
+
}
|
|
1420
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1421
|
+
0 && (module.exports = {
|
|
1422
|
+
runEmbedderWorker
|
|
1423
|
+
});
|
|
1424
|
+
//# sourceMappingURL=worker-entry.cjs.map
|