omnius 1.0.147 → 1.0.149
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/dist/index.js +1135 -206
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13138,6 +13138,27 @@ async function handleCmd(cmd) {
|
|
|
13138
13138
|
var _csAvgLatency = _cohereStats.queriesAnswered > 0 ? Math.round(_cohereStats.totalLatencyMs / _cohereStats.queriesAnswered) : 0;
|
|
13139
13139
|
var _csModels = Object.entries(_cohereStats.modelsUsed).sort(function(a, b) { return b[1] - a[1]; });
|
|
13140
13140
|
var _csPeers = Object.entries(_cohereStats.peersServed).sort(function(a, b) { return b[1] - a[1]; });
|
|
13141
|
+
var _csSnapshot = {
|
|
13142
|
+
status: cohereActive ? 'active' : 'inactive',
|
|
13143
|
+
active: cohereActive,
|
|
13144
|
+
daemonPid: process.pid,
|
|
13145
|
+
uptimeSec: _csUptime,
|
|
13146
|
+
lastQueryAt: _cohereStats.lastQueryAt || 0,
|
|
13147
|
+
queriesReceived: _cohereStats.queriesReceived,
|
|
13148
|
+
queriesAnswered: _cohereStats.queriesAnswered,
|
|
13149
|
+
queriesErrors: _cohereStats.queriesErrors,
|
|
13150
|
+
queriesSent: _cohereStats.queriesSent,
|
|
13151
|
+
avgLatencyMs: _csAvgLatency,
|
|
13152
|
+
bytesIn: _cohereStats.bytesIn,
|
|
13153
|
+
bytesOut: _cohereStats.bytesOut,
|
|
13154
|
+
modelsUsed: _cohereStats.modelsUsed,
|
|
13155
|
+
peersServed: _cohereStats.peersServed,
|
|
13156
|
+
allowedModels: _cohereAllowedModels ? [..._cohereAllowedModels] : null
|
|
13157
|
+
};
|
|
13158
|
+
if (args.format === 'json' || args.json === true || args.json === 'true' || args.json === '1') {
|
|
13159
|
+
writeResp(id, { ok: true, output: JSON.stringify(_csSnapshot) });
|
|
13160
|
+
break;
|
|
13161
|
+
}
|
|
13141
13162
|
var _csLines = [
|
|
13142
13163
|
'═══ COHERE Network Stats ═══',
|
|
13143
13164
|
'',
|
|
@@ -16549,6 +16570,14 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
16549
16570
|
max_tokens: {
|
|
16550
16571
|
type: "string",
|
|
16551
16572
|
description: "For remote_infer: maximum tokens to generate (e.g. '4096'). Default: 4096"
|
|
16573
|
+
},
|
|
16574
|
+
format: {
|
|
16575
|
+
type: "string",
|
|
16576
|
+
description: "For cohere_stats: set to 'json' for structured stats"
|
|
16577
|
+
},
|
|
16578
|
+
json: {
|
|
16579
|
+
type: "string",
|
|
16580
|
+
description: "For cohere_stats: set to '1' for structured stats"
|
|
16552
16581
|
}
|
|
16553
16582
|
},
|
|
16554
16583
|
required: ["action"],
|
|
@@ -16686,7 +16715,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
16686
16715
|
result = await this.sendDaemonCmd("cohere_disable", {});
|
|
16687
16716
|
break;
|
|
16688
16717
|
case "cohere_stats":
|
|
16689
|
-
result = await this.sendDaemonCmd("cohere_stats", {});
|
|
16718
|
+
result = await this.sendDaemonCmd("cohere_stats", { format: String(args.format ?? ""), json: String(args.json ?? "") });
|
|
16690
16719
|
break;
|
|
16691
16720
|
case "cohere_allow_model":
|
|
16692
16721
|
result = await this.sendDaemonCmd("cohere_allow_model", { model: String(args.model ?? "") });
|
|
@@ -124343,7 +124372,7 @@ var require_client_h1 = __commonJS({
|
|
|
124343
124372
|
kHTTPContext,
|
|
124344
124373
|
kClosed
|
|
124345
124374
|
} = require_symbols();
|
|
124346
|
-
var
|
|
124375
|
+
var constants2 = require_constants2();
|
|
124347
124376
|
var EMPTY_BUF = Buffer.alloc(0);
|
|
124348
124377
|
var FastBuffer = Buffer[Symbol.species];
|
|
124349
124378
|
var removeAllListeners = util2.removeAllListeners;
|
|
@@ -124469,7 +124498,7 @@ var require_client_h1 = __commonJS({
|
|
|
124469
124498
|
*/
|
|
124470
124499
|
constructor(client, socket, { exports: exports2 }) {
|
|
124471
124500
|
this.llhttp = exports2;
|
|
124472
|
-
this.ptr = this.llhttp.llhttp_alloc(
|
|
124501
|
+
this.ptr = this.llhttp.llhttp_alloc(constants2.TYPE.RESPONSE);
|
|
124473
124502
|
this.client = client;
|
|
124474
124503
|
this.socket = socket;
|
|
124475
124504
|
this.timeout = null;
|
|
@@ -124564,11 +124593,11 @@ var require_client_h1 = __commonJS({
|
|
|
124564
124593
|
currentParser = null;
|
|
124565
124594
|
currentBufferRef = null;
|
|
124566
124595
|
}
|
|
124567
|
-
if (ret !==
|
|
124596
|
+
if (ret !== constants2.ERROR.OK) {
|
|
124568
124597
|
const data = chunk.subarray(llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr);
|
|
124569
|
-
if (ret ===
|
|
124598
|
+
if (ret === constants2.ERROR.PAUSED_UPGRADE) {
|
|
124570
124599
|
this.onUpgrade(data);
|
|
124571
|
-
} else if (ret ===
|
|
124600
|
+
} else if (ret === constants2.ERROR.PAUSED) {
|
|
124572
124601
|
this.paused = true;
|
|
124573
124602
|
socket.unshift(data);
|
|
124574
124603
|
} else {
|
|
@@ -124578,7 +124607,7 @@ var require_client_h1 = __commonJS({
|
|
|
124578
124607
|
const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0);
|
|
124579
124608
|
message2 = "Response does not match the HTTP/1.1 protocol (" + Buffer.from(llhttp.memory.buffer, ptr, len).toString() + ")";
|
|
124580
124609
|
}
|
|
124581
|
-
throw new HTTPParserError(message2,
|
|
124610
|
+
throw new HTTPParserError(message2, constants2.ERROR[ret], data);
|
|
124582
124611
|
}
|
|
124583
124612
|
}
|
|
124584
124613
|
} catch (err) {
|
|
@@ -124785,7 +124814,7 @@ var require_client_h1 = __commonJS({
|
|
|
124785
124814
|
socket[kBlocking] = false;
|
|
124786
124815
|
client[kResume]();
|
|
124787
124816
|
}
|
|
124788
|
-
return pause ?
|
|
124817
|
+
return pause ? constants2.ERROR.PAUSED : 0;
|
|
124789
124818
|
}
|
|
124790
124819
|
/**
|
|
124791
124820
|
* @param {Buffer} buf
|
|
@@ -124811,7 +124840,7 @@ var require_client_h1 = __commonJS({
|
|
|
124811
124840
|
}
|
|
124812
124841
|
this.bytesRead += buf.length;
|
|
124813
124842
|
if (request.onData(buf) === false) {
|
|
124814
|
-
return
|
|
124843
|
+
return constants2.ERROR.PAUSED;
|
|
124815
124844
|
}
|
|
124816
124845
|
return 0;
|
|
124817
124846
|
}
|
|
@@ -124850,13 +124879,13 @@ var require_client_h1 = __commonJS({
|
|
|
124850
124879
|
if (socket[kWriting]) {
|
|
124851
124880
|
assert(client[kRunning] === 0);
|
|
124852
124881
|
util2.destroy(socket, new InformationalError("reset"));
|
|
124853
|
-
return
|
|
124882
|
+
return constants2.ERROR.PAUSED;
|
|
124854
124883
|
} else if (!shouldKeepAlive) {
|
|
124855
124884
|
util2.destroy(socket, new InformationalError("reset"));
|
|
124856
|
-
return
|
|
124885
|
+
return constants2.ERROR.PAUSED;
|
|
124857
124886
|
} else if (socket[kReset] && client[kRunning] === 0) {
|
|
124858
124887
|
util2.destroy(socket, new InformationalError("reset"));
|
|
124859
|
-
return
|
|
124888
|
+
return constants2.ERROR.PAUSED;
|
|
124860
124889
|
} else if (client[kPipelining] == null || client[kPipelining] === 1) {
|
|
124861
124890
|
setImmediate(client[kResume]);
|
|
124862
124891
|
} else {
|
|
@@ -247718,7 +247747,7 @@ var require_scan = __commonJS({
|
|
|
247718
247747
|
var require_parse3 = __commonJS({
|
|
247719
247748
|
"../node_modules/picomatch/lib/parse.js"(exports, module) {
|
|
247720
247749
|
"use strict";
|
|
247721
|
-
var
|
|
247750
|
+
var constants2 = require_constants8();
|
|
247722
247751
|
var utils = require_utils4();
|
|
247723
247752
|
var {
|
|
247724
247753
|
MAX_LENGTH,
|
|
@@ -247726,7 +247755,7 @@ var require_parse3 = __commonJS({
|
|
|
247726
247755
|
REGEX_NON_SPECIAL_CHARS,
|
|
247727
247756
|
REGEX_SPECIAL_CHARS_BACKREF,
|
|
247728
247757
|
REPLACEMENTS
|
|
247729
|
-
} =
|
|
247758
|
+
} = constants2;
|
|
247730
247759
|
var expandRange = (args, options2) => {
|
|
247731
247760
|
if (typeof options2.expandRange === "function") {
|
|
247732
247761
|
return options2.expandRange(...args, options2);
|
|
@@ -247932,7 +247961,7 @@ var require_parse3 = __commonJS({
|
|
|
247932
247961
|
if (options2.maxExtglobRecursion === false) {
|
|
247933
247962
|
return { risky: false };
|
|
247934
247963
|
}
|
|
247935
|
-
const max = typeof options2.maxExtglobRecursion === "number" ? options2.maxExtglobRecursion :
|
|
247964
|
+
const max = typeof options2.maxExtglobRecursion === "number" ? options2.maxExtglobRecursion : constants2.DEFAULT_MAX_EXTGLOB_RECURSION;
|
|
247936
247965
|
const branches = splitTopLevel(body).map((branch) => branch.trim());
|
|
247937
247966
|
if (branches.length > 1) {
|
|
247938
247967
|
if (branches.some((branch) => branch === "") || branches.some((branch) => /^[*?]+$/.test(branch)) || hasRepeatedCharPrefixOverlap(branches)) {
|
|
@@ -247965,8 +247994,8 @@ var require_parse3 = __commonJS({
|
|
|
247965
247994
|
const tokens = [bos];
|
|
247966
247995
|
const capture = opts.capture ? "" : "?:";
|
|
247967
247996
|
const win32 = utils.isWindows(options2);
|
|
247968
|
-
const PLATFORM_CHARS =
|
|
247969
|
-
const EXTGLOB_CHARS =
|
|
247997
|
+
const PLATFORM_CHARS = constants2.globChars(win32);
|
|
247998
|
+
const EXTGLOB_CHARS = constants2.extglobChars(PLATFORM_CHARS);
|
|
247970
247999
|
const {
|
|
247971
248000
|
DOT_LITERAL,
|
|
247972
248001
|
PLUS_LITERAL,
|
|
@@ -248665,7 +248694,7 @@ var require_parse3 = __commonJS({
|
|
|
248665
248694
|
NO_DOTS_SLASH,
|
|
248666
248695
|
STAR,
|
|
248667
248696
|
START_ANCHOR
|
|
248668
|
-
} =
|
|
248697
|
+
} = constants2.globChars(win32);
|
|
248669
248698
|
const nodot = opts.dot ? NO_DOTS : NO_DOT;
|
|
248670
248699
|
const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;
|
|
248671
248700
|
const capture = opts.capture ? "" : "?:";
|
|
@@ -248724,7 +248753,7 @@ var require_picomatch = __commonJS({
|
|
|
248724
248753
|
var scan = require_scan();
|
|
248725
248754
|
var parse3 = require_parse3();
|
|
248726
248755
|
var utils = require_utils4();
|
|
248727
|
-
var
|
|
248756
|
+
var constants2 = require_constants8();
|
|
248728
248757
|
var isObject = (val) => val && typeof val === "object" && !Array.isArray(val);
|
|
248729
248758
|
var picomatch = (glob3, options2, returnState = false) => {
|
|
248730
248759
|
if (Array.isArray(glob3)) {
|
|
@@ -248852,7 +248881,7 @@ var require_picomatch = __commonJS({
|
|
|
248852
248881
|
return /$^/;
|
|
248853
248882
|
}
|
|
248854
248883
|
};
|
|
248855
|
-
picomatch.constants =
|
|
248884
|
+
picomatch.constants = constants2;
|
|
248856
248885
|
module.exports = picomatch;
|
|
248857
248886
|
}
|
|
248858
248887
|
});
|
|
@@ -486467,7 +486496,7 @@ var require_scan2 = __commonJS({
|
|
|
486467
486496
|
var require_parse4 = __commonJS({
|
|
486468
486497
|
"node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/parse.js"(exports, module) {
|
|
486469
486498
|
"use strict";
|
|
486470
|
-
var
|
|
486499
|
+
var constants2 = require_constants10();
|
|
486471
486500
|
var utils = require_utils7();
|
|
486472
486501
|
var {
|
|
486473
486502
|
MAX_LENGTH,
|
|
@@ -486475,7 +486504,7 @@ var require_parse4 = __commonJS({
|
|
|
486475
486504
|
REGEX_NON_SPECIAL_CHARS,
|
|
486476
486505
|
REGEX_SPECIAL_CHARS_BACKREF,
|
|
486477
486506
|
REPLACEMENTS
|
|
486478
|
-
} =
|
|
486507
|
+
} = constants2;
|
|
486479
486508
|
var expandRange = (args, options2) => {
|
|
486480
486509
|
if (typeof options2.expandRange === "function") {
|
|
486481
486510
|
return options2.expandRange(...args, options2);
|
|
@@ -486681,7 +486710,7 @@ var require_parse4 = __commonJS({
|
|
|
486681
486710
|
if (options2.maxExtglobRecursion === false) {
|
|
486682
486711
|
return { risky: false };
|
|
486683
486712
|
}
|
|
486684
|
-
const max = typeof options2.maxExtglobRecursion === "number" ? options2.maxExtglobRecursion :
|
|
486713
|
+
const max = typeof options2.maxExtglobRecursion === "number" ? options2.maxExtglobRecursion : constants2.DEFAULT_MAX_EXTGLOB_RECURSION;
|
|
486685
486714
|
const branches = splitTopLevel(body).map((branch) => branch.trim());
|
|
486686
486715
|
if (branches.length > 1) {
|
|
486687
486716
|
if (branches.some((branch) => branch === "") || branches.some((branch) => /^[*?]+$/.test(branch)) || hasRepeatedCharPrefixOverlap(branches)) {
|
|
@@ -486713,8 +486742,8 @@ var require_parse4 = __commonJS({
|
|
|
486713
486742
|
const bos = { type: "bos", value: "", output: opts.prepend || "" };
|
|
486714
486743
|
const tokens = [bos];
|
|
486715
486744
|
const capture = opts.capture ? "" : "?:";
|
|
486716
|
-
const PLATFORM_CHARS =
|
|
486717
|
-
const EXTGLOB_CHARS =
|
|
486745
|
+
const PLATFORM_CHARS = constants2.globChars(opts.windows);
|
|
486746
|
+
const EXTGLOB_CHARS = constants2.extglobChars(PLATFORM_CHARS);
|
|
486718
486747
|
const {
|
|
486719
486748
|
DOT_LITERAL,
|
|
486720
486749
|
PLUS_LITERAL,
|
|
@@ -487409,7 +487438,7 @@ var require_parse4 = __commonJS({
|
|
|
487409
487438
|
NO_DOTS_SLASH,
|
|
487410
487439
|
STAR,
|
|
487411
487440
|
START_ANCHOR
|
|
487412
|
-
} =
|
|
487441
|
+
} = constants2.globChars(opts.windows);
|
|
487413
487442
|
const nodot = opts.dot ? NO_DOTS : NO_DOT;
|
|
487414
487443
|
const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;
|
|
487415
487444
|
const capture = opts.capture ? "" : "?:";
|
|
@@ -487467,7 +487496,7 @@ var require_picomatch3 = __commonJS({
|
|
|
487467
487496
|
var scan = require_scan2();
|
|
487468
487497
|
var parse3 = require_parse4();
|
|
487469
487498
|
var utils = require_utils7();
|
|
487470
|
-
var
|
|
487499
|
+
var constants2 = require_constants10();
|
|
487471
487500
|
var isObject = (val) => val && typeof val === "object" && !Array.isArray(val);
|
|
487472
487501
|
var picomatch = (glob3, options2, returnState = false) => {
|
|
487473
487502
|
if (Array.isArray(glob3)) {
|
|
@@ -487595,7 +487624,7 @@ var require_picomatch3 = __commonJS({
|
|
|
487595
487624
|
return /$^/;
|
|
487596
487625
|
}
|
|
487597
487626
|
};
|
|
487598
|
-
picomatch.constants =
|
|
487627
|
+
picomatch.constants = constants2;
|
|
487599
487628
|
module.exports = picomatch;
|
|
487600
487629
|
}
|
|
487601
487630
|
});
|
|
@@ -515917,7 +515946,7 @@ Saved to: ${tempFile}`,
|
|
|
515917
515946
|
|
|
515918
515947
|
// packages/execution/dist/tools/audio-playback.js
|
|
515919
515948
|
import { execFileSync as execFileSync5, execSync as execSync30, spawn as spawn16 } from "node:child_process";
|
|
515920
|
-
import { copyFileSync as copyFileSync3, existsSync as existsSync44, statSync as statSync22, writeFileSync as writeFileSync18, mkdirSync as mkdirSync19, readdirSync as readdirSync17 } from "node:fs";
|
|
515949
|
+
import { copyFileSync as copyFileSync3, existsSync as existsSync44, statSync as statSync22, writeFileSync as writeFileSync18, mkdirSync as mkdirSync19, readdirSync as readdirSync17, writeSync } from "node:fs";
|
|
515921
515950
|
import { basename as basename14, extname as extname10, isAbsolute as isAbsolute2, join as join61 } from "node:path";
|
|
515922
515951
|
import { homedir as homedir16, tmpdir as tmpdir11 } from "node:os";
|
|
515923
515952
|
function hasCommand3(command) {
|
|
@@ -516179,6 +516208,12 @@ function pythonCanImportLuxTts(venvPy) {
|
|
|
516179
516208
|
return false;
|
|
516180
516209
|
}
|
|
516181
516210
|
}
|
|
516211
|
+
function commandErrorText(err) {
|
|
516212
|
+
const anyErr = err;
|
|
516213
|
+
const stdout = anyErr?.stdout ? String(anyErr.stdout).trim() : "";
|
|
516214
|
+
const stderr = anyErr?.stderr ? String(anyErr.stderr).trim() : "";
|
|
516215
|
+
return [anyErr?.message ?? String(err), stderr, stdout].filter(Boolean).join("\n").slice(0, 1800);
|
|
516216
|
+
}
|
|
516182
516217
|
function pipInstall(venvPy, packages, timeout2 = 9e5) {
|
|
516183
516218
|
execFileSync5(venvPy, ["-m", "pip", "install", "--prefer-binary", ...packages], {
|
|
516184
516219
|
stdio: "pipe",
|
|
@@ -516186,9 +516221,133 @@ function pipInstall(venvPy, packages, timeout2 = 9e5) {
|
|
|
516186
516221
|
env: process.env
|
|
516187
516222
|
});
|
|
516188
516223
|
}
|
|
516224
|
+
function withVisibleElevationPrompt(reason, run2) {
|
|
516225
|
+
const hasInteractiveTty = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
516226
|
+
if (!hasInteractiveTty)
|
|
516227
|
+
return run2();
|
|
516228
|
+
const stdinAny = process.stdin;
|
|
516229
|
+
const hadRaw = Boolean(stdinAny.isTTY && stdinAny.isRaw);
|
|
516230
|
+
try {
|
|
516231
|
+
stdinAny.setRawMode?.(false);
|
|
516232
|
+
} catch {
|
|
516233
|
+
}
|
|
516234
|
+
writeSync(1, "\x1B[?2026l\x1B[?25h\x1B[?1000l\x1B[?1002l\x1B[?1003l\x1B[?1006l\x1B[r\x1B[0m\x1B[2J\x1B[H");
|
|
516235
|
+
writeSync(1, `Omnius needs administrator privileges
|
|
516236
|
+
${reason}
|
|
516237
|
+
|
|
516238
|
+
`);
|
|
516239
|
+
try {
|
|
516240
|
+
return run2();
|
|
516241
|
+
} finally {
|
|
516242
|
+
try {
|
|
516243
|
+
stdinAny.setRawMode?.(hadRaw);
|
|
516244
|
+
} catch {
|
|
516245
|
+
}
|
|
516246
|
+
writeSync(1, "\x1B[?2026l\x1B[?25h\x1B[r\x1B[0m\x1B[2J\x1B[H");
|
|
516247
|
+
}
|
|
516248
|
+
}
|
|
516249
|
+
function runPrivilegedInstall(command, args) {
|
|
516250
|
+
const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
|
|
516251
|
+
if (isRoot) {
|
|
516252
|
+
execFileSync5(command, args, { stdio: "pipe", timeout: 6e5 });
|
|
516253
|
+
return;
|
|
516254
|
+
}
|
|
516255
|
+
if (!hasCommand3("sudo")) {
|
|
516256
|
+
throw new Error("sudo is not installed and this process is not running as root");
|
|
516257
|
+
}
|
|
516258
|
+
const hasInteractiveTty = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
516259
|
+
if (hasInteractiveTty) {
|
|
516260
|
+
withVisibleElevationPrompt(`Installing LuxTTS system build dependencies with ${command}.`, () => {
|
|
516261
|
+
execFileSync5("sudo", ["-v"], { stdio: "inherit", timeout: 12e4 });
|
|
516262
|
+
execFileSync5("sudo", [command, ...args], { stdio: "inherit", timeout: 6e5 });
|
|
516263
|
+
});
|
|
516264
|
+
return;
|
|
516265
|
+
}
|
|
516266
|
+
execFileSync5("sudo", ["-n", command, ...args], { stdio: "pipe", timeout: 6e5 });
|
|
516267
|
+
}
|
|
516268
|
+
function installLuxttsSystemDepsBestEffort() {
|
|
516269
|
+
if (process.env["OMNIUS_VOICE_AUTO_SYSTEM_DEPS"] === "0") {
|
|
516270
|
+
return "system dependency install disabled by OMNIUS_VOICE_AUTO_SYSTEM_DEPS=0";
|
|
516271
|
+
}
|
|
516272
|
+
try {
|
|
516273
|
+
if (process.platform === "darwin") {
|
|
516274
|
+
if (!hasCommand3("brew"))
|
|
516275
|
+
return "Homebrew not found; cannot install macOS LuxTTS build dependencies automatically";
|
|
516276
|
+
execFileSync5("brew", ["install", "llvm", "gcc", "openblas", "libsndfile"], { stdio: "inherit", timeout: 6e5 });
|
|
516277
|
+
return "installed macOS LuxTTS build dependencies with brew";
|
|
516278
|
+
}
|
|
516279
|
+
if (process.platform !== "linux") {
|
|
516280
|
+
return `automatic system dependency install is unsupported on ${process.platform}`;
|
|
516281
|
+
}
|
|
516282
|
+
if (hasCommand3("apt-get")) {
|
|
516283
|
+
runPrivilegedInstall("apt-get", ["install", "-y", "--no-install-recommends", "git", "build-essential", "llvm-dev", "gcc", "g++", "gfortran", "libopenblas-dev", "libsndfile1-dev", "python3-dev"]);
|
|
516284
|
+
return "installed Linux LuxTTS build dependencies with apt-get";
|
|
516285
|
+
}
|
|
516286
|
+
if (hasCommand3("dnf")) {
|
|
516287
|
+
runPrivilegedInstall("dnf", ["install", "-y", "git", "gcc", "gcc-c++", "gcc-gfortran", "llvm-devel", "openblas-devel", "libsndfile-devel", "python3-devel"]);
|
|
516288
|
+
return "installed Linux LuxTTS build dependencies with dnf";
|
|
516289
|
+
}
|
|
516290
|
+
if (hasCommand3("yum")) {
|
|
516291
|
+
runPrivilegedInstall("yum", ["install", "-y", "git", "gcc", "gcc-c++", "gcc-gfortran", "llvm-devel", "openblas-devel", "libsndfile-devel", "python3-devel"]);
|
|
516292
|
+
return "installed Linux LuxTTS build dependencies with yum";
|
|
516293
|
+
}
|
|
516294
|
+
if (hasCommand3("pacman")) {
|
|
516295
|
+
runPrivilegedInstall("pacman", ["-S", "--needed", "--noconfirm", "git", "base-devel", "llvm", "openblas", "libsndfile", "python"]);
|
|
516296
|
+
return "installed Linux LuxTTS build dependencies with pacman";
|
|
516297
|
+
}
|
|
516298
|
+
if (hasCommand3("zypper")) {
|
|
516299
|
+
runPrivilegedInstall("zypper", ["--non-interactive", "install", "git", "gcc", "gcc-c++", "gcc-fortran", "llvm-devel", "openblas-devel", "libsndfile-devel", "python3-devel"]);
|
|
516300
|
+
return "installed Linux LuxTTS build dependencies with zypper";
|
|
516301
|
+
}
|
|
516302
|
+
return "no supported Linux package manager found for automatic LuxTTS system dependency install";
|
|
516303
|
+
} catch (err) {
|
|
516304
|
+
return `system dependency install skipped/failed: ${commandErrorText(err)}`;
|
|
516305
|
+
}
|
|
516306
|
+
}
|
|
516307
|
+
function runLuxttsInstallStep(venvPy, step, notes2) {
|
|
516308
|
+
try {
|
|
516309
|
+
pipInstall(venvPy, step.args, step.timeout ?? 9e5);
|
|
516310
|
+
return;
|
|
516311
|
+
} catch (firstErr) {
|
|
516312
|
+
if (step.retryWithSystemDeps) {
|
|
516313
|
+
notes2.push(`${step.label}: pip failed; attempting system dependency triage`);
|
|
516314
|
+
notes2.push(installLuxttsSystemDepsBestEffort());
|
|
516315
|
+
try {
|
|
516316
|
+
pipInstall(venvPy, step.args, step.timeout ?? 9e5);
|
|
516317
|
+
return;
|
|
516318
|
+
} catch (retryErr) {
|
|
516319
|
+
notes2.push(`${step.label}: retry failed: ${commandErrorText(retryErr)}`);
|
|
516320
|
+
}
|
|
516321
|
+
}
|
|
516322
|
+
if (!step.fatal) {
|
|
516323
|
+
notes2.push(`${step.label}: optional install skipped: ${commandErrorText(firstErr)}`);
|
|
516324
|
+
return;
|
|
516325
|
+
}
|
|
516326
|
+
throw new Error(`Failed to install LuxTTS dependency step '${step.label}': ${commandErrorText(firstErr)}${notes2.length ? `
|
|
516327
|
+
Triage:
|
|
516328
|
+
- ${notes2.join("\n- ")}` : ""}`);
|
|
516329
|
+
}
|
|
516330
|
+
}
|
|
516331
|
+
function collectLuxttsDiagnostics(venvPy, repoDir) {
|
|
516332
|
+
const lines = [];
|
|
516333
|
+
try {
|
|
516334
|
+
lines.push(execFileSync5(venvPy, ["-V"], { encoding: "utf8", timeout: 5e3 }).trim());
|
|
516335
|
+
} catch {
|
|
516336
|
+
}
|
|
516337
|
+
try {
|
|
516338
|
+
lines.push(execFileSync5(venvPy, ["-m", "pip", "--version"], { encoding: "utf8", timeout: 5e3 }).trim());
|
|
516339
|
+
} catch {
|
|
516340
|
+
}
|
|
516341
|
+
try {
|
|
516342
|
+
lines.push(`platform=${process.platform} arch=${process.arch} repo=${repoDir}`);
|
|
516343
|
+
} catch {
|
|
516344
|
+
}
|
|
516345
|
+
return lines.join("\n");
|
|
516346
|
+
}
|
|
516189
516347
|
function ensureLuxttsInstalled() {
|
|
516190
516348
|
const venvPy = luxttsVenvPy();
|
|
516191
516349
|
const repoDir = luxttsRepoDir();
|
|
516350
|
+
const notes2 = [];
|
|
516192
516351
|
mkdirSync19(voiceDir(), { recursive: true });
|
|
516193
516352
|
if (existsSync44(venvPy) && existsSync44(join61(repoDir, "zipvoice", "luxvoice.py")) && pythonCanImportLuxTts(venvPy)) {
|
|
516194
516353
|
writeFileSync18(luxttsInferScript(), LUXTTS_DAEMON_PY, "utf-8");
|
|
@@ -516204,7 +516363,6 @@ function ensureLuxttsInstalled() {
|
|
|
516204
516363
|
stdio: "pipe",
|
|
516205
516364
|
timeout: 3e5
|
|
516206
516365
|
});
|
|
516207
|
-
pipInstall(venvPy, ["torch", "torchaudio"], 12e5);
|
|
516208
516366
|
if (!existsSync44(join61(repoDir, "zipvoice", "luxvoice.py"))) {
|
|
516209
516367
|
if (!hasCommand3("git"))
|
|
516210
516368
|
throw new Error("git is required to set up LuxTTS voice cloning.");
|
|
@@ -516213,29 +516371,50 @@ function ensureLuxttsInstalled() {
|
|
|
516213
516371
|
timeout: 3e5
|
|
516214
516372
|
});
|
|
516215
516373
|
}
|
|
516216
|
-
|
|
516217
|
-
|
|
516218
|
-
"
|
|
516219
|
-
"
|
|
516220
|
-
"
|
|
516221
|
-
"
|
|
516222
|
-
"
|
|
516223
|
-
"
|
|
516224
|
-
"
|
|
516225
|
-
"
|
|
516226
|
-
"
|
|
516227
|
-
"
|
|
516228
|
-
"
|
|
516229
|
-
"
|
|
516230
|
-
|
|
516231
|
-
|
|
516232
|
-
|
|
516233
|
-
|
|
516374
|
+
const isArm = process.arch === "arm64" || process.arch === "arm";
|
|
516375
|
+
const installSteps = isArm ? [
|
|
516376
|
+
{ label: "PyTorch", args: ["torch", "torchaudio"], fatal: true, timeout: 12e5 },
|
|
516377
|
+
{ label: "numpy", args: ["numpy"], fatal: true },
|
|
516378
|
+
{ label: "huggingface_hub + safetensors", args: ["huggingface_hub", "safetensors"], fatal: true },
|
|
516379
|
+
{ label: "transformers", args: ["transformers<=4.57.6"], fatal: true },
|
|
516380
|
+
{ label: "pydub + inflect", args: ["pydub", "inflect"], fatal: true },
|
|
516381
|
+
{ label: "llvmlite", args: ["llvmlite"], fatal: false, retryWithSystemDeps: true },
|
|
516382
|
+
{ label: "numba", args: ["numba"], fatal: false, retryWithSystemDeps: true },
|
|
516383
|
+
{ label: "librosa", args: ["librosa"], fatal: true, retryWithSystemDeps: true },
|
|
516384
|
+
{ label: "lhotse", args: ["lhotse"], fatal: true, retryWithSystemDeps: true },
|
|
516385
|
+
{ label: "vocos", args: ["vocos"], fatal: true, retryWithSystemDeps: true },
|
|
516386
|
+
{ label: "LinaCodec", args: ["git+https://github.com/ysharma3501/LinaCodec.git"], fatal: true, retryWithSystemDeps: true, timeout: 12e5 },
|
|
516387
|
+
{ label: "piper-phonemize (optional)", args: ["piper-phonemize", "--find-links", "https://k2-fsa.github.io/icefall/piper_phonemize.html"], fatal: false, timeout: 6e5 },
|
|
516388
|
+
{ label: "Chinese text processing", args: ["jieba", "pypinyin", "cn2an"], fatal: true },
|
|
516389
|
+
{ label: "LuxTTS editable install", args: ["--no-deps", "-e", repoDir], fatal: true, timeout: 6e5 }
|
|
516390
|
+
] : [
|
|
516391
|
+
{ label: "PyTorch", args: ["torch", "torchaudio"], fatal: true, timeout: 12e5 },
|
|
516392
|
+
{ label: "core LuxTTS deps", args: ["lhotse", "huggingface_hub", "safetensors", "pydub", "onnxruntime", "librosa", "transformers<=4.57.6", "inflect", "numpy", "vocos", "setuptools<81"], fatal: true, retryWithSystemDeps: true, timeout: 12e5 },
|
|
516393
|
+
{ label: "piper-phonemize (optional)", args: ["piper-phonemize", "--find-links", "https://k2-fsa.github.io/icefall/piper_phonemize.html"], fatal: false, timeout: 6e5 },
|
|
516394
|
+
{ label: "Chinese text processing", args: ["jieba", "pypinyin", "cn2an"], fatal: true },
|
|
516395
|
+
{ label: "LinaCodec", args: ["git+https://github.com/ysharma3501/LinaCodec.git"], fatal: false, retryWithSystemDeps: true, timeout: 12e5 },
|
|
516396
|
+
{ label: "LuxTTS editable install", args: ["--no-deps", "-e", repoDir], fatal: true, timeout: 6e5 }
|
|
516397
|
+
];
|
|
516398
|
+
for (const step of installSteps) {
|
|
516399
|
+
runLuxttsInstallStep(venvPy, step, notes2);
|
|
516234
516400
|
}
|
|
516235
|
-
pipInstall(venvPy, ["-e", repoDir], 6e5);
|
|
516236
516401
|
writeFileSync18(luxttsInferScript(), LUXTTS_DAEMON_PY, "utf-8");
|
|
516237
516402
|
if (!pythonCanImportLuxTts(venvPy)) {
|
|
516238
|
-
|
|
516403
|
+
notes2.push("LuxTTS import failed after dependency install; retrying source/build dependencies once");
|
|
516404
|
+
notes2.push(installLuxttsSystemDepsBestEffort());
|
|
516405
|
+
try {
|
|
516406
|
+
pipInstall(venvPy, ["git+https://github.com/ysharma3501/LinaCodec.git"], 12e5);
|
|
516407
|
+
pipInstall(venvPy, ["--no-deps", "-e", repoDir], 6e5);
|
|
516408
|
+
} catch (err) {
|
|
516409
|
+
notes2.push(`final repair install failed: ${commandErrorText(err)}`);
|
|
516410
|
+
}
|
|
516411
|
+
}
|
|
516412
|
+
if (!pythonCanImportLuxTts(venvPy)) {
|
|
516413
|
+
throw new Error(`LuxTTS setup completed but import still fails in ${luxttsVenvDir()}.
|
|
516414
|
+
Diagnostics:
|
|
516415
|
+
${collectLuxttsDiagnostics(venvPy, repoDir)}
|
|
516416
|
+
Triage:
|
|
516417
|
+
- ${notes2.join("\n- ")}`);
|
|
516239
516418
|
}
|
|
516240
516419
|
return venvPy;
|
|
516241
516420
|
}
|
|
@@ -561506,7 +561685,7 @@ __export(listen_exports, {
|
|
|
561506
561685
|
waitForTranscribeCli: () => waitForTranscribeCli
|
|
561507
561686
|
});
|
|
561508
561687
|
import { spawn as spawn24, execSync as execSync47 } from "node:child_process";
|
|
561509
|
-
import { existsSync as existsSync87, mkdirSync as mkdirSync48, writeFileSync as writeFileSync43, readdirSync as readdirSync28 } from "node:fs";
|
|
561688
|
+
import { accessSync, constants, existsSync as existsSync87, mkdirSync as mkdirSync48, writeFileSync as writeFileSync43, readdirSync as readdirSync28 } from "node:fs";
|
|
561510
561689
|
import { join as join102, dirname as dirname27 } from "node:path";
|
|
561511
561690
|
import { homedir as homedir32 } from "node:os";
|
|
561512
561691
|
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
@@ -561749,10 +561928,40 @@ function ensureTranscribeCliBackground() {
|
|
|
561749
561928
|
} catch {
|
|
561750
561929
|
}
|
|
561751
561930
|
try {
|
|
561752
|
-
|
|
561931
|
+
let needsSudo = false;
|
|
561932
|
+
try {
|
|
561933
|
+
const prefix = execSync47("npm prefix -g", {
|
|
561934
|
+
encoding: "utf-8",
|
|
561935
|
+
timeout: 5e3,
|
|
561936
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
561937
|
+
}).trim();
|
|
561938
|
+
accessSync(prefix, constants.W_OK);
|
|
561939
|
+
} catch {
|
|
561940
|
+
needsSudo = process.platform !== "win32";
|
|
561941
|
+
}
|
|
561942
|
+
const terminalElevation = process.env["OMNIUS_ELEVATION_MODE"] === "terminal" && process.stdin.isTTY && process.stdout.isTTY;
|
|
561943
|
+
const command = terminalElevation && needsSudo ? "sudo" : "npm";
|
|
561944
|
+
const args = terminalElevation && needsSudo ? ["npm", "i", "-g", "transcribe-cli"] : ["i", "-g", "transcribe-cli"];
|
|
561753
561945
|
return new Promise((resolve56) => {
|
|
561754
|
-
|
|
561755
|
-
|
|
561946
|
+
const child = spawn24(command, args, {
|
|
561947
|
+
stdio: terminalElevation ? "inherit" : "ignore",
|
|
561948
|
+
timeout: 18e4
|
|
561949
|
+
});
|
|
561950
|
+
const timeout2 = setTimeout(() => {
|
|
561951
|
+
try {
|
|
561952
|
+
child.kill("SIGTERM");
|
|
561953
|
+
} catch {
|
|
561954
|
+
}
|
|
561955
|
+
resolve56(false);
|
|
561956
|
+
}, 18e4);
|
|
561957
|
+
timeout2.unref?.();
|
|
561958
|
+
onChildClose(child, (code8) => {
|
|
561959
|
+
clearTimeout(timeout2);
|
|
561960
|
+
resolve56(code8 === 0);
|
|
561961
|
+
});
|
|
561962
|
+
onChildError(child, () => {
|
|
561963
|
+
clearTimeout(timeout2);
|
|
561964
|
+
resolve56(false);
|
|
561756
561965
|
});
|
|
561757
561966
|
});
|
|
561758
561967
|
} catch {
|
|
@@ -571491,6 +571700,47 @@ var init_voice_soul = __esm({
|
|
|
571491
571700
|
}
|
|
571492
571701
|
});
|
|
571493
571702
|
|
|
571703
|
+
// packages/cli/src/tui/usage-bars.ts
|
|
571704
|
+
function formatCompactCount(value2) {
|
|
571705
|
+
const n2 = Math.max(0, Math.floor(Number.isFinite(value2) ? value2 : 0));
|
|
571706
|
+
if (n2 < 1e3) return String(n2);
|
|
571707
|
+
if (n2 < 1e6) return `${(n2 / 1e3).toFixed(n2 < 1e4 ? 1 : 0)}K`;
|
|
571708
|
+
return `${(n2 / 1e6).toFixed(n2 < 1e7 ? 1 : 0)}M`;
|
|
571709
|
+
}
|
|
571710
|
+
function formatResetDelta(resetAt, now = Date.now()) {
|
|
571711
|
+
if (!Number.isFinite(resetAt) || resetAt <= now) return "";
|
|
571712
|
+
const totalMinutes = Math.ceil((resetAt - now) / 6e4);
|
|
571713
|
+
if (totalMinutes < 60) return ` reset ${totalMinutes}m`;
|
|
571714
|
+
const hours = Math.floor(totalMinutes / 60);
|
|
571715
|
+
const minutes = totalMinutes % 60;
|
|
571716
|
+
return minutes > 0 ? ` reset ${hours}h ${minutes}m` : ` reset ${hours}h`;
|
|
571717
|
+
}
|
|
571718
|
+
function formatUsageBar(options2) {
|
|
571719
|
+
const total = Math.max(0, Math.floor(Number.isFinite(options2.total) ? options2.total : 0));
|
|
571720
|
+
const rawUsed = Math.max(0, Math.floor(Number.isFinite(options2.used) ? options2.used : 0));
|
|
571721
|
+
const used = total > 0 ? Math.min(total, rawUsed) : 0;
|
|
571722
|
+
const width = Math.max(4, options2.width ?? 18);
|
|
571723
|
+
const labelWidth = Math.max(options2.label.length, options2.labelWidth ?? 16);
|
|
571724
|
+
const pct = total > 0 ? Math.round(used / total * 100) : 0;
|
|
571725
|
+
const filled = total > 0 ? Math.min(width, Math.round(pct / 100 * width)) : 0;
|
|
571726
|
+
const color = pct >= 90 ? c3.red : pct >= 70 ? c3.yellow : c3.green;
|
|
571727
|
+
const bar = color("█".repeat(filled)) + c3.dim("░".repeat(width - filled));
|
|
571728
|
+
const reset = options2.resetAt ? c3.dim(formatResetDelta(options2.resetAt)) : "";
|
|
571729
|
+
return [
|
|
571730
|
+
c3.cyan(options2.label.padEnd(labelWidth)),
|
|
571731
|
+
bar,
|
|
571732
|
+
color(`${pct}%`.padStart(4)),
|
|
571733
|
+
c3.dim(`${formatCompactCount(rawUsed)}/${formatCompactCount(total)}`),
|
|
571734
|
+
reset
|
|
571735
|
+
].join(" ").trimEnd();
|
|
571736
|
+
}
|
|
571737
|
+
var init_usage_bars = __esm({
|
|
571738
|
+
"packages/cli/src/tui/usage-bars.ts"() {
|
|
571739
|
+
"use strict";
|
|
571740
|
+
init_render();
|
|
571741
|
+
}
|
|
571742
|
+
});
|
|
571743
|
+
|
|
571494
571744
|
// packages/cli/src/tui/expose.ts
|
|
571495
571745
|
import { createServer as createServer5, request as httpRequest } from "node:http";
|
|
571496
571746
|
import { request as httpsRequest } from "node:https";
|
|
@@ -571537,6 +571787,38 @@ function fmtTokens(n2) {
|
|
|
571537
571787
|
if (n2 < 1e6) return `${(n2 / 1e3).toFixed(1)}K`;
|
|
571538
571788
|
return `${(n2 / 1e6).toFixed(1)}M`;
|
|
571539
571789
|
}
|
|
571790
|
+
function safeNonNegativeInt(value2) {
|
|
571791
|
+
const n2 = Number(value2);
|
|
571792
|
+
return Number.isFinite(n2) && n2 > 0 ? Math.floor(n2) : 0;
|
|
571793
|
+
}
|
|
571794
|
+
function nextSponsorDailyReset(now = Date.now()) {
|
|
571795
|
+
return now + SPONSOR_DAILY_WINDOW_MS;
|
|
571796
|
+
}
|
|
571797
|
+
function readSponsorUsageState(stateDir) {
|
|
571798
|
+
try {
|
|
571799
|
+
const path12 = join105(stateDir, "sponsor", SPONSOR_USAGE_FILE_NAME);
|
|
571800
|
+
if (!existsSync90(path12)) return null;
|
|
571801
|
+
const parsed = JSON.parse(readFileSync71(path12, "utf8"));
|
|
571802
|
+
const dailyTokensUsed = safeNonNegativeInt(parsed.dailyTokensUsed);
|
|
571803
|
+
const dailyTokensResetAt = safeNonNegativeInt(parsed.dailyTokensResetAt);
|
|
571804
|
+
if (!dailyTokensResetAt) return null;
|
|
571805
|
+
return {
|
|
571806
|
+
dailyTokensUsed,
|
|
571807
|
+
dailyTokensResetAt,
|
|
571808
|
+
updatedAt: typeof parsed.updatedAt === "string" ? parsed.updatedAt : (/* @__PURE__ */ new Date()).toISOString()
|
|
571809
|
+
};
|
|
571810
|
+
} catch {
|
|
571811
|
+
return null;
|
|
571812
|
+
}
|
|
571813
|
+
}
|
|
571814
|
+
function writeSponsorUsageState(stateDir, state) {
|
|
571815
|
+
try {
|
|
571816
|
+
const dir = join105(stateDir, "sponsor");
|
|
571817
|
+
mkdirSync50(dir, { recursive: true });
|
|
571818
|
+
writeFileSync45(join105(dir, SPONSOR_USAGE_FILE_NAME), JSON.stringify(state, null, 2));
|
|
571819
|
+
} catch {
|
|
571820
|
+
}
|
|
571821
|
+
}
|
|
571540
571822
|
function readExposeState(stateDir) {
|
|
571541
571823
|
try {
|
|
571542
571824
|
const path12 = join105(stateDir, STATE_FILE_NAME);
|
|
@@ -571700,11 +571982,12 @@ function removeP2PExposeState(stateDir) {
|
|
|
571700
571982
|
} catch {
|
|
571701
571983
|
}
|
|
571702
571984
|
}
|
|
571703
|
-
var HOP_BY_HOP_HEADERS, CF_HEADERS_PREFIX, DEFAULT_EXPOSE_MAX_BODY_BYTES, INTERNAL_CAPABILITIES, DEFAULT_TARGETS, STATE_FILE_NAME, ExposeGateway, P2P_STATE_FILE_NAME, ExposeP2PGateway;
|
|
571985
|
+
var HOP_BY_HOP_HEADERS, CF_HEADERS_PREFIX, DEFAULT_EXPOSE_MAX_BODY_BYTES, INTERNAL_CAPABILITIES, DEFAULT_TARGETS, STATE_FILE_NAME, SPONSOR_USAGE_FILE_NAME, SPONSOR_DAILY_WINDOW_MS, SPONSOR_REQUEST_WINDOW_MS, ExposeGateway, P2P_STATE_FILE_NAME, ExposeP2PGateway;
|
|
571704
571986
|
var init_expose = __esm({
|
|
571705
571987
|
"packages/cli/src/tui/expose.ts"() {
|
|
571706
571988
|
"use strict";
|
|
571707
571989
|
init_render();
|
|
571990
|
+
init_usage_bars();
|
|
571708
571991
|
init_typed_node_events();
|
|
571709
571992
|
HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
|
|
571710
571993
|
"connection",
|
|
@@ -571726,6 +572009,9 @@ var init_expose = __esm({
|
|
|
571726
572009
|
custom: "http://127.0.0.1:11434"
|
|
571727
572010
|
};
|
|
571728
572011
|
STATE_FILE_NAME = "expose-state.json";
|
|
572012
|
+
SPONSOR_USAGE_FILE_NAME = "usage.json";
|
|
572013
|
+
SPONSOR_DAILY_WINDOW_MS = 864e5;
|
|
572014
|
+
SPONSOR_REQUEST_WINDOW_MS = 6e4;
|
|
571729
572015
|
ExposeGateway = class _ExposeGateway extends EventEmitter8 {
|
|
571730
572016
|
constructor(options2) {
|
|
571731
572017
|
super();
|
|
@@ -571743,6 +572029,8 @@ var init_expose = __esm({
|
|
|
571743
572029
|
} else {
|
|
571744
572030
|
this._authKey = options2.authKey;
|
|
571745
572031
|
}
|
|
572032
|
+
this.loadSponsorUsage();
|
|
572033
|
+
this.refreshSponsorUsageStats();
|
|
571746
572034
|
}
|
|
571747
572035
|
options;
|
|
571748
572036
|
server = null;
|
|
@@ -571765,6 +572053,7 @@ var init_expose = __esm({
|
|
|
571765
572053
|
_dailyTokensResetAt = 0;
|
|
571766
572054
|
/** Sponsor rate limits (set via setSponsorLimits) */
|
|
571767
572055
|
_sponsorLimits = null;
|
|
572056
|
+
_sponsorBlockedRequests = 0;
|
|
571768
572057
|
_authKey;
|
|
571769
572058
|
_targetUrl;
|
|
571770
572059
|
_kind;
|
|
@@ -571783,7 +572072,8 @@ var init_expose = __esm({
|
|
|
571783
572072
|
users: /* @__PURE__ */ new Map(),
|
|
571784
572073
|
budgetTokensRemaining: 0,
|
|
571785
572074
|
budgetTokensTotal: 0,
|
|
571786
|
-
budgetResetAt: 0
|
|
572075
|
+
budgetResetAt: 0,
|
|
572076
|
+
sponsorUsage: null
|
|
571787
572077
|
};
|
|
571788
572078
|
get tunnelUrl() {
|
|
571789
572079
|
return this._tunnelUrl;
|
|
@@ -571803,42 +572093,140 @@ var init_expose = __esm({
|
|
|
571803
572093
|
/** Set sponsor rate limits — enables rate limiting middleware in the proxy */
|
|
571804
572094
|
setSponsorLimits(limits) {
|
|
571805
572095
|
this._sponsorLimits = limits;
|
|
572096
|
+
this.ensureSponsorDailyWindow();
|
|
572097
|
+
this.refreshSponsorUsageStats();
|
|
572098
|
+
this.emitStats();
|
|
572099
|
+
}
|
|
572100
|
+
getSponsorUsageSnapshot() {
|
|
572101
|
+
this.refreshSponsorUsageStats();
|
|
572102
|
+
return this._stats.sponsorUsage ? { ...this._stats.sponsorUsage } : null;
|
|
572103
|
+
}
|
|
572104
|
+
loadSponsorUsage() {
|
|
572105
|
+
if (!this._stateDir) {
|
|
572106
|
+
this._dailyTokensResetAt = nextSponsorDailyReset();
|
|
572107
|
+
return;
|
|
572108
|
+
}
|
|
572109
|
+
const saved = readSponsorUsageState(this._stateDir);
|
|
572110
|
+
if (!saved) {
|
|
572111
|
+
this._dailyTokensUsed = 0;
|
|
572112
|
+
this._dailyTokensResetAt = nextSponsorDailyReset();
|
|
572113
|
+
return;
|
|
572114
|
+
}
|
|
572115
|
+
const now = Date.now();
|
|
572116
|
+
if (saved.dailyTokensResetAt <= now) {
|
|
572117
|
+
this._dailyTokensUsed = 0;
|
|
572118
|
+
this._dailyTokensResetAt = nextSponsorDailyReset(now);
|
|
572119
|
+
this.saveSponsorUsage();
|
|
572120
|
+
} else {
|
|
572121
|
+
this._dailyTokensUsed = saved.dailyTokensUsed;
|
|
572122
|
+
this._dailyTokensResetAt = saved.dailyTokensResetAt;
|
|
572123
|
+
}
|
|
572124
|
+
}
|
|
572125
|
+
saveSponsorUsage() {
|
|
572126
|
+
if (!this._stateDir) return;
|
|
572127
|
+
writeSponsorUsageState(this._stateDir, {
|
|
572128
|
+
dailyTokensUsed: this._dailyTokensUsed,
|
|
572129
|
+
dailyTokensResetAt: this._dailyTokensResetAt,
|
|
572130
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
572131
|
+
});
|
|
572132
|
+
}
|
|
572133
|
+
ensureSponsorDailyWindow(now = Date.now()) {
|
|
572134
|
+
if (!this._dailyTokensResetAt || this._dailyTokensResetAt <= now) {
|
|
572135
|
+
this._dailyTokensUsed = 0;
|
|
572136
|
+
this._dailyTokensResetAt = nextSponsorDailyReset(now);
|
|
572137
|
+
this.saveSponsorUsage();
|
|
572138
|
+
}
|
|
572139
|
+
}
|
|
572140
|
+
pruneSponsorRequestWindows(now = Date.now()) {
|
|
572141
|
+
for (const [ip, window2] of this._rateLimitWindows.entries()) {
|
|
572142
|
+
while (window2.length > 0 && window2[0] < now - SPONSOR_REQUEST_WINDOW_MS) window2.shift();
|
|
572143
|
+
if (window2.length === 0) this._rateLimitWindows.delete(ip);
|
|
572144
|
+
}
|
|
572145
|
+
}
|
|
572146
|
+
sponsorRequestWindowUsage(now = Date.now()) {
|
|
572147
|
+
this.pruneSponsorRequestWindows(now);
|
|
572148
|
+
let count = 0;
|
|
572149
|
+
let oldest = Number.POSITIVE_INFINITY;
|
|
572150
|
+
for (const window2 of this._rateLimitWindows.values()) {
|
|
572151
|
+
count += window2.length;
|
|
572152
|
+
if (window2.length > 0) oldest = Math.min(oldest, window2[0]);
|
|
572153
|
+
}
|
|
572154
|
+
return {
|
|
572155
|
+
count,
|
|
572156
|
+
resetAt: Number.isFinite(oldest) ? oldest + SPONSOR_REQUEST_WINDOW_MS : now + SPONSOR_REQUEST_WINDOW_MS
|
|
572157
|
+
};
|
|
572158
|
+
}
|
|
572159
|
+
refreshSponsorUsageStats(now = Date.now()) {
|
|
572160
|
+
if (!this._sponsorLimits) {
|
|
572161
|
+
this._stats.sponsorUsage = null;
|
|
572162
|
+
return;
|
|
572163
|
+
}
|
|
572164
|
+
this.ensureSponsorDailyWindow(now);
|
|
572165
|
+
const req2 = this.sponsorRequestWindowUsage(now);
|
|
572166
|
+
this._stats.sponsorUsage = {
|
|
572167
|
+
enabled: true,
|
|
572168
|
+
transport: "tunnel",
|
|
572169
|
+
dailyTokensUsed: this._dailyTokensUsed,
|
|
572170
|
+
dailyTokensLimit: this._sponsorLimits.maxTokensPerDay,
|
|
572171
|
+
dailyResetAt: this._dailyTokensResetAt,
|
|
572172
|
+
requestsInWindow: req2.count,
|
|
572173
|
+
requestsPerMinuteLimit: this._sponsorLimits.maxRequestsPerMinute,
|
|
572174
|
+
requestWindowResetAt: req2.resetAt,
|
|
572175
|
+
activeConnections: this._stats.activeConnections,
|
|
572176
|
+
maxConcurrent: this._sponsorLimits.maxConcurrent,
|
|
572177
|
+
blockedRequests: this._sponsorBlockedRequests,
|
|
572178
|
+
allowedModels: this._sponsorLimits.allowedModels === "all" ? "all" : [...this._sponsorLimits.allowedModels]
|
|
572179
|
+
};
|
|
572180
|
+
}
|
|
572181
|
+
markSponsorBlocked() {
|
|
572182
|
+
this._sponsorBlockedRequests++;
|
|
572183
|
+
this.refreshSponsorUsageStats();
|
|
571806
572184
|
}
|
|
571807
572185
|
/** Check rate limits for a request. Returns null if OK, or error message string if blocked. */
|
|
571808
|
-
checkRateLimit(userIp, model) {
|
|
572186
|
+
checkRateLimit(userIp, model, options2 = {}) {
|
|
571809
572187
|
if (!this._sponsorLimits) return null;
|
|
571810
572188
|
const lim = this._sponsorLimits;
|
|
572189
|
+
const now = Date.now();
|
|
572190
|
+
if (lim.maxRequestsPerMinute <= 0 || lim.maxTokensPerDay <= 0 || lim.maxConcurrent <= 0) {
|
|
572191
|
+
this.markSponsorBlocked();
|
|
572192
|
+
return "Sponsored endpoint is paused or has no quota configured.";
|
|
572193
|
+
}
|
|
571811
572194
|
if (lim.allowedModels !== "all" && model && !lim.allowedModels.includes(model)) {
|
|
572195
|
+
this.markSponsorBlocked();
|
|
571812
572196
|
return `Model '${model}' is not available on this sponsored endpoint. Available: ${lim.allowedModels.join(", ")}`;
|
|
571813
572197
|
}
|
|
571814
|
-
if (this._stats.activeConnections
|
|
572198
|
+
if (this._stats.activeConnections > lim.maxConcurrent) {
|
|
572199
|
+
this.markSponsorBlocked();
|
|
571815
572200
|
return `Too many concurrent requests (${this._stats.activeConnections}/${lim.maxConcurrent}). Try again shortly.`;
|
|
571816
572201
|
}
|
|
571817
|
-
const now = Date.now();
|
|
571818
|
-
const windowMs = 6e4;
|
|
571819
572202
|
let window2 = this._rateLimitWindows.get(userIp);
|
|
571820
572203
|
if (!window2) {
|
|
571821
572204
|
window2 = [];
|
|
571822
572205
|
this._rateLimitWindows.set(userIp, window2);
|
|
571823
572206
|
}
|
|
571824
|
-
while (window2.length > 0 && window2[0] < now -
|
|
572207
|
+
while (window2.length > 0 && window2[0] < now - SPONSOR_REQUEST_WINDOW_MS) window2.shift();
|
|
571825
572208
|
if (window2.length >= lim.maxRequestsPerMinute) {
|
|
571826
|
-
|
|
572209
|
+
this.markSponsorBlocked();
|
|
572210
|
+
const retryAfterMs = window2[0] + SPONSOR_REQUEST_WINDOW_MS - now;
|
|
571827
572211
|
return `Rate limited (${lim.maxRequestsPerMinute} req/min). Retry in ${Math.ceil(retryAfterMs / 1e3)}s.`;
|
|
571828
572212
|
}
|
|
571829
|
-
window2.push(now);
|
|
571830
|
-
|
|
571831
|
-
this._dailyTokensUsed = 0;
|
|
571832
|
-
this._dailyTokensResetAt = now + 864e5;
|
|
571833
|
-
}
|
|
572213
|
+
if (options2.commitRequest) window2.push(now);
|
|
572214
|
+
this.ensureSponsorDailyWindow(now);
|
|
571834
572215
|
if (this._dailyTokensUsed >= lim.maxTokensPerDay) {
|
|
572216
|
+
this.markSponsorBlocked();
|
|
571835
572217
|
return `Daily token budget exhausted (${fmtTokens(lim.maxTokensPerDay)}). Resets in ${Math.ceil((this._dailyTokensResetAt - now) / 36e5)}h.`;
|
|
571836
572218
|
}
|
|
572219
|
+
this.refreshSponsorUsageStats(now);
|
|
571837
572220
|
return null;
|
|
571838
572221
|
}
|
|
571839
572222
|
/** Track token usage from a completed response */
|
|
571840
572223
|
trackTokenUsage(tokensIn, tokensOut) {
|
|
571841
|
-
|
|
572224
|
+
const total = safeNonNegativeInt(tokensIn) + safeNonNegativeInt(tokensOut);
|
|
572225
|
+
if (total <= 0) return;
|
|
572226
|
+
this.ensureSponsorDailyWindow();
|
|
572227
|
+
this._dailyTokensUsed += total;
|
|
572228
|
+
this.saveSponsorUsage();
|
|
572229
|
+
this.refreshSponsorUsageStats();
|
|
571842
572230
|
}
|
|
571843
572231
|
// ── Lifecycle ───────────────────────────────────────────────────────────
|
|
571844
572232
|
async start() {
|
|
@@ -572047,7 +572435,7 @@ var init_expose = __esm({
|
|
|
572047
572435
|
user.activeRequests++;
|
|
572048
572436
|
user.lastSeen = Date.now();
|
|
572049
572437
|
this.emitStats();
|
|
572050
|
-
const preRateLimitCheck = this.checkRateLimit(userIp, "");
|
|
572438
|
+
const preRateLimitCheck = this.checkRateLimit(userIp, "", { commitRequest: false });
|
|
572051
572439
|
if (preRateLimitCheck) {
|
|
572052
572440
|
this._stats.activeConnections--;
|
|
572053
572441
|
user.activeRequests--;
|
|
@@ -572136,8 +572524,8 @@ var init_expose = __esm({
|
|
|
572136
572524
|
} catch {
|
|
572137
572525
|
}
|
|
572138
572526
|
}
|
|
572139
|
-
if (
|
|
572140
|
-
const modelCheck = this.checkRateLimit(userIp, requestModel);
|
|
572527
|
+
if (this._sponsorLimits) {
|
|
572528
|
+
const modelCheck = this.checkRateLimit(userIp, requestModel, { commitRequest: true });
|
|
572141
572529
|
if (modelCheck) {
|
|
572142
572530
|
this._stats.activeConnections--;
|
|
572143
572531
|
user.activeRequests--;
|
|
@@ -572523,10 +572911,12 @@ ${this.formatConnectionInfo()}`);
|
|
|
572523
572911
|
});
|
|
572524
572912
|
}
|
|
572525
572913
|
emitStats() {
|
|
572914
|
+
this.refreshSponsorUsageStats();
|
|
572526
572915
|
this.emit("stats", {
|
|
572527
572916
|
...this._stats,
|
|
572528
572917
|
modelUsage: new Map(this._stats.modelUsage),
|
|
572529
|
-
users: new Map(this._stats.users)
|
|
572918
|
+
users: new Map(this._stats.users),
|
|
572919
|
+
sponsorUsage: this._stats.sponsorUsage ? { ...this._stats.sponsorUsage } : null
|
|
572530
572920
|
});
|
|
572531
572921
|
}
|
|
572532
572922
|
/** Format connection info for display */
|
|
@@ -572568,6 +572958,28 @@ ${this.formatConnectionInfo()}`);
|
|
|
572568
572958
|
const budgetColor = pct > 50 ? c3.green : pct > 20 ? c3.yellow : c3.red;
|
|
572569
572959
|
lines.push(` ${c3.cyan("Budget".padEnd(18))} ${budgetColor(fmtTokens(s2.budgetTokensRemaining))}${c3.dim("/")}${fmtTokens(s2.budgetTokensTotal)} ${c3.dim(`(${pct}% left)`)}`);
|
|
572570
572960
|
}
|
|
572961
|
+
if (s2.sponsorUsage) {
|
|
572962
|
+
lines.push("");
|
|
572963
|
+
lines.push(` ${c3.bold("Sponsor Quota")}`);
|
|
572964
|
+
lines.push(` ${formatUsageBar({
|
|
572965
|
+
label: "Daily tokens",
|
|
572966
|
+
used: s2.sponsorUsage.dailyTokensUsed,
|
|
572967
|
+
total: s2.sponsorUsage.dailyTokensLimit,
|
|
572968
|
+
resetAt: s2.sponsorUsage.dailyResetAt
|
|
572969
|
+
})}`);
|
|
572970
|
+
lines.push(` ${formatUsageBar({
|
|
572971
|
+
label: "Requests/min",
|
|
572972
|
+
used: s2.sponsorUsage.requestsInWindow,
|
|
572973
|
+
total: s2.sponsorUsage.requestsPerMinuteLimit,
|
|
572974
|
+
resetAt: s2.sponsorUsage.requestWindowResetAt
|
|
572975
|
+
})}`);
|
|
572976
|
+
lines.push(` ${formatUsageBar({
|
|
572977
|
+
label: "Concurrency",
|
|
572978
|
+
used: s2.sponsorUsage.activeConnections,
|
|
572979
|
+
total: s2.sponsorUsage.maxConcurrent
|
|
572980
|
+
})}`);
|
|
572981
|
+
lines.push(` ${c3.cyan("Blocked".padEnd(18))} ${s2.sponsorUsage.blockedRequests}`);
|
|
572982
|
+
}
|
|
572571
572983
|
const visibleModels = Array.from(s2.modelUsage.entries()).filter(([model]) => !INTERNAL_CAPABILITIES.has(model));
|
|
572572
572984
|
if (visibleModels.length > 0) {
|
|
572573
572985
|
lines.push("");
|
|
@@ -572629,6 +573041,11 @@ ${this.formatConnectionInfo()}`);
|
|
|
572629
573041
|
_passthrough = false;
|
|
572630
573042
|
_loadbalance = false;
|
|
572631
573043
|
_endpointAuth;
|
|
573044
|
+
_sponsorLimits = null;
|
|
573045
|
+
_sponsorBlockedRequests = 0;
|
|
573046
|
+
_sponsorRequestWindow = [];
|
|
573047
|
+
_dailyTokensUsed = 0;
|
|
573048
|
+
_dailyTokensResetAt = 0;
|
|
572632
573049
|
_pollTimer = null;
|
|
572633
573050
|
_activityPollTimer = null;
|
|
572634
573051
|
/** Fast token flash timer — pulses LED at 200ms while inference is active */
|
|
@@ -572647,7 +573064,8 @@ ${this.formatConnectionInfo()}`);
|
|
|
572647
573064
|
users: /* @__PURE__ */ new Map(),
|
|
572648
573065
|
budgetTokensRemaining: 0,
|
|
572649
573066
|
budgetTokensTotal: 0,
|
|
572650
|
-
budgetResetAt: 0
|
|
573067
|
+
budgetResetAt: 0,
|
|
573068
|
+
sponsorUsage: null
|
|
572651
573069
|
};
|
|
572652
573070
|
get peerId() {
|
|
572653
573071
|
return this._peerId;
|
|
@@ -572689,6 +573107,93 @@ ${this.formatConnectionInfo()}`);
|
|
|
572689
573107
|
} else {
|
|
572690
573108
|
this._authKey = options2.authKey;
|
|
572691
573109
|
}
|
|
573110
|
+
this.loadSponsorUsage();
|
|
573111
|
+
this.refreshSponsorUsageStats();
|
|
573112
|
+
}
|
|
573113
|
+
setSponsorLimits(limits) {
|
|
573114
|
+
this._sponsorLimits = limits;
|
|
573115
|
+
this.ensureSponsorDailyWindow();
|
|
573116
|
+
this.refreshSponsorUsageStats();
|
|
573117
|
+
this.emitStats();
|
|
573118
|
+
}
|
|
573119
|
+
getSponsorUsageSnapshot() {
|
|
573120
|
+
this.refreshSponsorUsageStats();
|
|
573121
|
+
return this._stats.sponsorUsage ? { ...this._stats.sponsorUsage } : null;
|
|
573122
|
+
}
|
|
573123
|
+
loadSponsorUsage() {
|
|
573124
|
+
if (!this._stateDir) {
|
|
573125
|
+
this._dailyTokensResetAt = nextSponsorDailyReset();
|
|
573126
|
+
return;
|
|
573127
|
+
}
|
|
573128
|
+
const saved = readSponsorUsageState(this._stateDir);
|
|
573129
|
+
if (!saved) {
|
|
573130
|
+
this._dailyTokensUsed = 0;
|
|
573131
|
+
this._dailyTokensResetAt = nextSponsorDailyReset();
|
|
573132
|
+
return;
|
|
573133
|
+
}
|
|
573134
|
+
const now = Date.now();
|
|
573135
|
+
if (saved.dailyTokensResetAt <= now) {
|
|
573136
|
+
this._dailyTokensUsed = 0;
|
|
573137
|
+
this._dailyTokensResetAt = nextSponsorDailyReset(now);
|
|
573138
|
+
this.saveSponsorUsage();
|
|
573139
|
+
} else {
|
|
573140
|
+
this._dailyTokensUsed = saved.dailyTokensUsed;
|
|
573141
|
+
this._dailyTokensResetAt = saved.dailyTokensResetAt;
|
|
573142
|
+
}
|
|
573143
|
+
}
|
|
573144
|
+
saveSponsorUsage() {
|
|
573145
|
+
if (!this._stateDir) return;
|
|
573146
|
+
writeSponsorUsageState(this._stateDir, {
|
|
573147
|
+
dailyTokensUsed: this._dailyTokensUsed,
|
|
573148
|
+
dailyTokensResetAt: this._dailyTokensResetAt,
|
|
573149
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
573150
|
+
});
|
|
573151
|
+
}
|
|
573152
|
+
ensureSponsorDailyWindow(now = Date.now()) {
|
|
573153
|
+
if (!this._dailyTokensResetAt || this._dailyTokensResetAt <= now) {
|
|
573154
|
+
this._dailyTokensUsed = 0;
|
|
573155
|
+
this._dailyTokensResetAt = nextSponsorDailyReset(now);
|
|
573156
|
+
this.saveSponsorUsage();
|
|
573157
|
+
}
|
|
573158
|
+
}
|
|
573159
|
+
recordSponsorRequest(now = Date.now()) {
|
|
573160
|
+
this._sponsorRequestWindow.push(now);
|
|
573161
|
+
this.pruneSponsorRequestWindow(now);
|
|
573162
|
+
}
|
|
573163
|
+
pruneSponsorRequestWindow(now = Date.now()) {
|
|
573164
|
+
while (this._sponsorRequestWindow.length > 0 && this._sponsorRequestWindow[0] < now - SPONSOR_REQUEST_WINDOW_MS) {
|
|
573165
|
+
this._sponsorRequestWindow.shift();
|
|
573166
|
+
}
|
|
573167
|
+
}
|
|
573168
|
+
trackTokenUsage(tokensIn, tokensOut) {
|
|
573169
|
+
const total = safeNonNegativeInt(tokensIn) + safeNonNegativeInt(tokensOut);
|
|
573170
|
+
if (total <= 0) return;
|
|
573171
|
+
this.ensureSponsorDailyWindow();
|
|
573172
|
+
this._dailyTokensUsed += total;
|
|
573173
|
+
this.saveSponsorUsage();
|
|
573174
|
+
this.refreshSponsorUsageStats();
|
|
573175
|
+
}
|
|
573176
|
+
refreshSponsorUsageStats(now = Date.now()) {
|
|
573177
|
+
if (!this._sponsorLimits) {
|
|
573178
|
+
this._stats.sponsorUsage = null;
|
|
573179
|
+
return;
|
|
573180
|
+
}
|
|
573181
|
+
this.ensureSponsorDailyWindow(now);
|
|
573182
|
+
this.pruneSponsorRequestWindow(now);
|
|
573183
|
+
this._stats.sponsorUsage = {
|
|
573184
|
+
enabled: true,
|
|
573185
|
+
transport: "libp2p",
|
|
573186
|
+
dailyTokensUsed: this._dailyTokensUsed,
|
|
573187
|
+
dailyTokensLimit: this._sponsorLimits.maxTokensPerDay,
|
|
573188
|
+
dailyResetAt: this._dailyTokensResetAt,
|
|
573189
|
+
requestsInWindow: this._sponsorRequestWindow.length,
|
|
573190
|
+
requestsPerMinuteLimit: this._sponsorLimits.maxRequestsPerMinute,
|
|
573191
|
+
requestWindowResetAt: this._sponsorRequestWindow[0] ? this._sponsorRequestWindow[0] + SPONSOR_REQUEST_WINDOW_MS : now + SPONSOR_REQUEST_WINDOW_MS,
|
|
573192
|
+
activeConnections: this._stats.activeConnections,
|
|
573193
|
+
maxConcurrent: this._sponsorLimits.maxConcurrent,
|
|
573194
|
+
blockedRequests: this._sponsorBlockedRequests,
|
|
573195
|
+
allowedModels: this._sponsorLimits.allowedModels === "all" ? "all" : [...this._sponsorLimits.allowedModels]
|
|
573196
|
+
};
|
|
572692
573197
|
}
|
|
572693
573198
|
async start() {
|
|
572694
573199
|
this._onInfo?.("Connecting to nexus P2P network...");
|
|
@@ -572947,6 +573452,8 @@ ${this.formatConnectionInfo()}`);
|
|
|
572947
573452
|
}
|
|
572948
573453
|
this._stats.totalTokensIn += tokIn;
|
|
572949
573454
|
this._stats.totalTokensOut += tokOut;
|
|
573455
|
+
this.recordSponsorRequest();
|
|
573456
|
+
this.trackTokenUsage(tokIn, tokOut);
|
|
572950
573457
|
const peerId = record.from || record.peerId || "unknown";
|
|
572951
573458
|
const shortPeer = peerId.length > 16 ? peerId.slice(0, 16) + "..." : peerId;
|
|
572952
573459
|
let user = this._stats.users.get(shortPeer);
|
|
@@ -573010,10 +573517,12 @@ ${this.formatConnectionInfo()}`);
|
|
|
573010
573517
|
}
|
|
573011
573518
|
}
|
|
573012
573519
|
emitStats() {
|
|
573520
|
+
this.refreshSponsorUsageStats();
|
|
573013
573521
|
this.emit("stats", {
|
|
573014
573522
|
...this._stats,
|
|
573015
573523
|
modelUsage: new Map(this._stats.modelUsage),
|
|
573016
|
-
users: new Map(this._stats.users)
|
|
573524
|
+
users: new Map(this._stats.users),
|
|
573525
|
+
sponsorUsage: this._stats.sponsorUsage ? { ...this._stats.sponsorUsage } : null
|
|
573017
573526
|
});
|
|
573018
573527
|
}
|
|
573019
573528
|
/** Format connection info for display */
|
|
@@ -573061,6 +573570,28 @@ ${this.formatConnectionInfo()}`);
|
|
|
573061
573570
|
const budgetColor = pct > 50 ? c3.green : pct > 20 ? c3.yellow : c3.red;
|
|
573062
573571
|
lines.push(` ${c3.cyan("Budget".padEnd(18))} ${budgetColor(fmtTokens(s2.budgetTokensRemaining))}${c3.dim("/")}${fmtTokens(s2.budgetTokensTotal)} ${c3.dim(`(${pct}% left)`)}`);
|
|
573063
573572
|
}
|
|
573573
|
+
if (s2.sponsorUsage) {
|
|
573574
|
+
lines.push("");
|
|
573575
|
+
lines.push(` ${c3.bold("Sponsor Quota")}`);
|
|
573576
|
+
lines.push(` ${formatUsageBar({
|
|
573577
|
+
label: "Daily tokens",
|
|
573578
|
+
used: s2.sponsorUsage.dailyTokensUsed,
|
|
573579
|
+
total: s2.sponsorUsage.dailyTokensLimit,
|
|
573580
|
+
resetAt: s2.sponsorUsage.dailyResetAt
|
|
573581
|
+
})}`);
|
|
573582
|
+
lines.push(` ${formatUsageBar({
|
|
573583
|
+
label: "Requests/min",
|
|
573584
|
+
used: s2.sponsorUsage.requestsInWindow,
|
|
573585
|
+
total: s2.sponsorUsage.requestsPerMinuteLimit,
|
|
573586
|
+
resetAt: s2.sponsorUsage.requestWindowResetAt
|
|
573587
|
+
})}`);
|
|
573588
|
+
lines.push(` ${formatUsageBar({
|
|
573589
|
+
label: "Concurrency",
|
|
573590
|
+
used: s2.sponsorUsage.activeConnections,
|
|
573591
|
+
total: s2.sponsorUsage.maxConcurrent
|
|
573592
|
+
})}`);
|
|
573593
|
+
lines.push(` ${c3.cyan("Blocked".padEnd(18))} ${s2.sponsorUsage.blockedRequests}`);
|
|
573594
|
+
}
|
|
573064
573595
|
const visibleModels = Array.from(s2.modelUsage.entries()).filter(([model]) => !INTERNAL_CAPABILITIES.has(model));
|
|
573065
573596
|
if (visibleModels.length > 0) {
|
|
573066
573597
|
lines.push("");
|
|
@@ -583462,21 +583993,27 @@ function ensureZstd() {
|
|
|
583462
583993
|
process.stdout.write(`
|
|
583463
583994
|
${c3.cyan("●")} Installing zstd (required by ollama install.sh)...
|
|
583464
583995
|
`);
|
|
583996
|
+
const terminalElevation = process.env["OMNIUS_ELEVATION_MODE"] === "terminal" && process.stdin.isTTY && process.stdout.isTTY;
|
|
583465
583997
|
const hasDisplay = !!(process.env.DISPLAY || process.env.WAYLAND_DISPLAY);
|
|
583466
583998
|
const askpassHelper = detectAskpassHelper() ?? writeAskpassHelper();
|
|
583467
583999
|
const askpassEnv = askpassHelper ? { ...process.env, SUDO_ASKPASS: askpassHelper, DEBIAN_FRONTEND: "noninteractive" } : { ...process.env, DEBIAN_FRONTEND: "noninteractive" };
|
|
583468
584000
|
const candidates = [];
|
|
583469
|
-
if (
|
|
583470
|
-
|
|
583471
|
-
|
|
583472
|
-
|
|
583473
|
-
|
|
584001
|
+
if (terminalElevation) {
|
|
584002
|
+
const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
|
|
584003
|
+
candidates.push({ cmd: isRoot ? installCmd : `sudo ${installCmd}`, env: askpassEnv, stdio: "inherit" });
|
|
584004
|
+
} else {
|
|
584005
|
+
if (hasCmd("pkexec") && hasDisplay) {
|
|
584006
|
+
candidates.push({ cmd: `pkexec sh -c ${shellEscape(installCmd)}`, env: process.env });
|
|
584007
|
+
}
|
|
584008
|
+
if (askpassHelper) {
|
|
584009
|
+
candidates.push({ cmd: `sudo -A ${installCmd}`, env: askpassEnv });
|
|
584010
|
+
}
|
|
583474
584011
|
}
|
|
583475
584012
|
candidates.push({ cmd: installCmd, env: process.env });
|
|
583476
584013
|
for (const cand of candidates) {
|
|
583477
584014
|
try {
|
|
583478
584015
|
execSync51(cand.cmd, {
|
|
583479
|
-
stdio: ["ignore", "inherit", "pipe"],
|
|
584016
|
+
stdio: cand.stdio ?? ["ignore", "inherit", "pipe"],
|
|
583480
584017
|
env: cand.env,
|
|
583481
584018
|
timeout: 18e4
|
|
583482
584019
|
});
|
|
@@ -583564,6 +584101,14 @@ osascript -e 'Tell application "System Events" to display dialog "Omnius needs a
|
|
|
583564
584101
|
function buildElevatedInstall() {
|
|
583565
584102
|
const installCmd = "curl -fsSL https://ollama.com/install.sh | sh";
|
|
583566
584103
|
const baseEnv = { ...process.env };
|
|
584104
|
+
if (process.env["OMNIUS_ELEVATION_MODE"] === "terminal" && process.stdin.isTTY && process.stdout.isTTY) {
|
|
584105
|
+
const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
|
|
584106
|
+
return {
|
|
584107
|
+
cmd: isRoot ? `sh -c ${shellEscape(installCmd)}` : `sudo sh -c ${shellEscape(installCmd)}`,
|
|
584108
|
+
env: { ...baseEnv, DEBIAN_FRONTEND: "noninteractive" },
|
|
584109
|
+
mode: "terminal"
|
|
584110
|
+
};
|
|
584111
|
+
}
|
|
583567
584112
|
if (process.platform === "linux" && hasCmd("pkexec") && (process.env.DISPLAY || process.env.WAYLAND_DISPLAY)) {
|
|
583568
584113
|
return {
|
|
583569
584114
|
cmd: `pkexec sh -c ${shellEscape(installCmd)}`,
|
|
@@ -583595,20 +584140,29 @@ function runElevatedCommand(command, opts = {}) {
|
|
|
583595
584140
|
const hasDisplay = !!(process.env.DISPLAY || process.env.WAYLAND_DISPLAY);
|
|
583596
584141
|
const askpassHelper = detectAskpassHelper() ?? writeAskpassHelper();
|
|
583597
584142
|
const askpassEnv = askpassHelper ? { ...process.env, SUDO_ASKPASS: askpassHelper } : process.env;
|
|
584143
|
+
const terminalElevation = process.env["OMNIUS_ELEVATION_MODE"] === "terminal" && process.stdin.isTTY && process.stdout.isTTY;
|
|
583598
584144
|
const candidates = [];
|
|
583599
|
-
if (
|
|
583600
|
-
|
|
583601
|
-
|
|
583602
|
-
|
|
583603
|
-
|
|
584145
|
+
if (terminalElevation) {
|
|
584146
|
+
const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
|
|
584147
|
+
candidates.push({
|
|
584148
|
+
cmd: isRoot ? `sh -c ${shellEscape(command)}` : `sudo sh -c ${shellEscape(command)}`,
|
|
584149
|
+
env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" },
|
|
584150
|
+
stdio: "inherit"
|
|
584151
|
+
});
|
|
584152
|
+
} else {
|
|
584153
|
+
if (hasCmd("pkexec") && hasDisplay) {
|
|
584154
|
+
candidates.push({ cmd: `pkexec sh -c ${shellEscape(command)}`, env: process.env });
|
|
584155
|
+
}
|
|
584156
|
+
if (askpassHelper) {
|
|
584157
|
+
candidates.push({ cmd: `sudo -A sh -c ${shellEscape(command)}`, env: askpassEnv });
|
|
584158
|
+
}
|
|
583604
584159
|
}
|
|
583605
584160
|
candidates.push({ cmd: command, env: process.env });
|
|
583606
584161
|
let lastErr = null;
|
|
583607
584162
|
for (const cand of candidates) {
|
|
583608
584163
|
try {
|
|
583609
584164
|
execSync51(cand.cmd, {
|
|
583610
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
583611
|
-
// never inherit TUI stdin
|
|
584165
|
+
stdio: cand.stdio ?? ["ignore", "pipe", "pipe"],
|
|
583612
584166
|
env: cand.env,
|
|
583613
584167
|
timeout: timeout2
|
|
583614
584168
|
});
|
|
@@ -583628,7 +584182,10 @@ function runOllamaInstallScript() {
|
|
|
583628
584182
|
`);
|
|
583629
584183
|
}
|
|
583630
584184
|
const elevated = buildElevatedInstall();
|
|
583631
|
-
if (elevated.mode === "
|
|
584185
|
+
if (elevated.mode === "terminal") {
|
|
584186
|
+
process.stdout.write(` ${c3.cyan("●")} Elevation: sudo terminal prompt
|
|
584187
|
+
`);
|
|
584188
|
+
} else if (elevated.mode === "pkexec") {
|
|
583632
584189
|
process.stdout.write(` ${c3.cyan("●")} Elevation: pkexec (graphical PolicyKit prompt)
|
|
583633
584190
|
`);
|
|
583634
584191
|
} else if (elevated.mode === "askpass") {
|
|
@@ -583642,7 +584199,7 @@ function runOllamaInstallScript() {
|
|
|
583642
584199
|
}
|
|
583643
584200
|
const runOnce = () => {
|
|
583644
584201
|
execSync51(elevated.cmd, {
|
|
583645
|
-
stdio: ["ignore", "inherit", "pipe"],
|
|
584202
|
+
stdio: elevated.mode === "terminal" ? "inherit" : ["ignore", "inherit", "pipe"],
|
|
583646
584203
|
env: elevated.env,
|
|
583647
584204
|
timeout: 6e5
|
|
583648
584205
|
});
|
|
@@ -584919,6 +585476,20 @@ async function acquireSudoPassword(getSudoPassword, log22, cachedPasswordRef) {
|
|
|
584919
585476
|
}
|
|
584920
585477
|
async function sudoInstall(cmd, getSudoPassword, log22, cachedPasswordRef, timeoutMs = 12e4) {
|
|
584921
585478
|
if (trySudoPasswordless(cmd, timeoutMs)) return true;
|
|
585479
|
+
if (process.env["OMNIUS_ELEVATION_MODE"] === "terminal" && process.stdin.isTTY && process.stdout.isTTY) {
|
|
585480
|
+
try {
|
|
585481
|
+
const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
|
|
585482
|
+
const escaped = cmd.replace(/'/g, "'\\''");
|
|
585483
|
+
execSync51(isRoot ? `bash -c '${escaped}'` : `sudo bash -c '${escaped}'`, {
|
|
585484
|
+
stdio: "inherit",
|
|
585485
|
+
timeout: timeoutMs,
|
|
585486
|
+
env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
|
|
585487
|
+
});
|
|
585488
|
+
return true;
|
|
585489
|
+
} catch {
|
|
585490
|
+
return false;
|
|
585491
|
+
}
|
|
585492
|
+
}
|
|
584922
585493
|
const pw2 = await acquireSudoPassword(getSudoPassword, log22, cachedPasswordRef);
|
|
584923
585494
|
if (pw2 === null) return false;
|
|
584924
585495
|
if (pw2 === "") return false;
|
|
@@ -585218,9 +585789,11 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
585218
585789
|
} catch {
|
|
585219
585790
|
}
|
|
585220
585791
|
try {
|
|
585792
|
+
const terminalElevation = process.env["OMNIUS_ELEVATION_MODE"] === "terminal" && process.stdin.isTTY && process.stdout.isTTY;
|
|
585793
|
+
const sudoMove = terminalElevation ? `sudo mv /tmp/cloudflared /usr/local/bin/cloudflared` : `sudo mv /tmp/cloudflared /usr/local/bin/cloudflared 2>/dev/null`;
|
|
585221
585794
|
execSync51(
|
|
585222
|
-
`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared &&
|
|
585223
|
-
{ stdio: "pipe", timeout: 6e4 }
|
|
585795
|
+
`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && ` + sudoMove,
|
|
585796
|
+
{ stdio: terminalElevation ? "inherit" : "pipe", timeout: 6e4 }
|
|
585224
585797
|
);
|
|
585225
585798
|
if (hasCmd("cloudflared")) {
|
|
585226
585799
|
log22("cloudflared installed.");
|
|
@@ -590733,15 +591306,52 @@ async function stepReview(config, rl, availableRows) {
|
|
|
590733
591306
|
if (!result.confirmed || result.key === "cancel") return false;
|
|
590734
591307
|
return result.key === "go_live";
|
|
590735
591308
|
}
|
|
590736
|
-
async function showSponsorDashboard(config, projectDir2, rl, availableRows) {
|
|
591309
|
+
async function showSponsorDashboard(config, projectDir2, rl, availableRows, sponsorUsage) {
|
|
590737
591310
|
const isPaused = config.status === "paused";
|
|
590738
591311
|
const enabledEps = config.endpoints.filter((e2) => e2.enabled);
|
|
591312
|
+
const dailyTokensLimit = sponsorUsage?.dailyTokensLimit || config.rateLimits.maxTokensPerDay;
|
|
591313
|
+
const requestsPerMinuteLimit = sponsorUsage?.requestsPerMinuteLimit || config.rateLimits.maxRequestsPerMinute;
|
|
591314
|
+
const maxConcurrent = sponsorUsage?.maxConcurrent || config.rateLimits.maxConcurrent;
|
|
591315
|
+
const usageItems = [
|
|
591316
|
+
{
|
|
591317
|
+
key: "info_usage_daily",
|
|
591318
|
+
label: ` ${formatUsageBar({
|
|
591319
|
+
label: "Daily tokens",
|
|
591320
|
+
used: sponsorUsage?.dailyTokensUsed ?? 0,
|
|
591321
|
+
total: dailyTokensLimit,
|
|
591322
|
+
resetAt: sponsorUsage?.dailyResetAt
|
|
591323
|
+
})}`
|
|
591324
|
+
},
|
|
591325
|
+
{
|
|
591326
|
+
key: "info_usage_rpm",
|
|
591327
|
+
label: ` ${formatUsageBar({
|
|
591328
|
+
label: "Requests/min",
|
|
591329
|
+
used: sponsorUsage?.requestsInWindow ?? 0,
|
|
591330
|
+
total: requestsPerMinuteLimit,
|
|
591331
|
+
resetAt: sponsorUsage?.requestWindowResetAt
|
|
591332
|
+
})}`
|
|
591333
|
+
},
|
|
591334
|
+
{
|
|
591335
|
+
key: "info_usage_concurrent",
|
|
591336
|
+
label: ` ${formatUsageBar({
|
|
591337
|
+
label: "Concurrency",
|
|
591338
|
+
used: sponsorUsage?.activeConnections ?? 0,
|
|
591339
|
+
total: maxConcurrent
|
|
591340
|
+
})}`
|
|
591341
|
+
},
|
|
591342
|
+
{
|
|
591343
|
+
key: "info_usage_blocked",
|
|
591344
|
+
label: ` Blocked: ${sponsorUsage?.blockedRequests ?? 0}`
|
|
591345
|
+
}
|
|
591346
|
+
];
|
|
590739
591347
|
const items = [
|
|
590740
591348
|
{ key: "hdr", label: "Sponsor Dashboard" },
|
|
590741
591349
|
{ key: "info_status", label: ` Status: ${isPaused ? "● PAUSED" : "● ACTIVE"}` },
|
|
590742
591350
|
{ key: "info_ep", label: ` Endpoints: ${enabledEps.map((e2) => e2.label).join(", ")}` },
|
|
590743
591351
|
{ key: "info_transport", label: ` Transport: ${[config.transport.cloudflared ? "Cloudflared" : "", config.transport.libp2p ? "libp2p" : ""].filter(Boolean).join(" + ")}` },
|
|
590744
591352
|
{ key: "info_limits", label: ` Limits: ${config.rateLimits.maxRequestsPerMinute} req/min, ${config.rateLimits.maxTokensPerDay.toLocaleString()} tokens/day` },
|
|
591353
|
+
{ key: "info_usage_hdr", label: " Usage" },
|
|
591354
|
+
...usageItems,
|
|
590745
591355
|
{ key: "sep", label: "" },
|
|
590746
591356
|
{ key: "modify", label: " [Modify Settings]" },
|
|
590747
591357
|
{ key: isPaused ? "resume" : "pause", label: isPaused ? " [Resume Sponsorship]" : " [Pause Sponsorship]" },
|
|
@@ -590751,7 +591361,7 @@ async function showSponsorDashboard(config, projectDir2, rl, availableRows) {
|
|
|
590751
591361
|
items,
|
|
590752
591362
|
title: "Sponsor Dashboard",
|
|
590753
591363
|
rl,
|
|
590754
|
-
skipKeys: ["hdr", "sep", "info_status", "info_ep", "info_transport", "info_limits"],
|
|
591364
|
+
skipKeys: ["hdr", "sep", "info_status", "info_ep", "info_transport", "info_limits", "info_usage_hdr", "info_usage_daily", "info_usage_rpm", "info_usage_concurrent", "info_usage_blocked"],
|
|
590755
591365
|
availableRows
|
|
590756
591366
|
});
|
|
590757
591367
|
if (!result.confirmed) return "close";
|
|
@@ -590816,6 +591426,7 @@ var init_sponsor_wizard = __esm({
|
|
|
590816
591426
|
init_dist();
|
|
590817
591427
|
init_tui_select();
|
|
590818
591428
|
init_render();
|
|
591429
|
+
init_usage_bars();
|
|
590819
591430
|
}
|
|
590820
591431
|
});
|
|
590821
591432
|
|
|
@@ -595011,7 +595622,8 @@ import {
|
|
|
595011
595622
|
lstatSync,
|
|
595012
595623
|
statSync as statSync41,
|
|
595013
595624
|
rmSync as rmSync4,
|
|
595014
|
-
appendFileSync as appendFileSync8
|
|
595625
|
+
appendFileSync as appendFileSync8,
|
|
595626
|
+
writeSync as writeSync2
|
|
595015
595627
|
} from "node:fs";
|
|
595016
595628
|
import { relative as relative11, join as join120 } from "node:path";
|
|
595017
595629
|
async function _immediateReregister(newUrl) {
|
|
@@ -595102,6 +595714,17 @@ function stopSponsorHeartbeat() {
|
|
|
595102
595714
|
}
|
|
595103
595715
|
_lastRegisteredSponsorPayload = null;
|
|
595104
595716
|
}
|
|
595717
|
+
function sponsorUsageFromGateway(gateway) {
|
|
595718
|
+
if (!gateway) return null;
|
|
595719
|
+
try {
|
|
595720
|
+
if (typeof gateway.getSponsorUsageSnapshot === "function") {
|
|
595721
|
+
return gateway.getSponsorUsageSnapshot();
|
|
595722
|
+
}
|
|
595723
|
+
return gateway.stats?.sponsorUsage ?? null;
|
|
595724
|
+
} catch {
|
|
595725
|
+
return null;
|
|
595726
|
+
}
|
|
595727
|
+
}
|
|
595105
595728
|
function registerCommandHelp2(items) {
|
|
595106
595729
|
registerCommandHelp(items);
|
|
595107
595730
|
}
|
|
@@ -595219,50 +595842,161 @@ function parseTelegramMessageIdList(value2) {
|
|
|
595219
595842
|
if (!value2) return [];
|
|
595220
595843
|
return [...new Set(value2.split(",").map((part) => Number(part.trim())).filter((num) => Number.isFinite(num)))];
|
|
595221
595844
|
}
|
|
595222
|
-
|
|
595223
|
-
const stdinAny = process.stdin;
|
|
595224
|
-
const hadRaw = !!(stdinAny && stdinAny.isTTY && stdinAny.isRaw);
|
|
595845
|
+
function writeDirectTerminal(data) {
|
|
595225
595846
|
try {
|
|
595226
|
-
|
|
595847
|
+
writeSync2(1, data);
|
|
595227
595848
|
} catch {
|
|
595849
|
+
try {
|
|
595850
|
+
overlayWrite(data);
|
|
595851
|
+
} catch {
|
|
595852
|
+
process.stdout.write(data);
|
|
595853
|
+
}
|
|
595228
595854
|
}
|
|
595855
|
+
}
|
|
595856
|
+
function setRawInputMode(enabled2) {
|
|
595857
|
+
const stdinAny = process.stdin;
|
|
595229
595858
|
try {
|
|
595230
595859
|
if (stdinAny && stdinAny.isTTY && typeof stdinAny.setRawMode === "function") {
|
|
595231
|
-
stdinAny.setRawMode(
|
|
595860
|
+
stdinAny.setRawMode(enabled2);
|
|
595232
595861
|
}
|
|
595233
595862
|
} catch {
|
|
595234
595863
|
}
|
|
595864
|
+
}
|
|
595865
|
+
async function withTransientTerminalPrivilegePrompt(ctx3, reason, run2) {
|
|
595866
|
+
const hasInteractiveTty = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
595867
|
+
if (!hasInteractiveTty) return await run2();
|
|
595868
|
+
const stdinAny = process.stdin;
|
|
595869
|
+
const hadRaw = Boolean(stdinAny?.isTTY && stdinAny.isRaw);
|
|
595870
|
+
const hadMouse = ctx3.isMouseEnabled?.() ?? false;
|
|
595871
|
+
const hadElevationMode = Object.prototype.hasOwnProperty.call(
|
|
595872
|
+
process.env,
|
|
595873
|
+
"OMNIUS_ELEVATION_MODE"
|
|
595874
|
+
);
|
|
595875
|
+
const previousElevationMode = process.env["OMNIUS_ELEVATION_MODE"];
|
|
595235
595876
|
try {
|
|
595236
|
-
|
|
595237
|
-
const full = `set -e; ${script}`;
|
|
595238
|
-
await new Promise((resolve56) => {
|
|
595239
|
-
const usePkexec = process.platform === "linux";
|
|
595240
|
-
const cmd = usePkexec ? "pkexec" : "sudo";
|
|
595241
|
-
const args = usePkexec ? ["bash", "-lc", full] : ["-n", "bash", "-lc", full];
|
|
595242
|
-
const child = spawn34(cmd, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
595243
|
-
let stdout = "";
|
|
595244
|
-
let stderr = "";
|
|
595245
|
-
child.stdout?.on("data", (data) => {
|
|
595246
|
-
stdout += data.toString();
|
|
595247
|
-
});
|
|
595248
|
-
child.stderr?.on("data", (data) => {
|
|
595249
|
-
stderr += data.toString();
|
|
595250
|
-
});
|
|
595251
|
-
onChildExit(child, () => resolve56());
|
|
595252
|
-
onChildError(child, () => resolve56());
|
|
595253
|
-
});
|
|
595877
|
+
ctx3.lockFooter?.();
|
|
595254
595878
|
} catch {
|
|
595255
595879
|
}
|
|
595256
595880
|
try {
|
|
595257
|
-
|
|
595258
|
-
stdinAny.setRawMode(true);
|
|
595259
|
-
}
|
|
595881
|
+
lockFooterRedraws();
|
|
595260
595882
|
} catch {
|
|
595261
595883
|
}
|
|
595262
595884
|
try {
|
|
595263
|
-
ctx3.
|
|
595885
|
+
ctx3.disableMouse?.();
|
|
595264
595886
|
} catch {
|
|
595265
595887
|
}
|
|
595888
|
+
setRawInputMode(false);
|
|
595889
|
+
process.env["OMNIUS_ELEVATION_MODE"] = "terminal";
|
|
595890
|
+
writeDirectTerminal(
|
|
595891
|
+
"\x1B[?2026l\x1B[?25h\x1B[?1000l\x1B[?1002l\x1B[?1003l\x1B[?1006l\x1B[r\x1B[0m\x1B[2J\x1B[H"
|
|
595892
|
+
);
|
|
595893
|
+
writeDirectTerminal(
|
|
595894
|
+
`${c3.bold("Omnius needs administrator privileges")}
|
|
595895
|
+
${reason}
|
|
595896
|
+
|
|
595897
|
+
`
|
|
595898
|
+
);
|
|
595899
|
+
try {
|
|
595900
|
+
return await run2();
|
|
595901
|
+
} finally {
|
|
595902
|
+
if (hadElevationMode) {
|
|
595903
|
+
process.env["OMNIUS_ELEVATION_MODE"] = previousElevationMode;
|
|
595904
|
+
} else {
|
|
595905
|
+
delete process.env["OMNIUS_ELEVATION_MODE"];
|
|
595906
|
+
}
|
|
595907
|
+
setRawInputMode(hadRaw);
|
|
595908
|
+
writeDirectTerminal(
|
|
595909
|
+
"\x1B[?2026l\x1B[?25h\x1B[r\x1B[0m\x1B[2J\x1B[H"
|
|
595910
|
+
);
|
|
595911
|
+
try {
|
|
595912
|
+
ctx3.unlockFooter?.();
|
|
595913
|
+
} catch {
|
|
595914
|
+
}
|
|
595915
|
+
try {
|
|
595916
|
+
unlockFooterRedraws();
|
|
595917
|
+
} catch {
|
|
595918
|
+
}
|
|
595919
|
+
try {
|
|
595920
|
+
ctx3.refreshDisplay?.();
|
|
595921
|
+
} catch {
|
|
595922
|
+
}
|
|
595923
|
+
try {
|
|
595924
|
+
if (hadMouse) {
|
|
595925
|
+
ctx3.enableMouse?.();
|
|
595926
|
+
writeDirectTerminal("\x1B[?1002h\x1B[?1006h");
|
|
595927
|
+
} else {
|
|
595928
|
+
writeDirectTerminal("\x1B[?1002l\x1B[?1006l");
|
|
595929
|
+
}
|
|
595930
|
+
} catch {
|
|
595931
|
+
}
|
|
595932
|
+
try {
|
|
595933
|
+
ctx3.showPrompt?.();
|
|
595934
|
+
} catch {
|
|
595935
|
+
}
|
|
595936
|
+
}
|
|
595937
|
+
}
|
|
595938
|
+
async function acquireSudoCredentials(ctx3, reason) {
|
|
595939
|
+
const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
|
|
595940
|
+
if (isRoot) return true;
|
|
595941
|
+
const { spawnSync: spawnSync8 } = await import("node:child_process");
|
|
595942
|
+
return await withTransientTerminalPrivilegePrompt(ctx3, reason, () => {
|
|
595943
|
+
const hasInteractiveTty = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
595944
|
+
const sudoResult = spawnSync8(
|
|
595945
|
+
"sudo",
|
|
595946
|
+
hasInteractiveTty ? ["-v"] : ["-n", "-v"],
|
|
595947
|
+
{
|
|
595948
|
+
stdio: hasInteractiveTty ? "inherit" : "pipe",
|
|
595949
|
+
timeout: 6e4
|
|
595950
|
+
}
|
|
595951
|
+
);
|
|
595952
|
+
return sudoResult.status === 0;
|
|
595953
|
+
});
|
|
595954
|
+
}
|
|
595955
|
+
async function runSudoScript(ctx3, script) {
|
|
595956
|
+
try {
|
|
595957
|
+
const { spawn: spawn34 } = await import("node:child_process");
|
|
595958
|
+
const full = `set -e; ${script}`;
|
|
595959
|
+
await withTransientTerminalPrivilegePrompt(
|
|
595960
|
+
ctx3,
|
|
595961
|
+
"Running elevated system changes.",
|
|
595962
|
+
() => new Promise((resolve56, reject) => {
|
|
595963
|
+
const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
|
|
595964
|
+
const hasInteractiveTty = Boolean(
|
|
595965
|
+
process.stdin.isTTY && process.stdout.isTTY
|
|
595966
|
+
);
|
|
595967
|
+
const cmd = isRoot ? "bash" : "sudo";
|
|
595968
|
+
const args = isRoot ? ["-lc", full] : hasInteractiveTty ? ["bash", "-lc", full] : ["-n", "bash", "-lc", full];
|
|
595969
|
+
const child = spawn34(cmd, args, {
|
|
595970
|
+
stdio: hasInteractiveTty ? "inherit" : ["ignore", "pipe", "pipe"],
|
|
595971
|
+
env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
|
|
595972
|
+
});
|
|
595973
|
+
let stdout = "";
|
|
595974
|
+
let stderr = "";
|
|
595975
|
+
child.stdout?.on("data", (data) => {
|
|
595976
|
+
stdout += data.toString();
|
|
595977
|
+
});
|
|
595978
|
+
child.stderr?.on("data", (data) => {
|
|
595979
|
+
stderr += data.toString();
|
|
595980
|
+
});
|
|
595981
|
+
onChildExit(child, (code8) => {
|
|
595982
|
+
if (code8 === 0) {
|
|
595983
|
+
resolve56();
|
|
595984
|
+
return;
|
|
595985
|
+
}
|
|
595986
|
+
reject(
|
|
595987
|
+
new Error(
|
|
595988
|
+
(stderr || stdout || `elevated command exited with ${code8}`).trim().slice(0, 500)
|
|
595989
|
+
)
|
|
595990
|
+
);
|
|
595991
|
+
});
|
|
595992
|
+
onChildError(child, (err) => reject(err));
|
|
595993
|
+
})
|
|
595994
|
+
);
|
|
595995
|
+
} catch (err) {
|
|
595996
|
+
renderWarning(
|
|
595997
|
+
`Elevated command failed: ${err instanceof Error ? err.message : String(err)}`
|
|
595998
|
+
);
|
|
595999
|
+
}
|
|
595266
596000
|
}
|
|
595267
596001
|
async function ensureVoiceDeps(ctx3) {
|
|
595268
596002
|
try {
|
|
@@ -598581,6 +599315,10 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
|
|
|
598581
599315
|
return "handled";
|
|
598582
599316
|
}
|
|
598583
599317
|
case "cohere": {
|
|
599318
|
+
if (arg === "status" || arg === "stats") {
|
|
599319
|
+
await showCohereStatus(ctx3);
|
|
599320
|
+
return "handled";
|
|
599321
|
+
}
|
|
598584
599322
|
await showCohereDashboard(ctx3);
|
|
598585
599323
|
return "handled";
|
|
598586
599324
|
}
|
|
@@ -599324,11 +600062,16 @@ sleep 1
|
|
|
599324
600062
|
renderInfo("No active sponsorship. Run /sponsor to start.");
|
|
599325
600063
|
return "handled";
|
|
599326
600064
|
}
|
|
600065
|
+
const dashboardGw = ctx3.getExposeGateway?.();
|
|
600066
|
+
if (existingConfig.status === "active" && dashboardGw && "setSponsorLimits" in dashboardGw) {
|
|
600067
|
+
dashboardGw.setSponsorLimits(existingConfig.rateLimits);
|
|
600068
|
+
}
|
|
599327
600069
|
const action = await showSponsorDashboard2(
|
|
599328
600070
|
existingConfig,
|
|
599329
600071
|
projectDir2,
|
|
599330
600072
|
sponsorRl,
|
|
599331
|
-
ctx3.availableContentRows?.()
|
|
600073
|
+
ctx3.availableContentRows?.(),
|
|
600074
|
+
sponsorUsageFromGateway(dashboardGw)
|
|
599332
600075
|
);
|
|
599333
600076
|
switch (action) {
|
|
599334
600077
|
case "modify":
|
|
@@ -599355,6 +600098,9 @@ sleep 1
|
|
|
599355
600098
|
existingConfig.status = "active";
|
|
599356
600099
|
saveSponsorConfig2(projectDir2, existingConfig);
|
|
599357
600100
|
const resumeGw = ctx3.getExposeGateway?.();
|
|
600101
|
+
if (resumeGw && "setSponsorLimits" in resumeGw) {
|
|
600102
|
+
resumeGw.setSponsorLimits(existingConfig.rateLimits);
|
|
600103
|
+
}
|
|
599358
600104
|
if (resumeGw?.tunnelUrl) {
|
|
599359
600105
|
const resumePayload = {
|
|
599360
600106
|
name: existingConfig.header?.message || "Omnius Sponsor",
|
|
@@ -603263,15 +604009,65 @@ async function showHelpMenu(ctx3) {
|
|
|
603263
604009
|
}
|
|
603264
604010
|
}
|
|
603265
604011
|
}
|
|
603266
|
-
|
|
603267
|
-
|
|
603268
|
-
|
|
604012
|
+
function emptyCohereStats(isActive = false) {
|
|
604013
|
+
return {
|
|
604014
|
+
status: isActive ? "active" : "inactive",
|
|
604015
|
+
active: isActive,
|
|
604016
|
+
daemonPid: 0,
|
|
604017
|
+
uptimeSec: 0,
|
|
604018
|
+
lastQueryAt: 0,
|
|
604019
|
+
queriesReceived: 0,
|
|
603269
604020
|
queriesAnswered: 0,
|
|
604021
|
+
queriesErrors: 0,
|
|
603270
604022
|
queriesSent: 0,
|
|
603271
|
-
|
|
603272
|
-
|
|
604023
|
+
avgLatencyMs: 0,
|
|
604024
|
+
bytesIn: 0,
|
|
604025
|
+
bytesOut: 0,
|
|
604026
|
+
modelsUsed: {},
|
|
604027
|
+
peersServed: {},
|
|
604028
|
+
allowedModels: null
|
|
603273
604029
|
};
|
|
603274
|
-
|
|
604030
|
+
}
|
|
604031
|
+
function numberField(value2) {
|
|
604032
|
+
const n2 = Number(value2);
|
|
604033
|
+
return Number.isFinite(n2) && n2 > 0 ? Math.floor(n2) : 0;
|
|
604034
|
+
}
|
|
604035
|
+
function mapNumberRecord(value2) {
|
|
604036
|
+
if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) return {};
|
|
604037
|
+
const out = {};
|
|
604038
|
+
for (const [key, raw] of Object.entries(value2)) {
|
|
604039
|
+
out[key] = numberField(raw);
|
|
604040
|
+
}
|
|
604041
|
+
return out;
|
|
604042
|
+
}
|
|
604043
|
+
function parseCohereStatsOutput(output, isActive = false) {
|
|
604044
|
+
try {
|
|
604045
|
+
const parsed = JSON.parse(output);
|
|
604046
|
+
const active = typeof parsed.active === "boolean" ? parsed.active : String(parsed.status ?? "").toLowerCase() === "active";
|
|
604047
|
+
return {
|
|
604048
|
+
status: active ? "active" : "inactive",
|
|
604049
|
+
active,
|
|
604050
|
+
daemonPid: numberField(parsed.daemonPid),
|
|
604051
|
+
uptimeSec: numberField(parsed.uptimeSec),
|
|
604052
|
+
lastQueryAt: numberField(parsed.lastQueryAt),
|
|
604053
|
+
queriesReceived: numberField(parsed.queriesReceived),
|
|
604054
|
+
queriesAnswered: numberField(parsed.queriesAnswered),
|
|
604055
|
+
queriesErrors: numberField(parsed.queriesErrors),
|
|
604056
|
+
queriesSent: numberField(parsed.queriesSent),
|
|
604057
|
+
avgLatencyMs: numberField(parsed.avgLatencyMs),
|
|
604058
|
+
bytesIn: numberField(parsed.bytesIn),
|
|
604059
|
+
bytesOut: numberField(parsed.bytesOut),
|
|
604060
|
+
modelsUsed: mapNumberRecord(parsed.modelsUsed),
|
|
604061
|
+
peersServed: mapNumberRecord(parsed.peersServed),
|
|
604062
|
+
allowedModels: Array.isArray(parsed.allowedModels) ? parsed.allowedModels.map(String) : null
|
|
604063
|
+
};
|
|
604064
|
+
} catch {
|
|
604065
|
+
return emptyCohereStats(isActive);
|
|
604066
|
+
}
|
|
604067
|
+
}
|
|
604068
|
+
async function fetchCohereDashboardState(ctx3) {
|
|
604069
|
+
const isActive = ctx3.isCohere?.() ?? false;
|
|
604070
|
+
const state = { stats: emptyCohereStats(isActive), modelList: [] };
|
|
603275
604071
|
try {
|
|
603276
604072
|
const nexus = new NexusTool(ctx3.repoRoot);
|
|
603277
604073
|
try {
|
|
@@ -603283,29 +604079,52 @@ async function showCohereDashboard(ctx3) {
|
|
|
603283
604079
|
} catch {
|
|
603284
604080
|
}
|
|
603285
604081
|
try {
|
|
603286
|
-
const r2 = await nexus.execute({ action: "cohere_stats" });
|
|
603287
|
-
if (r2.success)
|
|
603288
|
-
try {
|
|
603289
|
-
const d2 = JSON.parse(r2.output);
|
|
603290
|
-
Object.assign(stats, d2);
|
|
603291
|
-
} catch {
|
|
603292
|
-
}
|
|
603293
|
-
}
|
|
604082
|
+
const r2 = await nexus.execute({ action: "cohere_stats", format: "json" });
|
|
604083
|
+
if (r2.success) state.stats = parseCohereStatsOutput(r2.output, isActive);
|
|
603294
604084
|
} catch {
|
|
603295
604085
|
}
|
|
603296
604086
|
try {
|
|
603297
604087
|
const r2 = await nexus.execute({ action: "cohere_list_models" });
|
|
603298
604088
|
if (r2.success) {
|
|
603299
604089
|
try {
|
|
603300
|
-
modelList = JSON.parse(r2.output).models || [];
|
|
604090
|
+
state.modelList = JSON.parse(r2.output).models || [];
|
|
603301
604091
|
} catch {
|
|
603302
|
-
modelList = r2.output.split("\n").
|
|
604092
|
+
state.modelList = r2.output.split("\n").map((l2) => l2.trim()).filter(Boolean);
|
|
603303
604093
|
}
|
|
603304
604094
|
}
|
|
603305
604095
|
} catch {
|
|
603306
604096
|
}
|
|
603307
604097
|
} catch {
|
|
603308
604098
|
}
|
|
604099
|
+
return state;
|
|
604100
|
+
}
|
|
604101
|
+
function cohereStatusLines(stats, modelList) {
|
|
604102
|
+
const modelEntries = Object.entries(stats.modelsUsed).sort((a2, b) => b[1] - a2[1]);
|
|
604103
|
+
const peerEntries = Object.entries(stats.peersServed).sort((a2, b) => b[1] - a2[1]);
|
|
604104
|
+
const uptime2 = stats.uptimeSec < 60 ? `${stats.uptimeSec}s` : stats.uptimeSec < 3600 ? `${Math.floor(stats.uptimeSec / 60)}m ${stats.uptimeSec % 60}s` : `${Math.floor(stats.uptimeSec / 3600)}h ${Math.floor(stats.uptimeSec % 3600 / 60)}m`;
|
|
604105
|
+
return [
|
|
604106
|
+
c3.bold("COHERE Status"),
|
|
604107
|
+
`Status: ${stats.active ? c3.green("ACTIVE") : c3.dim("inactive")}`,
|
|
604108
|
+
`Daemon: ${stats.daemonPid ? `pid ${stats.daemonPid}` : "not connected"} · uptime ${uptime2}`,
|
|
604109
|
+
`Last query: ${stats.lastQueryAt ? new Date(stats.lastQueryAt).toISOString() : "never"}`,
|
|
604110
|
+
"",
|
|
604111
|
+
formatUsageBar({ label: "Answered", used: stats.queriesAnswered, total: Math.max(1, stats.queriesReceived), width: 18 }),
|
|
604112
|
+
formatUsageBar({ label: "Errors", used: stats.queriesErrors, total: Math.max(1, stats.queriesReceived), width: 18 }),
|
|
604113
|
+
`Sent out: ${stats.queriesSent} · avg latency ${stats.avgLatencyMs}ms`,
|
|
604114
|
+
`Data: in ${formatFileSize(stats.bytesIn)} · out ${formatFileSize(stats.bytesOut)}`,
|
|
604115
|
+
"",
|
|
604116
|
+
`Models exposed: ${modelList.length}`,
|
|
604117
|
+
`Allowlist: ${stats.allowedModels ? stats.allowedModels.join(", ") || "(empty)" : "all downloaded models"}`,
|
|
604118
|
+
`Top models: ${modelEntries.length ? modelEntries.slice(0, 5).map(([m2, n2]) => `${m2} (${n2})`).join(", ") : "none yet"}`,
|
|
604119
|
+
`Peers served: ${peerEntries.length ? peerEntries.slice(0, 5).map(([p2, n2]) => `${p2.slice(0, 20)} (${n2})`).join(", ") : "none yet"}`
|
|
604120
|
+
];
|
|
604121
|
+
}
|
|
604122
|
+
async function showCohereStatus(ctx3) {
|
|
604123
|
+
const { stats, modelList } = await fetchCohereDashboardState(ctx3);
|
|
604124
|
+
safeLog(cohereStatusLines(stats, modelList).join("\n"));
|
|
604125
|
+
}
|
|
604126
|
+
async function showCohereDashboard(ctx3) {
|
|
604127
|
+
let { stats, modelList } = await fetchCohereDashboardState(ctx3);
|
|
603309
604128
|
while (true) {
|
|
603310
604129
|
const currentActive = ctx3.isCohere?.() ?? false;
|
|
603311
604130
|
const toggleLabel = currentActive ? "Disable COHERE" : "Enable COHERE";
|
|
@@ -603322,7 +604141,7 @@ async function showCohereDashboard(ctx3) {
|
|
|
603322
604141
|
{
|
|
603323
604142
|
key: "stats",
|
|
603324
604143
|
label: "Network Stats",
|
|
603325
|
-
detail: `${stats.queriesAnswered} answered · ${stats.queriesSent} sent · ${stats.
|
|
604144
|
+
detail: `${stats.queriesAnswered} answered · ${stats.queriesSent} sent · ${stats.queriesErrors} errors`
|
|
603326
604145
|
},
|
|
603327
604146
|
{
|
|
603328
604147
|
key: "identity",
|
|
@@ -603375,11 +604194,11 @@ async function showCohereDashboard(ctx3) {
|
|
|
603375
604194
|
},
|
|
603376
604195
|
{
|
|
603377
604196
|
key: "insights",
|
|
603378
|
-
label: `
|
|
604197
|
+
label: `Avg latency: ${c3.bold(String(stats.avgLatencyMs || 0))}ms`
|
|
603379
604198
|
},
|
|
603380
604199
|
{
|
|
603381
604200
|
key: "peers",
|
|
603382
|
-
label: `Peers
|
|
604201
|
+
label: `Peers served: ${c3.bold(String(Object.keys(stats.peersServed || {}).length))}`
|
|
603383
604202
|
},
|
|
603384
604203
|
{ key: "hdr2", label: selectColors.dim("─── Actions ───") },
|
|
603385
604204
|
{
|
|
@@ -603397,17 +604216,9 @@ async function showCohereDashboard(ctx3) {
|
|
|
603397
604216
|
availableRows: ctx3.availableContentRows?.()
|
|
603398
604217
|
});
|
|
603399
604218
|
if (statResult.key === "refresh") {
|
|
603400
|
-
|
|
603401
|
-
|
|
603402
|
-
|
|
603403
|
-
if (r2.success) {
|
|
603404
|
-
try {
|
|
603405
|
-
Object.assign(stats, JSON.parse(r2.output));
|
|
603406
|
-
} catch {
|
|
603407
|
-
}
|
|
603408
|
-
}
|
|
603409
|
-
} catch {
|
|
603410
|
-
}
|
|
604219
|
+
const refreshed = await fetchCohereDashboardState(ctx3);
|
|
604220
|
+
stats = refreshed.stats;
|
|
604221
|
+
modelList = refreshed.modelList;
|
|
603411
604222
|
}
|
|
603412
604223
|
continue;
|
|
603413
604224
|
}
|
|
@@ -606229,14 +607040,23 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
606229
607040
|
renderInfo("Updating Ollama to the latest version...");
|
|
606230
607041
|
}
|
|
606231
607042
|
try {
|
|
606232
|
-
|
|
607043
|
+
const updated = await withTransientTerminalPrivilegePrompt(
|
|
607044
|
+
ctx3,
|
|
607045
|
+
"Updating Ollama may need administrator privileges.",
|
|
607046
|
+
() => doUpdateOllama()
|
|
607047
|
+
);
|
|
607048
|
+
if (updated) {
|
|
606233
607049
|
renderInfo("Ollama updated successfully.");
|
|
606234
607050
|
try {
|
|
606235
607051
|
const { runElevatedCommand: runElevatedCommand2 } = await Promise.resolve().then(() => (init_setup(), setup_exports));
|
|
606236
|
-
|
|
606237
|
-
|
|
606238
|
-
|
|
606239
|
-
|
|
607052
|
+
await withTransientTerminalPrivilegePrompt(
|
|
607053
|
+
ctx3,
|
|
607054
|
+
"Restarting the Ollama service may need administrator privileges.",
|
|
607055
|
+
() => runElevatedCommand2("systemctl restart ollama", {
|
|
607056
|
+
timeoutMs: 1e4,
|
|
607057
|
+
swallowErrors: true
|
|
607058
|
+
})
|
|
607059
|
+
);
|
|
606240
607060
|
} catch {
|
|
606241
607061
|
}
|
|
606242
607062
|
} else {
|
|
@@ -606293,13 +607113,6 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
606293
607113
|
"⣀",
|
|
606294
607114
|
"⡀"
|
|
606295
607115
|
];
|
|
606296
|
-
const safeWrite = (text) => {
|
|
606297
|
-
if (isNeovimActive()) {
|
|
606298
|
-
writeToNeovimOutput(text);
|
|
606299
|
-
} else {
|
|
606300
|
-
process.stdout.write(text);
|
|
606301
|
-
}
|
|
606302
|
-
};
|
|
606303
607116
|
const PROGRESS_BLOCKS = [
|
|
606304
607117
|
" ",
|
|
606305
607118
|
"⠁",
|
|
@@ -606481,9 +607294,9 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
606481
607294
|
(async () => {
|
|
606482
607295
|
try {
|
|
606483
607296
|
const prefix = await execA("npm prefix -g", { timeout: 5e3 });
|
|
606484
|
-
const { accessSync, constants } = await import("node:fs");
|
|
607297
|
+
const { accessSync: accessSync2, constants: constants2 } = await import("node:fs");
|
|
606485
607298
|
try {
|
|
606486
|
-
|
|
607299
|
+
accessSync2(prefix, constants2.W_OK);
|
|
606487
607300
|
return false;
|
|
606488
607301
|
} catch {
|
|
606489
607302
|
return true;
|
|
@@ -606723,7 +607536,16 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
606723
607536
|
const globalModules = prefix.endsWith("/lib") ? prefix + "/node_modules" : prefix + "/lib/node_modules";
|
|
606724
607537
|
const { join: pj3 } = await import("node:path");
|
|
606725
607538
|
const omniusPkgDir = pj3(globalModules, "omnius");
|
|
606726
|
-
|
|
607539
|
+
if (needsSudo && !await acquireSudoCredentials(
|
|
607540
|
+
ctx3,
|
|
607541
|
+
`Updating ${depName} in the global Omnius install requires administrator privileges.`
|
|
607542
|
+
)) {
|
|
607543
|
+
renderWarning(
|
|
607544
|
+
"Could not acquire sudo credentials. Try: sudo npm i -g omnius"
|
|
607545
|
+
);
|
|
607546
|
+
return;
|
|
607547
|
+
}
|
|
607548
|
+
const sudoPrefix2 = needsSudo ? "sudo -n " : "";
|
|
606727
607549
|
const cmd = `${sudoPrefix2}npm install ${depName}@latest --prefer-online --save --prefix "${omniusPkgDir}" 2>&1`;
|
|
606728
607550
|
const result = await execA(cmd, { timeout: 6e4 }).catch(
|
|
606729
607551
|
(e2) => e2.message
|
|
@@ -606743,14 +607565,23 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
606743
607565
|
renderInfo("Updating Ollama...");
|
|
606744
607566
|
try {
|
|
606745
607567
|
const { updateOllama: updateOllama2 } = await Promise.resolve().then(() => (init_setup(), setup_exports));
|
|
606746
|
-
|
|
607568
|
+
const updated = await withTransientTerminalPrivilegePrompt(
|
|
607569
|
+
ctx3,
|
|
607570
|
+
"Updating Ollama may need administrator privileges.",
|
|
607571
|
+
() => updateOllama2()
|
|
607572
|
+
);
|
|
607573
|
+
if (updated) {
|
|
606747
607574
|
renderInfo(`Ollama updated successfully!`);
|
|
606748
607575
|
try {
|
|
606749
|
-
const {
|
|
606750
|
-
|
|
606751
|
-
|
|
606752
|
-
|
|
606753
|
-
|
|
607576
|
+
const { runElevatedCommand: runElevatedCommand2 } = await Promise.resolve().then(() => (init_setup(), setup_exports));
|
|
607577
|
+
await withTransientTerminalPrivilegePrompt(
|
|
607578
|
+
ctx3,
|
|
607579
|
+
"Restarting the Ollama service may need administrator privileges.",
|
|
607580
|
+
() => runElevatedCommand2("systemctl restart ollama", {
|
|
607581
|
+
timeoutMs: 1e4,
|
|
607582
|
+
swallowErrors: true
|
|
607583
|
+
})
|
|
607584
|
+
);
|
|
606754
607585
|
} catch {
|
|
606755
607586
|
}
|
|
606756
607587
|
} else {
|
|
@@ -606780,7 +607611,7 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
606780
607611
|
return compact3.slice(0, Math.max(1, max - 1)).trimEnd() + "…";
|
|
606781
607612
|
};
|
|
606782
607613
|
const summarizeInstallCommand = (cmd) => {
|
|
606783
|
-
const cleaned = cmd.replace(/^\s*sudo
|
|
607614
|
+
const cleaned = cmd.replace(/^\s*sudo(?:\s+-n)?\s+/, "").replace(/\s+2>\/dev\/null/g, "").replace(/\s+\|\|\s+true\s*$/g, "").replace(/\s+/g, " ").trim();
|
|
606784
607615
|
if (/^npm install -g omnius@/i.test(cleaned)) {
|
|
606785
607616
|
const match = cleaned.match(/omnius@([^\s]+)/i);
|
|
606786
607617
|
return `installing omnius@${match?.[1] ?? "latest"}`;
|
|
@@ -606912,17 +607743,11 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
606912
607743
|
installOverlay.stop("Requesting permissions...");
|
|
606913
607744
|
await new Promise((r2) => setTimeout(r2, 300));
|
|
606914
607745
|
installOverlay.dismiss();
|
|
606915
|
-
|
|
606916
|
-
|
|
606917
|
-
|
|
606918
|
-
|
|
606919
|
-
|
|
606920
|
-
const sudoResult = spawnSync8("sudo", ["-v"], {
|
|
606921
|
-
stdio: "inherit",
|
|
606922
|
-
timeout: 6e4
|
|
606923
|
-
});
|
|
606924
|
-
if (sudoResult.status !== 0) throw new Error("sudo failed");
|
|
606925
|
-
} catch {
|
|
607746
|
+
const sudoReady = await acquireSudoCredentials(
|
|
607747
|
+
ctx3,
|
|
607748
|
+
"The global npm directory requires elevated permissions for this update."
|
|
607749
|
+
);
|
|
607750
|
+
if (!sudoReady) {
|
|
606926
607751
|
renderWarning(
|
|
606927
607752
|
"Could not acquire sudo credentials. Try: sudo npm i -g omnius"
|
|
606928
607753
|
);
|
|
@@ -606931,7 +607756,8 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
606931
607756
|
const installOverlay2 = startInstallOverlay(targetVersion);
|
|
606932
607757
|
Object.assign(installOverlay, installOverlay2);
|
|
606933
607758
|
}
|
|
606934
|
-
const sudoPrefix = needsSudo ? "sudo " : "";
|
|
607759
|
+
const sudoPrefix = needsSudo ? "sudo -n " : "";
|
|
607760
|
+
const manualSudoPrefix = needsSudo ? "sudo " : "";
|
|
606935
607761
|
let primaryUpdated = false;
|
|
606936
607762
|
let depsUpdated = false;
|
|
606937
607763
|
const totalPhases = (doPackage && info ? 5 : 0) + (doDeps ? 5 : 0) + (doRebuild ? 3 : 0) + (doPython ? 3 : 0) + (doCloudflared ? 2 : 0) + (doOllama ? 2 : 0);
|
|
@@ -606986,7 +607812,7 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
606986
607812
|
installOverlay.stop("Install failed");
|
|
606987
607813
|
await new Promise((r2) => setTimeout(r2, 2e3));
|
|
606988
607814
|
installOverlay.dismiss();
|
|
606989
|
-
const hint = process.platform === "win32" ? `npm i -g omnius${versionSpec} (run terminal as Administrator)` : `${
|
|
607815
|
+
const hint = process.platform === "win32" ? `npm i -g omnius${versionSpec} (run terminal as Administrator)` : `${manualSudoPrefix}npm cache clean --force && ${manualSudoPrefix}npm i -g omnius${versionSpec}`;
|
|
606990
607816
|
renderWarning(
|
|
606991
607817
|
`Update failed: ${installError.slice(0, 150) || "unknown error"}`
|
|
606992
607818
|
);
|
|
@@ -607079,17 +607905,38 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
607079
607905
|
installOverlay.setPhase("Ollama");
|
|
607080
607906
|
installOverlay.setStatus("Updating Ollama...");
|
|
607081
607907
|
try {
|
|
607082
|
-
|
|
607083
|
-
|
|
607084
|
-
|
|
607085
|
-
|
|
607086
|
-
|
|
607087
|
-
|
|
607088
|
-
|
|
607089
|
-
|
|
607090
|
-
|
|
607091
|
-
|
|
607908
|
+
installOverlay.stop("Updating Ollama...");
|
|
607909
|
+
await new Promise((r2) => setTimeout(r2, 300));
|
|
607910
|
+
installOverlay.dismiss();
|
|
607911
|
+
const ollamaUpdated = await withTransientTerminalPrivilegePrompt(
|
|
607912
|
+
ctx3,
|
|
607913
|
+
"Updating Ollama may need administrator privileges.",
|
|
607914
|
+
async () => {
|
|
607915
|
+
const {
|
|
607916
|
+
updateOllama: doOllamaUpgrade,
|
|
607917
|
+
runElevatedCommand: runElevatedCommand2
|
|
607918
|
+
} = await Promise.resolve().then(() => (init_setup(), setup_exports));
|
|
607919
|
+
const ok3 = doOllamaUpgrade();
|
|
607920
|
+
if (ok3) {
|
|
607921
|
+
try {
|
|
607922
|
+
runElevatedCommand2("systemctl restart ollama", {
|
|
607923
|
+
timeoutMs: 1e4,
|
|
607924
|
+
swallowErrors: true
|
|
607925
|
+
});
|
|
607926
|
+
} catch {
|
|
607927
|
+
}
|
|
607928
|
+
}
|
|
607929
|
+
return ok3;
|
|
607092
607930
|
}
|
|
607931
|
+
);
|
|
607932
|
+
const installOverlay3 = startInstallOverlay(targetVersion);
|
|
607933
|
+
Object.assign(installOverlay, installOverlay3);
|
|
607934
|
+
installOverlay.setProgress(completedPhases, totalPhases);
|
|
607935
|
+
installOverlay.setPhase("Ollama");
|
|
607936
|
+
if (ollamaUpdated) {
|
|
607937
|
+
installOverlay.setStatus(`Ollama updated to ${ollamaUpdate.latest}`);
|
|
607938
|
+
} else {
|
|
607939
|
+
installOverlay.setStatus("Ollama update skipped/failed");
|
|
607093
607940
|
}
|
|
607094
607941
|
} catch {
|
|
607095
607942
|
}
|
|
@@ -607180,7 +608027,18 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
607180
608027
|
if (!hasPython) {
|
|
607181
608028
|
installOverlay.setStatus("Installing Python3...");
|
|
607182
608029
|
try {
|
|
607183
|
-
|
|
608030
|
+
installOverlay.stop("Installing Python3...");
|
|
608031
|
+
await new Promise((r2) => setTimeout(r2, 300));
|
|
608032
|
+
installOverlay.dismiss();
|
|
608033
|
+
await withTransientTerminalPrivilegePrompt(
|
|
608034
|
+
ctx3,
|
|
608035
|
+
"Installing Python3 may need administrator privileges.",
|
|
608036
|
+
() => ensurePython3()
|
|
608037
|
+
);
|
|
608038
|
+
const installOverlayPy = startInstallOverlay(targetVersion);
|
|
608039
|
+
Object.assign(installOverlay, installOverlayPy);
|
|
608040
|
+
installOverlay.setProgress(completedPhases, totalPhases);
|
|
608041
|
+
installOverlay.setPhase("Python");
|
|
607184
608042
|
hasPython = hasCmd("python3") || hasCmd("python");
|
|
607185
608043
|
} catch {
|
|
607186
608044
|
}
|
|
@@ -607191,7 +608049,18 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
607191
608049
|
if (hasPython && !checkPythonVenv()) {
|
|
607192
608050
|
installOverlay.setStatus("Installing python3-venv...");
|
|
607193
608051
|
try {
|
|
607194
|
-
|
|
608052
|
+
installOverlay.stop("Installing python3-venv...");
|
|
608053
|
+
await new Promise((r2) => setTimeout(r2, 300));
|
|
608054
|
+
installOverlay.dismiss();
|
|
608055
|
+
await withTransientTerminalPrivilegePrompt(
|
|
608056
|
+
ctx3,
|
|
608057
|
+
"Installing python3-venv may need administrator privileges.",
|
|
608058
|
+
() => ensurePythonVenv()
|
|
608059
|
+
);
|
|
608060
|
+
const installOverlayVenv = startInstallOverlay(targetVersion);
|
|
608061
|
+
Object.assign(installOverlay, installOverlayVenv);
|
|
608062
|
+
installOverlay.setProgress(completedPhases, totalPhases);
|
|
608063
|
+
installOverlay.setPhase("Python");
|
|
607195
608064
|
} catch {
|
|
607196
608065
|
}
|
|
607197
608066
|
}
|
|
@@ -607212,9 +608081,20 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
607212
608081
|
installOverlay.setStatus("Python packages updated");
|
|
607213
608082
|
} else {
|
|
607214
608083
|
installOverlay.setStatus("Setting up Python venv...");
|
|
607215
|
-
|
|
607216
|
-
|
|
608084
|
+
installOverlay.stop("Setting up Python dependencies...");
|
|
608085
|
+
await new Promise((r2) => setTimeout(r2, 300));
|
|
608086
|
+
installOverlay.dismiss();
|
|
608087
|
+
await withTransientTerminalPrivilegePrompt(
|
|
608088
|
+
ctx3,
|
|
608089
|
+
"Installing Python vision dependencies may need administrator privileges.",
|
|
608090
|
+
() => ensureVisionDeps(() => {
|
|
608091
|
+
})
|
|
608092
|
+
).catch(() => {
|
|
607217
608093
|
});
|
|
608094
|
+
const installOverlayVision = startInstallOverlay(targetVersion);
|
|
608095
|
+
Object.assign(installOverlay, installOverlayVision);
|
|
608096
|
+
installOverlay.setProgress(completedPhases, totalPhases);
|
|
608097
|
+
installOverlay.setPhase("Python");
|
|
607218
608098
|
installOverlay.setStatus("Python deps bootstrapped");
|
|
607219
608099
|
}
|
|
607220
608100
|
completedPhases += 3;
|
|
@@ -607232,13 +608112,33 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
607232
608112
|
}
|
|
607233
608113
|
if (!hasCf) {
|
|
607234
608114
|
installOverlay.setStatus("Installing cloudflared...");
|
|
607235
|
-
|
|
607236
|
-
|
|
607237
|
-
|
|
608115
|
+
installOverlay.stop("Installing cloudflared...");
|
|
608116
|
+
await new Promise((r2) => setTimeout(r2, 300));
|
|
608117
|
+
installOverlay.dismiss();
|
|
608118
|
+
await withTransientTerminalPrivilegePrompt(
|
|
608119
|
+
ctx3,
|
|
608120
|
+
"Installing cloudflared may need administrator privileges.",
|
|
608121
|
+
() => ensureCloudflaredBackground(() => {
|
|
608122
|
+
})
|
|
608123
|
+
).catch(() => false);
|
|
608124
|
+
const installOverlayCf = startInstallOverlay(targetVersion);
|
|
608125
|
+
Object.assign(installOverlay, installOverlayCf);
|
|
608126
|
+
installOverlay.setProgress(completedPhases, totalPhases);
|
|
608127
|
+
installOverlay.setPhase("Cloudflared");
|
|
607238
608128
|
} else {
|
|
607239
608129
|
installOverlay.setStatus("cloudflared ready");
|
|
607240
608130
|
}
|
|
607241
|
-
|
|
608131
|
+
installOverlay.setStatus("Checking transcribe-cli...");
|
|
608132
|
+
if (!hasCmd("transcribe-cli")) {
|
|
608133
|
+
await withTransientTerminalPrivilegePrompt(
|
|
608134
|
+
ctx3,
|
|
608135
|
+
"Installing transcribe-cli may need administrator privileges.",
|
|
608136
|
+
() => ensureTranscribeCliBackground()
|
|
608137
|
+
).catch(() => false);
|
|
608138
|
+
} else {
|
|
608139
|
+
await ensureTranscribeCliBackground().catch(() => false);
|
|
608140
|
+
}
|
|
608141
|
+
installOverlay.setStatus("cloudflared/transcribe checks complete");
|
|
607242
608142
|
}
|
|
607243
608143
|
if (!primaryUpdated) {
|
|
607244
608144
|
installOverlay.stop("Done — no restart needed");
|
|
@@ -607773,6 +608673,7 @@ var init_commands = __esm({
|
|
|
607773
608673
|
init_listen();
|
|
607774
608674
|
init_dist();
|
|
607775
608675
|
init_tui_select();
|
|
608676
|
+
init_usage_bars();
|
|
607776
608677
|
init_overlay_lock();
|
|
607777
608678
|
init_drop_panel();
|
|
607778
608679
|
init_memory_menu();
|
|
@@ -617483,6 +618384,13 @@ function senderKey2(entry) {
|
|
|
617483
618384
|
if (entry.role === "assistant") return entry.username || entry.speaker || "assistant";
|
|
617484
618385
|
return String(entry.fromUserId || entry.username || entry.firstName || senderLabel(entry));
|
|
617485
618386
|
}
|
|
618387
|
+
function speakerRole(entry) {
|
|
618388
|
+
if (entry.role === "assistant") return "agent_self";
|
|
618389
|
+
return entry.isBot ? "participant_bot" : "participant_human";
|
|
618390
|
+
}
|
|
618391
|
+
function identityBoundary(entry) {
|
|
618392
|
+
return speakerRole(entry) === "agent_self" ? "this message is authored by the Telegram agent itself" : "this message is authored by another Telegram participant; first-person claims belong to that participant, not the agent";
|
|
618393
|
+
}
|
|
617486
618394
|
function scopeFor(entry, options2) {
|
|
617487
618395
|
const chatType = entry.chatType || options2.chatType || "unknown";
|
|
617488
618396
|
return {
|
|
@@ -617496,7 +618404,7 @@ function senderFor(entry) {
|
|
|
617496
618404
|
id: senderKey2(entry),
|
|
617497
618405
|
username: entry.username,
|
|
617498
618406
|
displayName: senderLabel(entry),
|
|
617499
|
-
isBot: entry.role === "assistant"
|
|
618407
|
+
isBot: entry.role === "assistant" || entry.isBot === true
|
|
617500
618408
|
};
|
|
617501
618409
|
}
|
|
617502
618410
|
function messageIdFor(entry, sessionKey) {
|
|
@@ -617535,7 +618443,11 @@ function contentFor(entry, sessionKey, options2) {
|
|
|
617535
618443
|
`message_id: ${messageIdFor(entry, sessionKey)}`,
|
|
617536
618444
|
entry.messageThreadId != null ? `thread_id: ${entry.messageThreadId}` : "",
|
|
617537
618445
|
entry.replyToMessageId != null ? `reply_to_message_id: ${entry.replyToMessageId}` : "",
|
|
618446
|
+
`actor_key: ${senderKey2(entry)}`,
|
|
617538
618447
|
`speaker: ${senderLabel(entry)}`,
|
|
618448
|
+
`speaker_role: ${speakerRole(entry)}`,
|
|
618449
|
+
`identity_boundary: ${identityBoundary(entry)}`,
|
|
618450
|
+
entry.replyContext?.sender ? `reply_sender: ${entry.replyContext.sender.username || entry.replyContext.sender.firstName || entry.replyContext.sender.id || "unknown"} [${entry.replyContext.sender.isBot ? "participant_bot" : "participant_human"}]` : "",
|
|
617539
618451
|
entry.mode ? `mode: ${entry.mode}` : "",
|
|
617540
618452
|
entry.mediaSummary ? `media: ${compact(entry.mediaSummary, 260)}` : "",
|
|
617541
618453
|
"",
|
|
@@ -617559,7 +618471,11 @@ function metadataFor(entry, sessionKey, options2) {
|
|
|
617559
618471
|
username: entry.username,
|
|
617560
618472
|
firstName: entry.firstName,
|
|
617561
618473
|
fromUserId: entry.fromUserId,
|
|
618474
|
+
isBot: entry.isBot,
|
|
617562
618475
|
speaker: senderLabel(entry),
|
|
618476
|
+
actorKey: senderKey2(entry),
|
|
618477
|
+
speakerRole: speakerRole(entry),
|
|
618478
|
+
identityBoundary: identityBoundary(entry),
|
|
617563
618479
|
mediaSummary: entry.mediaSummary
|
|
617564
618480
|
}
|
|
617565
618481
|
};
|
|
@@ -617810,12 +618726,14 @@ function episodeLine(episode) {
|
|
|
617810
618726
|
const meta = episode.metadata;
|
|
617811
618727
|
const telegram = meta?.telegram;
|
|
617812
618728
|
const speaker = clean4(telegram?.speaker || telegram?.username || "unknown", 80);
|
|
618729
|
+
const role = clean4(telegram?.speakerRole || "participant_human", 40);
|
|
617813
618730
|
const messageId = telegram?.messageId == null ? "unknown" : String(telegram.messageId);
|
|
617814
618731
|
const replyTo = telegram?.replyToMessageId == null ? "" : ` reply_to=${telegram.replyToMessageId}`;
|
|
617815
618732
|
return [
|
|
617816
618733
|
`episode_id=${episode.id}`,
|
|
617817
618734
|
`message_id=${messageId}${replyTo}`,
|
|
617818
618735
|
`speaker=${speaker}`,
|
|
618736
|
+
`speaker_role=${role}`,
|
|
617819
618737
|
`modality=${episode.modality}`,
|
|
617820
618738
|
`content=${clean4(episode.content, 700)}`
|
|
617821
618739
|
].join(" | ");
|
|
@@ -617836,6 +618754,9 @@ function buildTelegramReflectionExtractionPrompt(options2) {
|
|
|
617836
618754
|
"- Use only the scoped Telegram corpus, graph nodes, graph edges, and source anchors below.",
|
|
617837
618755
|
"- Preserve message_id and episode_id anchors on every item when possible.",
|
|
617838
618756
|
"- Do not infer identity from a face, voice, or name unless the corpus explicitly says it.",
|
|
618757
|
+
"- speaker_role=agent_self is the Telegram agent; speaker_role=participant_human or participant_bot is another chat participant.",
|
|
618758
|
+
"- Do not assign participant first-person claims, preferences, names, or self-descriptions to the agent/self unless the source episode has speaker_role=agent_self.",
|
|
618759
|
+
"- Replies between non-agent participants are social context and relationship evidence, not direct agent self-reflection.",
|
|
617839
618760
|
"- Private DM followups may be proposed but must not be framed as already sent.",
|
|
617840
618761
|
"- same_group followups must be concise, low-intrusion, and anchored to a source message id.",
|
|
617841
618762
|
"- If a category has no evidence, return an empty array for that category.",
|
|
@@ -618253,6 +619174,8 @@ function formatTelegramSocialStateContext(state, input) {
|
|
|
618253
619174
|
const replyKey = input.replySender ? telegramSocialActorKey(input.replySender) : void 0;
|
|
618254
619175
|
const thread = state.threads[telegramSocialThreadKey(input)];
|
|
618255
619176
|
const participant = state.participants[senderKey3];
|
|
619177
|
+
const senderIdentity = selfKey && senderKey3 === selfKey ? "agent_self" : "participant";
|
|
619178
|
+
const replyIdentity = replyKey ? selfKey && replyKey === selfKey ? "agent_self" : "participant" : "none";
|
|
618256
619179
|
const relevantKeys = new Set([senderKey3, selfKey, replyKey].filter(Boolean));
|
|
618257
619180
|
const edges = state.relationships.filter((edge) => relevantKeys.has(edge.fromKey) || relevantKeys.has(edge.toKey)).sort((a2, b) => b.lastSeenAt - a2.lastSeenAt).slice(0, limit);
|
|
618258
619181
|
const outcomes = state.outcomes.filter((outcome) => outcome.senderKey === senderKey3 || outcome.chatId === String(input.chatId)).sort((a2, b) => b.ts - a2.ts).slice(0, limit);
|
|
@@ -618261,6 +619184,8 @@ function formatTelegramSocialStateContext(state, input) {
|
|
|
618261
619184
|
const preferences = preferenceLines(state.preferences[senderKey3]);
|
|
618262
619185
|
return [
|
|
618263
619186
|
"### Telegram Structured Social State",
|
|
619187
|
+
selfKey ? `Agent self node: ${selfKey}` : "Agent self node: unknown",
|
|
619188
|
+
`Identity boundary: the agent is the self node only. Current actor ${senderKey3} is ${senderIdentity}; reply target ${replyKey ?? "none"} is ${replyIdentity}. Participant first-person claims belong to their actor node, not the agent, unless that actor is the self node.`,
|
|
618264
619189
|
`Current actor node: ${senderKey3} [${participant?.actorKind || telegramSocialActorKind(input)}] messages=${participant?.messageCount ?? 0}${participant?.lastText ? ` last=${jsonLine(participant.lastText, 140)}` : ""}`,
|
|
618265
619190
|
thread ? `Active channel/thread: ${thread.key}; messages=${thread.messageCount}; participants=${thread.participantKeys.slice(-8).join(", ") || "none"}; last_outcomes=${thread.lastOutcomeIds.slice(-5).join(", ") || "none"}` : "",
|
|
618266
619191
|
preferences.length ? `Relevant preference vector for ${senderKey3}:
|
|
@@ -624918,6 +625843,7 @@ ${lines.join("\n")}`);
|
|
|
624918
625843
|
"Classify the live scenario by inference from the full context. Do not use a fixed taxonomy, keyword list, or preset scenario enum.",
|
|
624919
625844
|
"Create a situation-specific scenario_id and scenario_label, then summarize the active state loop that should govern the later attention decision.",
|
|
624920
625845
|
"Use the persona docs below as binding behavioral guidance.",
|
|
625846
|
+
"Maintain the Telegram identity boundary: the agent is only the bot/self actor. Other users and peer bots replying to each other are participants; their first-person claims are not the agent's identity or self-reflection.",
|
|
624921
625847
|
"Return JSON only. No markdown. No <think> tags.",
|
|
624922
625848
|
"",
|
|
624923
625849
|
'Schema: {"silent_disposition":"what happens silently with this message","mental_note":"concise observation of the turn","memory_note":"what scoped memory should retain or connect","relationship_note":"relationship/thread implication","procedure_note":"active tree/branch/abort implication","voice_note":"final voice implication if a reply happens","scenario_note":"identified scenario and transition state","scenario_id":"dynamic inferred scenario id","scenario_label":"human readable dynamic scenario label","scenario_confidence":0.0-1.0,"scenario_objective":"current scenario objective","scenario_state_loop":"state loop to maintain until transition"}',
|
|
@@ -661497,6 +662423,9 @@ Log: ${nexusLogPath}`)
|
|
|
661497
662423
|
statusBar.fillContentArea();
|
|
661498
662424
|
statusBar.refreshHeaderContent();
|
|
661499
662425
|
},
|
|
662426
|
+
refreshDisplay() {
|
|
662427
|
+
statusBar.refreshDisplay();
|
|
662428
|
+
},
|
|
661500
662429
|
exit() {
|
|
661501
662430
|
if (reminderDispatchTimer) {
|
|
661502
662431
|
clearInterval(reminderDispatchTimer);
|