@deeplake/hivemind 0.7.32 → 0.7.34
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 +332 -189
- package/codex/bundle/capture.js +365 -332
- package/codex/bundle/commands/auth-login.js +163 -30
- package/codex/bundle/pre-tool-use.js +334 -301
- package/codex/bundle/session-start-setup.js +193 -60
- package/codex/bundle/session-start.js +229 -87
- package/codex/bundle/shell/deeplake-shell.js +328 -295
- package/codex/bundle/skillify-worker.js +26 -18
- package/codex/bundle/stop.js +450 -394
- package/codex/bundle/wiki-worker.js +174 -292
- package/cursor/bundle/capture.js +448 -392
- package/cursor/bundle/commands/auth-login.js +163 -30
- package/cursor/bundle/pre-tool-use.js +324 -291
- package/cursor/bundle/session-end.js +43 -20
- package/cursor/bundle/session-start.js +272 -130
- package/cursor/bundle/shell/deeplake-shell.js +328 -295
- package/cursor/bundle/skillify-worker.js +26 -18
- package/cursor/bundle/wiki-worker.js +174 -292
- package/hermes/bundle/capture.js +448 -392
- package/hermes/bundle/commands/auth-login.js +163 -30
- package/hermes/bundle/pre-tool-use.js +324 -291
- package/hermes/bundle/session-end.js +43 -20
- package/hermes/bundle/session-start.js +269 -127
- package/hermes/bundle/shell/deeplake-shell.js +328 -295
- package/hermes/bundle/skillify-worker.js +26 -18
- package/hermes/bundle/wiki-worker.js +174 -292
- package/mcp/bundle/server.js +190 -57
- package/openclaw/dist/index.js +160 -32
- package/openclaw/dist/skillify-worker.js +26 -18
- package/openclaw/openclaw.plugin.json +1 -1
- package/openclaw/package.json +1 -1
- package/package.json +1 -1
|
@@ -17,21 +17,21 @@ __export(index_marker_store_exports, {
|
|
|
17
17
|
hasFreshIndexMarker: () => hasFreshIndexMarker,
|
|
18
18
|
writeIndexMarker: () => writeIndexMarker
|
|
19
19
|
});
|
|
20
|
-
import { existsSync as existsSync2, mkdirSync, readFileSync as
|
|
21
|
-
import { join as
|
|
20
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
21
|
+
import { join as join5 } from "node:path";
|
|
22
22
|
import { tmpdir } from "node:os";
|
|
23
23
|
function getIndexMarkerDir() {
|
|
24
|
-
return process.env.HIVEMIND_INDEX_MARKER_DIR ??
|
|
24
|
+
return process.env.HIVEMIND_INDEX_MARKER_DIR ?? join5(tmpdir(), "hivemind-deeplake-indexes");
|
|
25
25
|
}
|
|
26
26
|
function buildIndexMarkerPath(workspaceId, orgId, table, suffix) {
|
|
27
27
|
const markerKey = [workspaceId, orgId, table, suffix].join("__").replace(/[^a-zA-Z0-9_.-]/g, "_");
|
|
28
|
-
return
|
|
28
|
+
return join5(getIndexMarkerDir(), `${markerKey}.json`);
|
|
29
29
|
}
|
|
30
30
|
function hasFreshIndexMarker(markerPath) {
|
|
31
31
|
if (!existsSync2(markerPath))
|
|
32
32
|
return false;
|
|
33
33
|
try {
|
|
34
|
-
const raw = JSON.parse(
|
|
34
|
+
const raw = JSON.parse(readFileSync4(markerPath, "utf-8"));
|
|
35
35
|
const updatedAt = raw.updatedAt ? new Date(raw.updatedAt).getTime() : NaN;
|
|
36
36
|
if (!Number.isFinite(updatedAt) || Date.now() - updatedAt > INDEX_MARKER_TTL_MS)
|
|
37
37
|
return false;
|
|
@@ -41,8 +41,8 @@ function hasFreshIndexMarker(markerPath) {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
function writeIndexMarker(markerPath) {
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
mkdirSync3(getIndexMarkerDir(), { recursive: true });
|
|
45
|
+
writeFileSync3(markerPath, JSON.stringify({ updatedAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf-8");
|
|
46
46
|
}
|
|
47
47
|
var INDEX_MARKER_TTL_MS;
|
|
48
48
|
var init_index_marker_store = __esm({
|
|
@@ -55,7 +55,7 @@ var init_index_marker_store = __esm({
|
|
|
55
55
|
// dist/src/hooks/codex/pre-tool-use.js
|
|
56
56
|
import { execFileSync } from "node:child_process";
|
|
57
57
|
import { existsSync as existsSync5 } from "node:fs";
|
|
58
|
-
import { join as
|
|
58
|
+
import { join as join12, dirname as dirname3 } from "node:path";
|
|
59
59
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
60
60
|
|
|
61
61
|
// dist/src/utils/stdin.js
|
|
@@ -153,6 +153,125 @@ function deeplakeClientHeader() {
|
|
|
153
153
|
return { [DEEPLAKE_CLIENT_HEADER]: deeplakeClientValue() };
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
// dist/src/notifications/queue.js
|
|
157
|
+
import { readFileSync as readFileSync2, writeFileSync, renameSync, mkdirSync, openSync, closeSync, unlinkSync, statSync } from "node:fs";
|
|
158
|
+
import { join as join3, resolve } from "node:path";
|
|
159
|
+
import { homedir as homedir3 } from "node:os";
|
|
160
|
+
import { setTimeout as sleep } from "node:timers/promises";
|
|
161
|
+
var log2 = (msg) => log("notifications-queue", msg);
|
|
162
|
+
var LOCK_RETRY_MAX = 50;
|
|
163
|
+
var LOCK_RETRY_BASE_MS = 5;
|
|
164
|
+
var LOCK_STALE_MS = 5e3;
|
|
165
|
+
function queuePath() {
|
|
166
|
+
return join3(homedir3(), ".deeplake", "notifications-queue.json");
|
|
167
|
+
}
|
|
168
|
+
function lockPath() {
|
|
169
|
+
return `${queuePath()}.lock`;
|
|
170
|
+
}
|
|
171
|
+
function readQueue() {
|
|
172
|
+
try {
|
|
173
|
+
const raw = readFileSync2(queuePath(), "utf-8");
|
|
174
|
+
const parsed = JSON.parse(raw);
|
|
175
|
+
if (!parsed || !Array.isArray(parsed.queue)) {
|
|
176
|
+
log2(`queue malformed \u2192 treating as empty`);
|
|
177
|
+
return { queue: [] };
|
|
178
|
+
}
|
|
179
|
+
return { queue: parsed.queue };
|
|
180
|
+
} catch {
|
|
181
|
+
return { queue: [] };
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function _isQueuePathInsideHome(path, home) {
|
|
185
|
+
const r = resolve(path);
|
|
186
|
+
const h = resolve(home);
|
|
187
|
+
return r.startsWith(h + "/") || r === h;
|
|
188
|
+
}
|
|
189
|
+
function writeQueue(q) {
|
|
190
|
+
const path = queuePath();
|
|
191
|
+
const home = resolve(homedir3());
|
|
192
|
+
if (!_isQueuePathInsideHome(path, home)) {
|
|
193
|
+
throw new Error(`notifications-queue write blocked: ${path} is outside ${home}`);
|
|
194
|
+
}
|
|
195
|
+
mkdirSync(join3(home, ".deeplake"), { recursive: true, mode: 448 });
|
|
196
|
+
const tmp = `${path}.${process.pid}.tmp`;
|
|
197
|
+
writeFileSync(tmp, JSON.stringify(q, null, 2), { mode: 384 });
|
|
198
|
+
renameSync(tmp, path);
|
|
199
|
+
}
|
|
200
|
+
async function withQueueLock(fn) {
|
|
201
|
+
const path = lockPath();
|
|
202
|
+
mkdirSync(join3(homedir3(), ".deeplake"), { recursive: true, mode: 448 });
|
|
203
|
+
let fd = null;
|
|
204
|
+
for (let attempt = 0; attempt < LOCK_RETRY_MAX; attempt++) {
|
|
205
|
+
try {
|
|
206
|
+
fd = openSync(path, "wx", 384);
|
|
207
|
+
break;
|
|
208
|
+
} catch (e) {
|
|
209
|
+
const code = e.code;
|
|
210
|
+
if (code !== "EEXIST")
|
|
211
|
+
throw e;
|
|
212
|
+
try {
|
|
213
|
+
const age = Date.now() - statSync(path).mtimeMs;
|
|
214
|
+
if (age > LOCK_STALE_MS) {
|
|
215
|
+
unlinkSync(path);
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
} catch {
|
|
219
|
+
}
|
|
220
|
+
const delay = LOCK_RETRY_BASE_MS * (attempt + 1);
|
|
221
|
+
await sleep(delay);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (fd === null) {
|
|
225
|
+
log2(`lock acquisition gave up after ${LOCK_RETRY_MAX} attempts \u2014 proceeding unlocked (last-writer-wins)`);
|
|
226
|
+
return fn();
|
|
227
|
+
}
|
|
228
|
+
try {
|
|
229
|
+
return fn();
|
|
230
|
+
} finally {
|
|
231
|
+
try {
|
|
232
|
+
closeSync(fd);
|
|
233
|
+
} catch {
|
|
234
|
+
}
|
|
235
|
+
try {
|
|
236
|
+
unlinkSync(path);
|
|
237
|
+
} catch {
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
function sameDedupKey(a, b) {
|
|
242
|
+
if (a.id !== b.id)
|
|
243
|
+
return false;
|
|
244
|
+
return JSON.stringify(a.dedupKey) === JSON.stringify(b.dedupKey);
|
|
245
|
+
}
|
|
246
|
+
async function enqueueNotification(n) {
|
|
247
|
+
await withQueueLock(() => {
|
|
248
|
+
const q = readQueue();
|
|
249
|
+
if (q.queue.some((existing) => sameDedupKey(existing, n))) {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
q.queue.push(n);
|
|
253
|
+
writeQueue(q);
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// dist/src/commands/auth-creds.js
|
|
258
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2 } from "node:fs";
|
|
259
|
+
import { join as join4 } from "node:path";
|
|
260
|
+
import { homedir as homedir4 } from "node:os";
|
|
261
|
+
function configDir() {
|
|
262
|
+
return join4(homedir4(), ".deeplake");
|
|
263
|
+
}
|
|
264
|
+
function credsPath() {
|
|
265
|
+
return join4(configDir(), "credentials.json");
|
|
266
|
+
}
|
|
267
|
+
function loadCredentials() {
|
|
268
|
+
try {
|
|
269
|
+
return JSON.parse(readFileSync3(credsPath(), "utf-8"));
|
|
270
|
+
} catch {
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
156
275
|
// dist/src/deeplake-api.js
|
|
157
276
|
var indexMarkerStorePromise = null;
|
|
158
277
|
function getIndexMarkerStore() {
|
|
@@ -160,7 +279,7 @@ function getIndexMarkerStore() {
|
|
|
160
279
|
indexMarkerStorePromise = Promise.resolve().then(() => (init_index_marker_store(), index_marker_store_exports));
|
|
161
280
|
return indexMarkerStorePromise;
|
|
162
281
|
}
|
|
163
|
-
var
|
|
282
|
+
var log3 = (msg) => log("sdk", msg);
|
|
164
283
|
function summarizeSql(sql, maxLen = 220) {
|
|
165
284
|
const compact = sql.replace(/\s+/g, " ").trim();
|
|
166
285
|
return compact.length > maxLen ? `${compact.slice(0, maxLen)}...` : compact;
|
|
@@ -172,7 +291,38 @@ function traceSql(msg) {
|
|
|
172
291
|
process.stderr.write(`[deeplake-sql] ${msg}
|
|
173
292
|
`);
|
|
174
293
|
if (process.env.HIVEMIND_DEBUG === "1")
|
|
175
|
-
|
|
294
|
+
log3(msg);
|
|
295
|
+
}
|
|
296
|
+
var _signalledBalanceExhausted = false;
|
|
297
|
+
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
298
|
+
if (status !== 402)
|
|
299
|
+
return;
|
|
300
|
+
if (!bodyText.includes("balance_cents"))
|
|
301
|
+
return;
|
|
302
|
+
if (_signalledBalanceExhausted)
|
|
303
|
+
return;
|
|
304
|
+
_signalledBalanceExhausted = true;
|
|
305
|
+
log3(`balance exhausted \u2014 enqueuing session-start banner (body=${bodyText.slice(0, 120)})`);
|
|
306
|
+
enqueueNotification({
|
|
307
|
+
id: "balance-exhausted",
|
|
308
|
+
severity: "warn",
|
|
309
|
+
transient: true,
|
|
310
|
+
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
311
|
+
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
312
|
+
dedupKey: { reason: "balance-zero" }
|
|
313
|
+
}).catch((e) => {
|
|
314
|
+
log3(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
function billingUrl() {
|
|
318
|
+
try {
|
|
319
|
+
const c = loadCredentials();
|
|
320
|
+
if (c?.orgName && c?.workspaceId) {
|
|
321
|
+
return `https://deeplake.ai/${encodeURIComponent(c.orgName)}/workspace/${encodeURIComponent(c.workspaceId)}/billing`;
|
|
322
|
+
}
|
|
323
|
+
} catch {
|
|
324
|
+
}
|
|
325
|
+
return "https://deeplake.ai";
|
|
176
326
|
}
|
|
177
327
|
var RETRYABLE_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
178
328
|
var MAX_RETRIES = 3;
|
|
@@ -181,7 +331,7 @@ var MAX_CONCURRENCY = 5;
|
|
|
181
331
|
function getQueryTimeoutMs() {
|
|
182
332
|
return Number(process.env.HIVEMIND_QUERY_TIMEOUT_MS ?? 1e4);
|
|
183
333
|
}
|
|
184
|
-
function
|
|
334
|
+
function sleep2(ms) {
|
|
185
335
|
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
186
336
|
}
|
|
187
337
|
function isTimeoutError(error) {
|
|
@@ -283,8 +433,8 @@ var DeeplakeApi = class {
|
|
|
283
433
|
lastError = e instanceof Error ? e : new Error(String(e));
|
|
284
434
|
if (attempt < MAX_RETRIES) {
|
|
285
435
|
const delay = BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200;
|
|
286
|
-
|
|
287
|
-
await
|
|
436
|
+
log3(`query retry ${attempt + 1}/${MAX_RETRIES} (fetch error: ${lastError.message}) in ${delay.toFixed(0)}ms`);
|
|
437
|
+
await sleep2(delay);
|
|
288
438
|
continue;
|
|
289
439
|
}
|
|
290
440
|
throw lastError;
|
|
@@ -300,10 +450,11 @@ var DeeplakeApi = class {
|
|
|
300
450
|
const alreadyExists = resp.status === 500 && isDuplicateIndexError(text);
|
|
301
451
|
if (!alreadyExists && attempt < MAX_RETRIES && (RETRYABLE_CODES.has(resp.status) || retryable403)) {
|
|
302
452
|
const delay = BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200;
|
|
303
|
-
|
|
304
|
-
await
|
|
453
|
+
log3(`query retry ${attempt + 1}/${MAX_RETRIES} (${resp.status}) in ${delay.toFixed(0)}ms`);
|
|
454
|
+
await sleep2(delay);
|
|
305
455
|
continue;
|
|
306
456
|
}
|
|
457
|
+
maybeSignalBalanceExhausted(resp.status, text);
|
|
307
458
|
throw new Error(`Query failed: ${resp.status}: ${text.slice(0, 200)}`);
|
|
308
459
|
}
|
|
309
460
|
throw lastError ?? new Error("Query failed: max retries exceeded");
|
|
@@ -324,7 +475,7 @@ var DeeplakeApi = class {
|
|
|
324
475
|
const chunk = rows.slice(i, i + CONCURRENCY);
|
|
325
476
|
await Promise.allSettled(chunk.map((r) => this.upsertRowSql(r)));
|
|
326
477
|
}
|
|
327
|
-
|
|
478
|
+
log3(`commit: ${rows.length} rows`);
|
|
328
479
|
}
|
|
329
480
|
async upsertRowSql(row) {
|
|
330
481
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -380,7 +531,7 @@ var DeeplakeApi = class {
|
|
|
380
531
|
markers.writeIndexMarker(markerPath);
|
|
381
532
|
return;
|
|
382
533
|
}
|
|
383
|
-
|
|
534
|
+
log3(`index "${indexName}" skipped: ${e.message}`);
|
|
384
535
|
}
|
|
385
536
|
}
|
|
386
537
|
/**
|
|
@@ -470,13 +621,13 @@ var DeeplakeApi = class {
|
|
|
470
621
|
};
|
|
471
622
|
}
|
|
472
623
|
if (attempt < MAX_RETRIES && RETRYABLE_CODES.has(resp.status)) {
|
|
473
|
-
await
|
|
624
|
+
await sleep2(BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200);
|
|
474
625
|
continue;
|
|
475
626
|
}
|
|
476
627
|
return { tables: [], cacheable: false };
|
|
477
628
|
} catch {
|
|
478
629
|
if (attempt < MAX_RETRIES) {
|
|
479
|
-
await
|
|
630
|
+
await sleep2(BASE_DELAY_MS * Math.pow(2, attempt));
|
|
480
631
|
continue;
|
|
481
632
|
}
|
|
482
633
|
return { tables: [], cacheable: false };
|
|
@@ -504,9 +655,9 @@ var DeeplakeApi = class {
|
|
|
504
655
|
} catch (err) {
|
|
505
656
|
lastErr = err;
|
|
506
657
|
const msg = err instanceof Error ? err.message : String(err);
|
|
507
|
-
|
|
658
|
+
log3(`CREATE TABLE "${label}" attempt ${attempt + 1}/${OUTER_BACKOFFS_MS.length + 1} failed: ${msg}`);
|
|
508
659
|
if (attempt < OUTER_BACKOFFS_MS.length) {
|
|
509
|
-
await
|
|
660
|
+
await sleep2(OUTER_BACKOFFS_MS[attempt]);
|
|
510
661
|
}
|
|
511
662
|
}
|
|
512
663
|
}
|
|
@@ -517,9 +668,9 @@ var DeeplakeApi = class {
|
|
|
517
668
|
const tbl = sqlIdent(name ?? this.tableName);
|
|
518
669
|
const tables = await this.listTables();
|
|
519
670
|
if (!tables.includes(tbl)) {
|
|
520
|
-
|
|
671
|
+
log3(`table "${tbl}" not found, creating`);
|
|
521
672
|
await this.createTableWithRetry(`CREATE TABLE IF NOT EXISTS "${tbl}" (id TEXT NOT NULL DEFAULT '', path TEXT NOT NULL DEFAULT '', filename TEXT NOT NULL DEFAULT '', summary TEXT NOT NULL DEFAULT '', summary_embedding FLOAT4[], author TEXT NOT NULL DEFAULT '', mime_type TEXT NOT NULL DEFAULT 'text/plain', size_bytes BIGINT NOT NULL DEFAULT 0, project TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '', agent TEXT NOT NULL DEFAULT '', plugin_version TEXT NOT NULL DEFAULT '', creation_date TEXT NOT NULL DEFAULT '', last_update_date TEXT NOT NULL DEFAULT '') USING deeplake`, tbl);
|
|
522
|
-
|
|
673
|
+
log3(`table "${tbl}" created`);
|
|
523
674
|
if (!tables.includes(tbl))
|
|
524
675
|
this._tablesCache = [...tables, tbl];
|
|
525
676
|
}
|
|
@@ -532,9 +683,9 @@ var DeeplakeApi = class {
|
|
|
532
683
|
const safe = sqlIdent(name);
|
|
533
684
|
const tables = await this.listTables();
|
|
534
685
|
if (!tables.includes(safe)) {
|
|
535
|
-
|
|
686
|
+
log3(`table "${safe}" not found, creating`);
|
|
536
687
|
await this.createTableWithRetry(`CREATE TABLE IF NOT EXISTS "${safe}" (id TEXT NOT NULL DEFAULT '', path TEXT NOT NULL DEFAULT '', filename TEXT NOT NULL DEFAULT '', message JSONB, message_embedding FLOAT4[], author TEXT NOT NULL DEFAULT '', mime_type TEXT NOT NULL DEFAULT 'application/json', size_bytes BIGINT NOT NULL DEFAULT 0, project TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '', agent TEXT NOT NULL DEFAULT '', plugin_version TEXT NOT NULL DEFAULT '', creation_date TEXT NOT NULL DEFAULT '', last_update_date TEXT NOT NULL DEFAULT '') USING deeplake`, safe);
|
|
537
|
-
|
|
688
|
+
log3(`table "${safe}" created`);
|
|
538
689
|
if (!tables.includes(safe))
|
|
539
690
|
this._tablesCache = [...tables, safe];
|
|
540
691
|
}
|
|
@@ -557,9 +708,9 @@ var DeeplakeApi = class {
|
|
|
557
708
|
const safe = sqlIdent(name);
|
|
558
709
|
const tables = await this.listTables();
|
|
559
710
|
if (!tables.includes(safe)) {
|
|
560
|
-
|
|
711
|
+
log3(`table "${safe}" not found, creating`);
|
|
561
712
|
await this.createTableWithRetry(`CREATE TABLE IF NOT EXISTS "${safe}" (id TEXT NOT NULL DEFAULT '', name TEXT NOT NULL DEFAULT '', project TEXT NOT NULL DEFAULT '', project_key TEXT NOT NULL DEFAULT '', local_path TEXT NOT NULL DEFAULT '', install TEXT NOT NULL DEFAULT 'project', source_sessions TEXT NOT NULL DEFAULT '[]', source_agent TEXT NOT NULL DEFAULT '', scope TEXT NOT NULL DEFAULT 'me', author TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '', trigger_text TEXT NOT NULL DEFAULT '', body TEXT NOT NULL DEFAULT '', version BIGINT NOT NULL DEFAULT 1, created_at TEXT NOT NULL DEFAULT '', updated_at TEXT NOT NULL DEFAULT '') USING deeplake`, safe);
|
|
562
|
-
|
|
713
|
+
log3(`table "${safe}" created`);
|
|
563
714
|
if (!tables.includes(safe))
|
|
564
715
|
this._tablesCache = [...tables, safe];
|
|
565
716
|
}
|
|
@@ -1049,9 +1200,9 @@ function capOutputForClaude(output, options = {}) {
|
|
|
1049
1200
|
// dist/src/embeddings/client.js
|
|
1050
1201
|
import { connect } from "node:net";
|
|
1051
1202
|
import { spawn } from "node:child_process";
|
|
1052
|
-
import { openSync as openSync2, closeSync as closeSync2, writeSync, unlinkSync as
|
|
1053
|
-
import { homedir as
|
|
1054
|
-
import { join as
|
|
1203
|
+
import { openSync as openSync2, closeSync as closeSync2, writeSync, unlinkSync as unlinkSync3, existsSync as existsSync3, readFileSync as readFileSync5 } from "node:fs";
|
|
1204
|
+
import { homedir as homedir5 } from "node:os";
|
|
1205
|
+
import { join as join6 } from "node:path";
|
|
1055
1206
|
|
|
1056
1207
|
// dist/src/embeddings/protocol.js
|
|
1057
1208
|
var DEFAULT_SOCKET_DIR = "/tmp";
|
|
@@ -1064,233 +1215,13 @@ function pidPathFor(uid, dir = DEFAULT_SOCKET_DIR) {
|
|
|
1064
1215
|
return `${dir}/hivemind-embed-${uid}.pid`;
|
|
1065
1216
|
}
|
|
1066
1217
|
|
|
1067
|
-
// dist/src/notifications/queue.js
|
|
1068
|
-
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, renameSync, mkdirSync as mkdirSync2, openSync, closeSync, unlinkSync, statSync } from "node:fs";
|
|
1069
|
-
import { join as join4, resolve } from "node:path";
|
|
1070
|
-
import { homedir as homedir3 } from "node:os";
|
|
1071
|
-
import { setTimeout as sleep2 } from "node:timers/promises";
|
|
1072
|
-
var log3 = (msg) => log("notifications-queue", msg);
|
|
1073
|
-
var LOCK_RETRY_MAX = 50;
|
|
1074
|
-
var LOCK_RETRY_BASE_MS = 5;
|
|
1075
|
-
var LOCK_STALE_MS = 5e3;
|
|
1076
|
-
function queuePath() {
|
|
1077
|
-
return join4(homedir3(), ".deeplake", "notifications-queue.json");
|
|
1078
|
-
}
|
|
1079
|
-
function lockPath() {
|
|
1080
|
-
return `${queuePath()}.lock`;
|
|
1081
|
-
}
|
|
1082
|
-
function readQueue() {
|
|
1083
|
-
try {
|
|
1084
|
-
const raw = readFileSync3(queuePath(), "utf-8");
|
|
1085
|
-
const parsed = JSON.parse(raw);
|
|
1086
|
-
if (!parsed || !Array.isArray(parsed.queue)) {
|
|
1087
|
-
log3(`queue malformed \u2192 treating as empty`);
|
|
1088
|
-
return { queue: [] };
|
|
1089
|
-
}
|
|
1090
|
-
return { queue: parsed.queue };
|
|
1091
|
-
} catch {
|
|
1092
|
-
return { queue: [] };
|
|
1093
|
-
}
|
|
1094
|
-
}
|
|
1095
|
-
function _isQueuePathInsideHome(path, home) {
|
|
1096
|
-
const r = resolve(path);
|
|
1097
|
-
const h = resolve(home);
|
|
1098
|
-
return r.startsWith(h + "/") || r === h;
|
|
1099
|
-
}
|
|
1100
|
-
function writeQueue(q) {
|
|
1101
|
-
const path = queuePath();
|
|
1102
|
-
const home = resolve(homedir3());
|
|
1103
|
-
if (!_isQueuePathInsideHome(path, home)) {
|
|
1104
|
-
throw new Error(`notifications-queue write blocked: ${path} is outside ${home}`);
|
|
1105
|
-
}
|
|
1106
|
-
mkdirSync2(join4(home, ".deeplake"), { recursive: true, mode: 448 });
|
|
1107
|
-
const tmp = `${path}.${process.pid}.tmp`;
|
|
1108
|
-
writeFileSync2(tmp, JSON.stringify(q, null, 2), { mode: 384 });
|
|
1109
|
-
renameSync(tmp, path);
|
|
1110
|
-
}
|
|
1111
|
-
async function withQueueLock(fn) {
|
|
1112
|
-
const path = lockPath();
|
|
1113
|
-
mkdirSync2(join4(homedir3(), ".deeplake"), { recursive: true, mode: 448 });
|
|
1114
|
-
let fd = null;
|
|
1115
|
-
for (let attempt = 0; attempt < LOCK_RETRY_MAX; attempt++) {
|
|
1116
|
-
try {
|
|
1117
|
-
fd = openSync(path, "wx", 384);
|
|
1118
|
-
break;
|
|
1119
|
-
} catch (e) {
|
|
1120
|
-
const code = e.code;
|
|
1121
|
-
if (code !== "EEXIST")
|
|
1122
|
-
throw e;
|
|
1123
|
-
try {
|
|
1124
|
-
const age = Date.now() - statSync(path).mtimeMs;
|
|
1125
|
-
if (age > LOCK_STALE_MS) {
|
|
1126
|
-
unlinkSync(path);
|
|
1127
|
-
continue;
|
|
1128
|
-
}
|
|
1129
|
-
} catch {
|
|
1130
|
-
}
|
|
1131
|
-
const delay = LOCK_RETRY_BASE_MS * (attempt + 1);
|
|
1132
|
-
await sleep2(delay);
|
|
1133
|
-
}
|
|
1134
|
-
}
|
|
1135
|
-
if (fd === null) {
|
|
1136
|
-
log3(`lock acquisition gave up after ${LOCK_RETRY_MAX} attempts \u2014 proceeding unlocked (last-writer-wins)`);
|
|
1137
|
-
return fn();
|
|
1138
|
-
}
|
|
1139
|
-
try {
|
|
1140
|
-
return fn();
|
|
1141
|
-
} finally {
|
|
1142
|
-
try {
|
|
1143
|
-
closeSync(fd);
|
|
1144
|
-
} catch {
|
|
1145
|
-
}
|
|
1146
|
-
try {
|
|
1147
|
-
unlinkSync(path);
|
|
1148
|
-
} catch {
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1151
|
-
}
|
|
1152
|
-
function sameDedupKey(a, b) {
|
|
1153
|
-
if (a.id !== b.id)
|
|
1154
|
-
return false;
|
|
1155
|
-
return JSON.stringify(a.dedupKey) === JSON.stringify(b.dedupKey);
|
|
1156
|
-
}
|
|
1157
|
-
async function enqueueNotification(n) {
|
|
1158
|
-
await withQueueLock(() => {
|
|
1159
|
-
const q = readQueue();
|
|
1160
|
-
if (q.queue.some((existing) => sameDedupKey(existing, n))) {
|
|
1161
|
-
return;
|
|
1162
|
-
}
|
|
1163
|
-
q.queue.push(n);
|
|
1164
|
-
writeQueue(q);
|
|
1165
|
-
});
|
|
1166
|
-
}
|
|
1167
|
-
|
|
1168
|
-
// dist/src/embeddings/disable.js
|
|
1169
|
-
import { createRequire } from "node:module";
|
|
1170
|
-
import { homedir as homedir5 } from "node:os";
|
|
1171
|
-
import { join as join6 } from "node:path";
|
|
1172
|
-
import { pathToFileURL } from "node:url";
|
|
1173
|
-
|
|
1174
|
-
// dist/src/user-config.js
|
|
1175
|
-
import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
1176
|
-
import { homedir as homedir4 } from "node:os";
|
|
1177
|
-
import { dirname, join as join5 } from "node:path";
|
|
1178
|
-
var _configPath = () => process.env.HIVEMIND_CONFIG_PATH ?? join5(homedir4(), ".deeplake", "config.json");
|
|
1179
|
-
var _cache = null;
|
|
1180
|
-
var _migrated = false;
|
|
1181
|
-
function readUserConfig() {
|
|
1182
|
-
if (_cache !== null)
|
|
1183
|
-
return _cache;
|
|
1184
|
-
const path = _configPath();
|
|
1185
|
-
if (!existsSync3(path)) {
|
|
1186
|
-
_cache = {};
|
|
1187
|
-
return _cache;
|
|
1188
|
-
}
|
|
1189
|
-
try {
|
|
1190
|
-
const raw = readFileSync4(path, "utf-8");
|
|
1191
|
-
const parsed = JSON.parse(raw);
|
|
1192
|
-
_cache = isPlainObject(parsed) ? parsed : {};
|
|
1193
|
-
} catch {
|
|
1194
|
-
_cache = {};
|
|
1195
|
-
}
|
|
1196
|
-
return _cache;
|
|
1197
|
-
}
|
|
1198
|
-
function writeUserConfig(patch) {
|
|
1199
|
-
const current = readUserConfig();
|
|
1200
|
-
const merged = deepMerge(current, patch);
|
|
1201
|
-
const path = _configPath();
|
|
1202
|
-
const dir = dirname(path);
|
|
1203
|
-
if (!existsSync3(dir))
|
|
1204
|
-
mkdirSync3(dir, { recursive: true });
|
|
1205
|
-
const tmp = `${path}.tmp.${process.pid}`;
|
|
1206
|
-
writeFileSync3(tmp, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
1207
|
-
renameSync2(tmp, path);
|
|
1208
|
-
_cache = merged;
|
|
1209
|
-
return merged;
|
|
1210
|
-
}
|
|
1211
|
-
function getEmbeddingsEnabled() {
|
|
1212
|
-
const cfg = readUserConfig();
|
|
1213
|
-
if (cfg.embeddings && typeof cfg.embeddings.enabled === "boolean") {
|
|
1214
|
-
return cfg.embeddings.enabled;
|
|
1215
|
-
}
|
|
1216
|
-
if (_migrated) {
|
|
1217
|
-
return migrationValueFromEnv();
|
|
1218
|
-
}
|
|
1219
|
-
_migrated = true;
|
|
1220
|
-
const enabled = migrationValueFromEnv();
|
|
1221
|
-
try {
|
|
1222
|
-
writeUserConfig({ embeddings: { enabled } });
|
|
1223
|
-
} catch {
|
|
1224
|
-
_cache = { ...cfg ?? {}, embeddings: { ...cfg?.embeddings ?? {}, enabled } };
|
|
1225
|
-
}
|
|
1226
|
-
return enabled;
|
|
1227
|
-
}
|
|
1228
|
-
function migrationValueFromEnv() {
|
|
1229
|
-
const raw = process.env.HIVEMIND_EMBEDDINGS;
|
|
1230
|
-
if (raw === void 0)
|
|
1231
|
-
return false;
|
|
1232
|
-
if (raw === "false")
|
|
1233
|
-
return false;
|
|
1234
|
-
return true;
|
|
1235
|
-
}
|
|
1236
|
-
function isPlainObject(value) {
|
|
1237
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1238
|
-
}
|
|
1239
|
-
function deepMerge(base, patch) {
|
|
1240
|
-
const out = { ...base };
|
|
1241
|
-
for (const key of Object.keys(patch)) {
|
|
1242
|
-
const patchVal = patch[key];
|
|
1243
|
-
const baseVal = base[key];
|
|
1244
|
-
if (isPlainObject(patchVal) && isPlainObject(baseVal)) {
|
|
1245
|
-
out[key] = { ...baseVal, ...patchVal };
|
|
1246
|
-
} else if (patchVal !== void 0) {
|
|
1247
|
-
out[key] = patchVal;
|
|
1248
|
-
}
|
|
1249
|
-
}
|
|
1250
|
-
return out;
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
// dist/src/embeddings/disable.js
|
|
1254
|
-
var cachedStatus = null;
|
|
1255
|
-
function defaultResolveTransformers() {
|
|
1256
|
-
const sharedDir = join6(homedir5(), ".hivemind", "embed-deps");
|
|
1257
|
-
try {
|
|
1258
|
-
createRequire(pathToFileURL(`${sharedDir}/`).href).resolve("@huggingface/transformers");
|
|
1259
|
-
return;
|
|
1260
|
-
} catch {
|
|
1261
|
-
}
|
|
1262
|
-
createRequire(import.meta.url).resolve("@huggingface/transformers");
|
|
1263
|
-
}
|
|
1264
|
-
var _resolve = defaultResolveTransformers;
|
|
1265
|
-
var _readEnabled = getEmbeddingsEnabled;
|
|
1266
|
-
function detectStatus() {
|
|
1267
|
-
if (!_readEnabled())
|
|
1268
|
-
return "user-disabled";
|
|
1269
|
-
try {
|
|
1270
|
-
_resolve();
|
|
1271
|
-
return "enabled";
|
|
1272
|
-
} catch {
|
|
1273
|
-
return "no-transformers";
|
|
1274
|
-
}
|
|
1275
|
-
}
|
|
1276
|
-
function embeddingsStatus() {
|
|
1277
|
-
if (cachedStatus !== null)
|
|
1278
|
-
return cachedStatus;
|
|
1279
|
-
cachedStatus = detectStatus();
|
|
1280
|
-
return cachedStatus;
|
|
1281
|
-
}
|
|
1282
|
-
function embeddingsDisabled() {
|
|
1283
|
-
return embeddingsStatus() !== "enabled";
|
|
1284
|
-
}
|
|
1285
|
-
|
|
1286
1218
|
// dist/src/embeddings/client.js
|
|
1287
|
-
var SHARED_DAEMON_PATH =
|
|
1219
|
+
var SHARED_DAEMON_PATH = join6(homedir5(), ".hivemind", "embed-deps", "embed-daemon.js");
|
|
1288
1220
|
var log4 = (m) => log("embed-client", m);
|
|
1289
1221
|
function getUid() {
|
|
1290
1222
|
const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
|
|
1291
1223
|
return uid !== void 0 ? String(uid) : process.env.USER ?? "default";
|
|
1292
1224
|
}
|
|
1293
|
-
var _signalledMissingDeps = false;
|
|
1294
1225
|
var _recycledStuckDaemon = false;
|
|
1295
1226
|
var EmbedClient = class {
|
|
1296
1227
|
socketPath;
|
|
@@ -1307,7 +1238,7 @@ var EmbedClient = class {
|
|
|
1307
1238
|
this.socketPath = socketPathFor(uid, dir);
|
|
1308
1239
|
this.pidPath = pidPathFor(uid, dir);
|
|
1309
1240
|
this.timeoutMs = opts.timeoutMs ?? DEFAULT_CLIENT_TIMEOUT_MS;
|
|
1310
|
-
this.daemonEntry = opts.daemonEntry ?? process.env.HIVEMIND_EMBED_DAEMON ?? (
|
|
1241
|
+
this.daemonEntry = opts.daemonEntry ?? process.env.HIVEMIND_EMBED_DAEMON ?? (existsSync3(SHARED_DAEMON_PATH) ? SHARED_DAEMON_PATH : void 0);
|
|
1311
1242
|
this.autoSpawn = opts.autoSpawn ?? true;
|
|
1312
1243
|
this.spawnWaitMs = opts.spawnWaitMs ?? 5e3;
|
|
1313
1244
|
}
|
|
@@ -1388,7 +1319,7 @@ var EmbedClient = class {
|
|
|
1388
1319
|
async waitForDaemonReady() {
|
|
1389
1320
|
const deadline = Date.now() + this.spawnWaitMs;
|
|
1390
1321
|
while (Date.now() < deadline) {
|
|
1391
|
-
if (
|
|
1322
|
+
if (existsSync3(this.socketPath))
|
|
1392
1323
|
return;
|
|
1393
1324
|
await new Promise((r) => setTimeout(r, 50));
|
|
1394
1325
|
}
|
|
@@ -1431,7 +1362,7 @@ var EmbedClient = class {
|
|
|
1431
1362
|
this.recycleDaemon(hello.pid);
|
|
1432
1363
|
return true;
|
|
1433
1364
|
}
|
|
1434
|
-
if (hello.daemonPath !== this.daemonEntry && !
|
|
1365
|
+
if (hello.daemonPath !== this.daemonEntry && !existsSync3(hello.daemonPath)) {
|
|
1435
1366
|
_recycledStuckDaemon = true;
|
|
1436
1367
|
log4(`daemon path no longer on disk \u2014 running=${hello.daemonPath} (gone) expected=${this.daemonEntry}; recycling`);
|
|
1437
1368
|
this.recycleDaemon(hello.pid);
|
|
@@ -1443,37 +1374,21 @@ var EmbedClient = class {
|
|
|
1443
1374
|
/**
|
|
1444
1375
|
* On a transformers-missing error from the daemon, SIGTERM the stuck
|
|
1445
1376
|
* daemon (the bundle daemon that can't find its deps) and clear
|
|
1446
|
-
* sock/pid so the next call spawns fresh.
|
|
1447
|
-
*
|
|
1448
|
-
*
|
|
1449
|
-
*
|
|
1450
|
-
*
|
|
1377
|
+
* sock/pid so the next call spawns fresh.
|
|
1378
|
+
*
|
|
1379
|
+
* Previously this also enqueued a user-visible "Hivemind embeddings
|
|
1380
|
+
* disabled — deps missing" notification telling the user to run
|
|
1381
|
+
* `hivemind embeddings install`. The notification was removed because
|
|
1382
|
+
* (a) the recycle alone often fixes the issue silently, and (b) the
|
|
1383
|
+
* warning kept stacking on top of the primary session-start banner
|
|
1384
|
+
* which clashed with the single-slot priority model. The `detail`
|
|
1385
|
+
* argument is retained for future telemetry / debug logging.
|
|
1451
1386
|
*/
|
|
1452
|
-
handleTransformersMissing(
|
|
1387
|
+
handleTransformersMissing(_detail) {
|
|
1453
1388
|
if (!_recycledStuckDaemon) {
|
|
1454
1389
|
_recycledStuckDaemon = true;
|
|
1455
1390
|
this.recycleDaemon(null);
|
|
1456
1391
|
}
|
|
1457
|
-
if (_signalledMissingDeps)
|
|
1458
|
-
return;
|
|
1459
|
-
_signalledMissingDeps = true;
|
|
1460
|
-
let status;
|
|
1461
|
-
try {
|
|
1462
|
-
status = embeddingsStatus();
|
|
1463
|
-
} catch {
|
|
1464
|
-
status = "enabled";
|
|
1465
|
-
}
|
|
1466
|
-
if (status === "user-disabled")
|
|
1467
|
-
return;
|
|
1468
|
-
enqueueNotification({
|
|
1469
|
-
id: "embed-deps-missing",
|
|
1470
|
-
severity: "warn",
|
|
1471
|
-
title: "Hivemind embeddings disabled \u2014 deps missing",
|
|
1472
|
-
body: `Semantic memory search is off because @huggingface/transformers is not installed where the daemon can find it. Run \`hivemind embeddings install\` to enable.`,
|
|
1473
|
-
dedupKey: { reason: "transformers-missing", detail: detail.slice(0, 200) }
|
|
1474
|
-
}).catch((e) => {
|
|
1475
|
-
log4(`enqueue embed-deps-missing failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
1476
|
-
});
|
|
1477
1392
|
}
|
|
1478
1393
|
/**
|
|
1479
1394
|
* Best-effort SIGTERM + sock/pid cleanup. Tolerant of every missing-file
|
|
@@ -1496,7 +1411,7 @@ var EmbedClient = class {
|
|
|
1496
1411
|
} catch {
|
|
1497
1412
|
}
|
|
1498
1413
|
}
|
|
1499
|
-
if (Number.isFinite(pid) && pid !== null && pid > 0 &&
|
|
1414
|
+
if (Number.isFinite(pid) && pid !== null && pid > 0 && existsSync3(this.socketPath)) {
|
|
1500
1415
|
try {
|
|
1501
1416
|
process.kill(pid, "SIGTERM");
|
|
1502
1417
|
} catch {
|
|
@@ -1505,11 +1420,11 @@ var EmbedClient = class {
|
|
|
1505
1420
|
log4(`recycle: socket gone, skipping SIGTERM on possibly-stale pid ${pid}`);
|
|
1506
1421
|
}
|
|
1507
1422
|
try {
|
|
1508
|
-
|
|
1423
|
+
unlinkSync3(this.socketPath);
|
|
1509
1424
|
} catch {
|
|
1510
1425
|
}
|
|
1511
1426
|
try {
|
|
1512
|
-
|
|
1427
|
+
unlinkSync3(this.pidPath);
|
|
1513
1428
|
} catch {
|
|
1514
1429
|
}
|
|
1515
1430
|
}
|
|
@@ -1560,7 +1475,7 @@ var EmbedClient = class {
|
|
|
1560
1475
|
} catch (e) {
|
|
1561
1476
|
if (this.isPidFileStale()) {
|
|
1562
1477
|
try {
|
|
1563
|
-
|
|
1478
|
+
unlinkSync3(this.pidPath);
|
|
1564
1479
|
} catch {
|
|
1565
1480
|
}
|
|
1566
1481
|
try {
|
|
@@ -1573,11 +1488,11 @@ var EmbedClient = class {
|
|
|
1573
1488
|
return;
|
|
1574
1489
|
}
|
|
1575
1490
|
}
|
|
1576
|
-
if (!this.daemonEntry || !
|
|
1491
|
+
if (!this.daemonEntry || !existsSync3(this.daemonEntry)) {
|
|
1577
1492
|
log4(`daemonEntry not configured or missing: ${this.daemonEntry}`);
|
|
1578
1493
|
try {
|
|
1579
1494
|
closeSync2(fd);
|
|
1580
|
-
|
|
1495
|
+
unlinkSync3(this.pidPath);
|
|
1581
1496
|
} catch {
|
|
1582
1497
|
}
|
|
1583
1498
|
return;
|
|
@@ -1616,7 +1531,7 @@ var EmbedClient = class {
|
|
|
1616
1531
|
while (Date.now() < deadline) {
|
|
1617
1532
|
await sleep3(delay);
|
|
1618
1533
|
delay = Math.min(delay * 1.5, 300);
|
|
1619
|
-
if (!
|
|
1534
|
+
if (!existsSync3(this.socketPath))
|
|
1620
1535
|
continue;
|
|
1621
1536
|
try {
|
|
1622
1537
|
return await this.connectOnce();
|
|
@@ -1667,13 +1582,131 @@ function isTransformersMissingError(err) {
|
|
|
1667
1582
|
return /@huggingface\/transformers/i.test(err);
|
|
1668
1583
|
}
|
|
1669
1584
|
|
|
1585
|
+
// dist/src/embeddings/disable.js
|
|
1586
|
+
import { createRequire } from "node:module";
|
|
1587
|
+
import { homedir as homedir7 } from "node:os";
|
|
1588
|
+
import { join as join8 } from "node:path";
|
|
1589
|
+
import { pathToFileURL } from "node:url";
|
|
1590
|
+
|
|
1591
|
+
// dist/src/user-config.js
|
|
1592
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync6, renameSync as renameSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
1593
|
+
import { homedir as homedir6 } from "node:os";
|
|
1594
|
+
import { dirname, join as join7 } from "node:path";
|
|
1595
|
+
var _configPath = () => process.env.HIVEMIND_CONFIG_PATH ?? join7(homedir6(), ".deeplake", "config.json");
|
|
1596
|
+
var _cache = null;
|
|
1597
|
+
var _migrated = false;
|
|
1598
|
+
function readUserConfig() {
|
|
1599
|
+
if (_cache !== null)
|
|
1600
|
+
return _cache;
|
|
1601
|
+
const path = _configPath();
|
|
1602
|
+
if (!existsSync4(path)) {
|
|
1603
|
+
_cache = {};
|
|
1604
|
+
return _cache;
|
|
1605
|
+
}
|
|
1606
|
+
try {
|
|
1607
|
+
const raw = readFileSync6(path, "utf-8");
|
|
1608
|
+
const parsed = JSON.parse(raw);
|
|
1609
|
+
_cache = isPlainObject(parsed) ? parsed : {};
|
|
1610
|
+
} catch {
|
|
1611
|
+
_cache = {};
|
|
1612
|
+
}
|
|
1613
|
+
return _cache;
|
|
1614
|
+
}
|
|
1615
|
+
function writeUserConfig(patch) {
|
|
1616
|
+
const current = readUserConfig();
|
|
1617
|
+
const merged = deepMerge(current, patch);
|
|
1618
|
+
const path = _configPath();
|
|
1619
|
+
const dir = dirname(path);
|
|
1620
|
+
if (!existsSync4(dir))
|
|
1621
|
+
mkdirSync4(dir, { recursive: true });
|
|
1622
|
+
const tmp = `${path}.tmp.${process.pid}`;
|
|
1623
|
+
writeFileSync4(tmp, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
1624
|
+
renameSync2(tmp, path);
|
|
1625
|
+
_cache = merged;
|
|
1626
|
+
return merged;
|
|
1627
|
+
}
|
|
1628
|
+
function getEmbeddingsEnabled() {
|
|
1629
|
+
const cfg = readUserConfig();
|
|
1630
|
+
if (cfg.embeddings && typeof cfg.embeddings.enabled === "boolean") {
|
|
1631
|
+
return cfg.embeddings.enabled;
|
|
1632
|
+
}
|
|
1633
|
+
if (_migrated) {
|
|
1634
|
+
return migrationValueFromEnv();
|
|
1635
|
+
}
|
|
1636
|
+
_migrated = true;
|
|
1637
|
+
const enabled = migrationValueFromEnv();
|
|
1638
|
+
try {
|
|
1639
|
+
writeUserConfig({ embeddings: { enabled } });
|
|
1640
|
+
} catch {
|
|
1641
|
+
_cache = { ...cfg ?? {}, embeddings: { ...cfg?.embeddings ?? {}, enabled } };
|
|
1642
|
+
}
|
|
1643
|
+
return enabled;
|
|
1644
|
+
}
|
|
1645
|
+
function migrationValueFromEnv() {
|
|
1646
|
+
const raw = process.env.HIVEMIND_EMBEDDINGS;
|
|
1647
|
+
if (raw === void 0)
|
|
1648
|
+
return false;
|
|
1649
|
+
if (raw === "false")
|
|
1650
|
+
return false;
|
|
1651
|
+
return true;
|
|
1652
|
+
}
|
|
1653
|
+
function isPlainObject(value) {
|
|
1654
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1655
|
+
}
|
|
1656
|
+
function deepMerge(base, patch) {
|
|
1657
|
+
const out = { ...base };
|
|
1658
|
+
for (const key of Object.keys(patch)) {
|
|
1659
|
+
const patchVal = patch[key];
|
|
1660
|
+
const baseVal = base[key];
|
|
1661
|
+
if (isPlainObject(patchVal) && isPlainObject(baseVal)) {
|
|
1662
|
+
out[key] = { ...baseVal, ...patchVal };
|
|
1663
|
+
} else if (patchVal !== void 0) {
|
|
1664
|
+
out[key] = patchVal;
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
return out;
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
// dist/src/embeddings/disable.js
|
|
1671
|
+
var cachedStatus = null;
|
|
1672
|
+
function defaultResolveTransformers() {
|
|
1673
|
+
const sharedDir = join8(homedir7(), ".hivemind", "embed-deps");
|
|
1674
|
+
try {
|
|
1675
|
+
createRequire(pathToFileURL(`${sharedDir}/`).href).resolve("@huggingface/transformers");
|
|
1676
|
+
return;
|
|
1677
|
+
} catch {
|
|
1678
|
+
}
|
|
1679
|
+
createRequire(import.meta.url).resolve("@huggingface/transformers");
|
|
1680
|
+
}
|
|
1681
|
+
var _resolve = defaultResolveTransformers;
|
|
1682
|
+
var _readEnabled = getEmbeddingsEnabled;
|
|
1683
|
+
function detectStatus() {
|
|
1684
|
+
if (!_readEnabled())
|
|
1685
|
+
return "user-disabled";
|
|
1686
|
+
try {
|
|
1687
|
+
_resolve();
|
|
1688
|
+
return "enabled";
|
|
1689
|
+
} catch {
|
|
1690
|
+
return "no-transformers";
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
function embeddingsStatus() {
|
|
1694
|
+
if (cachedStatus !== null)
|
|
1695
|
+
return cachedStatus;
|
|
1696
|
+
cachedStatus = detectStatus();
|
|
1697
|
+
return cachedStatus;
|
|
1698
|
+
}
|
|
1699
|
+
function embeddingsDisabled() {
|
|
1700
|
+
return embeddingsStatus() !== "enabled";
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1670
1703
|
// dist/src/hooks/grep-direct.js
|
|
1671
1704
|
import { fileURLToPath } from "node:url";
|
|
1672
|
-
import { dirname as dirname2, join as
|
|
1705
|
+
import { dirname as dirname2, join as join9 } from "node:path";
|
|
1673
1706
|
var SEMANTIC_ENABLED = process.env.HIVEMIND_SEMANTIC_SEARCH !== "false" && !embeddingsDisabled();
|
|
1674
1707
|
var SEMANTIC_TIMEOUT_MS = Number(process.env.HIVEMIND_SEMANTIC_EMBED_TIMEOUT_MS ?? "500");
|
|
1675
1708
|
function resolveDaemonPath() {
|
|
1676
|
-
return
|
|
1709
|
+
return join9(dirname2(fileURLToPath(import.meta.url)), "..", "embeddings", "embed-daemon.js");
|
|
1677
1710
|
}
|
|
1678
1711
|
var sharedEmbedClient = null;
|
|
1679
1712
|
function getEmbedClient() {
|
|
@@ -2676,20 +2709,20 @@ async function executeCompiledBashCommand(api, memoryTable, sessionsTable, cmd,
|
|
|
2676
2709
|
}
|
|
2677
2710
|
|
|
2678
2711
|
// dist/src/hooks/query-cache.js
|
|
2679
|
-
import { mkdirSync as
|
|
2680
|
-
import { join as
|
|
2681
|
-
import { homedir as
|
|
2712
|
+
import { mkdirSync as mkdirSync5, readFileSync as readFileSync7, rmSync, writeFileSync as writeFileSync5 } from "node:fs";
|
|
2713
|
+
import { join as join10 } from "node:path";
|
|
2714
|
+
import { homedir as homedir8 } from "node:os";
|
|
2682
2715
|
var log5 = (msg) => log("query-cache", msg);
|
|
2683
|
-
var DEFAULT_CACHE_ROOT =
|
|
2716
|
+
var DEFAULT_CACHE_ROOT = join10(homedir8(), ".deeplake", "query-cache");
|
|
2684
2717
|
var INDEX_CACHE_FILE = "index.md";
|
|
2685
2718
|
function getSessionQueryCacheDir(sessionId, deps = {}) {
|
|
2686
2719
|
const { cacheRoot = DEFAULT_CACHE_ROOT } = deps;
|
|
2687
|
-
return
|
|
2720
|
+
return join10(cacheRoot, sessionId);
|
|
2688
2721
|
}
|
|
2689
2722
|
function readCachedIndexContent(sessionId, deps = {}) {
|
|
2690
2723
|
const { logFn = log5 } = deps;
|
|
2691
2724
|
try {
|
|
2692
|
-
return
|
|
2725
|
+
return readFileSync7(join10(getSessionQueryCacheDir(sessionId, deps), INDEX_CACHE_FILE), "utf-8");
|
|
2693
2726
|
} catch (e) {
|
|
2694
2727
|
if (e?.code === "ENOENT")
|
|
2695
2728
|
return null;
|
|
@@ -2701,8 +2734,8 @@ function writeCachedIndexContent(sessionId, content, deps = {}) {
|
|
|
2701
2734
|
const { logFn = log5 } = deps;
|
|
2702
2735
|
try {
|
|
2703
2736
|
const dir = getSessionQueryCacheDir(sessionId, deps);
|
|
2704
|
-
|
|
2705
|
-
|
|
2737
|
+
mkdirSync5(dir, { recursive: true });
|
|
2738
|
+
writeFileSync5(join10(dir, INDEX_CACHE_FILE), content, "utf-8");
|
|
2706
2739
|
} catch (e) {
|
|
2707
2740
|
logFn(`write failed for session=${sessionId}: ${e.message}`);
|
|
2708
2741
|
}
|
|
@@ -2723,9 +2756,9 @@ function isDirectRun(metaUrl) {
|
|
|
2723
2756
|
}
|
|
2724
2757
|
|
|
2725
2758
|
// dist/src/hooks/memory-path-utils.js
|
|
2726
|
-
import { homedir as
|
|
2727
|
-
import { join as
|
|
2728
|
-
var MEMORY_PATH =
|
|
2759
|
+
import { homedir as homedir9 } from "node:os";
|
|
2760
|
+
import { join as join11 } from "node:path";
|
|
2761
|
+
var MEMORY_PATH = join11(homedir9(), ".deeplake", "memory");
|
|
2729
2762
|
var TILDE_PATH = "~/.deeplake/memory";
|
|
2730
2763
|
var HOME_VAR_PATH = "$HOME/.deeplake/memory";
|
|
2731
2764
|
var SAFE_BUILTINS = /* @__PURE__ */ new Set([
|
|
@@ -2843,7 +2876,7 @@ function rewritePaths(cmd) {
|
|
|
2843
2876
|
// dist/src/hooks/codex/pre-tool-use.js
|
|
2844
2877
|
var log6 = (msg) => log("codex-pre", msg);
|
|
2845
2878
|
var __bundleDir = dirname3(fileURLToPath3(import.meta.url));
|
|
2846
|
-
var SHELL_BUNDLE = existsSync5(
|
|
2879
|
+
var SHELL_BUNDLE = existsSync5(join12(__bundleDir, "shell", "deeplake-shell.js")) ? join12(__bundleDir, "shell", "deeplake-shell.js") : join12(__bundleDir, "..", "shell", "deeplake-shell.js");
|
|
2847
2880
|
function buildUnsupportedGuidance() {
|
|
2848
2881
|
return "This command is not supported for ~/.deeplake/memory/ operations. Only bash builtins are available: cat, ls, grep, echo, jq, head, tail, sed, awk, wc, sort, find, etc. Do NOT use python, python3, node, curl, or other interpreters. Rewrite your command using only bash tools and retry.";
|
|
2849
2882
|
}
|