grepmax 0.26.70 → 0.26.72

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.
@@ -51,6 +51,8 @@ exports.validateMlxEmbeddingResponse = validateMlxEmbeddingResponse;
51
51
  exports.requestMlxJSON = requestMlxJSON;
52
52
  exports.isMlxUp = isMlxUp;
53
53
  exports.mlxEmbed = mlxEmbed;
54
+ exports.isMlxExistingReady = isMlxExistingReady;
55
+ exports.mlxEmbedExisting = mlxEmbedExisting;
54
56
  const http = __importStar(require("node:http"));
55
57
  const logger_1 = require("../../utils/logger");
56
58
  const MLX_PORT = parseInt(process.env.MLX_EMBED_PORT || "8100", 10);
@@ -267,3 +269,28 @@ function mlxEmbed(texts, options) {
267
269
  return data.vectors.map((v) => new Float32Array(v));
268
270
  });
269
271
  }
272
+ /** Cached positive identity permits one bounded call to the existing backend.
273
+ * Every response verifies model/dimensions again; no polling or startup follows
274
+ * from an idle cache. A failed call revokes eligibility until external work
275
+ * confirms readiness again.
276
+ */
277
+ function isMlxExistingReady(expectedModel) {
278
+ return mlxAvailable === true && checkedModel === expectedModel;
279
+ }
280
+ function mlxEmbedExisting(texts, options) {
281
+ return __awaiter(this, void 0, void 0, function* () {
282
+ if (!isMlxExistingReady(options.expectedModel))
283
+ throw new Error("embedding_unavailable");
284
+ const result = yield requestMlxJSON("/embed", {
285
+ texts,
286
+ expected_model: options.expectedModel,
287
+ });
288
+ if (!result.ok ||
289
+ !validateMlxEmbeddingResponse(result.data, texts.length, options.expectedModel, options.expectedDim)) {
290
+ mlxAvailable = false;
291
+ throw new Error("embedding_unavailable");
292
+ }
293
+ lastCheck = Date.now();
294
+ return result.data.vectors.map((v) => new Float32Array(v));
295
+ });
296
+ }
@@ -54,9 +54,11 @@ const chunker_1 = require("../index/chunker");
54
54
  const embedding_generation_1 = require("../index/embedding-generation");
55
55
  const embedding_reuse_1 = require("../index/embedding-reuse");
56
56
  const skeleton_1 = require("../skeleton");
57
+ const autostart_1 = require("../utils/autostart");
57
58
  const file_utils_1 = require("../utils/file-utils");
58
59
  const logger_1 = require("../utils/logger");
59
60
  const path_containment_1 = require("../utils/path-containment");
61
+ const resource_budget_1 = require("../utils/resource-budget");
60
62
  const colbert_math_1 = require("./colbert-math");
61
63
  const embedding_error_1 = require("./embedding-error");
62
64
  const colbert_1 = require("./embeddings/colbert");
@@ -323,20 +325,56 @@ class WorkerOrchestrator {
323
325
  : { vectors, hash, mtimeMs, size };
324
326
  });
325
327
  }
326
- encodeQuery(text) {
327
- return __awaiter(this, void 0, void 0, function* () {
328
+ isExistingQueryReady() {
329
+ return this.embedMode === "cpu"
330
+ ? this.granite.isReady()
331
+ : (0, mlx_client_1.isMlxExistingReady)(this.generation.mlxModel);
332
+ }
333
+ encodeQuery(text_1) {
334
+ return __awaiter(this, arguments, void 0, function* (text, existingOnly = false, expectedGeneration) {
328
335
  var _a;
329
- yield this.ensureReady();
336
+ if (existingOnly) {
337
+ if (expectedGeneration !== this.generation.fingerprint)
338
+ throw Object.assign(new Error("embedding_mismatch"), {
339
+ code: "embedding_mismatch",
340
+ });
341
+ try {
342
+ if ((0, autostart_1.daemonStartDeniedReason)())
343
+ throw new Error();
344
+ resource_budget_1.resourceBudget.checkExisting();
345
+ if ((0, autostart_1.daemonStartDeniedReason)())
346
+ throw new Error();
347
+ }
348
+ catch (_b) {
349
+ throw Object.assign(new Error("host_pressure"), {
350
+ code: "host_pressure",
351
+ });
352
+ }
353
+ if (!this.isExistingQueryReady())
354
+ throw new Error("embedding_unavailable");
355
+ }
356
+ else
357
+ yield this.ensureReady();
330
358
  // Try MLX GPU server first, fall back to ONNX CPU
331
- const mlxResult = yield (0, mlx_client_1.mlxEmbed)([text], {
332
- mode: this.embedMode,
333
- expectedModel: this.generation.mlxModel,
334
- expectedDim: this.generation.vectorDim,
335
- });
359
+ const mlxResult = existingOnly
360
+ ? this.embedMode === "gpu"
361
+ ? yield (0, mlx_client_1.mlxEmbedExisting)([text], {
362
+ mode: this.embedMode,
363
+ expectedModel: this.generation.mlxModel,
364
+ expectedDim: this.generation.vectorDim,
365
+ })
366
+ : null
367
+ : yield (0, mlx_client_1.mlxEmbed)([text], {
368
+ mode: this.embedMode,
369
+ expectedModel: this.generation.mlxModel,
370
+ expectedDim: this.generation.vectorDim,
371
+ });
336
372
  if (!mlxResult && !this.allowOnnxFallback) {
337
373
  throw new Error(`MLX embedding model ${this.generation.mlxModel} is unavailable; ONNX fallback is disabled for this custom embedding generation`);
338
374
  }
339
- const denseVector = (_a = mlxResult === null || mlxResult === void 0 ? void 0 : mlxResult[0]) !== null && _a !== void 0 ? _a : (yield this.granite.runBatch([text]))[0];
375
+ const denseVector = (_a = mlxResult === null || mlxResult === void 0 ? void 0 : mlxResult[0]) !== null && _a !== void 0 ? _a : (yield this.granite.runBatch([text], existingOnly))[0];
376
+ if (existingOnly)
377
+ return { dense: Array.from(denseVector), colbert: [], colbertDim: 0 };
340
378
  const encoded = yield this.colbert.encodeQuery(text);
341
379
  const feeds = {
342
380
  input_ids: new ort.Tensor("int64", encoded.input_ids, [
@@ -42,7 +42,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
42
42
  });
43
43
  };
44
44
  Object.defineProperty(exports, "__esModule", { value: true });
45
- exports.WorkerPool = void 0;
45
+ exports.WorkerPool = exports.EXISTING_QUERY_QUEUE_LIMIT = exports.EXISTING_QUERY_WAIT_MS = void 0;
46
46
  exports.embeddingEnv = embeddingEnv;
47
47
  exports.getWorkerPool = getWorkerPool;
48
48
  exports.destroyWorkerPool = destroyWorkerPool;
@@ -63,6 +63,9 @@ const kernel_zone_1 = require("../utils/kernel-zone");
63
63
  const logger_1 = require("../utils/logger");
64
64
  const resource_budget_1 = require("../utils/resource-budget");
65
65
  const safety_latch_1 = require("../utils/safety-latch");
66
+ exports.EXISTING_QUERY_WAIT_MS = 2000;
67
+ exports.EXISTING_QUERY_QUEUE_LIMIT = 4;
68
+ const EXISTING_QUERY_DEADLINE_MS = 10000;
66
69
  const TASK_TIMEOUT_MS = (() => {
67
70
  var _a;
68
71
  const fromEnv = Number.parseInt((_a = process.env.GMAX_WORKER_TASK_TIMEOUT_MS) !== null && _a !== void 0 ? _a : "", 10);
@@ -122,6 +125,8 @@ class ProcessWorker {
122
125
  this.modulePath = modulePath;
123
126
  this.execArgv = execArgv;
124
127
  this.busy = false;
128
+ this.queryReady = false;
129
+ this.suppressReplacement = false;
125
130
  this.pendingTaskId = null;
126
131
  this.lastBusyTime = Date.now();
127
132
  // Wall-clock at which this worker became busy with its current task; null
@@ -247,6 +252,9 @@ class WorkerPool {
247
252
  this.priorityQueue = [];
248
253
  this.taskQueue = [];
249
254
  this.tasks = new Map();
255
+ // Separate from ordinary queues: these requests must never trigger expansion.
256
+ this.existingWaiters = new Map();
257
+ this.existingBurst = 0;
250
258
  this.nextId = 1;
251
259
  this.destroyed = false;
252
260
  this.destroyPromise = null;
@@ -296,6 +304,10 @@ class WorkerPool {
296
304
  : [{ pid: worker.child.pid, rssBytes: worker.lastRssBytes }]);
297
305
  }
298
306
  clearTaskTimeout(task) {
307
+ if (task.waitTimeout) {
308
+ clearTimeout(task.waitTimeout);
309
+ task.waitTimeout = undefined;
310
+ }
299
311
  if (task.timeout) {
300
312
  clearTimeout(task.timeout);
301
313
  task.timeout = undefined;
@@ -350,6 +362,7 @@ class WorkerPool {
350
362
  task.abortListener = undefined;
351
363
  }
352
364
  this.tasks.delete(task.id);
365
+ this.existingWaiters.delete(task.id);
353
366
  this.removeFromQueue(task.id);
354
367
  if (worker) {
355
368
  worker.busy = false;
@@ -383,7 +396,8 @@ class WorkerPool {
383
396
  if (!this.destroyed) {
384
397
  // Only respawn if we have no workers left or there are pending tasks
385
398
  const hasPendingTasks = this.hasUnassignedTasks();
386
- if (this.workers.length === 0 || hasPendingTasks) {
399
+ if ((!worker.suppressReplacement && this.workers.length === 0) ||
400
+ hasPendingTasks) {
387
401
  this.maybeRespawn(reason, hasPendingTasks);
388
402
  }
389
403
  this.dispatch();
@@ -467,12 +481,16 @@ class WorkerPool {
467
481
  const onMessage = (msg) => {
468
482
  var _a, _b, _c, _d;
469
483
  var _e, _f, _g, _h;
484
+ if (typeof msg.queryReady === "boolean")
485
+ worker.queryReady = msg.queryReady;
470
486
  if (typeof msg.rss === "number")
471
487
  worker.lastRssBytes = msg.rss;
472
488
  const task = this.tasks.get(msg.id);
473
489
  if (!task)
474
490
  return;
475
491
  if ("heartbeat" in msg) {
492
+ if (task.existingOnly)
493
+ return;
476
494
  // Reset only the no-progress timeout. The hard deadline is left
477
495
  // untouched on purpose — heartbeats must not be able to extend a task
478
496
  // past its absolute ceiling.
@@ -610,19 +628,25 @@ class WorkerPool {
610
628
  if (this.destroyed)
611
629
  return;
612
630
  if (this.spawnDeniedReason) {
631
+ this.rejectExistingWaiters("host_pressure");
613
632
  this.rejectUnassignedTasks(this.spawnDeniedReason, "HOST_SAFETY");
614
633
  return;
615
634
  }
616
635
  // Work admitted before another process quarantines the host may still
617
636
  // be queued. Do not send it to an existing worker after that stop.
618
637
  try {
638
+ this.dispatchExistingWaiters();
639
+ if (this.destroyed)
640
+ return;
619
641
  const quarantine = (0, autostart_1.daemonStartDeniedReason)();
620
642
  if (quarantine) {
643
+ this.rejectExistingWaiters("host_pressure");
621
644
  this.denySpawn(quarantine, false);
622
645
  return;
623
646
  }
624
647
  }
625
648
  catch (_f) {
649
+ this.rejectExistingWaiters("host_pressure");
626
650
  this.denySpawn("quarantine check failed");
627
651
  return;
628
652
  }
@@ -673,6 +697,8 @@ class WorkerPool {
673
697
  : "aggregate resource admission unavailable");
674
698
  return;
675
699
  }
700
+ idle.suppressReplacement = false;
701
+ this.existingBurst = 0;
676
702
  idle.busy = true;
677
703
  idle.pendingTaskId = task.id;
678
704
  idle.busySince = Date.now();
@@ -744,6 +770,165 @@ class WorkerPool {
744
770
  processFile(input, signal) {
745
771
  return this.enqueue("processFile", input, signal);
746
772
  }
773
+ existingWorkerState() {
774
+ if (this.destroyed || this.spawnDeniedReason || (0, autostart_1.daemonStartDeniedReason)())
775
+ return "host_pressure";
776
+ const warm = this.workers.filter((w) => w.queryReady && !w.cleanedUp && w.child.connected !== false);
777
+ return warm.some((w) => !w.busy)
778
+ ? "ready"
779
+ : warm.length
780
+ ? "busy"
781
+ : "embedding_unavailable";
782
+ }
783
+ /** Admission readiness includes a short bounded wait for an already-warm worker. */
784
+ existingQueryState() {
785
+ const state = this.existingWorkerState();
786
+ return state === "busy" &&
787
+ this.existingWaiters.size < exports.EXISTING_QUERY_QUEUE_LIMIT
788
+ ? "ready"
789
+ : this.existingWaiters.size >= exports.EXISTING_QUERY_QUEUE_LIMIT &&
790
+ state === "ready"
791
+ ? "busy"
792
+ : state;
793
+ }
794
+ rejectExistingWaiters(state) {
795
+ for (const task of this.existingWaiters.values()) {
796
+ task.reject(Object.assign(new Error(state), { code: state }));
797
+ this.completeTask(task, null);
798
+ }
799
+ }
800
+ dispatchExistingWaiters() {
801
+ while (this.existingWaiters.size) {
802
+ const state = this.existingWorkerState();
803
+ if (state === "host_pressure" || state === "embedding_unavailable") {
804
+ this.rejectExistingWaiters(state);
805
+ return;
806
+ }
807
+ // A continuous caller stream cannot keep indexing behind this queue.
808
+ if (this.existingBurst >= exports.EXISTING_QUERY_QUEUE_LIMIT &&
809
+ [...this.tasks.values()].some((t) => !t.worker && !t.existingOnly))
810
+ return;
811
+ if (state === "busy")
812
+ return;
813
+ const task = this.existingWaiters.values().next().value;
814
+ const age = Date.now() - task.queuedAt;
815
+ if (age < 0 || age >= exports.EXISTING_QUERY_WAIT_MS) {
816
+ task.reject(Object.assign(new Error("busy"), { code: "busy" }));
817
+ this.completeTask(task, null);
818
+ continue;
819
+ }
820
+ // The worker wait ends here; synchronous admission has its own bound and
821
+ // the request's overall timer/signal still applies during inference.
822
+ if (task.waitTimeout)
823
+ clearTimeout(task.waitTimeout);
824
+ task.waitTimeout = undefined;
825
+ try {
826
+ resource_budget_1.resourceBudget.checkExisting();
827
+ }
828
+ catch (_a) {
829
+ this.rejectExistingWaiters("host_pressure");
830
+ // Ordinary work performs its own admission; a document refusal must
831
+ // not strand that queue. The dispatcher rechecks containment next.
832
+ return;
833
+ }
834
+ // Cancellation during admission may have removed this waiter.
835
+ if (!this.existingWaiters.has(task.id))
836
+ continue;
837
+ const admittedAge = Date.now() - task.queuedAt;
838
+ if (admittedAge < 0 || admittedAge >= EXISTING_QUERY_DEADLINE_MS) {
839
+ task.reject(new Error("timeout"));
840
+ this.completeTask(task, null);
841
+ continue;
842
+ }
843
+ const after = this.existingWorkerState();
844
+ if (after !== "ready") {
845
+ if (after === "busy") {
846
+ task.reject(Object.assign(new Error("busy"), { code: "busy" }));
847
+ this.completeTask(task, null);
848
+ continue;
849
+ }
850
+ this.rejectExistingWaiters(after);
851
+ return;
852
+ }
853
+ const worker = this.workers.find((w) => w.queryReady &&
854
+ !w.busy &&
855
+ !w.cleanedUp &&
856
+ w.child.connected !== false);
857
+ this.existingWaiters.delete(task.id);
858
+ if (task.waitTimeout)
859
+ clearTimeout(task.waitTimeout);
860
+ task.waitTimeout = undefined;
861
+ task.worker = worker;
862
+ task.startTime = Date.now();
863
+ worker.busy = true;
864
+ worker.suppressReplacement = true;
865
+ worker.busySince = Date.now();
866
+ worker.pendingTaskId = task.id;
867
+ this.tasks.set(task.id, task);
868
+ this.existingBurst++;
869
+ try {
870
+ worker.child.send({
871
+ id: task.id,
872
+ method: task.method,
873
+ payload: task.payload,
874
+ });
875
+ }
876
+ catch (_b) {
877
+ this.completeTask(task, worker);
878
+ worker.queryReady = false;
879
+ task.reject(new Error("embedding_unavailable"));
880
+ }
881
+ }
882
+ }
883
+ encodeQueryExisting(text, signal) {
884
+ const state = this.existingQueryState();
885
+ if (state !== "ready")
886
+ return Promise.reject(Object.assign(new Error(state), { code: state }));
887
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted)
888
+ return Promise.reject(Object.assign(new Error("Aborted"), { name: "AbortError" }));
889
+ return new Promise((resolve, reject) => {
890
+ const id = this.nextId++;
891
+ const task = {
892
+ id,
893
+ method: "encodeQuery",
894
+ payload: {
895
+ text,
896
+ existingOnly: true,
897
+ generation: this.generation.fingerprint,
898
+ },
899
+ resolve,
900
+ reject,
901
+ queuedAt: Date.now(),
902
+ signal,
903
+ existingOnly: true,
904
+ };
905
+ const cancel = () => {
906
+ task.callerAborted = true;
907
+ reject(Object.assign(new Error("Aborted"), { name: "AbortError" }));
908
+ if (!task.worker) {
909
+ this.completeTask(task, null);
910
+ this.dispatch();
911
+ }
912
+ };
913
+ task.abortListener = cancel;
914
+ signal === null || signal === void 0 ? void 0 : signal.addEventListener("abort", cancel, { once: true });
915
+ // Caller deadline does not kill or replace this shared worker. Its bounded
916
+ // inference settles lifecycle independently, just like normal cancellation.
917
+ task.timeout = setTimeout(() => {
918
+ task.callerAborted = true;
919
+ reject(new Error("timeout"));
920
+ if (!task.worker)
921
+ this.completeTask(task, null);
922
+ }, EXISTING_QUERY_DEADLINE_MS);
923
+ task.waitTimeout = setTimeout(() => {
924
+ reject(Object.assign(new Error("busy"), { code: "busy" }));
925
+ this.completeTask(task, null);
926
+ this.dispatch();
927
+ }, exports.EXISTING_QUERY_WAIT_MS);
928
+ this.existingWaiters.set(id, task);
929
+ this.dispatch();
930
+ });
931
+ }
747
932
  encodeQuery(text, signal) {
748
933
  return this.enqueue("encodeQuery", { text }, signal);
749
934
  }
@@ -826,7 +1011,7 @@ class WorkerPool {
826
1011
  * floor with a fresh, lean worker. Shared by the idle and post-task RSS paths.
827
1012
  */
828
1013
  recycleWorker(w, reason) {
829
- if (w.cleanedUp)
1014
+ if (w.cleanedUp || w.busy)
830
1015
  return;
831
1016
  (0, logger_1.log)("pool", `recycle bloated worker PID:${w.child.pid} (${reason}, rss ${Math.round(w.lastRssBytes / 1048576)}MB > ${WORKER_RSS_RECYCLE_MB}MB)`);
832
1017
  w.cleanedUp = true;
@@ -856,7 +1041,9 @@ class WorkerPool {
856
1041
  }, REAP_FORCE_KILL_GRACE_MS);
857
1042
  }
858
1043
  // Replace anything we dropped below the floor with fresh, lean workers.
859
- while (!this.destroyed && this.workers.length < MIN_KEEP_WORKERS) {
1044
+ while (!w.suppressReplacement &&
1045
+ !this.destroyed &&
1046
+ this.workers.length < MIN_KEEP_WORKERS) {
860
1047
  if (!this.spawnWorker())
861
1048
  break;
862
1049
  }
@@ -924,6 +1111,7 @@ class WorkerPool {
924
1111
  this.idleReapInterval = null;
925
1112
  }
926
1113
  this.clearScaleUpTimer();
1114
+ this.rejectExistingWaiters("embedding_unavailable");
927
1115
  for (const task of this.tasks.values()) {
928
1116
  task.reject(new Error("Worker pool destroyed"));
929
1117
  this.completeTask(task, null);
@@ -59,11 +59,14 @@ const send = (msg) => {
59
59
  if (node_process_1.default.send) {
60
60
  // Attach current RSS so the pool can recycle workers whose native (ONNX)
61
61
  // memory has ballooned — the V8 --max-old-space-size cap can't see it.
62
- node_process_1.default.send(Object.assign(Object.assign({}, msg), { rss: node_process_1.default.memoryUsage().rss }));
62
+ node_process_1.default.send(Object.assign(Object.assign({}, msg), { rss: node_process_1.default.memoryUsage().rss, queryReady: (0, worker_1.isExistingQueryReady)() }));
63
63
  }
64
64
  };
65
+ let restrictedInFlight = false;
65
66
  const handleMessage = (msg) => __awaiter(void 0, void 0, void 0, function* () {
66
67
  const { id, method, payload } = msg;
68
+ restrictedInFlight =
69
+ method === "encodeQuery" && payload.existingOnly === true;
67
70
  const start = performance.now();
68
71
  (0, logger_1.debug)("worker", `recv task=${id} method=${method}${method === "processFile" ? ` file=${payload.path}` : ""}`);
69
72
  try {
@@ -91,23 +94,37 @@ const handleMessage = (msg) => __awaiter(void 0, void 0, void 0, function* () {
91
94
  send({ id, error: `Unknown method: ${method}` });
92
95
  }
93
96
  catch (err) {
94
- const message = err instanceof Error ? err.message : String(err);
97
+ const rawCode = err === null || err === void 0 ? void 0 : err.code;
98
+ const safeCode = typeof rawCode === "string" &&
99
+ ["host_pressure", "embedding_mismatch", "embedding_unavailable"].includes(rawCode)
100
+ ? rawCode
101
+ : "embedding_unavailable";
102
+ const message = restrictedInFlight
103
+ ? safeCode
104
+ : err instanceof Error
105
+ ? err.message
106
+ : String(err);
95
107
  (0, logger_1.debug)("worker", `fail task=${id} method=${method} ${(performance.now() - start).toFixed(0)}ms: ${message}`);
96
- const code = err === null || err === void 0 ? void 0 : err.code;
108
+ const code = restrictedInFlight
109
+ ? safeCode
110
+ : err === null || err === void 0 ? void 0 : err.code;
97
111
  send(Object.assign({ id, error: message }, (typeof code === "string" ? { code } : {})));
98
112
  }
113
+ finally {
114
+ restrictedInFlight = false;
115
+ }
99
116
  });
100
117
  const handleMessageSerially = (0, serialized_handler_1.createSerializedHandler)(handleMessage);
101
118
  node_process_1.default.on("message", (msg) => {
102
119
  void handleMessageSerially(msg);
103
120
  });
104
121
  node_process_1.default.on("uncaughtException", (err) => {
105
- console.error("[process-worker] uncaughtException", err);
122
+ console.error("[process-worker] uncaughtException", restrictedInFlight ? "restricted query failed" : err);
106
123
  node_process_1.default.exitCode = 1;
107
124
  node_process_1.default.exit();
108
125
  });
109
126
  node_process_1.default.on("unhandledRejection", (reason) => {
110
- console.error("[process-worker] unhandledRejection", reason);
127
+ console.error("[process-worker] unhandledRejection", restrictedInFlight ? "restricted query failed" : reason);
111
128
  node_process_1.default.exitCode = 1;
112
129
  node_process_1.default.exit();
113
130
  });
@@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.isExistingQueryReady = void 0;
12
13
  exports.default = processFile;
13
14
  exports.encodeQuery = encodeQuery;
14
15
  exports.rerank = rerank;
@@ -33,9 +34,11 @@ function processFile(input, onProgress) {
33
34
  }
34
35
  function encodeQuery(input) {
35
36
  return __awaiter(this, void 0, void 0, function* () {
36
- return orchestrator.encodeQuery(input.text);
37
+ return orchestrator.encodeQuery(input.text, input.existingOnly, input.generation);
37
38
  });
38
39
  }
40
+ const isExistingQueryReady = () => orchestrator.isExistingQueryReady();
41
+ exports.isExistingQueryReady = isExistingQueryReady;
39
42
  function rerank(input) {
40
43
  return __awaiter(this, void 0, void 0, function* () {
41
44
  return orchestrator.rerank(input);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grepmax",
3
- "version": "0.26.70",
3
+ "version": "0.26.72",
4
4
  "author": "Robert Owens <78518764+reowens@users.noreply.github.com>",
5
5
  "homepage": "https://github.com/reowens/grepmax",
6
6
  "bugs": {
@@ -46,7 +46,8 @@
46
46
  "postversion": "bash scripts/postrelease.sh",
47
47
  "audit:consumer": "node scripts/audit-consumer.cjs",
48
48
  "audit:python": "python3 scripts/audit-python.py && python3 scripts/audit-python.py --lockfile lance-maintenance/uv.lock",
49
- "test:python": "python3 -m unittest discover -s tests/python"
49
+ "test:python": "python3 -m unittest discover -s tests/python",
50
+ "audit:document-search": "node scripts/audit-document-search.cjs"
50
51
  },
51
52
  "keywords": [
52
53
  "grepmax",
@@ -79,7 +80,8 @@
79
80
  "lance-maintenance/uv.lock",
80
81
  "README.md",
81
82
  "LICENSE",
82
- "NOTICE"
83
+ "NOTICE",
84
+ "DOCUMENT-SEARCH.md"
83
85
  ],
84
86
  "license": "Apache-2.0",
85
87
  "description": "Semantic code search for coding agents. Local embeddings, call graph tracing, compact code context.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grepmax",
3
- "version": "0.26.70",
3
+ "version": "0.26.72",
4
4
  "description": "Semantic code search for Claude Code. Automatically indexes your project and provides intelligent search capabilities.",
5
5
  "author": {
6
6
  "name": "Robert Owens",