@deeplake/hivemind 0.7.65 → 0.7.67
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 +3 -3
- package/.claude-plugin/plugin.json +1 -1
- package/bundle/cli.js +23 -40
- package/codex/bundle/capture.js +37 -44
- package/codex/bundle/commands/auth-login.js +5 -35
- package/codex/bundle/graph-pull-worker.js +5 -35
- package/codex/bundle/pre-tool-use.js +5 -35
- package/codex/bundle/session-start-setup.js +12 -36
- package/codex/bundle/session-start.js +5 -35
- package/codex/bundle/shell/deeplake-shell.js +5 -35
- package/codex/bundle/stop.js +40 -51
- package/cursor/bundle/capture.js +40 -51
- package/cursor/bundle/commands/auth-login.js +5 -35
- package/cursor/bundle/graph-pull-worker.js +5 -35
- package/cursor/bundle/pre-tool-use.js +5 -35
- package/cursor/bundle/session-end.js +32 -13
- package/cursor/bundle/session-start.js +12 -36
- package/cursor/bundle/shell/deeplake-shell.js +5 -35
- package/hermes/bundle/capture.js +40 -51
- package/hermes/bundle/commands/auth-login.js +5 -35
- package/hermes/bundle/graph-pull-worker.js +5 -35
- package/hermes/bundle/pre-tool-use.js +5 -35
- package/hermes/bundle/session-end.js +32 -13
- package/hermes/bundle/session-start.js +12 -36
- package/hermes/bundle/shell/deeplake-shell.js +5 -35
- package/mcp/bundle/server.js +5 -35
- package/openclaw/dist/index.js +6 -30
- package/openclaw/openclaw.plugin.json +1 -1
- package/openclaw/package.json +1 -1
- package/package.json +1 -1
|
@@ -6,18 +6,18 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Cloud-backed persistent shared memory for AI agents powered by Deeplake",
|
|
9
|
-
"version": "0.7.
|
|
9
|
+
"version": "0.7.67"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "hivemind",
|
|
14
14
|
"description": "Persistent shared memory powered by Deeplake — captures all session activity and provides cross-session, cross-agent memory search",
|
|
15
|
-
"version": "0.7.
|
|
15
|
+
"version": "0.7.67",
|
|
16
16
|
"source": {
|
|
17
17
|
"source": "git-subdir",
|
|
18
18
|
"url": "https://github.com/activeloopai/hivemind.git",
|
|
19
19
|
"path": "claude-code",
|
|
20
|
-
"sha": "
|
|
20
|
+
"sha": "7d1de6ab6b8a13bc52305e69d1a8ccc0b6e4d92a"
|
|
21
21
|
},
|
|
22
22
|
"homepage": "https://github.com/activeloopai/hivemind"
|
|
23
23
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hivemind",
|
|
3
3
|
"description": "Cloud-backed persistent memory powered by Deeplake — read, write, and share memory across Claude Code sessions and agents",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.67",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Activeloop",
|
|
7
7
|
"url": "https://deeplake.ai"
|
package/bundle/cli.js
CHANGED
|
@@ -382,9 +382,11 @@ function isHivemindHookEntry(entry, pluginDir = PLUGIN_DIR) {
|
|
|
382
382
|
const cmd = h.command;
|
|
383
383
|
if (typeof cmd !== "string")
|
|
384
384
|
return false;
|
|
385
|
-
|
|
385
|
+
const nCmd = cmd.replace(/\\/g, "/");
|
|
386
|
+
const nPluginDir = pluginDir.replace(/\\/g, "/");
|
|
387
|
+
if (nCmd.includes(`${nPluginDir}/bundle/`))
|
|
386
388
|
return true;
|
|
387
|
-
return HIVEMIND_BUNDLE_FILES.some((f) =>
|
|
389
|
+
return HIVEMIND_BUNDLE_FILES.some((f) => nCmd.includes(`/bundle/${f}`));
|
|
388
390
|
});
|
|
389
391
|
}
|
|
390
392
|
function isForeignHivemindHookEntry(entry, pluginDir = PLUGIN_DIR) {
|
|
@@ -398,7 +400,7 @@ function isForeignHivemindHookEntry(entry, pluginDir = PLUGIN_DIR) {
|
|
|
398
400
|
const cmd = h.command;
|
|
399
401
|
if (typeof cmd !== "string")
|
|
400
402
|
return false;
|
|
401
|
-
return !cmd.includes(`${pluginDir}/bundle/`);
|
|
403
|
+
return !cmd.replace(/\\/g, "/").includes(`${pluginDir.replace(/\\/g, "/")}/bundle/`);
|
|
402
404
|
});
|
|
403
405
|
}
|
|
404
406
|
function mergeHooks(existing, ours, pluginDir = PLUGIN_DIR) {
|
|
@@ -707,7 +709,9 @@ function isHivemindEntry(entry) {
|
|
|
707
709
|
if (!entry || typeof entry !== "object")
|
|
708
710
|
return false;
|
|
709
711
|
const cmd = entry.command;
|
|
710
|
-
|
|
712
|
+
if (typeof cmd !== "string")
|
|
713
|
+
return false;
|
|
714
|
+
return cmd.replace(/\\/g, "/").includes("/.cursor/hivemind/bundle/");
|
|
711
715
|
}
|
|
712
716
|
function mergeHooks2(existing) {
|
|
713
717
|
const root = existing ?? { version: 1, hooks: {} };
|
|
@@ -4816,9 +4820,6 @@ function traceSql(msg) {
|
|
|
4816
4820
|
log4(msg);
|
|
4817
4821
|
}
|
|
4818
4822
|
var _signalledBalanceExhausted = false;
|
|
4819
|
-
var _signalledLowBalance = false;
|
|
4820
|
-
var LOW_BALANCE_THRESHOLD_CENTS = 200;
|
|
4821
|
-
var BALANCE_HEADER = "X-Activeloop-Balance-Cents";
|
|
4822
4823
|
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
4823
4824
|
if (status !== 402)
|
|
4824
4825
|
return;
|
|
@@ -4834,40 +4835,15 @@ function maybeSignalBalanceExhausted(status, bodyText) {
|
|
|
4834
4835
|
transient: true,
|
|
4835
4836
|
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
4836
4837
|
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
4837
|
-
dedupKey: { reason: "balance-zero" }
|
|
4838
|
+
dedupKey: { reason: "balance-zero" },
|
|
4839
|
+
// User-facing billing notice → user channel only. Never the model's
|
|
4840
|
+
// additionalContext: a "top up at <url>" instruction in the agent prompt
|
|
4841
|
+
// is a prompt-injection pattern external agents flag.
|
|
4842
|
+
userVisibleOnly: true
|
|
4838
4843
|
}).catch((e) => {
|
|
4839
4844
|
log4(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
4840
4845
|
});
|
|
4841
4846
|
}
|
|
4842
|
-
function signalLowBalanceFromHeader(resp) {
|
|
4843
|
-
if (_signalledLowBalance)
|
|
4844
|
-
return;
|
|
4845
|
-
const raw = resp.headers?.get?.(BALANCE_HEADER);
|
|
4846
|
-
if (!raw)
|
|
4847
|
-
return;
|
|
4848
|
-
if (!/^-?\d+$/.test(raw.trim()))
|
|
4849
|
-
return;
|
|
4850
|
-
const balance = Number(raw.trim());
|
|
4851
|
-
if (!Number.isFinite(balance))
|
|
4852
|
-
return;
|
|
4853
|
-
if (balance >= LOW_BALANCE_THRESHOLD_CENTS)
|
|
4854
|
-
return;
|
|
4855
|
-
if (balance <= 0)
|
|
4856
|
-
return;
|
|
4857
|
-
_signalledLowBalance = true;
|
|
4858
|
-
log4(`balance below threshold (${balance}\xA2) \u2014 enqueuing low-balance banner`);
|
|
4859
|
-
enqueueNotification({
|
|
4860
|
-
id: "low-balance-warning",
|
|
4861
|
-
severity: "warn",
|
|
4862
|
-
transient: true,
|
|
4863
|
-
title: "Your org's Hivemind balance is running low",
|
|
4864
|
-
body: `Only $${(balance / 100).toFixed(2)} of prepaid balance remains. Admins can top up at ${billingUrl()}; otherwise ask an org admin to top up before requests start failing.`,
|
|
4865
|
-
dedupKey: { reason: "low-balance" }
|
|
4866
|
-
}).catch((e) => {
|
|
4867
|
-
_signalledLowBalance = false;
|
|
4868
|
-
log4(`enqueue low-balance failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
4869
|
-
});
|
|
4870
|
-
}
|
|
4871
4847
|
function billingUrl() {
|
|
4872
4848
|
try {
|
|
4873
4849
|
const c = loadCredentials();
|
|
@@ -4993,7 +4969,6 @@ var DeeplakeApi = class {
|
|
|
4993
4969
|
}
|
|
4994
4970
|
throw lastError;
|
|
4995
4971
|
}
|
|
4996
|
-
signalLowBalanceFromHeader(resp);
|
|
4997
4972
|
if (resp.ok) {
|
|
4998
4973
|
const raw = await resp.json();
|
|
4999
4974
|
if (!raw?.rows || !raw?.columns)
|
|
@@ -5154,7 +5129,6 @@ var DeeplakeApi = class {
|
|
|
5154
5129
|
...deeplakeClientHeader()
|
|
5155
5130
|
}
|
|
5156
5131
|
});
|
|
5157
|
-
signalLowBalanceFromHeader(resp);
|
|
5158
5132
|
if (resp.ok) {
|
|
5159
5133
|
const data = await resp.json();
|
|
5160
5134
|
return {
|
|
@@ -7535,6 +7509,14 @@ var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
|
7535
7509
|
function cacheFilePath() {
|
|
7536
7510
|
return join28(homedir11(), ".deeplake", "hivemind-stats-cache.json");
|
|
7537
7511
|
}
|
|
7512
|
+
var BALANCE_HEADER = "X-Activeloop-Balance-Cents";
|
|
7513
|
+
function parseBalanceHeader(resp) {
|
|
7514
|
+
const raw = resp.headers?.get?.(BALANCE_HEADER);
|
|
7515
|
+
if (!raw || !/^-?\d+$/.test(raw.trim()))
|
|
7516
|
+
return null;
|
|
7517
|
+
const n = Number(raw.trim());
|
|
7518
|
+
return Number.isFinite(n) ? n : null;
|
|
7519
|
+
}
|
|
7538
7520
|
function cacheScopeKey(creds) {
|
|
7539
7521
|
return JSON.stringify({
|
|
7540
7522
|
apiUrl: creds.apiUrl ?? DEFAULT_API_URL3,
|
|
@@ -7614,7 +7596,8 @@ async function fetchOrgStats(creds) {
|
|
|
7614
7596
|
}
|
|
7615
7597
|
const data = {
|
|
7616
7598
|
org: scopeFromServer(body.org),
|
|
7617
|
-
user: scopeFromServer(body.user)
|
|
7599
|
+
user: scopeFromServer(body.user),
|
|
7600
|
+
balanceCents: parseBalanceHeader(resp)
|
|
7618
7601
|
};
|
|
7619
7602
|
writeCache2(scopeKey, data);
|
|
7620
7603
|
log5(`fetched org stats from ${apiUrl}`);
|
package/codex/bundle/capture.js
CHANGED
|
@@ -478,9 +478,6 @@ function traceSql(msg) {
|
|
|
478
478
|
log3(msg);
|
|
479
479
|
}
|
|
480
480
|
var _signalledBalanceExhausted = false;
|
|
481
|
-
var _signalledLowBalance = false;
|
|
482
|
-
var LOW_BALANCE_THRESHOLD_CENTS = 200;
|
|
483
|
-
var BALANCE_HEADER = "X-Activeloop-Balance-Cents";
|
|
484
481
|
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
485
482
|
if (status !== 402)
|
|
486
483
|
return;
|
|
@@ -496,40 +493,15 @@ function maybeSignalBalanceExhausted(status, bodyText) {
|
|
|
496
493
|
transient: true,
|
|
497
494
|
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
498
495
|
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
499
|
-
dedupKey: { reason: "balance-zero" }
|
|
496
|
+
dedupKey: { reason: "balance-zero" },
|
|
497
|
+
// User-facing billing notice → user channel only. Never the model's
|
|
498
|
+
// additionalContext: a "top up at <url>" instruction in the agent prompt
|
|
499
|
+
// is a prompt-injection pattern external agents flag.
|
|
500
|
+
userVisibleOnly: true
|
|
500
501
|
}).catch((e) => {
|
|
501
502
|
log3(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
502
503
|
});
|
|
503
504
|
}
|
|
504
|
-
function signalLowBalanceFromHeader(resp) {
|
|
505
|
-
if (_signalledLowBalance)
|
|
506
|
-
return;
|
|
507
|
-
const raw = resp.headers?.get?.(BALANCE_HEADER);
|
|
508
|
-
if (!raw)
|
|
509
|
-
return;
|
|
510
|
-
if (!/^-?\d+$/.test(raw.trim()))
|
|
511
|
-
return;
|
|
512
|
-
const balance = Number(raw.trim());
|
|
513
|
-
if (!Number.isFinite(balance))
|
|
514
|
-
return;
|
|
515
|
-
if (balance >= LOW_BALANCE_THRESHOLD_CENTS)
|
|
516
|
-
return;
|
|
517
|
-
if (balance <= 0)
|
|
518
|
-
return;
|
|
519
|
-
_signalledLowBalance = true;
|
|
520
|
-
log3(`balance below threshold (${balance}\xA2) \u2014 enqueuing low-balance banner`);
|
|
521
|
-
enqueueNotification({
|
|
522
|
-
id: "low-balance-warning",
|
|
523
|
-
severity: "warn",
|
|
524
|
-
transient: true,
|
|
525
|
-
title: "Your org's Hivemind balance is running low",
|
|
526
|
-
body: `Only $${(balance / 100).toFixed(2)} of prepaid balance remains. Admins can top up at ${billingUrl()}; otherwise ask an org admin to top up before requests start failing.`,
|
|
527
|
-
dedupKey: { reason: "low-balance" }
|
|
528
|
-
}).catch((e) => {
|
|
529
|
-
_signalledLowBalance = false;
|
|
530
|
-
log3(`enqueue low-balance failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
531
|
-
});
|
|
532
|
-
}
|
|
533
505
|
function billingUrl() {
|
|
534
506
|
try {
|
|
535
507
|
const c = loadCredentials();
|
|
@@ -655,7 +627,6 @@ var DeeplakeApi = class {
|
|
|
655
627
|
}
|
|
656
628
|
throw lastError;
|
|
657
629
|
}
|
|
658
|
-
signalLowBalanceFromHeader(resp);
|
|
659
630
|
if (resp.ok) {
|
|
660
631
|
const raw = await resp.json();
|
|
661
632
|
if (!raw?.rows || !raw?.columns)
|
|
@@ -816,7 +787,6 @@ var DeeplakeApi = class {
|
|
|
816
787
|
...deeplakeClientHeader()
|
|
817
788
|
}
|
|
818
789
|
});
|
|
819
|
-
signalLowBalanceFromHeader(resp);
|
|
820
790
|
if (resp.ok) {
|
|
821
791
|
const data = await resp.json();
|
|
822
792
|
return {
|
|
@@ -1005,6 +975,12 @@ var DeeplakeApi = class {
|
|
|
1005
975
|
}
|
|
1006
976
|
};
|
|
1007
977
|
|
|
978
|
+
// dist/src/utils/project-name.js
|
|
979
|
+
import { basename } from "node:path";
|
|
980
|
+
function projectNameFromCwd(cwd) {
|
|
981
|
+
return basename(cwd ?? "") || "unknown";
|
|
982
|
+
}
|
|
983
|
+
|
|
1008
984
|
// dist/src/utils/session-path.js
|
|
1009
985
|
function buildSessionPath(config, sessionId) {
|
|
1010
986
|
const workspace = config.workspaceId ?? "default";
|
|
@@ -1530,9 +1506,9 @@ function embeddingsDisabled() {
|
|
|
1530
1506
|
// dist/src/embeddings/self-heal.js
|
|
1531
1507
|
import { existsSync as existsSync5, lstatSync, mkdirSync as mkdirSync5, readlinkSync, renameSync as renameSync3, rmSync, symlinkSync, statSync as statSync2 } from "node:fs";
|
|
1532
1508
|
import { homedir as homedir8 } from "node:os";
|
|
1533
|
-
import { basename, dirname as dirname2, join as join9 } from "node:path";
|
|
1509
|
+
import { basename as basename2, dirname as dirname2, join as join9 } from "node:path";
|
|
1534
1510
|
function ensurePluginNodeModulesLink(opts) {
|
|
1535
|
-
if (
|
|
1511
|
+
if (basename2(opts.bundleDir) !== "bundle") {
|
|
1536
1512
|
return { kind: "not-bundle-layout", bundleDir: opts.bundleDir };
|
|
1537
1513
|
}
|
|
1538
1514
|
const target = opts.sharedNodeModules ?? join9(homedir8(), ".hivemind", "embed-deps", "node_modules");
|
|
@@ -1731,7 +1707,7 @@ function releaseLock(sessionId) {
|
|
|
1731
1707
|
}
|
|
1732
1708
|
|
|
1733
1709
|
// dist/src/hooks/codex/spawn-wiki-worker.js
|
|
1734
|
-
import {
|
|
1710
|
+
import { execSync } from "node:child_process";
|
|
1735
1711
|
import { fileURLToPath } from "node:url";
|
|
1736
1712
|
import { dirname as dirname4, join as join13 } from "node:path";
|
|
1737
1713
|
import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync8 } from "node:fs";
|
|
@@ -1797,6 +1773,26 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
|
|
|
1797
1773
|
return null;
|
|
1798
1774
|
}
|
|
1799
1775
|
|
|
1776
|
+
// dist/src/utils/spawn-detached.js
|
|
1777
|
+
import { spawn as nodeSpawn } from "node:child_process";
|
|
1778
|
+
function spawnDetachedNodeWorker(workerPath, args = [], deps = {}) {
|
|
1779
|
+
const spawn2 = deps.spawn ?? nodeSpawn;
|
|
1780
|
+
const execPath = deps.execPath ?? process.execPath;
|
|
1781
|
+
try {
|
|
1782
|
+
const child = spawn2(execPath, [workerPath, ...args], {
|
|
1783
|
+
detached: true,
|
|
1784
|
+
stdio: ["ignore", "ignore", "ignore"],
|
|
1785
|
+
// Suppress the transient console window Windows would otherwise pop for
|
|
1786
|
+
// the detached worker. No-op on POSIX.
|
|
1787
|
+
windowsHide: true
|
|
1788
|
+
});
|
|
1789
|
+
child.on("error", () => {
|
|
1790
|
+
});
|
|
1791
|
+
child.unref();
|
|
1792
|
+
} catch {
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1800
1796
|
// dist/src/hooks/codex/spawn-wiki-worker.js
|
|
1801
1797
|
var HOME = homedir10();
|
|
1802
1798
|
var wikiLogger = makeWikiLogger(join13(HOME, ".codex", "hooks"));
|
|
@@ -1860,7 +1856,7 @@ function findCodexBin() {
|
|
|
1860
1856
|
}
|
|
1861
1857
|
function spawnCodexWikiWorker(opts) {
|
|
1862
1858
|
const { config, sessionId, cwd, bundleDir, reason } = opts;
|
|
1863
|
-
const projectName = cwd
|
|
1859
|
+
const projectName = projectNameFromCwd(cwd);
|
|
1864
1860
|
const tmpDir = join13(tmpdir2(), `deeplake-wiki-${sessionId}-${Date.now()}`);
|
|
1865
1861
|
mkdirSync8(tmpDir, { recursive: true });
|
|
1866
1862
|
const pluginVersion = getInstalledVersion(bundleDir, ".codex-plugin") ?? "";
|
|
@@ -1884,10 +1880,7 @@ function spawnCodexWikiWorker(opts) {
|
|
|
1884
1880
|
}));
|
|
1885
1881
|
wikiLog(`${reason}: spawning summary worker for ${sessionId}`);
|
|
1886
1882
|
const workerPath = join13(bundleDir, "wiki-worker.js");
|
|
1887
|
-
|
|
1888
|
-
detached: true,
|
|
1889
|
-
stdio: ["ignore", "ignore", "ignore"]
|
|
1890
|
-
}).unref();
|
|
1883
|
+
spawnDetachedNodeWorker(workerPath, [configFile]);
|
|
1891
1884
|
wikiLog(`${reason}: spawned summary worker for ${sessionId}`);
|
|
1892
1885
|
}
|
|
1893
1886
|
function bundleDirFromImportMeta(importMetaUrl) {
|
|
@@ -1956,7 +1949,7 @@ async function main() {
|
|
|
1956
1949
|
const sessionPath = buildSessionPath(config, input.session_id);
|
|
1957
1950
|
const line = JSON.stringify(entry);
|
|
1958
1951
|
log5(`writing to ${sessionPath}`);
|
|
1959
|
-
const projectName = (input.cwd
|
|
1952
|
+
const projectName = projectNameFromCwd(input.cwd);
|
|
1960
1953
|
const filename = sessionPath.split("/").pop() ?? "";
|
|
1961
1954
|
const jsonForSql = line.replace(/'/g, "''");
|
|
1962
1955
|
const embedding = embeddingsDisabled() ? null : await new EmbedClient({ daemonEntry: resolveEmbedDaemonPath() }).embed(line, "document");
|
|
@@ -741,9 +741,6 @@ function traceSql(msg) {
|
|
|
741
741
|
log3(msg);
|
|
742
742
|
}
|
|
743
743
|
var _signalledBalanceExhausted = false;
|
|
744
|
-
var _signalledLowBalance = false;
|
|
745
|
-
var LOW_BALANCE_THRESHOLD_CENTS = 200;
|
|
746
|
-
var BALANCE_HEADER = "X-Activeloop-Balance-Cents";
|
|
747
744
|
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
748
745
|
if (status !== 402)
|
|
749
746
|
return;
|
|
@@ -759,40 +756,15 @@ function maybeSignalBalanceExhausted(status, bodyText) {
|
|
|
759
756
|
transient: true,
|
|
760
757
|
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
761
758
|
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
762
|
-
dedupKey: { reason: "balance-zero" }
|
|
759
|
+
dedupKey: { reason: "balance-zero" },
|
|
760
|
+
// User-facing billing notice → user channel only. Never the model's
|
|
761
|
+
// additionalContext: a "top up at <url>" instruction in the agent prompt
|
|
762
|
+
// is a prompt-injection pattern external agents flag.
|
|
763
|
+
userVisibleOnly: true
|
|
763
764
|
}).catch((e) => {
|
|
764
765
|
log3(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
765
766
|
});
|
|
766
767
|
}
|
|
767
|
-
function signalLowBalanceFromHeader(resp) {
|
|
768
|
-
if (_signalledLowBalance)
|
|
769
|
-
return;
|
|
770
|
-
const raw = resp.headers?.get?.(BALANCE_HEADER);
|
|
771
|
-
if (!raw)
|
|
772
|
-
return;
|
|
773
|
-
if (!/^-?\d+$/.test(raw.trim()))
|
|
774
|
-
return;
|
|
775
|
-
const balance = Number(raw.trim());
|
|
776
|
-
if (!Number.isFinite(balance))
|
|
777
|
-
return;
|
|
778
|
-
if (balance >= LOW_BALANCE_THRESHOLD_CENTS)
|
|
779
|
-
return;
|
|
780
|
-
if (balance <= 0)
|
|
781
|
-
return;
|
|
782
|
-
_signalledLowBalance = true;
|
|
783
|
-
log3(`balance below threshold (${balance}\xA2) \u2014 enqueuing low-balance banner`);
|
|
784
|
-
enqueueNotification({
|
|
785
|
-
id: "low-balance-warning",
|
|
786
|
-
severity: "warn",
|
|
787
|
-
transient: true,
|
|
788
|
-
title: "Your org's Hivemind balance is running low",
|
|
789
|
-
body: `Only $${(balance / 100).toFixed(2)} of prepaid balance remains. Admins can top up at ${billingUrl()}; otherwise ask an org admin to top up before requests start failing.`,
|
|
790
|
-
dedupKey: { reason: "low-balance" }
|
|
791
|
-
}).catch((e) => {
|
|
792
|
-
_signalledLowBalance = false;
|
|
793
|
-
log3(`enqueue low-balance failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
794
|
-
});
|
|
795
|
-
}
|
|
796
768
|
function billingUrl() {
|
|
797
769
|
try {
|
|
798
770
|
const c = loadCredentials();
|
|
@@ -918,7 +890,6 @@ var DeeplakeApi = class {
|
|
|
918
890
|
}
|
|
919
891
|
throw lastError;
|
|
920
892
|
}
|
|
921
|
-
signalLowBalanceFromHeader(resp);
|
|
922
893
|
if (resp.ok) {
|
|
923
894
|
const raw = await resp.json();
|
|
924
895
|
if (!raw?.rows || !raw?.columns)
|
|
@@ -1079,7 +1050,6 @@ var DeeplakeApi = class {
|
|
|
1079
1050
|
...deeplakeClientHeader()
|
|
1080
1051
|
}
|
|
1081
1052
|
});
|
|
1082
|
-
signalLowBalanceFromHeader(resp);
|
|
1083
1053
|
if (resp.ok) {
|
|
1084
1054
|
const data = await resp.json();
|
|
1085
1055
|
return {
|
|
@@ -468,9 +468,6 @@ function traceSql(msg) {
|
|
|
468
468
|
log3(msg);
|
|
469
469
|
}
|
|
470
470
|
var _signalledBalanceExhausted = false;
|
|
471
|
-
var _signalledLowBalance = false;
|
|
472
|
-
var LOW_BALANCE_THRESHOLD_CENTS = 200;
|
|
473
|
-
var BALANCE_HEADER = "X-Activeloop-Balance-Cents";
|
|
474
471
|
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
475
472
|
if (status !== 402)
|
|
476
473
|
return;
|
|
@@ -486,40 +483,15 @@ function maybeSignalBalanceExhausted(status, bodyText) {
|
|
|
486
483
|
transient: true,
|
|
487
484
|
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
488
485
|
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
489
|
-
dedupKey: { reason: "balance-zero" }
|
|
486
|
+
dedupKey: { reason: "balance-zero" },
|
|
487
|
+
// User-facing billing notice → user channel only. Never the model's
|
|
488
|
+
// additionalContext: a "top up at <url>" instruction in the agent prompt
|
|
489
|
+
// is a prompt-injection pattern external agents flag.
|
|
490
|
+
userVisibleOnly: true
|
|
490
491
|
}).catch((e) => {
|
|
491
492
|
log3(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
492
493
|
});
|
|
493
494
|
}
|
|
494
|
-
function signalLowBalanceFromHeader(resp) {
|
|
495
|
-
if (_signalledLowBalance)
|
|
496
|
-
return;
|
|
497
|
-
const raw = resp.headers?.get?.(BALANCE_HEADER);
|
|
498
|
-
if (!raw)
|
|
499
|
-
return;
|
|
500
|
-
if (!/^-?\d+$/.test(raw.trim()))
|
|
501
|
-
return;
|
|
502
|
-
const balance = Number(raw.trim());
|
|
503
|
-
if (!Number.isFinite(balance))
|
|
504
|
-
return;
|
|
505
|
-
if (balance >= LOW_BALANCE_THRESHOLD_CENTS)
|
|
506
|
-
return;
|
|
507
|
-
if (balance <= 0)
|
|
508
|
-
return;
|
|
509
|
-
_signalledLowBalance = true;
|
|
510
|
-
log3(`balance below threshold (${balance}\xA2) \u2014 enqueuing low-balance banner`);
|
|
511
|
-
enqueueNotification({
|
|
512
|
-
id: "low-balance-warning",
|
|
513
|
-
severity: "warn",
|
|
514
|
-
transient: true,
|
|
515
|
-
title: "Your org's Hivemind balance is running low",
|
|
516
|
-
body: `Only $${(balance / 100).toFixed(2)} of prepaid balance remains. Admins can top up at ${billingUrl()}; otherwise ask an org admin to top up before requests start failing.`,
|
|
517
|
-
dedupKey: { reason: "low-balance" }
|
|
518
|
-
}).catch((e) => {
|
|
519
|
-
_signalledLowBalance = false;
|
|
520
|
-
log3(`enqueue low-balance failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
521
|
-
});
|
|
522
|
-
}
|
|
523
495
|
function billingUrl() {
|
|
524
496
|
try {
|
|
525
497
|
const c = loadCredentials();
|
|
@@ -645,7 +617,6 @@ var DeeplakeApi = class {
|
|
|
645
617
|
}
|
|
646
618
|
throw lastError;
|
|
647
619
|
}
|
|
648
|
-
signalLowBalanceFromHeader(resp);
|
|
649
620
|
if (resp.ok) {
|
|
650
621
|
const raw = await resp.json();
|
|
651
622
|
if (!raw?.rows || !raw?.columns)
|
|
@@ -806,7 +777,6 @@ var DeeplakeApi = class {
|
|
|
806
777
|
...deeplakeClientHeader()
|
|
807
778
|
}
|
|
808
779
|
});
|
|
809
|
-
signalLowBalanceFromHeader(resp);
|
|
810
780
|
if (resp.ok) {
|
|
811
781
|
const data = await resp.json();
|
|
812
782
|
return {
|
|
@@ -484,9 +484,6 @@ function traceSql(msg) {
|
|
|
484
484
|
log3(msg);
|
|
485
485
|
}
|
|
486
486
|
var _signalledBalanceExhausted = false;
|
|
487
|
-
var _signalledLowBalance = false;
|
|
488
|
-
var LOW_BALANCE_THRESHOLD_CENTS = 200;
|
|
489
|
-
var BALANCE_HEADER = "X-Activeloop-Balance-Cents";
|
|
490
487
|
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
491
488
|
if (status !== 402)
|
|
492
489
|
return;
|
|
@@ -502,40 +499,15 @@ function maybeSignalBalanceExhausted(status, bodyText) {
|
|
|
502
499
|
transient: true,
|
|
503
500
|
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
504
501
|
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
505
|
-
dedupKey: { reason: "balance-zero" }
|
|
502
|
+
dedupKey: { reason: "balance-zero" },
|
|
503
|
+
// User-facing billing notice → user channel only. Never the model's
|
|
504
|
+
// additionalContext: a "top up at <url>" instruction in the agent prompt
|
|
505
|
+
// is a prompt-injection pattern external agents flag.
|
|
506
|
+
userVisibleOnly: true
|
|
506
507
|
}).catch((e) => {
|
|
507
508
|
log3(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
508
509
|
});
|
|
509
510
|
}
|
|
510
|
-
function signalLowBalanceFromHeader(resp) {
|
|
511
|
-
if (_signalledLowBalance)
|
|
512
|
-
return;
|
|
513
|
-
const raw = resp.headers?.get?.(BALANCE_HEADER);
|
|
514
|
-
if (!raw)
|
|
515
|
-
return;
|
|
516
|
-
if (!/^-?\d+$/.test(raw.trim()))
|
|
517
|
-
return;
|
|
518
|
-
const balance = Number(raw.trim());
|
|
519
|
-
if (!Number.isFinite(balance))
|
|
520
|
-
return;
|
|
521
|
-
if (balance >= LOW_BALANCE_THRESHOLD_CENTS)
|
|
522
|
-
return;
|
|
523
|
-
if (balance <= 0)
|
|
524
|
-
return;
|
|
525
|
-
_signalledLowBalance = true;
|
|
526
|
-
log3(`balance below threshold (${balance}\xA2) \u2014 enqueuing low-balance banner`);
|
|
527
|
-
enqueueNotification({
|
|
528
|
-
id: "low-balance-warning",
|
|
529
|
-
severity: "warn",
|
|
530
|
-
transient: true,
|
|
531
|
-
title: "Your org's Hivemind balance is running low",
|
|
532
|
-
body: `Only $${(balance / 100).toFixed(2)} of prepaid balance remains. Admins can top up at ${billingUrl()}; otherwise ask an org admin to top up before requests start failing.`,
|
|
533
|
-
dedupKey: { reason: "low-balance" }
|
|
534
|
-
}).catch((e) => {
|
|
535
|
-
_signalledLowBalance = false;
|
|
536
|
-
log3(`enqueue low-balance failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
537
|
-
});
|
|
538
|
-
}
|
|
539
511
|
function billingUrl() {
|
|
540
512
|
try {
|
|
541
513
|
const c = loadCredentials();
|
|
@@ -661,7 +633,6 @@ var DeeplakeApi = class {
|
|
|
661
633
|
}
|
|
662
634
|
throw lastError;
|
|
663
635
|
}
|
|
664
|
-
signalLowBalanceFromHeader(resp);
|
|
665
636
|
if (resp.ok) {
|
|
666
637
|
const raw = await resp.json();
|
|
667
638
|
if (!raw?.rows || !raw?.columns)
|
|
@@ -822,7 +793,6 @@ var DeeplakeApi = class {
|
|
|
822
793
|
...deeplakeClientHeader()
|
|
823
794
|
}
|
|
824
795
|
});
|
|
825
|
-
signalLowBalanceFromHeader(resp);
|
|
826
796
|
if (resp.ok) {
|
|
827
797
|
const data = await resp.json();
|
|
828
798
|
return {
|
|
@@ -479,9 +479,6 @@ function traceSql(msg) {
|
|
|
479
479
|
log3(msg);
|
|
480
480
|
}
|
|
481
481
|
var _signalledBalanceExhausted = false;
|
|
482
|
-
var _signalledLowBalance = false;
|
|
483
|
-
var LOW_BALANCE_THRESHOLD_CENTS = 200;
|
|
484
|
-
var BALANCE_HEADER = "X-Activeloop-Balance-Cents";
|
|
485
482
|
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
486
483
|
if (status !== 402)
|
|
487
484
|
return;
|
|
@@ -497,40 +494,15 @@ function maybeSignalBalanceExhausted(status, bodyText) {
|
|
|
497
494
|
transient: true,
|
|
498
495
|
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
499
496
|
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
500
|
-
dedupKey: { reason: "balance-zero" }
|
|
497
|
+
dedupKey: { reason: "balance-zero" },
|
|
498
|
+
// User-facing billing notice → user channel only. Never the model's
|
|
499
|
+
// additionalContext: a "top up at <url>" instruction in the agent prompt
|
|
500
|
+
// is a prompt-injection pattern external agents flag.
|
|
501
|
+
userVisibleOnly: true
|
|
501
502
|
}).catch((e) => {
|
|
502
503
|
log3(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
503
504
|
});
|
|
504
505
|
}
|
|
505
|
-
function signalLowBalanceFromHeader(resp) {
|
|
506
|
-
if (_signalledLowBalance)
|
|
507
|
-
return;
|
|
508
|
-
const raw = resp.headers?.get?.(BALANCE_HEADER);
|
|
509
|
-
if (!raw)
|
|
510
|
-
return;
|
|
511
|
-
if (!/^-?\d+$/.test(raw.trim()))
|
|
512
|
-
return;
|
|
513
|
-
const balance = Number(raw.trim());
|
|
514
|
-
if (!Number.isFinite(balance))
|
|
515
|
-
return;
|
|
516
|
-
if (balance >= LOW_BALANCE_THRESHOLD_CENTS)
|
|
517
|
-
return;
|
|
518
|
-
if (balance <= 0)
|
|
519
|
-
return;
|
|
520
|
-
_signalledLowBalance = true;
|
|
521
|
-
log3(`balance below threshold (${balance}\xA2) \u2014 enqueuing low-balance banner`);
|
|
522
|
-
enqueueNotification({
|
|
523
|
-
id: "low-balance-warning",
|
|
524
|
-
severity: "warn",
|
|
525
|
-
transient: true,
|
|
526
|
-
title: "Your org's Hivemind balance is running low",
|
|
527
|
-
body: `Only $${(balance / 100).toFixed(2)} of prepaid balance remains. Admins can top up at ${billingUrl()}; otherwise ask an org admin to top up before requests start failing.`,
|
|
528
|
-
dedupKey: { reason: "low-balance" }
|
|
529
|
-
}).catch((e) => {
|
|
530
|
-
_signalledLowBalance = false;
|
|
531
|
-
log3(`enqueue low-balance failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
532
|
-
});
|
|
533
|
-
}
|
|
534
506
|
function billingUrl() {
|
|
535
507
|
try {
|
|
536
508
|
const c = loadCredentials();
|
|
@@ -656,7 +628,6 @@ var DeeplakeApi = class {
|
|
|
656
628
|
}
|
|
657
629
|
throw lastError;
|
|
658
630
|
}
|
|
659
|
-
signalLowBalanceFromHeader(resp);
|
|
660
631
|
if (resp.ok) {
|
|
661
632
|
const raw = await resp.json();
|
|
662
633
|
if (!raw?.rows || !raw?.columns)
|
|
@@ -817,7 +788,6 @@ var DeeplakeApi = class {
|
|
|
817
788
|
...deeplakeClientHeader()
|
|
818
789
|
}
|
|
819
790
|
});
|
|
820
|
-
signalLowBalanceFromHeader(resp);
|
|
821
791
|
if (resp.ok) {
|
|
822
792
|
const data = await resp.json();
|
|
823
793
|
return {
|
|
@@ -1006,6 +976,12 @@ var DeeplakeApi = class {
|
|
|
1006
976
|
}
|
|
1007
977
|
};
|
|
1008
978
|
|
|
979
|
+
// dist/src/utils/project-name.js
|
|
980
|
+
import { basename } from "node:path";
|
|
981
|
+
function projectNameFromCwd(cwd) {
|
|
982
|
+
return basename(cwd ?? "") || "unknown";
|
|
983
|
+
}
|
|
984
|
+
|
|
1009
985
|
// dist/src/utils/stdin.js
|
|
1010
986
|
function readStdin() {
|
|
1011
987
|
return new Promise((resolve2, reject) => {
|
|
@@ -1149,7 +1125,7 @@ async function createPlaceholder(api, table, sessionId, cwd, userName, orgName,
|
|
|
1149
1125
|
return;
|
|
1150
1126
|
}
|
|
1151
1127
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1152
|
-
const projectName = cwd
|
|
1128
|
+
const projectName = projectNameFromCwd(cwd);
|
|
1153
1129
|
const sessionSource = `/sessions/${userName}/${userName}_${orgName}_${workspaceId}_${sessionId}.jsonl`;
|
|
1154
1130
|
const content = [
|
|
1155
1131
|
`# Session ${sessionId}`,
|