grepmax 0.26.59 → 0.26.61
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/.claude-plugin/marketplace.json +1 -1
- package/README.md +18 -0
- package/dist/commands/mcp.js +13 -0
- package/dist/lib/daemon/daemon.js +57 -5
- package/dist/lib/daemon/mlx-server-manager.js +41 -6
- package/dist/lib/llm/server.js +40 -6
- package/dist/lib/store/vector-db.js +51 -5
- package/dist/lib/utils/host-guard-policy.js +84 -0
- package/dist/lib/utils/host-resource.js +248 -0
- package/dist/lib/utils/resource-budget.js +437 -0
- package/dist/lib/utils/resource-snapshot.js +1 -14
- package/dist/lib/workers/pool.js +62 -14
- package/package.json +1 -1
- package/plugins/grepmax/.claude-plugin/plugin.json +1 -1
|
@@ -3,18 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.buildResourceSnapshot = buildResourceSnapshot;
|
|
4
4
|
function buildResourceSnapshot(counters, memory = process.memoryUsage(), at = Date.now()) {
|
|
5
5
|
const mb = (bytes) => Math.round(bytes / 1024 / 1024);
|
|
6
|
-
return {
|
|
7
|
-
at,
|
|
8
|
-
reason: counters.reason,
|
|
9
|
-
footprintMb: counters.footprintMb,
|
|
10
|
-
rssMb: mb(memory.rss),
|
|
11
|
-
heapUsedMb: mb(memory.heapUsed),
|
|
12
|
-
externalMb: mb(memory.external),
|
|
13
|
-
arrayBuffersMb: mb(memory.arrayBuffers),
|
|
14
|
-
lanceCacheMb: counters.lanceCacheBytes === null ? null : mb(counters.lanceCacheBytes),
|
|
15
|
-
workers: counters.workers,
|
|
16
|
-
pendingFiles: counters.pendingFiles,
|
|
17
|
-
operations: counters.operations,
|
|
18
|
-
maintenance: counters.maintenance,
|
|
19
|
-
};
|
|
6
|
+
return Object.assign({ at, reason: counters.reason, footprintMb: counters.footprintMb, rssMb: mb(memory.rss), heapUsedMb: mb(memory.heapUsed), externalMb: mb(memory.external), arrayBuffersMb: mb(memory.arrayBuffers), lanceCacheMb: counters.lanceCacheBytes === null ? null : mb(counters.lanceCacheBytes), workers: counters.workers, pendingFiles: counters.pendingFiles, operations: counters.operations, maintenance: counters.maintenance }, (counters.host ? { host: counters.host } : {}));
|
|
20
7
|
}
|
package/dist/lib/workers/pool.js
CHANGED
|
@@ -58,8 +58,10 @@ const config_1 = require("../../config");
|
|
|
58
58
|
const embedding_generation_1 = require("../index/embedding-generation");
|
|
59
59
|
const index_config_1 = require("../index/index-config");
|
|
60
60
|
const autostart_1 = require("../utils/autostart");
|
|
61
|
+
const host_guard_policy_1 = require("../utils/host-guard-policy");
|
|
61
62
|
const kernel_zone_1 = require("../utils/kernel-zone");
|
|
62
63
|
const logger_1 = require("../utils/logger");
|
|
64
|
+
const resource_budget_1 = require("../utils/resource-budget");
|
|
63
65
|
const safety_latch_1 = require("../utils/safety-latch");
|
|
64
66
|
const TASK_TIMEOUT_MS = (() => {
|
|
65
67
|
var _a;
|
|
@@ -135,11 +137,37 @@ class ProcessWorker {
|
|
|
135
137
|
// fire for the same crash.
|
|
136
138
|
this.cleanedUp = false;
|
|
137
139
|
const memArgs = maxMemoryMb ? [`--max-old-space-size=${maxMemoryMb}`] : [];
|
|
138
|
-
this.
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
this.resourceReservation = resource_budget_1.resourceBudget.reserve(resource_budget_1.WORKER_RESOURCE_RESERVE_MB, "worker");
|
|
141
|
+
try {
|
|
142
|
+
const denied = (0, autostart_1.daemonStartDeniedReason)();
|
|
143
|
+
if (denied)
|
|
144
|
+
throw new Error(denied);
|
|
145
|
+
this.child = childProcess.fork(modulePath, {
|
|
146
|
+
execArgv: [...memArgs, ...execArgv],
|
|
147
|
+
env: Object.assign(Object.assign({}, process.env), embeddingEnvironment),
|
|
148
|
+
serialization: "advanced",
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
this.resourceReservation.release();
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
155
|
+
// Keep the reservation until close, including SIGKILL/timeout paths.
|
|
156
|
+
this.child.once("close", () => {
|
|
157
|
+
try {
|
|
158
|
+
this.resourceReservation.release();
|
|
159
|
+
}
|
|
160
|
+
catch (_a) { }
|
|
142
161
|
});
|
|
162
|
+
try {
|
|
163
|
+
if (!this.child.pid)
|
|
164
|
+
throw new Error("worker PID unavailable");
|
|
165
|
+
this.resourceReservation.attach(this.child.pid);
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
this.child.kill("SIGKILL");
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
143
171
|
}
|
|
144
172
|
}
|
|
145
173
|
function resolveProcessWorker() {
|
|
@@ -365,7 +393,7 @@ class WorkerPool {
|
|
|
365
393
|
var _a;
|
|
366
394
|
return Object.assign(new Error((_a = this.spawnDeniedReason) !== null && _a !== void 0 ? _a : "Worker spawn denied"), { code: "HOST_SAFETY" });
|
|
367
395
|
}
|
|
368
|
-
denySpawn(reason, persist =
|
|
396
|
+
denySpawn(reason, persist = false) {
|
|
369
397
|
// A pool cannot automatically recover after a failed admission. In
|
|
370
398
|
// particular, timer/exit callbacks must not retry forks or strand queues.
|
|
371
399
|
this.spawnDeniedReason = `Worker spawn denied: ${reason}`;
|
|
@@ -396,22 +424,31 @@ class WorkerPool {
|
|
|
396
424
|
const quarantine = (0, autostart_1.daemonStartDeniedReason)();
|
|
397
425
|
if (quarantine)
|
|
398
426
|
return this.denySpawn(quarantine, false);
|
|
427
|
+
const strictHostGuard = (0, host_guard_policy_1.hostGuardPolicy)() === "strict";
|
|
399
428
|
if (process.platform === "darwin") {
|
|
400
429
|
const memory = (0, kernel_zone_1.probeMemoryPressure)();
|
|
401
|
-
if (memory.status
|
|
402
|
-
|
|
430
|
+
if ((memory.status === "known" && memory.pressure === "critical") ||
|
|
431
|
+
(strictHostGuard &&
|
|
432
|
+
(memory.status !== "known" || memory.pressure !== "normal"))) {
|
|
433
|
+
return this.denySpawn(`OS memory pressure ${memory.status === "known" ? memory.pressure : memory.status}; ${(0, kernel_zone_1.formatPressureProbe)(memory)}`, memory.status === "known" && memory.pressure === "critical");
|
|
403
434
|
}
|
|
404
435
|
const kernel = (0, kernel_zone_1.probeKernelZoneUsage)();
|
|
405
|
-
if (kernel.status
|
|
406
|
-
|
|
436
|
+
if ((kernel.status === "known" && kernel.usage.pressure === "critical") ||
|
|
437
|
+
(strictHostGuard &&
|
|
438
|
+
(kernel.status !== "known" || kernel.usage.pressure !== "ok"))) {
|
|
439
|
+
return this.denySpawn(`kernel pressure ${kernel.status === "known" ? kernel.usage.pressure : kernel.status}; ${(0, kernel_zone_1.formatPressureProbe)(kernel)}`, kernel.status === "known" && kernel.usage.pressure === "critical");
|
|
407
440
|
}
|
|
408
441
|
}
|
|
409
442
|
if (process.platform === "darwin") {
|
|
410
443
|
// Refresh the cheap OS sample after the potentially slow kernel probe.
|
|
411
444
|
const freshMemory = (0, kernel_zone_1.probeMemoryPressure)();
|
|
412
|
-
if (freshMemory.status
|
|
413
|
-
freshMemory.pressure
|
|
414
|
-
|
|
445
|
+
if ((freshMemory.status === "known" &&
|
|
446
|
+
freshMemory.pressure === "critical") ||
|
|
447
|
+
(strictHostGuard &&
|
|
448
|
+
(freshMemory.status !== "known" ||
|
|
449
|
+
freshMemory.pressure !== "normal"))) {
|
|
450
|
+
return this.denySpawn(`OS memory pressure ${freshMemory.status === "known" ? freshMemory.pressure : freshMemory.status}; ${(0, kernel_zone_1.formatPressureProbe)(freshMemory)}`, freshMemory.status === "known" &&
|
|
451
|
+
freshMemory.pressure === "critical");
|
|
415
452
|
}
|
|
416
453
|
}
|
|
417
454
|
// Probes are synchronous but another process can quarantine the host
|
|
@@ -421,8 +458,10 @@ class WorkerPool {
|
|
|
421
458
|
return this.denySpawn(finalQuarantine, false);
|
|
422
459
|
worker = new ProcessWorker(this.modulePath, this.execArgv, this.embeddingEnvironment, config_1.MAX_WORKER_MEMORY_MB);
|
|
423
460
|
}
|
|
424
|
-
catch (
|
|
425
|
-
return this.denySpawn(
|
|
461
|
+
catch (error) {
|
|
462
|
+
return this.denySpawn(error instanceof Error
|
|
463
|
+
? error.message
|
|
464
|
+
: "host admission or fork failed");
|
|
426
465
|
}
|
|
427
466
|
(0, logger_1.log)("pool", `spawn PID:${worker.child.pid} (${this.workers.length + 1}/${Math.max(1, config_1.CONFIG.WORKER_THREADS)})`);
|
|
428
467
|
const onMessage = (msg) => {
|
|
@@ -625,6 +664,15 @@ class WorkerPool {
|
|
|
625
664
|
this.dispatch();
|
|
626
665
|
return;
|
|
627
666
|
}
|
|
667
|
+
try {
|
|
668
|
+
resource_budget_1.resourceBudget.check();
|
|
669
|
+
}
|
|
670
|
+
catch (error) {
|
|
671
|
+
this.denySpawn(error instanceof Error
|
|
672
|
+
? error.message
|
|
673
|
+
: "aggregate resource admission unavailable");
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
628
676
|
idle.busy = true;
|
|
629
677
|
idle.pendingTaskId = task.id;
|
|
630
678
|
idle.busySince = Date.now();
|
package/package.json
CHANGED