@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
|
@@ -477,9 +477,6 @@ function traceSql(msg) {
|
|
|
477
477
|
log3(msg);
|
|
478
478
|
}
|
|
479
479
|
var _signalledBalanceExhausted = false;
|
|
480
|
-
var _signalledLowBalance = false;
|
|
481
|
-
var LOW_BALANCE_THRESHOLD_CENTS = 200;
|
|
482
|
-
var BALANCE_HEADER = "X-Activeloop-Balance-Cents";
|
|
483
480
|
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
484
481
|
if (status !== 402)
|
|
485
482
|
return;
|
|
@@ -495,40 +492,15 @@ function maybeSignalBalanceExhausted(status, bodyText) {
|
|
|
495
492
|
transient: true,
|
|
496
493
|
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
497
494
|
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
498
|
-
dedupKey: { reason: "balance-zero" }
|
|
495
|
+
dedupKey: { reason: "balance-zero" },
|
|
496
|
+
// User-facing billing notice → user channel only. Never the model's
|
|
497
|
+
// additionalContext: a "top up at <url>" instruction in the agent prompt
|
|
498
|
+
// is a prompt-injection pattern external agents flag.
|
|
499
|
+
userVisibleOnly: true
|
|
499
500
|
}).catch((e) => {
|
|
500
501
|
log3(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
501
502
|
});
|
|
502
503
|
}
|
|
503
|
-
function signalLowBalanceFromHeader(resp) {
|
|
504
|
-
if (_signalledLowBalance)
|
|
505
|
-
return;
|
|
506
|
-
const raw = resp.headers?.get?.(BALANCE_HEADER);
|
|
507
|
-
if (!raw)
|
|
508
|
-
return;
|
|
509
|
-
if (!/^-?\d+$/.test(raw.trim()))
|
|
510
|
-
return;
|
|
511
|
-
const balance = Number(raw.trim());
|
|
512
|
-
if (!Number.isFinite(balance))
|
|
513
|
-
return;
|
|
514
|
-
if (balance >= LOW_BALANCE_THRESHOLD_CENTS)
|
|
515
|
-
return;
|
|
516
|
-
if (balance <= 0)
|
|
517
|
-
return;
|
|
518
|
-
_signalledLowBalance = true;
|
|
519
|
-
log3(`balance below threshold (${balance}\xA2) \u2014 enqueuing low-balance banner`);
|
|
520
|
-
enqueueNotification({
|
|
521
|
-
id: "low-balance-warning",
|
|
522
|
-
severity: "warn",
|
|
523
|
-
transient: true,
|
|
524
|
-
title: "Your org's Hivemind balance is running low",
|
|
525
|
-
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.`,
|
|
526
|
-
dedupKey: { reason: "low-balance" }
|
|
527
|
-
}).catch((e) => {
|
|
528
|
-
_signalledLowBalance = false;
|
|
529
|
-
log3(`enqueue low-balance failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
530
|
-
});
|
|
531
|
-
}
|
|
532
504
|
function billingUrl() {
|
|
533
505
|
try {
|
|
534
506
|
const c = loadCredentials();
|
|
@@ -654,7 +626,6 @@ var DeeplakeApi = class {
|
|
|
654
626
|
}
|
|
655
627
|
throw lastError;
|
|
656
628
|
}
|
|
657
|
-
signalLowBalanceFromHeader(resp);
|
|
658
629
|
if (resp.ok) {
|
|
659
630
|
const raw = await resp.json();
|
|
660
631
|
if (!raw?.rows || !raw?.columns)
|
|
@@ -815,7 +786,6 @@ var DeeplakeApi = class {
|
|
|
815
786
|
...deeplakeClientHeader()
|
|
816
787
|
}
|
|
817
788
|
});
|
|
818
|
-
signalLowBalanceFromHeader(resp);
|
|
819
789
|
if (resp.ok) {
|
|
820
790
|
const data = await resp.json();
|
|
821
791
|
return {
|
|
@@ -124,7 +124,7 @@ function tryAcquireLock(sessionId, maxAgeMs = 10 * 60 * 1e3) {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
// dist/src/hooks/hermes/spawn-wiki-worker.js
|
|
127
|
-
import {
|
|
127
|
+
import { execSync } from "node:child_process";
|
|
128
128
|
import { fileURLToPath } from "node:url";
|
|
129
129
|
import { dirname as dirname2, join as join6 } from "node:path";
|
|
130
130
|
import { writeFileSync as writeFileSync2, mkdirSync as mkdirSync3 } from "node:fs";
|
|
@@ -190,6 +190,32 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
|
|
|
190
190
|
return null;
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
+
// dist/src/utils/spawn-detached.js
|
|
194
|
+
import { spawn as nodeSpawn } from "node:child_process";
|
|
195
|
+
function spawnDetachedNodeWorker(workerPath, args = [], deps = {}) {
|
|
196
|
+
const spawn = deps.spawn ?? nodeSpawn;
|
|
197
|
+
const execPath = deps.execPath ?? process.execPath;
|
|
198
|
+
try {
|
|
199
|
+
const child = spawn(execPath, [workerPath, ...args], {
|
|
200
|
+
detached: true,
|
|
201
|
+
stdio: ["ignore", "ignore", "ignore"],
|
|
202
|
+
// Suppress the transient console window Windows would otherwise pop for
|
|
203
|
+
// the detached worker. No-op on POSIX.
|
|
204
|
+
windowsHide: true
|
|
205
|
+
});
|
|
206
|
+
child.on("error", () => {
|
|
207
|
+
});
|
|
208
|
+
child.unref();
|
|
209
|
+
} catch {
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// dist/src/utils/project-name.js
|
|
214
|
+
import { basename } from "node:path";
|
|
215
|
+
function projectNameFromCwd(cwd) {
|
|
216
|
+
return basename(cwd ?? "") || "unknown";
|
|
217
|
+
}
|
|
218
|
+
|
|
193
219
|
// dist/src/hooks/hermes/spawn-wiki-worker.js
|
|
194
220
|
var HOME = homedir4();
|
|
195
221
|
var wikiLogger = makeWikiLogger(join6(HOME, ".hermes", "hooks"));
|
|
@@ -253,7 +279,7 @@ function findHermesBin() {
|
|
|
253
279
|
}
|
|
254
280
|
function spawnHermesWikiWorker(opts) {
|
|
255
281
|
const { config, sessionId, cwd, bundleDir, reason } = opts;
|
|
256
|
-
const projectName = cwd
|
|
282
|
+
const projectName = projectNameFromCwd(cwd);
|
|
257
283
|
const tmpDir = join6(tmpdir(), `deeplake-wiki-${sessionId}-${Date.now()}`);
|
|
258
284
|
mkdirSync3(tmpDir, { recursive: true });
|
|
259
285
|
const pluginVersion = getInstalledVersion(bundleDir, ".claude-plugin") ?? "";
|
|
@@ -279,10 +305,7 @@ function spawnHermesWikiWorker(opts) {
|
|
|
279
305
|
}));
|
|
280
306
|
wikiLog(`${reason}: spawning summary worker for ${sessionId}`);
|
|
281
307
|
const workerPath = join6(bundleDir, "wiki-worker.js");
|
|
282
|
-
|
|
283
|
-
detached: true,
|
|
284
|
-
stdio: ["ignore", "ignore", "ignore"]
|
|
285
|
-
}).unref();
|
|
308
|
+
spawnDetachedNodeWorker(workerPath, [configFile]);
|
|
286
309
|
wikiLog(`${reason}: spawned summary worker for ${sessionId}`);
|
|
287
310
|
}
|
|
288
311
|
function bundleDirFromImportMeta(importMetaUrl) {
|
|
@@ -290,7 +313,6 @@ function bundleDirFromImportMeta(importMetaUrl) {
|
|
|
290
313
|
}
|
|
291
314
|
|
|
292
315
|
// dist/src/skillify/spawn-skillify-worker.js
|
|
293
|
-
import { spawn as spawn2 } from "node:child_process";
|
|
294
316
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
295
317
|
import { dirname as dirname3, join as join8 } from "node:path";
|
|
296
318
|
import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync4, appendFileSync as appendFileSync3, chmodSync } from "node:fs";
|
|
@@ -411,10 +433,7 @@ function spawnSkillifyWorker(opts) {
|
|
|
411
433
|
}
|
|
412
434
|
skillifyLog(`${reason}: spawning skillify worker for project=${project} key=${projectKey}`);
|
|
413
435
|
const workerPath = join8(bundleDir, "skillify-worker.js");
|
|
414
|
-
|
|
415
|
-
detached: true,
|
|
416
|
-
stdio: ["ignore", "ignore", "ignore"]
|
|
417
|
-
}).unref();
|
|
436
|
+
spawnDetachedNodeWorker(workerPath, [configFile]);
|
|
418
437
|
skillifyLog(`${reason}: spawned skillify worker for ${projectKey}`);
|
|
419
438
|
}
|
|
420
439
|
|
|
@@ -425,7 +444,7 @@ import { join as join11 } from "node:path";
|
|
|
425
444
|
// dist/src/utils/repo-identity.js
|
|
426
445
|
import { execSync as execSync2 } from "node:child_process";
|
|
427
446
|
import { createHash } from "node:crypto";
|
|
428
|
-
import { basename, resolve } from "node:path";
|
|
447
|
+
import { basename as basename2, resolve } from "node:path";
|
|
429
448
|
var DEFAULT_PORTS = {
|
|
430
449
|
http: "80",
|
|
431
450
|
https: "443",
|
|
@@ -453,7 +472,7 @@ function normalizeGitRemoteUrl(url) {
|
|
|
453
472
|
}
|
|
454
473
|
function deriveProjectKey(cwd) {
|
|
455
474
|
const absCwd = resolve(cwd);
|
|
456
|
-
const project =
|
|
475
|
+
const project = basename2(absCwd) || "unknown";
|
|
457
476
|
let signature = null;
|
|
458
477
|
try {
|
|
459
478
|
const raw = execSync2("git config --get remote.origin.url", {
|
|
@@ -532,9 +532,6 @@ function traceSql(msg) {
|
|
|
532
532
|
log3(msg);
|
|
533
533
|
}
|
|
534
534
|
var _signalledBalanceExhausted = false;
|
|
535
|
-
var _signalledLowBalance = false;
|
|
536
|
-
var LOW_BALANCE_THRESHOLD_CENTS = 200;
|
|
537
|
-
var BALANCE_HEADER = "X-Activeloop-Balance-Cents";
|
|
538
535
|
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
539
536
|
if (status !== 402)
|
|
540
537
|
return;
|
|
@@ -550,40 +547,15 @@ function maybeSignalBalanceExhausted(status, bodyText) {
|
|
|
550
547
|
transient: true,
|
|
551
548
|
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
552
549
|
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
553
|
-
dedupKey: { reason: "balance-zero" }
|
|
550
|
+
dedupKey: { reason: "balance-zero" },
|
|
551
|
+
// User-facing billing notice → user channel only. Never the model's
|
|
552
|
+
// additionalContext: a "top up at <url>" instruction in the agent prompt
|
|
553
|
+
// is a prompt-injection pattern external agents flag.
|
|
554
|
+
userVisibleOnly: true
|
|
554
555
|
}).catch((e) => {
|
|
555
556
|
log3(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
556
557
|
});
|
|
557
558
|
}
|
|
558
|
-
function signalLowBalanceFromHeader(resp) {
|
|
559
|
-
if (_signalledLowBalance)
|
|
560
|
-
return;
|
|
561
|
-
const raw = resp.headers?.get?.(BALANCE_HEADER);
|
|
562
|
-
if (!raw)
|
|
563
|
-
return;
|
|
564
|
-
if (!/^-?\d+$/.test(raw.trim()))
|
|
565
|
-
return;
|
|
566
|
-
const balance = Number(raw.trim());
|
|
567
|
-
if (!Number.isFinite(balance))
|
|
568
|
-
return;
|
|
569
|
-
if (balance >= LOW_BALANCE_THRESHOLD_CENTS)
|
|
570
|
-
return;
|
|
571
|
-
if (balance <= 0)
|
|
572
|
-
return;
|
|
573
|
-
_signalledLowBalance = true;
|
|
574
|
-
log3(`balance below threshold (${balance}\xA2) \u2014 enqueuing low-balance banner`);
|
|
575
|
-
enqueueNotification({
|
|
576
|
-
id: "low-balance-warning",
|
|
577
|
-
severity: "warn",
|
|
578
|
-
transient: true,
|
|
579
|
-
title: "Your org's Hivemind balance is running low",
|
|
580
|
-
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.`,
|
|
581
|
-
dedupKey: { reason: "low-balance" }
|
|
582
|
-
}).catch((e) => {
|
|
583
|
-
_signalledLowBalance = false;
|
|
584
|
-
log3(`enqueue low-balance failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
585
|
-
});
|
|
586
|
-
}
|
|
587
559
|
function billingUrl() {
|
|
588
560
|
try {
|
|
589
561
|
const c = loadCredentials();
|
|
@@ -709,7 +681,6 @@ var DeeplakeApi = class {
|
|
|
709
681
|
}
|
|
710
682
|
throw lastError;
|
|
711
683
|
}
|
|
712
|
-
signalLowBalanceFromHeader(resp);
|
|
713
684
|
if (resp.ok) {
|
|
714
685
|
const raw = await resp.json();
|
|
715
686
|
if (!raw?.rows || !raw?.columns)
|
|
@@ -870,7 +841,6 @@ var DeeplakeApi = class {
|
|
|
870
841
|
...deeplakeClientHeader()
|
|
871
842
|
}
|
|
872
843
|
});
|
|
873
|
-
signalLowBalanceFromHeader(resp);
|
|
874
844
|
if (resp.ok) {
|
|
875
845
|
const data = await resp.json();
|
|
876
846
|
return {
|
|
@@ -1221,6 +1191,12 @@ function sanitizeForInject(text) {
|
|
|
1221
1191
|
}
|
|
1222
1192
|
var LINE_TERMINATOR_RE = /\r\n?|[\n\u2028\u2029\u0085]/g;
|
|
1223
1193
|
|
|
1194
|
+
// dist/src/utils/project-name.js
|
|
1195
|
+
import { basename } from "node:path";
|
|
1196
|
+
function projectNameFromCwd(cwd) {
|
|
1197
|
+
return basename(cwd ?? "") || "unknown";
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1224
1200
|
// dist/src/cli/skillify-spec.js
|
|
1225
1201
|
var SKILLIFY_COMMANDS = [
|
|
1226
1202
|
{ cmd: "hivemind skillify", desc: "show scope, team, install, per-project state" },
|
|
@@ -2264,7 +2240,7 @@ async function createPlaceholder(api, table, sessionId, cwd, userName, orgName,
|
|
|
2264
2240
|
if (existing.length > 0)
|
|
2265
2241
|
return;
|
|
2266
2242
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2267
|
-
const projectName = cwd
|
|
2243
|
+
const projectName = projectNameFromCwd(cwd);
|
|
2268
2244
|
const sessionSource = `/sessions/${userName}/${userName}_${orgName}_${workspaceId}_${sessionId}.jsonl`;
|
|
2269
2245
|
const content = [
|
|
2270
2246
|
`# Session ${sessionId}`,
|
|
@@ -67172,9 +67172,6 @@ function traceSql(msg) {
|
|
|
67172
67172
|
log3(msg);
|
|
67173
67173
|
}
|
|
67174
67174
|
var _signalledBalanceExhausted = false;
|
|
67175
|
-
var _signalledLowBalance = false;
|
|
67176
|
-
var LOW_BALANCE_THRESHOLD_CENTS = 200;
|
|
67177
|
-
var BALANCE_HEADER = "X-Activeloop-Balance-Cents";
|
|
67178
67175
|
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
67179
67176
|
if (status !== 402)
|
|
67180
67177
|
return;
|
|
@@ -67190,40 +67187,15 @@ function maybeSignalBalanceExhausted(status, bodyText) {
|
|
|
67190
67187
|
transient: true,
|
|
67191
67188
|
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
67192
67189
|
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
67193
|
-
dedupKey: { reason: "balance-zero" }
|
|
67190
|
+
dedupKey: { reason: "balance-zero" },
|
|
67191
|
+
// User-facing billing notice → user channel only. Never the model's
|
|
67192
|
+
// additionalContext: a "top up at <url>" instruction in the agent prompt
|
|
67193
|
+
// is a prompt-injection pattern external agents flag.
|
|
67194
|
+
userVisibleOnly: true
|
|
67194
67195
|
}).catch((e6) => {
|
|
67195
67196
|
log3(`enqueue balance-exhausted failed: ${e6 instanceof Error ? e6.message : String(e6)}`);
|
|
67196
67197
|
});
|
|
67197
67198
|
}
|
|
67198
|
-
function signalLowBalanceFromHeader(resp) {
|
|
67199
|
-
if (_signalledLowBalance)
|
|
67200
|
-
return;
|
|
67201
|
-
const raw = resp.headers?.get?.(BALANCE_HEADER);
|
|
67202
|
-
if (!raw)
|
|
67203
|
-
return;
|
|
67204
|
-
if (!/^-?\d+$/.test(raw.trim()))
|
|
67205
|
-
return;
|
|
67206
|
-
const balance = Number(raw.trim());
|
|
67207
|
-
if (!Number.isFinite(balance))
|
|
67208
|
-
return;
|
|
67209
|
-
if (balance >= LOW_BALANCE_THRESHOLD_CENTS)
|
|
67210
|
-
return;
|
|
67211
|
-
if (balance <= 0)
|
|
67212
|
-
return;
|
|
67213
|
-
_signalledLowBalance = true;
|
|
67214
|
-
log3(`balance below threshold (${balance}\xA2) \u2014 enqueuing low-balance banner`);
|
|
67215
|
-
enqueueNotification({
|
|
67216
|
-
id: "low-balance-warning",
|
|
67217
|
-
severity: "warn",
|
|
67218
|
-
transient: true,
|
|
67219
|
-
title: "Your org's Hivemind balance is running low",
|
|
67220
|
-
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.`,
|
|
67221
|
-
dedupKey: { reason: "low-balance" }
|
|
67222
|
-
}).catch((e6) => {
|
|
67223
|
-
_signalledLowBalance = false;
|
|
67224
|
-
log3(`enqueue low-balance failed: ${e6 instanceof Error ? e6.message : String(e6)}`);
|
|
67225
|
-
});
|
|
67226
|
-
}
|
|
67227
67199
|
function billingUrl() {
|
|
67228
67200
|
try {
|
|
67229
67201
|
const c15 = loadCredentials();
|
|
@@ -67349,7 +67321,6 @@ var DeeplakeApi = class {
|
|
|
67349
67321
|
}
|
|
67350
67322
|
throw lastError;
|
|
67351
67323
|
}
|
|
67352
|
-
signalLowBalanceFromHeader(resp);
|
|
67353
67324
|
if (resp.ok) {
|
|
67354
67325
|
const raw = await resp.json();
|
|
67355
67326
|
if (!raw?.rows || !raw?.columns)
|
|
@@ -67510,7 +67481,6 @@ var DeeplakeApi = class {
|
|
|
67510
67481
|
...deeplakeClientHeader()
|
|
67511
67482
|
}
|
|
67512
67483
|
});
|
|
67513
|
-
signalLowBalanceFromHeader(resp);
|
|
67514
67484
|
if (resp.ok) {
|
|
67515
67485
|
const data = await resp.json();
|
|
67516
67486
|
return {
|
package/mcp/bundle/server.js
CHANGED
|
@@ -23683,9 +23683,6 @@ function traceSql(msg) {
|
|
|
23683
23683
|
log3(msg);
|
|
23684
23684
|
}
|
|
23685
23685
|
var _signalledBalanceExhausted = false;
|
|
23686
|
-
var _signalledLowBalance = false;
|
|
23687
|
-
var LOW_BALANCE_THRESHOLD_CENTS = 200;
|
|
23688
|
-
var BALANCE_HEADER = "X-Activeloop-Balance-Cents";
|
|
23689
23686
|
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
23690
23687
|
if (status !== 402)
|
|
23691
23688
|
return;
|
|
@@ -23701,40 +23698,15 @@ function maybeSignalBalanceExhausted(status, bodyText) {
|
|
|
23701
23698
|
transient: true,
|
|
23702
23699
|
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
23703
23700
|
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
23704
|
-
dedupKey: { reason: "balance-zero" }
|
|
23701
|
+
dedupKey: { reason: "balance-zero" },
|
|
23702
|
+
// User-facing billing notice → user channel only. Never the model's
|
|
23703
|
+
// additionalContext: a "top up at <url>" instruction in the agent prompt
|
|
23704
|
+
// is a prompt-injection pattern external agents flag.
|
|
23705
|
+
userVisibleOnly: true
|
|
23705
23706
|
}).catch((e) => {
|
|
23706
23707
|
log3(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
23707
23708
|
});
|
|
23708
23709
|
}
|
|
23709
|
-
function signalLowBalanceFromHeader(resp) {
|
|
23710
|
-
if (_signalledLowBalance)
|
|
23711
|
-
return;
|
|
23712
|
-
const raw = resp.headers?.get?.(BALANCE_HEADER);
|
|
23713
|
-
if (!raw)
|
|
23714
|
-
return;
|
|
23715
|
-
if (!/^-?\d+$/.test(raw.trim()))
|
|
23716
|
-
return;
|
|
23717
|
-
const balance = Number(raw.trim());
|
|
23718
|
-
if (!Number.isFinite(balance))
|
|
23719
|
-
return;
|
|
23720
|
-
if (balance >= LOW_BALANCE_THRESHOLD_CENTS)
|
|
23721
|
-
return;
|
|
23722
|
-
if (balance <= 0)
|
|
23723
|
-
return;
|
|
23724
|
-
_signalledLowBalance = true;
|
|
23725
|
-
log3(`balance below threshold (${balance}\xA2) \u2014 enqueuing low-balance banner`);
|
|
23726
|
-
enqueueNotification({
|
|
23727
|
-
id: "low-balance-warning",
|
|
23728
|
-
severity: "warn",
|
|
23729
|
-
transient: true,
|
|
23730
|
-
title: "Your org's Hivemind balance is running low",
|
|
23731
|
-
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.`,
|
|
23732
|
-
dedupKey: { reason: "low-balance" }
|
|
23733
|
-
}).catch((e) => {
|
|
23734
|
-
_signalledLowBalance = false;
|
|
23735
|
-
log3(`enqueue low-balance failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
23736
|
-
});
|
|
23737
|
-
}
|
|
23738
23710
|
function billingUrl() {
|
|
23739
23711
|
try {
|
|
23740
23712
|
const c = loadCredentials();
|
|
@@ -23860,7 +23832,6 @@ var DeeplakeApi = class {
|
|
|
23860
23832
|
}
|
|
23861
23833
|
throw lastError;
|
|
23862
23834
|
}
|
|
23863
|
-
signalLowBalanceFromHeader(resp);
|
|
23864
23835
|
if (resp.ok) {
|
|
23865
23836
|
const raw = await resp.json();
|
|
23866
23837
|
if (!raw?.rows || !raw?.columns)
|
|
@@ -24021,7 +23992,6 @@ var DeeplakeApi = class {
|
|
|
24021
23992
|
...deeplakeClientHeader()
|
|
24022
23993
|
}
|
|
24023
23994
|
});
|
|
24024
|
-
signalLowBalanceFromHeader(resp);
|
|
24025
23995
|
if (resp.ok) {
|
|
24026
23996
|
const data = await resp.json();
|
|
24027
23997
|
return {
|
package/openclaw/dist/index.js
CHANGED
|
@@ -494,9 +494,6 @@ function traceSql(msg) {
|
|
|
494
494
|
if (globalThis.__hivemind_tuning__.HIVEMIND_DEBUG === "1") log3(msg);
|
|
495
495
|
}
|
|
496
496
|
var _signalledBalanceExhausted = false;
|
|
497
|
-
var _signalledLowBalance = false;
|
|
498
|
-
var LOW_BALANCE_THRESHOLD_CENTS = 200;
|
|
499
|
-
var BALANCE_HEADER = "X-Activeloop-Balance-Cents";
|
|
500
497
|
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
501
498
|
if (status !== 402) return;
|
|
502
499
|
if (!bodyText.includes("balance_cents")) return;
|
|
@@ -509,34 +506,15 @@ function maybeSignalBalanceExhausted(status, bodyText) {
|
|
|
509
506
|
transient: true,
|
|
510
507
|
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
511
508
|
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
512
|
-
dedupKey: { reason: "balance-zero" }
|
|
509
|
+
dedupKey: { reason: "balance-zero" },
|
|
510
|
+
// User-facing billing notice → user channel only. Never the model's
|
|
511
|
+
// additionalContext: a "top up at <url>" instruction in the agent prompt
|
|
512
|
+
// is a prompt-injection pattern external agents flag.
|
|
513
|
+
userVisibleOnly: true
|
|
513
514
|
}).catch((e) => {
|
|
514
515
|
log3(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
515
516
|
});
|
|
516
517
|
}
|
|
517
|
-
function signalLowBalanceFromHeader(resp) {
|
|
518
|
-
if (_signalledLowBalance) return;
|
|
519
|
-
const raw = resp.headers?.get?.(BALANCE_HEADER);
|
|
520
|
-
if (!raw) return;
|
|
521
|
-
if (!/^-?\d+$/.test(raw.trim())) return;
|
|
522
|
-
const balance = Number(raw.trim());
|
|
523
|
-
if (!Number.isFinite(balance)) return;
|
|
524
|
-
if (balance >= LOW_BALANCE_THRESHOLD_CENTS) return;
|
|
525
|
-
if (balance <= 0) return;
|
|
526
|
-
_signalledLowBalance = true;
|
|
527
|
-
log3(`balance below threshold (${balance}\xA2) \u2014 enqueuing low-balance banner`);
|
|
528
|
-
enqueueNotification({
|
|
529
|
-
id: "low-balance-warning",
|
|
530
|
-
severity: "warn",
|
|
531
|
-
transient: true,
|
|
532
|
-
title: "Your org's Hivemind balance is running low",
|
|
533
|
-
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.`,
|
|
534
|
-
dedupKey: { reason: "low-balance" }
|
|
535
|
-
}).catch((e) => {
|
|
536
|
-
_signalledLowBalance = false;
|
|
537
|
-
log3(`enqueue low-balance failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
538
|
-
});
|
|
539
|
-
}
|
|
540
518
|
function billingUrl() {
|
|
541
519
|
try {
|
|
542
520
|
const c = loadCredentials();
|
|
@@ -662,7 +640,6 @@ var DeeplakeApi = class {
|
|
|
662
640
|
}
|
|
663
641
|
throw lastError;
|
|
664
642
|
}
|
|
665
|
-
signalLowBalanceFromHeader(resp);
|
|
666
643
|
if (resp.ok) {
|
|
667
644
|
const raw = await resp.json();
|
|
668
645
|
if (!raw?.rows || !raw?.columns) return [];
|
|
@@ -824,7 +801,6 @@ var DeeplakeApi = class {
|
|
|
824
801
|
...deeplakeClientHeader()
|
|
825
802
|
}
|
|
826
803
|
});
|
|
827
|
-
signalLowBalanceFromHeader(resp);
|
|
828
804
|
if (resp.ok) {
|
|
829
805
|
const data = await resp.json();
|
|
830
806
|
return {
|
|
@@ -1823,7 +1799,7 @@ function extractLatestVersion(body) {
|
|
|
1823
1799
|
return typeof v === "string" && v.length > 0 ? v : null;
|
|
1824
1800
|
}
|
|
1825
1801
|
function getInstalledVersion() {
|
|
1826
|
-
return "0.7.
|
|
1802
|
+
return "0.7.67".length > 0 ? "0.7.67" : null;
|
|
1827
1803
|
}
|
|
1828
1804
|
function isNewer(latest, current) {
|
|
1829
1805
|
const parse = (v) => v.replace(/-.*$/, "").split(".").map(Number);
|
package/openclaw/package.json
CHANGED