@deeplake/hivemind 0.7.31 → 0.7.32
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 +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/bundle/cli.js +427 -233
- package/codex/bundle/capture.js +550 -122
- package/codex/bundle/embeddings/embed-daemon.js +55 -4
- package/codex/bundle/pre-tool-use.js +447 -90
- package/codex/bundle/shell/deeplake-shell.js +431 -74
- package/codex/bundle/stop.js +437 -80
- package/codex/bundle/wiki-worker.js +429 -72
- package/cursor/bundle/capture.js +625 -197
- package/cursor/bundle/embeddings/embed-daemon.js +55 -4
- package/cursor/bundle/pre-tool-use.js +432 -75
- package/cursor/bundle/session-start.js +8 -1
- package/cursor/bundle/shell/deeplake-shell.js +431 -74
- package/cursor/bundle/wiki-worker.js +429 -72
- package/hermes/bundle/capture.js +626 -198
- package/hermes/bundle/embeddings/embed-daemon.js +55 -4
- package/hermes/bundle/pre-tool-use.js +431 -74
- package/hermes/bundle/session-start.js +8 -1
- package/hermes/bundle/shell/deeplake-shell.js +431 -74
- package/hermes/bundle/wiki-worker.js +429 -72
- package/openclaw/dist/index.js +1 -1
- package/openclaw/openclaw.plugin.json +1 -1
- package/openclaw/package.json +1 -1
- package/package.json +1 -1
|
@@ -46081,14 +46081,14 @@ var require_turndown_cjs = __commonJS({
|
|
|
46081
46081
|
} else if (node.nodeType === 1) {
|
|
46082
46082
|
replacement = replacementForNode.call(self2, node);
|
|
46083
46083
|
}
|
|
46084
|
-
return
|
|
46084
|
+
return join13(output, replacement);
|
|
46085
46085
|
}, "");
|
|
46086
46086
|
}
|
|
46087
46087
|
function postProcess(output) {
|
|
46088
46088
|
var self2 = this;
|
|
46089
46089
|
this.rules.forEach(function(rule) {
|
|
46090
46090
|
if (typeof rule.append === "function") {
|
|
46091
|
-
output =
|
|
46091
|
+
output = join13(output, rule.append(self2.options));
|
|
46092
46092
|
}
|
|
46093
46093
|
});
|
|
46094
46094
|
return output.replace(/^[\t\r\n]+/, "").replace(/[\t\r\n\s]+$/, "");
|
|
@@ -46100,7 +46100,7 @@ var require_turndown_cjs = __commonJS({
|
|
|
46100
46100
|
if (whitespace.leading || whitespace.trailing) content = content.trim();
|
|
46101
46101
|
return whitespace.leading + rule.replacement(content, node, this.options) + whitespace.trailing;
|
|
46102
46102
|
}
|
|
46103
|
-
function
|
|
46103
|
+
function join13(output, replacement) {
|
|
46104
46104
|
var s12 = trimTrailingNewlines(output);
|
|
46105
46105
|
var s22 = trimLeadingNewlines(replacement);
|
|
46106
46106
|
var nls = Math.max(output.length - s12.length, replacement.length - s22.length);
|
|
@@ -66870,7 +66870,7 @@ function getQueryTimeoutMs() {
|
|
|
66870
66870
|
return Number(process.env.HIVEMIND_QUERY_TIMEOUT_MS ?? 1e4);
|
|
66871
66871
|
}
|
|
66872
66872
|
function sleep(ms3) {
|
|
66873
|
-
return new Promise((
|
|
66873
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms3));
|
|
66874
66874
|
}
|
|
66875
66875
|
function isTimeoutError(error) {
|
|
66876
66876
|
const name = error instanceof Error ? error.name.toLowerCase() : "";
|
|
@@ -66900,7 +66900,7 @@ var Semaphore = class {
|
|
|
66900
66900
|
this.active++;
|
|
66901
66901
|
return;
|
|
66902
66902
|
}
|
|
66903
|
-
await new Promise((
|
|
66903
|
+
await new Promise((resolve6) => this.waiting.push(resolve6));
|
|
66904
66904
|
}
|
|
66905
66905
|
release() {
|
|
66906
66906
|
this.active--;
|
|
@@ -67259,7 +67259,7 @@ var DeeplakeApi = class {
|
|
|
67259
67259
|
import { basename as basename4, posix } from "node:path";
|
|
67260
67260
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
67261
67261
|
import { fileURLToPath } from "node:url";
|
|
67262
|
-
import { dirname as
|
|
67262
|
+
import { dirname as dirname5, join as join11 } from "node:path";
|
|
67263
67263
|
|
|
67264
67264
|
// dist/src/shell/grep-core.js
|
|
67265
67265
|
var TOOL_INPUT_FIELDS = [
|
|
@@ -67689,9 +67689,9 @@ function refineGrepMatches(rows, params, forceMultiFilePrefix) {
|
|
|
67689
67689
|
// dist/src/embeddings/client.js
|
|
67690
67690
|
import { connect } from "node:net";
|
|
67691
67691
|
import { spawn } from "node:child_process";
|
|
67692
|
-
import { openSync, closeSync, writeSync, unlinkSync, existsSync as
|
|
67693
|
-
import { homedir as
|
|
67694
|
-
import { join as
|
|
67692
|
+
import { openSync as openSync2, closeSync as closeSync2, writeSync, unlinkSync as unlinkSync2, existsSync as existsSync5, readFileSync as readFileSync5 } from "node:fs";
|
|
67693
|
+
import { homedir as homedir6 } from "node:os";
|
|
67694
|
+
import { join as join10 } from "node:path";
|
|
67695
67695
|
|
|
67696
67696
|
// dist/src/embeddings/protocol.js
|
|
67697
67697
|
var DEFAULT_SOCKET_DIR = "/tmp";
|
|
@@ -67704,13 +67704,234 @@ function pidPathFor(uid, dir = DEFAULT_SOCKET_DIR) {
|
|
|
67704
67704
|
return `${dir}/hivemind-embed-${uid}.pid`;
|
|
67705
67705
|
}
|
|
67706
67706
|
|
|
67707
|
+
// dist/src/notifications/queue.js
|
|
67708
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, renameSync, mkdirSync as mkdirSync2, openSync, closeSync, unlinkSync, statSync as statSync2 } from "node:fs";
|
|
67709
|
+
import { join as join7, resolve as resolve4 } from "node:path";
|
|
67710
|
+
import { homedir as homedir3 } from "node:os";
|
|
67711
|
+
import { setTimeout as sleep2 } from "node:timers/promises";
|
|
67712
|
+
var log3 = (msg) => log("notifications-queue", msg);
|
|
67713
|
+
var LOCK_RETRY_MAX = 50;
|
|
67714
|
+
var LOCK_RETRY_BASE_MS = 5;
|
|
67715
|
+
var LOCK_STALE_MS = 5e3;
|
|
67716
|
+
function queuePath() {
|
|
67717
|
+
return join7(homedir3(), ".deeplake", "notifications-queue.json");
|
|
67718
|
+
}
|
|
67719
|
+
function lockPath() {
|
|
67720
|
+
return `${queuePath()}.lock`;
|
|
67721
|
+
}
|
|
67722
|
+
function readQueue() {
|
|
67723
|
+
try {
|
|
67724
|
+
const raw = readFileSync3(queuePath(), "utf-8");
|
|
67725
|
+
const parsed = JSON.parse(raw);
|
|
67726
|
+
if (!parsed || !Array.isArray(parsed.queue)) {
|
|
67727
|
+
log3(`queue malformed \u2192 treating as empty`);
|
|
67728
|
+
return { queue: [] };
|
|
67729
|
+
}
|
|
67730
|
+
return { queue: parsed.queue };
|
|
67731
|
+
} catch {
|
|
67732
|
+
return { queue: [] };
|
|
67733
|
+
}
|
|
67734
|
+
}
|
|
67735
|
+
function _isQueuePathInsideHome(path2, home) {
|
|
67736
|
+
const r10 = resolve4(path2);
|
|
67737
|
+
const h18 = resolve4(home);
|
|
67738
|
+
return r10.startsWith(h18 + "/") || r10 === h18;
|
|
67739
|
+
}
|
|
67740
|
+
function writeQueue(q17) {
|
|
67741
|
+
const path2 = queuePath();
|
|
67742
|
+
const home = resolve4(homedir3());
|
|
67743
|
+
if (!_isQueuePathInsideHome(path2, home)) {
|
|
67744
|
+
throw new Error(`notifications-queue write blocked: ${path2} is outside ${home}`);
|
|
67745
|
+
}
|
|
67746
|
+
mkdirSync2(join7(home, ".deeplake"), { recursive: true, mode: 448 });
|
|
67747
|
+
const tmp = `${path2}.${process.pid}.tmp`;
|
|
67748
|
+
writeFileSync2(tmp, JSON.stringify(q17, null, 2), { mode: 384 });
|
|
67749
|
+
renameSync(tmp, path2);
|
|
67750
|
+
}
|
|
67751
|
+
async function withQueueLock(fn4) {
|
|
67752
|
+
const path2 = lockPath();
|
|
67753
|
+
mkdirSync2(join7(homedir3(), ".deeplake"), { recursive: true, mode: 448 });
|
|
67754
|
+
let fd = null;
|
|
67755
|
+
for (let attempt = 0; attempt < LOCK_RETRY_MAX; attempt++) {
|
|
67756
|
+
try {
|
|
67757
|
+
fd = openSync(path2, "wx", 384);
|
|
67758
|
+
break;
|
|
67759
|
+
} catch (e6) {
|
|
67760
|
+
const code = e6.code;
|
|
67761
|
+
if (code !== "EEXIST")
|
|
67762
|
+
throw e6;
|
|
67763
|
+
try {
|
|
67764
|
+
const age = Date.now() - statSync2(path2).mtimeMs;
|
|
67765
|
+
if (age > LOCK_STALE_MS) {
|
|
67766
|
+
unlinkSync(path2);
|
|
67767
|
+
continue;
|
|
67768
|
+
}
|
|
67769
|
+
} catch {
|
|
67770
|
+
}
|
|
67771
|
+
const delay = LOCK_RETRY_BASE_MS * (attempt + 1);
|
|
67772
|
+
await sleep2(delay);
|
|
67773
|
+
}
|
|
67774
|
+
}
|
|
67775
|
+
if (fd === null) {
|
|
67776
|
+
log3(`lock acquisition gave up after ${LOCK_RETRY_MAX} attempts \u2014 proceeding unlocked (last-writer-wins)`);
|
|
67777
|
+
return fn4();
|
|
67778
|
+
}
|
|
67779
|
+
try {
|
|
67780
|
+
return fn4();
|
|
67781
|
+
} finally {
|
|
67782
|
+
try {
|
|
67783
|
+
closeSync(fd);
|
|
67784
|
+
} catch {
|
|
67785
|
+
}
|
|
67786
|
+
try {
|
|
67787
|
+
unlinkSync(path2);
|
|
67788
|
+
} catch {
|
|
67789
|
+
}
|
|
67790
|
+
}
|
|
67791
|
+
}
|
|
67792
|
+
function sameDedupKey(a15, b26) {
|
|
67793
|
+
if (a15.id !== b26.id)
|
|
67794
|
+
return false;
|
|
67795
|
+
return JSON.stringify(a15.dedupKey) === JSON.stringify(b26.dedupKey);
|
|
67796
|
+
}
|
|
67797
|
+
async function enqueueNotification(n24) {
|
|
67798
|
+
await withQueueLock(() => {
|
|
67799
|
+
const q17 = readQueue();
|
|
67800
|
+
if (q17.queue.some((existing) => sameDedupKey(existing, n24))) {
|
|
67801
|
+
return;
|
|
67802
|
+
}
|
|
67803
|
+
q17.queue.push(n24);
|
|
67804
|
+
writeQueue(q17);
|
|
67805
|
+
});
|
|
67806
|
+
}
|
|
67807
|
+
|
|
67808
|
+
// dist/src/embeddings/disable.js
|
|
67809
|
+
import { createRequire } from "node:module";
|
|
67810
|
+
import { homedir as homedir5 } from "node:os";
|
|
67811
|
+
import { join as join9 } from "node:path";
|
|
67812
|
+
import { pathToFileURL } from "node:url";
|
|
67813
|
+
|
|
67814
|
+
// dist/src/user-config.js
|
|
67815
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
67816
|
+
import { homedir as homedir4 } from "node:os";
|
|
67817
|
+
import { dirname as dirname4, join as join8 } from "node:path";
|
|
67818
|
+
var _configPath = () => process.env.HIVEMIND_CONFIG_PATH ?? join8(homedir4(), ".deeplake", "config.json");
|
|
67819
|
+
var _cache = null;
|
|
67820
|
+
var _migrated = false;
|
|
67821
|
+
function readUserConfig() {
|
|
67822
|
+
if (_cache !== null)
|
|
67823
|
+
return _cache;
|
|
67824
|
+
const path2 = _configPath();
|
|
67825
|
+
if (!existsSync4(path2)) {
|
|
67826
|
+
_cache = {};
|
|
67827
|
+
return _cache;
|
|
67828
|
+
}
|
|
67829
|
+
try {
|
|
67830
|
+
const raw = readFileSync4(path2, "utf-8");
|
|
67831
|
+
const parsed = JSON.parse(raw);
|
|
67832
|
+
_cache = isPlainObject(parsed) ? parsed : {};
|
|
67833
|
+
} catch {
|
|
67834
|
+
_cache = {};
|
|
67835
|
+
}
|
|
67836
|
+
return _cache;
|
|
67837
|
+
}
|
|
67838
|
+
function writeUserConfig(patch) {
|
|
67839
|
+
const current = readUserConfig();
|
|
67840
|
+
const merged = deepMerge(current, patch);
|
|
67841
|
+
const path2 = _configPath();
|
|
67842
|
+
const dir = dirname4(path2);
|
|
67843
|
+
if (!existsSync4(dir))
|
|
67844
|
+
mkdirSync3(dir, { recursive: true });
|
|
67845
|
+
const tmp = `${path2}.tmp.${process.pid}`;
|
|
67846
|
+
writeFileSync3(tmp, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
67847
|
+
renameSync2(tmp, path2);
|
|
67848
|
+
_cache = merged;
|
|
67849
|
+
return merged;
|
|
67850
|
+
}
|
|
67851
|
+
function getEmbeddingsEnabled() {
|
|
67852
|
+
const cfg = readUserConfig();
|
|
67853
|
+
if (cfg.embeddings && typeof cfg.embeddings.enabled === "boolean") {
|
|
67854
|
+
return cfg.embeddings.enabled;
|
|
67855
|
+
}
|
|
67856
|
+
if (_migrated) {
|
|
67857
|
+
return migrationValueFromEnv();
|
|
67858
|
+
}
|
|
67859
|
+
_migrated = true;
|
|
67860
|
+
const enabled = migrationValueFromEnv();
|
|
67861
|
+
try {
|
|
67862
|
+
writeUserConfig({ embeddings: { enabled } });
|
|
67863
|
+
} catch {
|
|
67864
|
+
_cache = { ...cfg ?? {}, embeddings: { ...cfg?.embeddings ?? {}, enabled } };
|
|
67865
|
+
}
|
|
67866
|
+
return enabled;
|
|
67867
|
+
}
|
|
67868
|
+
function migrationValueFromEnv() {
|
|
67869
|
+
const raw = process.env.HIVEMIND_EMBEDDINGS;
|
|
67870
|
+
if (raw === void 0)
|
|
67871
|
+
return false;
|
|
67872
|
+
if (raw === "false")
|
|
67873
|
+
return false;
|
|
67874
|
+
return true;
|
|
67875
|
+
}
|
|
67876
|
+
function isPlainObject(value) {
|
|
67877
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
67878
|
+
}
|
|
67879
|
+
function deepMerge(base, patch) {
|
|
67880
|
+
const out = { ...base };
|
|
67881
|
+
for (const key of Object.keys(patch)) {
|
|
67882
|
+
const patchVal = patch[key];
|
|
67883
|
+
const baseVal = base[key];
|
|
67884
|
+
if (isPlainObject(patchVal) && isPlainObject(baseVal)) {
|
|
67885
|
+
out[key] = { ...baseVal, ...patchVal };
|
|
67886
|
+
} else if (patchVal !== void 0) {
|
|
67887
|
+
out[key] = patchVal;
|
|
67888
|
+
}
|
|
67889
|
+
}
|
|
67890
|
+
return out;
|
|
67891
|
+
}
|
|
67892
|
+
|
|
67893
|
+
// dist/src/embeddings/disable.js
|
|
67894
|
+
var cachedStatus = null;
|
|
67895
|
+
function defaultResolveTransformers() {
|
|
67896
|
+
const sharedDir = join9(homedir5(), ".hivemind", "embed-deps");
|
|
67897
|
+
try {
|
|
67898
|
+
createRequire(pathToFileURL(`${sharedDir}/`).href).resolve("@huggingface/transformers");
|
|
67899
|
+
return;
|
|
67900
|
+
} catch {
|
|
67901
|
+
}
|
|
67902
|
+
createRequire(import.meta.url).resolve("@huggingface/transformers");
|
|
67903
|
+
}
|
|
67904
|
+
var _resolve = defaultResolveTransformers;
|
|
67905
|
+
var _readEnabled = getEmbeddingsEnabled;
|
|
67906
|
+
function detectStatus() {
|
|
67907
|
+
if (!_readEnabled())
|
|
67908
|
+
return "user-disabled";
|
|
67909
|
+
try {
|
|
67910
|
+
_resolve();
|
|
67911
|
+
return "enabled";
|
|
67912
|
+
} catch {
|
|
67913
|
+
return "no-transformers";
|
|
67914
|
+
}
|
|
67915
|
+
}
|
|
67916
|
+
function embeddingsStatus() {
|
|
67917
|
+
if (cachedStatus !== null)
|
|
67918
|
+
return cachedStatus;
|
|
67919
|
+
cachedStatus = detectStatus();
|
|
67920
|
+
return cachedStatus;
|
|
67921
|
+
}
|
|
67922
|
+
function embeddingsDisabled() {
|
|
67923
|
+
return embeddingsStatus() !== "enabled";
|
|
67924
|
+
}
|
|
67925
|
+
|
|
67707
67926
|
// dist/src/embeddings/client.js
|
|
67708
|
-
var SHARED_DAEMON_PATH =
|
|
67709
|
-
var
|
|
67927
|
+
var SHARED_DAEMON_PATH = join10(homedir6(), ".hivemind", "embed-deps", "embed-daemon.js");
|
|
67928
|
+
var log4 = (m26) => log("embed-client", m26);
|
|
67710
67929
|
function getUid() {
|
|
67711
67930
|
const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
|
|
67712
67931
|
return uid !== void 0 ? String(uid) : process.env.USER ?? "default";
|
|
67713
67932
|
}
|
|
67933
|
+
var _signalledMissingDeps = false;
|
|
67934
|
+
var _recycledStuckDaemon = false;
|
|
67714
67935
|
var EmbedClient = class {
|
|
67715
67936
|
socketPath;
|
|
67716
67937
|
pidPath;
|
|
@@ -67719,13 +67940,14 @@ var EmbedClient = class {
|
|
|
67719
67940
|
autoSpawn;
|
|
67720
67941
|
spawnWaitMs;
|
|
67721
67942
|
nextId = 0;
|
|
67943
|
+
helloVerified = false;
|
|
67722
67944
|
constructor(opts = {}) {
|
|
67723
67945
|
const uid = getUid();
|
|
67724
67946
|
const dir = opts.socketDir ?? "/tmp";
|
|
67725
67947
|
this.socketPath = socketPathFor(uid, dir);
|
|
67726
67948
|
this.pidPath = pidPathFor(uid, dir);
|
|
67727
67949
|
this.timeoutMs = opts.timeoutMs ?? DEFAULT_CLIENT_TIMEOUT_MS;
|
|
67728
|
-
this.daemonEntry = opts.daemonEntry ?? process.env.HIVEMIND_EMBED_DAEMON ?? (
|
|
67950
|
+
this.daemonEntry = opts.daemonEntry ?? process.env.HIVEMIND_EMBED_DAEMON ?? (existsSync5(SHARED_DAEMON_PATH) ? SHARED_DAEMON_PATH : void 0);
|
|
67729
67951
|
this.autoSpawn = opts.autoSpawn ?? true;
|
|
67730
67952
|
this.spawnWaitMs = opts.spawnWaitMs ?? 5e3;
|
|
67731
67953
|
}
|
|
@@ -67735,8 +67957,33 @@ var EmbedClient = class {
|
|
|
67735
67957
|
*
|
|
67736
67958
|
* Fire-and-forget spawn on miss: if the daemon isn't up, this call returns
|
|
67737
67959
|
* null AND kicks off a background spawn. The next call finds a ready daemon.
|
|
67960
|
+
*
|
|
67961
|
+
* Stuck-daemon recycle: if the daemon returns a transformers-missing
|
|
67962
|
+
* error (typical after a marketplace upgrade left an older daemon process
|
|
67963
|
+
* alive but with no node_modules accessible from its bundle path), we
|
|
67964
|
+
* SIGTERM it and clear its sock/pid so the very next call spawns a fresh
|
|
67965
|
+
* daemon from the current bundle. Without this, the stuck daemon would
|
|
67966
|
+
* keep poisoning every session until its 10-minute idle-out fires.
|
|
67738
67967
|
*/
|
|
67739
67968
|
async embed(text, kind = "document") {
|
|
67969
|
+
const v27 = await this.embedAttempt(text, kind);
|
|
67970
|
+
if (v27 !== "recycled")
|
|
67971
|
+
return v27;
|
|
67972
|
+
if (!this.autoSpawn)
|
|
67973
|
+
return null;
|
|
67974
|
+
this.trySpawnDaemon();
|
|
67975
|
+
await this.waitForDaemonReady();
|
|
67976
|
+
const retry = await this.embedAttempt(text, kind);
|
|
67977
|
+
return retry === "recycled" ? null : retry;
|
|
67978
|
+
}
|
|
67979
|
+
/**
|
|
67980
|
+
* One round-trip: connect → verify → embed. Returns:
|
|
67981
|
+
* - number[] : embedding vector (happy path)
|
|
67982
|
+
* - null : timeout / daemon error / transformers-missing
|
|
67983
|
+
* - "recycled": verifyDaemonOnce killed the daemon mid-call;
|
|
67984
|
+
* caller should respawn and retry once.
|
|
67985
|
+
*/
|
|
67986
|
+
async embedAttempt(text, kind) {
|
|
67740
67987
|
let sock;
|
|
67741
67988
|
try {
|
|
67742
67989
|
sock = await this.connectOnce();
|
|
@@ -67746,17 +67993,25 @@ var EmbedClient = class {
|
|
|
67746
67993
|
return null;
|
|
67747
67994
|
}
|
|
67748
67995
|
try {
|
|
67996
|
+
const recycled = await this.verifyDaemonOnce(sock);
|
|
67997
|
+
if (recycled) {
|
|
67998
|
+
return "recycled";
|
|
67999
|
+
}
|
|
67749
68000
|
const id = String(++this.nextId);
|
|
67750
68001
|
const req = { op: "embed", id, kind, text };
|
|
67751
68002
|
const resp = await this.sendAndWait(sock, req);
|
|
67752
68003
|
if (resp.error || !("embedding" in resp) || !resp.embedding) {
|
|
67753
|
-
|
|
68004
|
+
const err = resp.error ?? "no embedding";
|
|
68005
|
+
log4(`embed err: ${err}`);
|
|
68006
|
+
if (isTransformersMissingError(err)) {
|
|
68007
|
+
this.handleTransformersMissing(err);
|
|
68008
|
+
}
|
|
67754
68009
|
return null;
|
|
67755
68010
|
}
|
|
67756
68011
|
return resp.embedding;
|
|
67757
68012
|
} catch (e6) {
|
|
67758
68013
|
const err = e6 instanceof Error ? e6.message : String(e6);
|
|
67759
|
-
|
|
68014
|
+
log4(`embed failed: ${err}`);
|
|
67760
68015
|
return null;
|
|
67761
68016
|
} finally {
|
|
67762
68017
|
try {
|
|
@@ -67765,6 +68020,139 @@ var EmbedClient = class {
|
|
|
67765
68020
|
}
|
|
67766
68021
|
}
|
|
67767
68022
|
}
|
|
68023
|
+
/**
|
|
68024
|
+
* Poll for the sock file to come back after `trySpawnDaemon` — used by
|
|
68025
|
+
* the recycle retry path. Best-effort: caps at `spawnWaitMs` and
|
|
68026
|
+
* returns regardless so the retry attempt can run.
|
|
68027
|
+
*/
|
|
68028
|
+
async waitForDaemonReady() {
|
|
68029
|
+
const deadline = Date.now() + this.spawnWaitMs;
|
|
68030
|
+
while (Date.now() < deadline) {
|
|
68031
|
+
if (existsSync5(this.socketPath))
|
|
68032
|
+
return;
|
|
68033
|
+
await new Promise((r10) => setTimeout(r10, 50));
|
|
68034
|
+
}
|
|
68035
|
+
}
|
|
68036
|
+
/**
|
|
68037
|
+
* Send a `hello` on first successful connect per EmbedClient instance.
|
|
68038
|
+
* If the daemon answers with a path that doesn't match our configured
|
|
68039
|
+
* daemonEntry — typical after a marketplace upgrade replaced the bundle
|
|
68040
|
+
* — SIGTERM the daemon + clear sock/pid so the next call spawns from the
|
|
68041
|
+
* current bundle.
|
|
68042
|
+
*
|
|
68043
|
+
* `helloVerified` is set ONLY after we've seen a compatible response,
|
|
68044
|
+
* so a transient probe failure or a recycle-triggering mismatch leaves
|
|
68045
|
+
* the flag false; the next reconnect re-runs verification against
|
|
68046
|
+
* whatever daemon is then live (typically the fresh spawn).
|
|
68047
|
+
*/
|
|
68048
|
+
async verifyDaemonOnce(sock) {
|
|
68049
|
+
if (this.helloVerified)
|
|
68050
|
+
return false;
|
|
68051
|
+
if (!this.daemonEntry) {
|
|
68052
|
+
this.helloVerified = true;
|
|
68053
|
+
return false;
|
|
68054
|
+
}
|
|
68055
|
+
const id = String(++this.nextId);
|
|
68056
|
+
const req = { op: "hello", id };
|
|
68057
|
+
let resp;
|
|
68058
|
+
try {
|
|
68059
|
+
resp = await this.sendAndWait(sock, req);
|
|
68060
|
+
} catch (e6) {
|
|
68061
|
+
log4(`hello probe failed (inconclusive, will retry next connect): ${e6 instanceof Error ? e6.message : String(e6)}`);
|
|
68062
|
+
return false;
|
|
68063
|
+
}
|
|
68064
|
+
const hello = resp;
|
|
68065
|
+
if (_recycledStuckDaemon) {
|
|
68066
|
+
return false;
|
|
68067
|
+
}
|
|
68068
|
+
if (!hello.daemonPath) {
|
|
68069
|
+
_recycledStuckDaemon = true;
|
|
68070
|
+
log4(`daemon does not implement hello (older protocol); recycling`);
|
|
68071
|
+
this.recycleDaemon(hello.pid);
|
|
68072
|
+
return true;
|
|
68073
|
+
}
|
|
68074
|
+
if (hello.daemonPath !== this.daemonEntry && !existsSync5(hello.daemonPath)) {
|
|
68075
|
+
_recycledStuckDaemon = true;
|
|
68076
|
+
log4(`daemon path no longer on disk \u2014 running=${hello.daemonPath} (gone) expected=${this.daemonEntry}; recycling`);
|
|
68077
|
+
this.recycleDaemon(hello.pid);
|
|
68078
|
+
return true;
|
|
68079
|
+
}
|
|
68080
|
+
this.helloVerified = true;
|
|
68081
|
+
return false;
|
|
68082
|
+
}
|
|
68083
|
+
/**
|
|
68084
|
+
* On a transformers-missing error from the daemon, SIGTERM the stuck
|
|
68085
|
+
* daemon (the bundle daemon that can't find its deps) and clear
|
|
68086
|
+
* sock/pid so the next call spawns fresh. Also enqueue a one-time
|
|
68087
|
+
* notification telling the user to run `hivemind embeddings install`
|
|
68088
|
+
* — but only when the user has opted in. Suppressed when
|
|
68089
|
+
* embeddingsStatus() === "user-disabled" so we don't nag users who
|
|
68090
|
+
* explicitly chose to turn embeddings off.
|
|
68091
|
+
*/
|
|
68092
|
+
handleTransformersMissing(detail) {
|
|
68093
|
+
if (!_recycledStuckDaemon) {
|
|
68094
|
+
_recycledStuckDaemon = true;
|
|
68095
|
+
this.recycleDaemon(null);
|
|
68096
|
+
}
|
|
68097
|
+
if (_signalledMissingDeps)
|
|
68098
|
+
return;
|
|
68099
|
+
_signalledMissingDeps = true;
|
|
68100
|
+
let status;
|
|
68101
|
+
try {
|
|
68102
|
+
status = embeddingsStatus();
|
|
68103
|
+
} catch {
|
|
68104
|
+
status = "enabled";
|
|
68105
|
+
}
|
|
68106
|
+
if (status === "user-disabled")
|
|
68107
|
+
return;
|
|
68108
|
+
enqueueNotification({
|
|
68109
|
+
id: "embed-deps-missing",
|
|
68110
|
+
severity: "warn",
|
|
68111
|
+
title: "Hivemind embeddings disabled \u2014 deps missing",
|
|
68112
|
+
body: `Semantic memory search is off because @huggingface/transformers is not installed where the daemon can find it. Run \`hivemind embeddings install\` to enable.`,
|
|
68113
|
+
dedupKey: { reason: "transformers-missing", detail: detail.slice(0, 200) }
|
|
68114
|
+
}).catch((e6) => {
|
|
68115
|
+
log4(`enqueue embed-deps-missing failed: ${e6 instanceof Error ? e6.message : String(e6)}`);
|
|
68116
|
+
});
|
|
68117
|
+
}
|
|
68118
|
+
/**
|
|
68119
|
+
* Best-effort SIGTERM + sock/pid cleanup. Tolerant of every missing-file
|
|
68120
|
+
* combination and dead-PID cases.
|
|
68121
|
+
*
|
|
68122
|
+
* Identity check: gate the SIGTERM on the daemon's socket file still
|
|
68123
|
+
* existing. We know the daemon was alive moments ago (we either just
|
|
68124
|
+
* got a hello response or the caller saw a transformers-missing error
|
|
68125
|
+
* the daemon emitted), but if the socket file is gone by the time we
|
|
68126
|
+
* try to kill, the daemon process is also gone and the PID we
|
|
68127
|
+
* captured may already have been recycled by the OS to an unrelated
|
|
68128
|
+
* user process. Mirrors the gate added to `killEmbedDaemon` in the
|
|
68129
|
+
* CLI — same failure mode, rarer trigger.
|
|
68130
|
+
*/
|
|
68131
|
+
recycleDaemon(reportedPid) {
|
|
68132
|
+
let pid = reportedPid;
|
|
68133
|
+
if (pid === null) {
|
|
68134
|
+
try {
|
|
68135
|
+
pid = Number.parseInt(readFileSync5(this.pidPath, "utf-8").trim(), 10);
|
|
68136
|
+
} catch {
|
|
68137
|
+
}
|
|
68138
|
+
}
|
|
68139
|
+
if (Number.isFinite(pid) && pid !== null && pid > 0 && existsSync5(this.socketPath)) {
|
|
68140
|
+
try {
|
|
68141
|
+
process.kill(pid, "SIGTERM");
|
|
68142
|
+
} catch {
|
|
68143
|
+
}
|
|
68144
|
+
} else if (pid !== null) {
|
|
68145
|
+
log4(`recycle: socket gone, skipping SIGTERM on possibly-stale pid ${pid}`);
|
|
68146
|
+
}
|
|
68147
|
+
try {
|
|
68148
|
+
unlinkSync2(this.socketPath);
|
|
68149
|
+
} catch {
|
|
68150
|
+
}
|
|
68151
|
+
try {
|
|
68152
|
+
unlinkSync2(this.pidPath);
|
|
68153
|
+
} catch {
|
|
68154
|
+
}
|
|
68155
|
+
}
|
|
67768
68156
|
/**
|
|
67769
68157
|
* Wait up to spawnWaitMs for the daemon to accept connections, spawning if
|
|
67770
68158
|
* necessary. Meant for SessionStart / long-running batches — not the hot path.
|
|
@@ -67788,7 +68176,7 @@ var EmbedClient = class {
|
|
|
67788
68176
|
}
|
|
67789
68177
|
}
|
|
67790
68178
|
connectOnce() {
|
|
67791
|
-
return new Promise((
|
|
68179
|
+
return new Promise((resolve6, reject) => {
|
|
67792
68180
|
const sock = connect(this.socketPath);
|
|
67793
68181
|
const to3 = setTimeout(() => {
|
|
67794
68182
|
sock.destroy();
|
|
@@ -67796,7 +68184,7 @@ var EmbedClient = class {
|
|
|
67796
68184
|
}, this.timeoutMs);
|
|
67797
68185
|
sock.once("connect", () => {
|
|
67798
68186
|
clearTimeout(to3);
|
|
67799
|
-
|
|
68187
|
+
resolve6(sock);
|
|
67800
68188
|
});
|
|
67801
68189
|
sock.once("error", (e6) => {
|
|
67802
68190
|
clearTimeout(to3);
|
|
@@ -67807,16 +68195,16 @@ var EmbedClient = class {
|
|
|
67807
68195
|
trySpawnDaemon() {
|
|
67808
68196
|
let fd;
|
|
67809
68197
|
try {
|
|
67810
|
-
fd =
|
|
68198
|
+
fd = openSync2(this.pidPath, "wx", 384);
|
|
67811
68199
|
writeSync(fd, String(process.pid));
|
|
67812
68200
|
} catch (e6) {
|
|
67813
68201
|
if (this.isPidFileStale()) {
|
|
67814
68202
|
try {
|
|
67815
|
-
|
|
68203
|
+
unlinkSync2(this.pidPath);
|
|
67816
68204
|
} catch {
|
|
67817
68205
|
}
|
|
67818
68206
|
try {
|
|
67819
|
-
fd =
|
|
68207
|
+
fd = openSync2(this.pidPath, "wx", 384);
|
|
67820
68208
|
writeSync(fd, String(process.pid));
|
|
67821
68209
|
} catch {
|
|
67822
68210
|
return;
|
|
@@ -67825,11 +68213,11 @@ var EmbedClient = class {
|
|
|
67825
68213
|
return;
|
|
67826
68214
|
}
|
|
67827
68215
|
}
|
|
67828
|
-
if (!this.daemonEntry || !
|
|
67829
|
-
|
|
68216
|
+
if (!this.daemonEntry || !existsSync5(this.daemonEntry)) {
|
|
68217
|
+
log4(`daemonEntry not configured or missing: ${this.daemonEntry}`);
|
|
67830
68218
|
try {
|
|
67831
|
-
|
|
67832
|
-
|
|
68219
|
+
closeSync2(fd);
|
|
68220
|
+
unlinkSync2(this.pidPath);
|
|
67833
68221
|
} catch {
|
|
67834
68222
|
}
|
|
67835
68223
|
return;
|
|
@@ -67841,14 +68229,14 @@ var EmbedClient = class {
|
|
|
67841
68229
|
env: process.env
|
|
67842
68230
|
});
|
|
67843
68231
|
child.unref();
|
|
67844
|
-
|
|
68232
|
+
log4(`spawned daemon pid=${child.pid}`);
|
|
67845
68233
|
} finally {
|
|
67846
|
-
|
|
68234
|
+
closeSync2(fd);
|
|
67847
68235
|
}
|
|
67848
68236
|
}
|
|
67849
68237
|
isPidFileStale() {
|
|
67850
68238
|
try {
|
|
67851
|
-
const raw =
|
|
68239
|
+
const raw = readFileSync5(this.pidPath, "utf-8").trim();
|
|
67852
68240
|
const pid = Number(raw);
|
|
67853
68241
|
if (!pid || Number.isNaN(pid))
|
|
67854
68242
|
return true;
|
|
@@ -67866,9 +68254,9 @@ var EmbedClient = class {
|
|
|
67866
68254
|
const deadline = Date.now() + this.spawnWaitMs;
|
|
67867
68255
|
let delay = 30;
|
|
67868
68256
|
while (Date.now() < deadline) {
|
|
67869
|
-
await
|
|
68257
|
+
await sleep3(delay);
|
|
67870
68258
|
delay = Math.min(delay * 1.5, 300);
|
|
67871
|
-
if (!
|
|
68259
|
+
if (!existsSync5(this.socketPath))
|
|
67872
68260
|
continue;
|
|
67873
68261
|
try {
|
|
67874
68262
|
return await this.connectOnce();
|
|
@@ -67878,7 +68266,7 @@ var EmbedClient = class {
|
|
|
67878
68266
|
throw new Error("daemon did not become ready within spawnWaitMs");
|
|
67879
68267
|
}
|
|
67880
68268
|
sendAndWait(sock, req) {
|
|
67881
|
-
return new Promise((
|
|
68269
|
+
return new Promise((resolve6, reject) => {
|
|
67882
68270
|
let buf = "";
|
|
67883
68271
|
const to3 = setTimeout(() => {
|
|
67884
68272
|
sock.destroy();
|
|
@@ -67893,7 +68281,7 @@ var EmbedClient = class {
|
|
|
67893
68281
|
const line = buf.slice(0, nl3);
|
|
67894
68282
|
clearTimeout(to3);
|
|
67895
68283
|
try {
|
|
67896
|
-
|
|
68284
|
+
resolve6(JSON.parse(line));
|
|
67897
68285
|
} catch (e6) {
|
|
67898
68286
|
reject(e6);
|
|
67899
68287
|
}
|
|
@@ -67910,9 +68298,14 @@ var EmbedClient = class {
|
|
|
67910
68298
|
});
|
|
67911
68299
|
}
|
|
67912
68300
|
};
|
|
67913
|
-
function
|
|
68301
|
+
function sleep3(ms3) {
|
|
67914
68302
|
return new Promise((r10) => setTimeout(r10, ms3));
|
|
67915
68303
|
}
|
|
68304
|
+
function isTransformersMissingError(err) {
|
|
68305
|
+
if (/hivemind embeddings install/i.test(err))
|
|
68306
|
+
return true;
|
|
68307
|
+
return /@huggingface\/transformers/i.test(err);
|
|
68308
|
+
}
|
|
67916
68309
|
|
|
67917
68310
|
// dist/src/embeddings/sql.js
|
|
67918
68311
|
function embeddingSqlLiteral(vec) {
|
|
@@ -67927,42 +68320,6 @@ function embeddingSqlLiteral(vec) {
|
|
|
67927
68320
|
return `ARRAY[${parts.join(",")}]::float4[]`;
|
|
67928
68321
|
}
|
|
67929
68322
|
|
|
67930
|
-
// dist/src/embeddings/disable.js
|
|
67931
|
-
import { createRequire } from "node:module";
|
|
67932
|
-
import { homedir as homedir4 } from "node:os";
|
|
67933
|
-
import { join as join8 } from "node:path";
|
|
67934
|
-
import { pathToFileURL } from "node:url";
|
|
67935
|
-
var cachedStatus = null;
|
|
67936
|
-
function defaultResolveTransformers() {
|
|
67937
|
-
try {
|
|
67938
|
-
createRequire(import.meta.url).resolve("@huggingface/transformers");
|
|
67939
|
-
return;
|
|
67940
|
-
} catch {
|
|
67941
|
-
}
|
|
67942
|
-
const sharedDir = join8(homedir4(), ".hivemind", "embed-deps");
|
|
67943
|
-
createRequire(pathToFileURL(`${sharedDir}/`).href).resolve("@huggingface/transformers");
|
|
67944
|
-
}
|
|
67945
|
-
var _resolve = defaultResolveTransformers;
|
|
67946
|
-
function detectStatus() {
|
|
67947
|
-
if (process.env.HIVEMIND_EMBEDDINGS === "false")
|
|
67948
|
-
return "env-disabled";
|
|
67949
|
-
try {
|
|
67950
|
-
_resolve();
|
|
67951
|
-
return "enabled";
|
|
67952
|
-
} catch {
|
|
67953
|
-
return "no-transformers";
|
|
67954
|
-
}
|
|
67955
|
-
}
|
|
67956
|
-
function embeddingsStatus() {
|
|
67957
|
-
if (cachedStatus !== null)
|
|
67958
|
-
return cachedStatus;
|
|
67959
|
-
cachedStatus = detectStatus();
|
|
67960
|
-
return cachedStatus;
|
|
67961
|
-
}
|
|
67962
|
-
function embeddingsDisabled() {
|
|
67963
|
-
return embeddingsStatus() !== "enabled";
|
|
67964
|
-
}
|
|
67965
|
-
|
|
67966
68323
|
// dist/src/hooks/virtual-table-query.js
|
|
67967
68324
|
var INDEX_LIMIT_PER_SECTION = 50;
|
|
67968
68325
|
function buildVirtualIndexContent(summaryRows, sessionRows = [], opts = {}) {
|
|
@@ -68055,7 +68412,7 @@ function normalizeSessionMessage(path2, message) {
|
|
|
68055
68412
|
return normalizeContent(path2, raw);
|
|
68056
68413
|
}
|
|
68057
68414
|
function resolveEmbedDaemonPath() {
|
|
68058
|
-
return
|
|
68415
|
+
return join11(dirname5(fileURLToPath(import.meta.url)), "..", "embeddings", "embed-daemon.js");
|
|
68059
68416
|
}
|
|
68060
68417
|
function joinSessionMessages(path2, messages) {
|
|
68061
68418
|
return messages.map((message) => normalizeSessionMessage(path2, message)).join("\n");
|
|
@@ -68621,7 +68978,7 @@ var DeeplakeFs = class _DeeplakeFs {
|
|
|
68621
68978
|
|
|
68622
68979
|
// node_modules/yargs-parser/build/lib/index.js
|
|
68623
68980
|
import { format } from "util";
|
|
68624
|
-
import { normalize, resolve as
|
|
68981
|
+
import { normalize, resolve as resolve5 } from "path";
|
|
68625
68982
|
|
|
68626
68983
|
// node_modules/yargs-parser/build/lib/string-utils.js
|
|
68627
68984
|
function camelCase2(str) {
|
|
@@ -69559,7 +69916,7 @@ function stripQuotes(val) {
|
|
|
69559
69916
|
}
|
|
69560
69917
|
|
|
69561
69918
|
// node_modules/yargs-parser/build/lib/index.js
|
|
69562
|
-
import { readFileSync as
|
|
69919
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
69563
69920
|
import { createRequire as createRequire2 } from "node:module";
|
|
69564
69921
|
var _a3;
|
|
69565
69922
|
var _b;
|
|
@@ -69581,12 +69938,12 @@ var parser = new YargsParser({
|
|
|
69581
69938
|
},
|
|
69582
69939
|
format,
|
|
69583
69940
|
normalize,
|
|
69584
|
-
resolve:
|
|
69941
|
+
resolve: resolve5,
|
|
69585
69942
|
require: (path2) => {
|
|
69586
69943
|
if (typeof require2 !== "undefined") {
|
|
69587
69944
|
return require2(path2);
|
|
69588
69945
|
} else if (path2.match(/\.json$/)) {
|
|
69589
|
-
return JSON.parse(
|
|
69946
|
+
return JSON.parse(readFileSync6(path2, "utf8"));
|
|
69590
69947
|
} else {
|
|
69591
69948
|
throw Error("only .json config files are supported in ESM");
|
|
69592
69949
|
}
|
|
@@ -69606,11 +69963,11 @@ var lib_default = yargsParser;
|
|
|
69606
69963
|
|
|
69607
69964
|
// dist/src/shell/grep-interceptor.js
|
|
69608
69965
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
69609
|
-
import { dirname as
|
|
69966
|
+
import { dirname as dirname6, join as join12 } from "node:path";
|
|
69610
69967
|
var SEMANTIC_SEARCH_ENABLED = process.env.HIVEMIND_SEMANTIC_SEARCH !== "false" && !embeddingsDisabled();
|
|
69611
69968
|
var SEMANTIC_EMBED_TIMEOUT_MS = Number(process.env.HIVEMIND_SEMANTIC_EMBED_TIMEOUT_MS ?? "500");
|
|
69612
69969
|
function resolveGrepEmbedDaemonPath() {
|
|
69613
|
-
return
|
|
69970
|
+
return join12(dirname6(fileURLToPath2(import.meta.url)), "..", "embeddings", "embed-daemon.js");
|
|
69614
69971
|
}
|
|
69615
69972
|
var sharedGrepEmbedClient = null;
|
|
69616
69973
|
function getGrepEmbedClient() {
|