open-agents-ai 0.103.50 → 0.103.52
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 +328 -23
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13579,9 +13579,19 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13579
13579
|
}
|
|
13580
13580
|
}
|
|
13581
13581
|
async sendDaemonCmd(action, args, timeoutMs = 15e3) {
|
|
13582
|
-
|
|
13583
|
-
if (!pid)
|
|
13584
|
-
|
|
13582
|
+
let pid = this.getDaemonPid();
|
|
13583
|
+
if (!pid) {
|
|
13584
|
+
try {
|
|
13585
|
+
await this.doConnect({
|
|
13586
|
+
agent_name: "open-agents-node",
|
|
13587
|
+
agent_type: "general"
|
|
13588
|
+
});
|
|
13589
|
+
pid = this.getDaemonPid();
|
|
13590
|
+
} catch {
|
|
13591
|
+
}
|
|
13592
|
+
if (!pid)
|
|
13593
|
+
throw new Error("Nexus daemon not running. Use action 'connect' first.");
|
|
13594
|
+
}
|
|
13585
13595
|
const cmdId = randomBytes6(8).toString("hex");
|
|
13586
13596
|
const cmdFile = join30(this.nexusDir, "cmd.json");
|
|
13587
13597
|
const respFile = join30(this.nexusDir, "resp.json");
|
|
@@ -20732,11 +20742,13 @@ var NexusAgenticBackend;
|
|
|
20732
20742
|
var init_nexusBackend = __esm({
|
|
20733
20743
|
"packages/orchestrator/dist/nexusBackend.js"() {
|
|
20734
20744
|
"use strict";
|
|
20735
|
-
NexusAgenticBackend = class {
|
|
20745
|
+
NexusAgenticBackend = class _NexusAgenticBackend {
|
|
20736
20746
|
sendFn;
|
|
20737
20747
|
model;
|
|
20738
20748
|
targetPeer;
|
|
20739
20749
|
authKey;
|
|
20750
|
+
consecutiveFailures = 0;
|
|
20751
|
+
static MAX_CONSECUTIVE_FAILURES = 3;
|
|
20740
20752
|
constructor(sendFn, model, targetPeer, authKey) {
|
|
20741
20753
|
this.sendFn = sendFn;
|
|
20742
20754
|
this.model = model;
|
|
@@ -20744,6 +20756,11 @@ var init_nexusBackend = __esm({
|
|
|
20744
20756
|
this.authKey = authKey || "";
|
|
20745
20757
|
}
|
|
20746
20758
|
async chatCompletion(request) {
|
|
20759
|
+
if (this.consecutiveFailures >= _NexusAgenticBackend.MAX_CONSECUTIVE_FAILURES) {
|
|
20760
|
+
const err = new Error(`Remote peer unreachable after ${this.consecutiveFailures} attempts. Use /endpoint to switch to a local model or reconnect.`);
|
|
20761
|
+
err.fatal = true;
|
|
20762
|
+
throw err;
|
|
20763
|
+
}
|
|
20747
20764
|
const daemonArgs = {
|
|
20748
20765
|
model: this.model,
|
|
20749
20766
|
messages: JSON.stringify(request.messages),
|
|
@@ -20757,16 +20774,25 @@ var init_nexusBackend = __esm({
|
|
|
20757
20774
|
if (this.authKey) {
|
|
20758
20775
|
daemonArgs.auth_key = this.authKey;
|
|
20759
20776
|
}
|
|
20760
|
-
|
|
20777
|
+
let rawResult;
|
|
20778
|
+
try {
|
|
20779
|
+
rawResult = await this.sendFn("remote_infer", daemonArgs, request.timeoutMs || 12e4);
|
|
20780
|
+
} catch (sendErr) {
|
|
20781
|
+
this.consecutiveFailures++;
|
|
20782
|
+
throw sendErr;
|
|
20783
|
+
}
|
|
20761
20784
|
let parsed;
|
|
20762
20785
|
try {
|
|
20763
20786
|
parsed = JSON.parse(rawResult);
|
|
20764
20787
|
} catch {
|
|
20788
|
+
this.consecutiveFailures++;
|
|
20765
20789
|
throw new Error(rawResult.slice(0, 500));
|
|
20766
20790
|
}
|
|
20767
20791
|
if (parsed.success === false) {
|
|
20792
|
+
this.consecutiveFailures++;
|
|
20768
20793
|
throw new Error(`Remote inference failed: ${parsed.output || rawResult}`);
|
|
20769
20794
|
}
|
|
20795
|
+
this.consecutiveFailures = 0;
|
|
20770
20796
|
const invokeResult = parsed.result;
|
|
20771
20797
|
let responseData = null;
|
|
20772
20798
|
if (typeof invokeResult === "string") {
|
|
@@ -28811,10 +28837,21 @@ ${this.formatConnectionInfo()}`);
|
|
|
28811
28837
|
continue;
|
|
28812
28838
|
try {
|
|
28813
28839
|
const record = JSON.parse(line);
|
|
28814
|
-
|
|
28815
|
-
|
|
28816
|
-
|
|
28840
|
+
const recInputBytes = record.inputBytes || 0;
|
|
28841
|
+
const recOutputBytes = record.outputBytes || 0;
|
|
28842
|
+
const recTotalTokens = typeof record.tokens === "number" ? record.tokens : typeof record.tokens === "object" && record.tokens ? (record.tokens.input || 0) + (record.tokens.output || 0) : 0;
|
|
28843
|
+
const totalBytes = recInputBytes + recOutputBytes;
|
|
28844
|
+
let tokIn = 0;
|
|
28845
|
+
let tokOut = 0;
|
|
28846
|
+
if (recTotalTokens > 0 && totalBytes > 0) {
|
|
28847
|
+
tokIn = Math.round(recTotalTokens * (recInputBytes / totalBytes));
|
|
28848
|
+
tokOut = recTotalTokens - tokIn;
|
|
28849
|
+
} else if (recTotalTokens > 0) {
|
|
28850
|
+
tokIn = Math.round(recTotalTokens / 2);
|
|
28851
|
+
tokOut = recTotalTokens - tokIn;
|
|
28817
28852
|
}
|
|
28853
|
+
this._stats.totalTokensIn += tokIn;
|
|
28854
|
+
this._stats.totalTokensOut += tokOut;
|
|
28818
28855
|
const peerId = record.from || record.peerId || "unknown";
|
|
28819
28856
|
const shortPeer = peerId.length > 16 ? peerId.slice(0, 16) + "..." : peerId;
|
|
28820
28857
|
let user = this._stats.users.get(shortPeer);
|
|
@@ -28833,12 +28870,10 @@ ${this.formatConnectionInfo()}`);
|
|
|
28833
28870
|
}
|
|
28834
28871
|
user.requests++;
|
|
28835
28872
|
user.lastSeen = Date.now();
|
|
28836
|
-
|
|
28837
|
-
|
|
28838
|
-
|
|
28839
|
-
|
|
28840
|
-
if (record.model || record.capability) {
|
|
28841
|
-
const modelName = record.model || record.capability.replace("inference:", "") || "unknown";
|
|
28873
|
+
user.tokensIn += tokIn;
|
|
28874
|
+
user.tokensOut += tokOut;
|
|
28875
|
+
if (record.model || record.capability || record.service) {
|
|
28876
|
+
const modelName = record.model || (record.capability || record.service || "").replace("inference:", "") || "unknown";
|
|
28842
28877
|
this._stats.modelUsage.set(modelName, (this._stats.modelUsage.get(modelName) ?? 0) + 1);
|
|
28843
28878
|
let mm = user.models.get(modelName);
|
|
28844
28879
|
if (!mm) {
|
|
@@ -28847,10 +28882,8 @@ ${this.formatConnectionInfo()}`);
|
|
|
28847
28882
|
}
|
|
28848
28883
|
mm.requests++;
|
|
28849
28884
|
mm.lastUsed = Date.now();
|
|
28850
|
-
|
|
28851
|
-
|
|
28852
|
-
mm.tokensOut += record.tokens.output || 0;
|
|
28853
|
-
}
|
|
28885
|
+
mm.tokensIn += tokIn;
|
|
28886
|
+
mm.tokensOut += tokOut;
|
|
28854
28887
|
}
|
|
28855
28888
|
} catch {
|
|
28856
28889
|
}
|
|
@@ -33836,12 +33869,12 @@ async function handleSlashCommand(input, ctx) {
|
|
|
33836
33869
|
return "handled";
|
|
33837
33870
|
}
|
|
33838
33871
|
if (arg === "status") {
|
|
33839
|
-
const
|
|
33840
|
-
if (
|
|
33841
|
-
process.stdout.write("\n" + info.stats + "\n\n");
|
|
33842
|
-
} else {
|
|
33872
|
+
const gateway = ctx.getExposeGateway?.();
|
|
33873
|
+
if (!gateway) {
|
|
33843
33874
|
renderWarning("No active expose gateway.");
|
|
33875
|
+
return "handled";
|
|
33844
33876
|
}
|
|
33877
|
+
await showExposeDashboard(gateway, ctx.rl);
|
|
33845
33878
|
return "handled";
|
|
33846
33879
|
}
|
|
33847
33880
|
if (arg === "config") {
|
|
@@ -35292,6 +35325,254 @@ async function switchModel(query, ctx, local = false) {
|
|
|
35292
35325
|
renderError(`Failed to switch model: ${err instanceof Error ? err.message : String(err)}`);
|
|
35293
35326
|
}
|
|
35294
35327
|
}
|
|
35328
|
+
function fmtDashTokens(n) {
|
|
35329
|
+
if (n < 1e3)
|
|
35330
|
+
return String(n);
|
|
35331
|
+
if (n < 1e6)
|
|
35332
|
+
return `${(n / 1e3).toFixed(1)}K`;
|
|
35333
|
+
return `${(n / 1e6).toFixed(1)}M`;
|
|
35334
|
+
}
|
|
35335
|
+
function fmtUptime(ms) {
|
|
35336
|
+
const sec = Math.floor(ms / 1e3);
|
|
35337
|
+
if (sec < 60)
|
|
35338
|
+
return `${sec}s`;
|
|
35339
|
+
if (sec < 3600)
|
|
35340
|
+
return `${Math.floor(sec / 60)}m ${sec % 60}s`;
|
|
35341
|
+
return `${Math.floor(sec / 3600)}h ${Math.floor(sec % 3600 / 60)}m`;
|
|
35342
|
+
}
|
|
35343
|
+
function getLocalSystemMetrics() {
|
|
35344
|
+
const os = __require("node:os");
|
|
35345
|
+
const cpus2 = os.cpus();
|
|
35346
|
+
const loads = os.loadavg();
|
|
35347
|
+
const totalMem = os.totalmem();
|
|
35348
|
+
const freeMem = os.freemem();
|
|
35349
|
+
const usedMem = totalMem - freeMem;
|
|
35350
|
+
const result = {
|
|
35351
|
+
cpuModel: cpus2[0]?.model?.trim() ?? "unknown",
|
|
35352
|
+
cpuCores: cpus2.length,
|
|
35353
|
+
cpuUtil: Math.min(100, Math.round(loads[0] / cpus2.length * 100)),
|
|
35354
|
+
memTotalGB: Math.round(totalMem / (1024 * 1024 * 1024) * 10) / 10,
|
|
35355
|
+
memUsedGB: Math.round(usedMem / (1024 * 1024 * 1024) * 10) / 10,
|
|
35356
|
+
memUtil: Math.round(usedMem / totalMem * 100),
|
|
35357
|
+
gpuAvailable: false,
|
|
35358
|
+
gpuName: "",
|
|
35359
|
+
gpuUtil: 0,
|
|
35360
|
+
vramUsedMB: 0,
|
|
35361
|
+
vramTotalMB: 0,
|
|
35362
|
+
vramUtil: 0
|
|
35363
|
+
};
|
|
35364
|
+
try {
|
|
35365
|
+
const { execSync: execSync29 } = __require("node:child_process");
|
|
35366
|
+
const smiOut = execSync29("nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 3e3 });
|
|
35367
|
+
const line = smiOut.trim().split("\n")[0];
|
|
35368
|
+
if (line) {
|
|
35369
|
+
const parts = line.split(",").map((s) => s.trim());
|
|
35370
|
+
result.gpuAvailable = true;
|
|
35371
|
+
result.gpuUtil = parseInt(parts[0] || "0", 10) || 0;
|
|
35372
|
+
result.vramUsedMB = parseInt(parts[1] || "0", 10) || 0;
|
|
35373
|
+
result.vramTotalMB = parseInt(parts[2] || "0", 10) || 0;
|
|
35374
|
+
result.gpuName = parts[3] || "";
|
|
35375
|
+
result.vramUtil = result.vramTotalMB > 0 ? Math.round(result.vramUsedMB / result.vramTotalMB * 100) : 0;
|
|
35376
|
+
}
|
|
35377
|
+
} catch {
|
|
35378
|
+
}
|
|
35379
|
+
return result;
|
|
35380
|
+
}
|
|
35381
|
+
async function showExposeDashboard(gateway, rl) {
|
|
35382
|
+
const stdin = process.stdin;
|
|
35383
|
+
const stdout = process.stdout;
|
|
35384
|
+
if (!stdin.isTTY) {
|
|
35385
|
+
if (typeof gateway.formatStats === "function") {
|
|
35386
|
+
stdout.write("\n" + gateway.formatStats() + "\n\n");
|
|
35387
|
+
}
|
|
35388
|
+
return;
|
|
35389
|
+
}
|
|
35390
|
+
let lastRenderedLines = 0;
|
|
35391
|
+
let refreshTimer = null;
|
|
35392
|
+
const hadRawMode = stdin.isRaw;
|
|
35393
|
+
let sysMetrics = getLocalSystemMetrics();
|
|
35394
|
+
const savedListeners = rl ? stdin.listeners("data").slice() : [];
|
|
35395
|
+
if (rl) {
|
|
35396
|
+
rl.pause();
|
|
35397
|
+
for (const fn of savedListeners)
|
|
35398
|
+
stdin.removeListener("data", fn);
|
|
35399
|
+
}
|
|
35400
|
+
stdin.setRawMode(true);
|
|
35401
|
+
stdin.resume();
|
|
35402
|
+
stdout.write("\x1B[?25l");
|
|
35403
|
+
function buildDashboard() {
|
|
35404
|
+
const s = gateway.stats ?? gateway._stats;
|
|
35405
|
+
if (!s)
|
|
35406
|
+
return [" No stats available.", "", " Press Escape or 'q' to close."];
|
|
35407
|
+
const lines = [];
|
|
35408
|
+
const now = Date.now();
|
|
35409
|
+
const uptime = fmtUptime(now - (s.startedAt || now));
|
|
35410
|
+
const statusColor = s.status === "active" ? c2.green : s.status === "error" ? c2.red : c2.yellow;
|
|
35411
|
+
lines.push("");
|
|
35412
|
+
lines.push(` ${c2.bold("Expose Dashboard")} ${statusColor("\u25CF")} ${statusColor(s.status || "unknown")} ${c2.dim(`uptime ${uptime}`)}`);
|
|
35413
|
+
lines.push(` ${c2.dim("\u2500".repeat(60))}`);
|
|
35414
|
+
const activeConns = s.activeConnections || 0;
|
|
35415
|
+
const totalReqs = s.totalRequests || 0;
|
|
35416
|
+
const errors = s.errors || 0;
|
|
35417
|
+
const tokIn = s.totalTokensIn || 0;
|
|
35418
|
+
const tokOut = s.totalTokensOut || 0;
|
|
35419
|
+
lines.push(` ${c2.cyan("Requests")} ${c2.bold(String(totalReqs))} ${c2.dim("|")} ${c2.cyan("Active")} ${activeConns > 0 ? c2.green(c2.bold(String(activeConns))) : c2.dim("0")} ${c2.dim("|")} ${c2.cyan("Errors")} ${errors > 0 ? c2.red(String(errors)) : c2.dim("0")}`);
|
|
35420
|
+
lines.push(` ${c2.cyan("Tokens")} ${c2.dim("in:")}${c2.bold(fmtDashTokens(tokIn))} ${c2.dim("out:")}${c2.bold(fmtDashTokens(tokOut))} ${c2.dim("total:")}${fmtDashTokens(tokIn + tokOut)}`);
|
|
35421
|
+
if (s.budgetTokensTotal > 0) {
|
|
35422
|
+
const pct = Math.round(s.budgetTokensRemaining / s.budgetTokensTotal * 100);
|
|
35423
|
+
const budgetColor = pct > 50 ? c2.green : pct > 20 ? c2.yellow : c2.red;
|
|
35424
|
+
const barLen = 20;
|
|
35425
|
+
const filledLen = Math.round(pct / 100 * barLen);
|
|
35426
|
+
const bar = budgetColor("\u2588".repeat(filledLen)) + c2.dim("\u2591".repeat(barLen - filledLen));
|
|
35427
|
+
lines.push(` ${c2.cyan("Budget")} ${bar} ${budgetColor(`${pct}%`)} ${c2.dim(`(${fmtDashTokens(s.budgetTokensRemaining)}/${fmtDashTokens(s.budgetTokensTotal)})`)}`);
|
|
35428
|
+
}
|
|
35429
|
+
const sys = sysMetrics;
|
|
35430
|
+
lines.push("");
|
|
35431
|
+
lines.push(` ${c2.bold("System")}`);
|
|
35432
|
+
const cpuColor = sys.cpuUtil > 80 ? c2.red : sys.cpuUtil > 50 ? c2.yellow : c2.green;
|
|
35433
|
+
const memColor = sys.memUtil > 80 ? c2.red : sys.memUtil > 50 ? c2.yellow : c2.green;
|
|
35434
|
+
lines.push(` ${c2.cyan("CPU")} ${cpuColor(sys.cpuUtil + "%")} ${c2.dim(`(${sys.cpuCores} cores, ${sys.cpuModel.slice(0, 40)})`)}`);
|
|
35435
|
+
lines.push(` ${c2.cyan("RAM")} ${memColor(sys.memUtil + "%")} ${c2.dim(`(${sys.memUsedGB}/${sys.memTotalGB} GB)`)}`);
|
|
35436
|
+
if (sys.gpuAvailable) {
|
|
35437
|
+
const gpuColor = sys.gpuUtil > 80 ? c2.red : sys.gpuUtil > 50 ? c2.yellow : c2.green;
|
|
35438
|
+
const vramColor = sys.vramUtil > 80 ? c2.red : sys.vramUtil > 50 ? c2.yellow : c2.green;
|
|
35439
|
+
lines.push(` ${c2.cyan("GPU")} ${gpuColor(sys.gpuUtil + "%")} ${c2.dim(`(${sys.gpuName.trim()})`)}`);
|
|
35440
|
+
lines.push(` ${c2.cyan("VRAM")} ${vramColor(sys.vramUtil + "%")} ${c2.dim(`(${sys.vramUsedMB}/${sys.vramTotalMB} MB)`)}`);
|
|
35441
|
+
}
|
|
35442
|
+
const modelEntries = s.modelUsage ? Array.from(s.modelUsage.entries()).filter(([m]) => !DASH_INTERNAL.has(m)) : [];
|
|
35443
|
+
if (modelEntries.length > 0) {
|
|
35444
|
+
lines.push("");
|
|
35445
|
+
lines.push(` ${c2.bold("Models")}`);
|
|
35446
|
+
for (const [model, count] of modelEntries) {
|
|
35447
|
+
let mIn = 0, mOut = 0;
|
|
35448
|
+
if (s.users) {
|
|
35449
|
+
for (const user of s.users.values()) {
|
|
35450
|
+
const mm = user.models?.get?.(model);
|
|
35451
|
+
if (mm) {
|
|
35452
|
+
mIn += mm.tokensIn || 0;
|
|
35453
|
+
mOut += mm.tokensOut || 0;
|
|
35454
|
+
}
|
|
35455
|
+
}
|
|
35456
|
+
}
|
|
35457
|
+
const bar = count > 0 ? c2.green("\u25AE".repeat(Math.min(count, 20))) : "";
|
|
35458
|
+
lines.push(` ${c2.cyan(model.padEnd(35))} ${c2.bold(String(count).padStart(4))} req ${c2.dim(`in:${fmtDashTokens(mIn).padStart(6)} out:${fmtDashTokens(mOut).padStart(6)}`)} ${bar}`);
|
|
35459
|
+
}
|
|
35460
|
+
}
|
|
35461
|
+
const users = s.users ? Array.from(s.users.values()) : [];
|
|
35462
|
+
if (users.length > 0) {
|
|
35463
|
+
lines.push("");
|
|
35464
|
+
lines.push(` ${c2.bold("Connected Peers")} (${users.length})`);
|
|
35465
|
+
for (const user of users) {
|
|
35466
|
+
const ageSec = Math.floor((now - (user.firstSeen || now)) / 1e3);
|
|
35467
|
+
const ageStr = ageSec < 60 ? `${ageSec}s` : ageSec < 3600 ? `${Math.floor(ageSec / 60)}m` : `${Math.floor(ageSec / 3600)}h${Math.floor(ageSec % 3600 / 60)}m`;
|
|
35468
|
+
const lastSec = Math.floor((now - (user.lastSeen || now)) / 1e3);
|
|
35469
|
+
const lastStr = lastSec < 5 ? c2.green("now") : lastSec < 60 ? `${lastSec}s ago` : `${Math.floor(lastSec / 60)}m ago`;
|
|
35470
|
+
const activeStr = (user.activeRequests || 0) > 0 ? c2.green(` \u25CF ${user.activeRequests} active`) : "";
|
|
35471
|
+
lines.push(` ${c2.bold(user.ip || "unknown")}${activeStr}`);
|
|
35472
|
+
lines.push(` ${c2.dim("session")} ${ageStr} ${c2.dim("last")} ${lastStr} ${c2.dim("reqs")} ${user.requests || 0} ${c2.dim("tok")} ${c2.cyan("in:")}${fmtDashTokens(user.tokensIn || 0)} ${c2.cyan("out:")}${fmtDashTokens(user.tokensOut || 0)}`);
|
|
35473
|
+
const userModels = user.models ? Array.from(user.models.entries()).filter(([m]) => !DASH_INTERNAL.has(m)) : [];
|
|
35474
|
+
for (const [m, mm] of userModels) {
|
|
35475
|
+
lines.push(` ${c2.dim("\u2514")} ${c2.cyan(m)} ${c2.dim(`${mm.requests || 0}req ${fmtDashTokens((mm.tokensIn || 0) + (mm.tokensOut || 0))}tok`)}`);
|
|
35476
|
+
}
|
|
35477
|
+
}
|
|
35478
|
+
}
|
|
35479
|
+
lines.push("");
|
|
35480
|
+
lines.push(` ${c2.dim("Press Escape or 'q' to close \u2502 Live \u25CF updates every 2s")}`);
|
|
35481
|
+
lines.push("");
|
|
35482
|
+
return lines;
|
|
35483
|
+
}
|
|
35484
|
+
function render() {
|
|
35485
|
+
sysMetrics = getLocalSystemMetrics();
|
|
35486
|
+
const lines = buildDashboard();
|
|
35487
|
+
if (lastRenderedLines > 0) {
|
|
35488
|
+
stdout.write(`\x1B[${lastRenderedLines}A`);
|
|
35489
|
+
for (let i = 0; i < lastRenderedLines; i++) {
|
|
35490
|
+
stdout.write("\x1B[2K\n");
|
|
35491
|
+
}
|
|
35492
|
+
stdout.write(`\x1B[${lastRenderedLines}A`);
|
|
35493
|
+
}
|
|
35494
|
+
stdout.write(lines.join("\n") + "\n");
|
|
35495
|
+
lastRenderedLines = lines.length;
|
|
35496
|
+
}
|
|
35497
|
+
function cleanup() {
|
|
35498
|
+
if (refreshTimer) {
|
|
35499
|
+
clearInterval(refreshTimer);
|
|
35500
|
+
refreshTimer = null;
|
|
35501
|
+
}
|
|
35502
|
+
gateway.removeListener?.("stats", onStats);
|
|
35503
|
+
if (lastRenderedLines > 0) {
|
|
35504
|
+
stdout.write(`\x1B[${lastRenderedLines}A`);
|
|
35505
|
+
for (let i = 0; i < lastRenderedLines; i++) {
|
|
35506
|
+
stdout.write("\x1B[2K\n");
|
|
35507
|
+
}
|
|
35508
|
+
stdout.write(`\x1B[${lastRenderedLines}A`);
|
|
35509
|
+
}
|
|
35510
|
+
stdout.write("\x1B[?25h");
|
|
35511
|
+
stdin.setRawMode(hadRawMode ?? false);
|
|
35512
|
+
stdin.removeListener("data", onKey);
|
|
35513
|
+
if (rl) {
|
|
35514
|
+
for (const fn of savedListeners)
|
|
35515
|
+
stdin.on("data", fn);
|
|
35516
|
+
rl.resume();
|
|
35517
|
+
}
|
|
35518
|
+
}
|
|
35519
|
+
function onStats() {
|
|
35520
|
+
render();
|
|
35521
|
+
}
|
|
35522
|
+
function onKey(chunk) {
|
|
35523
|
+
const key = chunk.toString();
|
|
35524
|
+
if (key === "\x1B" || key === "q" || key === "Q") {
|
|
35525
|
+
cleanup();
|
|
35526
|
+
return;
|
|
35527
|
+
}
|
|
35528
|
+
if (key === "") {
|
|
35529
|
+
cleanup();
|
|
35530
|
+
return;
|
|
35531
|
+
}
|
|
35532
|
+
}
|
|
35533
|
+
if (typeof gateway.on === "function") {
|
|
35534
|
+
gateway.on("stats", onStats);
|
|
35535
|
+
}
|
|
35536
|
+
refreshTimer = setInterval(render, 2e3);
|
|
35537
|
+
render();
|
|
35538
|
+
stdin.on("data", onKey);
|
|
35539
|
+
return new Promise((resolve31) => {
|
|
35540
|
+
const origCleanup = cleanup;
|
|
35541
|
+
function wrappedCleanup() {
|
|
35542
|
+
origCleanup();
|
|
35543
|
+
resolve31();
|
|
35544
|
+
}
|
|
35545
|
+
stdin.removeListener("data", onKey);
|
|
35546
|
+
function onKeyWrapped(chunk) {
|
|
35547
|
+
const key = chunk.toString();
|
|
35548
|
+
if (key === "\x1B" || key === "q" || key === "Q" || key === "") {
|
|
35549
|
+
if (refreshTimer) {
|
|
35550
|
+
clearInterval(refreshTimer);
|
|
35551
|
+
refreshTimer = null;
|
|
35552
|
+
}
|
|
35553
|
+
gateway.removeListener?.("stats", onStats);
|
|
35554
|
+
if (lastRenderedLines > 0) {
|
|
35555
|
+
stdout.write(`\x1B[${lastRenderedLines}A`);
|
|
35556
|
+
for (let i = 0; i < lastRenderedLines; i++) {
|
|
35557
|
+
stdout.write("\x1B[2K\n");
|
|
35558
|
+
}
|
|
35559
|
+
stdout.write(`\x1B[${lastRenderedLines}A`);
|
|
35560
|
+
}
|
|
35561
|
+
stdout.write("\x1B[?25h");
|
|
35562
|
+
stdin.setRawMode(hadRawMode ?? false);
|
|
35563
|
+
stdin.removeListener("data", onKeyWrapped);
|
|
35564
|
+
if (rl) {
|
|
35565
|
+
for (const fn of savedListeners)
|
|
35566
|
+
stdin.on("data", fn);
|
|
35567
|
+
rl.resume();
|
|
35568
|
+
}
|
|
35569
|
+
resolve31();
|
|
35570
|
+
}
|
|
35571
|
+
}
|
|
35572
|
+
stdin.on("data", onKeyWrapped);
|
|
35573
|
+
});
|
|
35574
|
+
}
|
|
35575
|
+
var DASH_INTERNAL;
|
|
35295
35576
|
var init_commands = __esm({
|
|
35296
35577
|
"packages/cli/dist/tui/commands.js"() {
|
|
35297
35578
|
"use strict";
|
|
@@ -35307,6 +35588,7 @@ var init_commands = __esm({
|
|
|
35307
35588
|
init_listen();
|
|
35308
35589
|
init_dist();
|
|
35309
35590
|
init_tui_select();
|
|
35591
|
+
DASH_INTERNAL = /* @__PURE__ */ new Set(["system_metrics", "__list_capabilities"]);
|
|
35310
35592
|
}
|
|
35311
35593
|
});
|
|
35312
35594
|
|
|
@@ -44207,15 +44489,34 @@ var init_status_bar = __esm({
|
|
|
44207
44489
|
}
|
|
44208
44490
|
/** Expose gateway status — shown after capability emojis */
|
|
44209
44491
|
_expose = null;
|
|
44492
|
+
/** Blink state for expose icon during active inference */
|
|
44493
|
+
_exposeBlinkOn = true;
|
|
44494
|
+
_exposeBlinkTimer = null;
|
|
44210
44495
|
/** Update expose gateway status */
|
|
44211
44496
|
setExposeStatus(status) {
|
|
44212
44497
|
this._expose = status;
|
|
44498
|
+
if (status.activeConnections > 0 && !this._exposeBlinkTimer) {
|
|
44499
|
+
this._exposeBlinkTimer = setInterval(() => {
|
|
44500
|
+
this._exposeBlinkOn = !this._exposeBlinkOn;
|
|
44501
|
+
if (this.active)
|
|
44502
|
+
this.renderFooterPreserveCursor();
|
|
44503
|
+
}, 500);
|
|
44504
|
+
} else if (status.activeConnections === 0 && this._exposeBlinkTimer) {
|
|
44505
|
+
clearInterval(this._exposeBlinkTimer);
|
|
44506
|
+
this._exposeBlinkTimer = null;
|
|
44507
|
+
this._exposeBlinkOn = true;
|
|
44508
|
+
}
|
|
44213
44509
|
if (this.active)
|
|
44214
44510
|
this.renderFooterPreserveCursor();
|
|
44215
44511
|
}
|
|
44216
44512
|
/** Clear expose gateway status */
|
|
44217
44513
|
clearExposeStatus() {
|
|
44218
44514
|
this._expose = null;
|
|
44515
|
+
if (this._exposeBlinkTimer) {
|
|
44516
|
+
clearInterval(this._exposeBlinkTimer);
|
|
44517
|
+
this._exposeBlinkTimer = null;
|
|
44518
|
+
this._exposeBlinkOn = true;
|
|
44519
|
+
}
|
|
44219
44520
|
if (this.active)
|
|
44220
44521
|
this.renderFooterPreserveCursor();
|
|
44221
44522
|
}
|
|
@@ -44674,7 +44975,7 @@ var init_status_bar = __esm({
|
|
|
44674
44975
|
}
|
|
44675
44976
|
if (this._expose) {
|
|
44676
44977
|
const INTERNAL_CAPS = /* @__PURE__ */ new Set(["system_metrics", "__list_capabilities"]);
|
|
44677
|
-
const statusEmoji = this._expose.status === "active" ? "\u{1F7E2}" : this._expose.status === "error" ? "\u{1F534}" : "\u{1F7E0}";
|
|
44978
|
+
const statusEmoji = this._expose.activeConnections > 0 ? this._exposeBlinkOn ? "\u{1F7E2}" : "\u26AB" : this._expose.status === "active" ? "\u{1F7E2}" : this._expose.status === "error" ? "\u{1F534}" : "\u{1F7E0}";
|
|
44678
44979
|
const models = Array.from(this._expose.modelUsage.keys()).filter((m2) => !INTERNAL_CAPS.has(m2));
|
|
44679
44980
|
const modelParams = models.map((mdl) => {
|
|
44680
44981
|
const pm = mdl.match(/(\d+[bBmM])/);
|
|
@@ -47277,6 +47578,10 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
47277
47578
|
stats: infos[0].stats
|
|
47278
47579
|
};
|
|
47279
47580
|
},
|
|
47581
|
+
/** Get the raw expose gateway instance for live dashboard */
|
|
47582
|
+
getExposeGateway() {
|
|
47583
|
+
return p2pGateway ?? tunnelGateway ?? null;
|
|
47584
|
+
},
|
|
47280
47585
|
// ── Nexus daemon connect ──────────────────────────────────────────────
|
|
47281
47586
|
async nexusConnect() {
|
|
47282
47587
|
const nexusTool = new NexusTool(repoRoot);
|
package/package.json
CHANGED