open-agents-ai 0.103.35 → 0.103.36
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 +234 -40
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -27527,6 +27527,33 @@ function isProcessAlive(pid) {
|
|
|
27527
27527
|
return false;
|
|
27528
27528
|
}
|
|
27529
27529
|
}
|
|
27530
|
+
function parseRateLimitHeaders(headers) {
|
|
27531
|
+
const get = (name) => {
|
|
27532
|
+
const v = headers[name] ?? headers[name.toLowerCase()];
|
|
27533
|
+
return typeof v === "string" ? v : Array.isArray(v) ? v[0] : void 0;
|
|
27534
|
+
};
|
|
27535
|
+
const remaining = parseInt(get("x-ratelimit-remaining-tokens") ?? get("x-ratelimit-remaining") ?? "", 10);
|
|
27536
|
+
const total = parseInt(get("x-ratelimit-limit-tokens") ?? get("x-ratelimit-limit") ?? "", 10);
|
|
27537
|
+
const resetRaw = get("x-ratelimit-reset-tokens") ?? get("x-ratelimit-reset") ?? "";
|
|
27538
|
+
let resetAt = 0;
|
|
27539
|
+
if (resetRaw) {
|
|
27540
|
+
const n = Number(resetRaw);
|
|
27541
|
+
if (!isNaN(n)) {
|
|
27542
|
+
resetAt = n < 1e12 ? n * 1e3 : n;
|
|
27543
|
+
} else {
|
|
27544
|
+
const d = new Date(resetRaw).getTime();
|
|
27545
|
+
if (!isNaN(d))
|
|
27546
|
+
resetAt = d;
|
|
27547
|
+
}
|
|
27548
|
+
}
|
|
27549
|
+
if (isNaN(remaining) && isNaN(total))
|
|
27550
|
+
return null;
|
|
27551
|
+
return {
|
|
27552
|
+
remaining: isNaN(remaining) ? 0 : remaining,
|
|
27553
|
+
total: isNaN(total) ? 0 : total,
|
|
27554
|
+
resetAt
|
|
27555
|
+
};
|
|
27556
|
+
}
|
|
27530
27557
|
async function collectSystemMetricsAsync() {
|
|
27531
27558
|
const [l1, l5, l15] = loadavg();
|
|
27532
27559
|
const cores = cpus().length;
|
|
@@ -27602,7 +27629,7 @@ function removeP2PExposeState(stateDir) {
|
|
|
27602
27629
|
} catch {
|
|
27603
27630
|
}
|
|
27604
27631
|
}
|
|
27605
|
-
var HOP_BY_HOP_HEADERS, CF_HEADERS_PREFIX, DEFAULT_TARGETS, STATE_FILE_NAME, ExposeGateway, P2P_STATE_FILE_NAME, ExposeP2PGateway;
|
|
27632
|
+
var HOP_BY_HOP_HEADERS, CF_HEADERS_PREFIX, INTERNAL_CAPABILITIES, DEFAULT_TARGETS, STATE_FILE_NAME, ExposeGateway, P2P_STATE_FILE_NAME, ExposeP2PGateway;
|
|
27606
27633
|
var init_expose = __esm({
|
|
27607
27634
|
"packages/cli/dist/tui/expose.js"() {
|
|
27608
27635
|
"use strict";
|
|
@@ -27618,6 +27645,7 @@ var init_expose = __esm({
|
|
|
27618
27645
|
"upgrade"
|
|
27619
27646
|
]);
|
|
27620
27647
|
CF_HEADERS_PREFIX = ["cf-", "cdn-"];
|
|
27648
|
+
INTERNAL_CAPABILITIES = /* @__PURE__ */ new Set(["system_metrics", "__list_capabilities"]);
|
|
27621
27649
|
DEFAULT_TARGETS = {
|
|
27622
27650
|
ollama: "http://127.0.0.1:11434",
|
|
27623
27651
|
vllm: "http://127.0.0.1:8000",
|
|
@@ -27648,7 +27676,10 @@ var init_expose = __esm({
|
|
|
27648
27676
|
totalTokensOut: 0,
|
|
27649
27677
|
startedAt: Date.now(),
|
|
27650
27678
|
modelUsage: /* @__PURE__ */ new Map(),
|
|
27651
|
-
users: /* @__PURE__ */ new Map()
|
|
27679
|
+
users: /* @__PURE__ */ new Map(),
|
|
27680
|
+
budgetTokensRemaining: 0,
|
|
27681
|
+
budgetTokensTotal: 0,
|
|
27682
|
+
budgetResetAt: 0
|
|
27652
27683
|
};
|
|
27653
27684
|
get tunnelUrl() {
|
|
27654
27685
|
return this._tunnelUrl;
|
|
@@ -27995,6 +28026,13 @@ var init_expose = __esm({
|
|
|
27995
28026
|
headers: forwardHeaders
|
|
27996
28027
|
}, (proxyRes) => {
|
|
27997
28028
|
cleanupHeartbeat();
|
|
28029
|
+
const rlHeaders = proxyRes.headers;
|
|
28030
|
+
const rl = parseRateLimitHeaders(rlHeaders);
|
|
28031
|
+
if (rl && (rl.total > 0 || rl.remaining > 0)) {
|
|
28032
|
+
this._stats.budgetTokensRemaining = rl.remaining;
|
|
28033
|
+
this._stats.budgetTokensTotal = rl.total;
|
|
28034
|
+
this._stats.budgetResetAt = rl.resetAt;
|
|
28035
|
+
}
|
|
27998
28036
|
proxyRes.on("error", () => {
|
|
27999
28037
|
finalizeRequest();
|
|
28000
28038
|
});
|
|
@@ -28250,10 +28288,16 @@ ${this.formatConnectionInfo()}`);
|
|
|
28250
28288
|
lines.push(` ${c2.cyan("Errors".padEnd(18))} ${s.errors}`);
|
|
28251
28289
|
lines.push(` ${c2.cyan("Tokens in".padEnd(18))} ${fmtTokens(s.totalTokensIn)}`);
|
|
28252
28290
|
lines.push(` ${c2.cyan("Tokens out".padEnd(18))} ${fmtTokens(s.totalTokensOut)}`);
|
|
28253
|
-
if (s.
|
|
28291
|
+
if (s.budgetTokensTotal > 0) {
|
|
28292
|
+
const pct = Math.round(s.budgetTokensRemaining / s.budgetTokensTotal * 100);
|
|
28293
|
+
const budgetColor = pct > 50 ? c2.green : pct > 20 ? c2.yellow : c2.red;
|
|
28294
|
+
lines.push(` ${c2.cyan("Budget".padEnd(18))} ${budgetColor(fmtTokens(s.budgetTokensRemaining))}${c2.dim("/")}${fmtTokens(s.budgetTokensTotal)} ${c2.dim(`(${pct}% left)`)}`);
|
|
28295
|
+
}
|
|
28296
|
+
const visibleModels = Array.from(s.modelUsage.entries()).filter(([model]) => !INTERNAL_CAPABILITIES.has(model));
|
|
28297
|
+
if (visibleModels.length > 0) {
|
|
28254
28298
|
lines.push("");
|
|
28255
28299
|
lines.push(` ${c2.bold("Models")}`);
|
|
28256
|
-
for (const [model, count] of
|
|
28300
|
+
for (const [model, count] of visibleModels) {
|
|
28257
28301
|
let mIn = 0, mOut = 0;
|
|
28258
28302
|
for (const user of s.users.values()) {
|
|
28259
28303
|
const mm = user.models.get(model);
|
|
@@ -28277,17 +28321,23 @@ ${this.formatConnectionInfo()}`);
|
|
|
28277
28321
|
lines.push(` ${c2.bold(user.ip)}${activeTag}`);
|
|
28278
28322
|
lines.push(` ${c2.dim("Session:")} ${ageStr} ${c2.dim("Last seen:")} ${lastStr} ${c2.dim("Requests:")} ${user.requests}`);
|
|
28279
28323
|
lines.push(` ${c2.dim("Tokens:")} in:${fmtTokens(user.tokensIn)} out:${fmtTokens(user.tokensOut)} ${c2.dim("Total:")} ${fmtTokens(user.tokensIn + user.tokensOut)}`);
|
|
28280
|
-
|
|
28281
|
-
|
|
28282
|
-
for (const [m, mm] of
|
|
28283
|
-
|
|
28324
|
+
const userModels = Array.from(user.models.entries()).filter(([m]) => !INTERNAL_CAPABILITIES.has(m));
|
|
28325
|
+
if (userModels.length > 0) {
|
|
28326
|
+
for (const [m, mm] of userModels) {
|
|
28327
|
+
lines.push(` ${c2.dim("\xB7")} ${c2.cyan(m)} ${c2.dim(`${mm.requests}req ${fmtTokens(mm.tokensIn + mm.tokensOut)}tok`)}`);
|
|
28284
28328
|
}
|
|
28285
|
-
lines.push(` ${c2.dim("Models:")} ${modelParts.join(", ")}`);
|
|
28286
28329
|
}
|
|
28287
28330
|
}
|
|
28288
28331
|
}
|
|
28289
28332
|
return lines.join("\n");
|
|
28290
28333
|
}
|
|
28334
|
+
/** Update budget from rate limit headers */
|
|
28335
|
+
updateBudget(remaining, total, resetAt) {
|
|
28336
|
+
this._stats.budgetTokensRemaining = remaining;
|
|
28337
|
+
this._stats.budgetTokensTotal = total;
|
|
28338
|
+
this._stats.budgetResetAt = resetAt;
|
|
28339
|
+
this.emitStats();
|
|
28340
|
+
}
|
|
28291
28341
|
};
|
|
28292
28342
|
P2P_STATE_FILE_NAME = "expose-p2p-state.json";
|
|
28293
28343
|
ExposeP2PGateway = class _ExposeP2PGateway extends EventEmitter3 {
|
|
@@ -28301,6 +28351,8 @@ ${this.formatConnectionInfo()}`);
|
|
|
28301
28351
|
_exposedModels = 0;
|
|
28302
28352
|
_stateDir;
|
|
28303
28353
|
_margin;
|
|
28354
|
+
_passthrough = false;
|
|
28355
|
+
_loadbalance = false;
|
|
28304
28356
|
_pollTimer = null;
|
|
28305
28357
|
_stats = {
|
|
28306
28358
|
status: "standby",
|
|
@@ -28311,7 +28363,10 @@ ${this.formatConnectionInfo()}`);
|
|
|
28311
28363
|
totalTokensOut: 0,
|
|
28312
28364
|
startedAt: Date.now(),
|
|
28313
28365
|
modelUsage: /* @__PURE__ */ new Map(),
|
|
28314
|
-
users: /* @__PURE__ */ new Map()
|
|
28366
|
+
users: /* @__PURE__ */ new Map(),
|
|
28367
|
+
budgetTokensRemaining: 0,
|
|
28368
|
+
budgetTokensTotal: 0,
|
|
28369
|
+
budgetResetAt: 0
|
|
28315
28370
|
};
|
|
28316
28371
|
get peerId() {
|
|
28317
28372
|
return this._peerId;
|
|
@@ -28340,6 +28395,8 @@ ${this.formatConnectionInfo()}`);
|
|
|
28340
28395
|
this._targetUrl = options.targetUrl ?? DEFAULT_TARGETS[options.kind];
|
|
28341
28396
|
this._stateDir = options.stateDir ?? null;
|
|
28342
28397
|
this._margin = options.margin ?? 0.5;
|
|
28398
|
+
this._passthrough = options.passthrough ?? false;
|
|
28399
|
+
this._loadbalance = options.loadbalance ?? false;
|
|
28343
28400
|
this._onInfo = options.onInfo;
|
|
28344
28401
|
this._onError = options.onError;
|
|
28345
28402
|
if (options.authKey === void 0 || options.authKey === "") {
|
|
@@ -28406,6 +28463,8 @@ ${this.formatConnectionInfo()}`);
|
|
|
28406
28463
|
kind: this._kind,
|
|
28407
28464
|
targetUrl: this._targetUrl,
|
|
28408
28465
|
margin: this._margin,
|
|
28466
|
+
passthrough: this._passthrough || void 0,
|
|
28467
|
+
loadbalance: this._loadbalance || void 0,
|
|
28409
28468
|
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
28410
28469
|
});
|
|
28411
28470
|
}
|
|
@@ -28456,6 +28515,8 @@ ${this.formatConnectionInfo()}`);
|
|
|
28456
28515
|
authKey: state.authKey,
|
|
28457
28516
|
stateDir,
|
|
28458
28517
|
margin: state.margin,
|
|
28518
|
+
passthrough: state.passthrough,
|
|
28519
|
+
loadbalance: state.loadbalance,
|
|
28459
28520
|
...options
|
|
28460
28521
|
}, nexusTool);
|
|
28461
28522
|
gateway._peerId = state.peerId;
|
|
@@ -28575,8 +28636,9 @@ ${this.formatConnectionInfo()}`);
|
|
|
28575
28636
|
formatConnectionInfo() {
|
|
28576
28637
|
const endpointCmd = `/endpoint ${this._peerId ?? "<peer-id>"} --auth ${this._authKey}`;
|
|
28577
28638
|
const lines = [];
|
|
28578
|
-
|
|
28579
|
-
lines.push(` ${c2.
|
|
28639
|
+
const modeLabel = this._passthrough ? "libp2p passthrough" : "libp2p";
|
|
28640
|
+
lines.push(` ${c2.green("\u25CF")} Expose gateway active ${c2.dim(`(${modeLabel})`)}`);
|
|
28641
|
+
lines.push(` ${c2.cyan("Backend".padEnd(12))} ${this._passthrough ? "passthrough" : this._kind} (${this._targetUrl})`);
|
|
28580
28642
|
lines.push(` ${c2.cyan("Transport".padEnd(12))} ${c2.bold("libp2p")} (DHT + mDNS + NATS relay)`);
|
|
28581
28643
|
lines.push(` ${c2.cyan("Peer ID".padEnd(12))} ${c2.bold(this._peerId ?? "connecting...")}`);
|
|
28582
28644
|
lines.push(` ${c2.cyan("Auth Key".padEnd(12))} ${c2.bold(this._authKey)}`);
|
|
@@ -28607,9 +28669,10 @@ ${this.formatConnectionInfo()}`);
|
|
|
28607
28669
|
const lines = [];
|
|
28608
28670
|
const uptimeSec = Math.floor((Date.now() - s.startedAt) / 1e3);
|
|
28609
28671
|
const uptimeStr = uptimeSec < 60 ? `${uptimeSec}s` : uptimeSec < 3600 ? `${Math.floor(uptimeSec / 60)}m ${uptimeSec % 60}s` : `${Math.floor(uptimeSec / 3600)}h ${Math.floor(uptimeSec % 3600 / 60)}m`;
|
|
28610
|
-
|
|
28672
|
+
const modeTag = this._passthrough ? c2.dim("(libp2p passthrough)") : c2.dim("(libp2p)");
|
|
28673
|
+
lines.push(` ${c2.bold("Expose Gateway Stats")} ${modeTag}`);
|
|
28611
28674
|
lines.push(` ${c2.cyan("Status".padEnd(18))} ${s.status === "active" ? c2.green("active") : s.status === "error" ? c2.red("error") : c2.yellow("standby")}`);
|
|
28612
|
-
lines.push(` ${c2.cyan("Transport".padEnd(18))} libp2p`);
|
|
28675
|
+
lines.push(` ${c2.cyan("Transport".padEnd(18))} libp2p${this._passthrough ? " (passthrough)" : ""}`);
|
|
28613
28676
|
lines.push(` ${c2.cyan("Peer ID".padEnd(18))} ${this._peerId ?? "n/a"}`);
|
|
28614
28677
|
lines.push(` ${c2.cyan("Uptime".padEnd(18))} ${uptimeStr}`);
|
|
28615
28678
|
lines.push(` ${c2.cyan("Total requests".padEnd(18))} ${s.totalRequests}`);
|
|
@@ -28617,10 +28680,16 @@ ${this.formatConnectionInfo()}`);
|
|
|
28617
28680
|
lines.push(` ${c2.cyan("Errors".padEnd(18))} ${s.errors}`);
|
|
28618
28681
|
lines.push(` ${c2.cyan("Tokens in".padEnd(18))} ${fmtTokens(s.totalTokensIn)}`);
|
|
28619
28682
|
lines.push(` ${c2.cyan("Tokens out".padEnd(18))} ${fmtTokens(s.totalTokensOut)}`);
|
|
28620
|
-
if (s.
|
|
28683
|
+
if (s.budgetTokensTotal > 0) {
|
|
28684
|
+
const pct = Math.round(s.budgetTokensRemaining / s.budgetTokensTotal * 100);
|
|
28685
|
+
const budgetColor = pct > 50 ? c2.green : pct > 20 ? c2.yellow : c2.red;
|
|
28686
|
+
lines.push(` ${c2.cyan("Budget".padEnd(18))} ${budgetColor(fmtTokens(s.budgetTokensRemaining))}${c2.dim("/")}${fmtTokens(s.budgetTokensTotal)} ${c2.dim(`(${pct}% left)`)}`);
|
|
28687
|
+
}
|
|
28688
|
+
const visibleModels = Array.from(s.modelUsage.entries()).filter(([model]) => !INTERNAL_CAPABILITIES.has(model));
|
|
28689
|
+
if (visibleModels.length > 0) {
|
|
28621
28690
|
lines.push("");
|
|
28622
28691
|
lines.push(` ${c2.bold("Models")}`);
|
|
28623
|
-
for (const [model, count] of
|
|
28692
|
+
for (const [model, count] of visibleModels) {
|
|
28624
28693
|
let mIn = 0, mOut = 0;
|
|
28625
28694
|
for (const user of s.users.values()) {
|
|
28626
28695
|
const mm = user.models.get(model);
|
|
@@ -28643,17 +28712,29 @@ ${this.formatConnectionInfo()}`);
|
|
|
28643
28712
|
lines.push(` ${c2.bold(user.ip)}`);
|
|
28644
28713
|
lines.push(` ${c2.dim("Session:")} ${ageStr} ${c2.dim("Last seen:")} ${lastStr} ${c2.dim("Requests:")} ${user.requests}`);
|
|
28645
28714
|
lines.push(` ${c2.dim("Tokens:")} in:${fmtTokens(user.tokensIn)} out:${fmtTokens(user.tokensOut)}`);
|
|
28646
|
-
|
|
28647
|
-
|
|
28648
|
-
for (const [m, mm] of
|
|
28649
|
-
|
|
28715
|
+
const userModels = Array.from(user.models.entries()).filter(([m]) => !INTERNAL_CAPABILITIES.has(m));
|
|
28716
|
+
if (userModels.length > 0) {
|
|
28717
|
+
for (const [m, mm] of userModels) {
|
|
28718
|
+
lines.push(` ${c2.dim("\xB7")} ${c2.cyan(m)} ${c2.dim(`${mm.requests}req ${fmtTokens(mm.tokensIn + mm.tokensOut)}tok`)}`);
|
|
28650
28719
|
}
|
|
28651
|
-
lines.push(` ${c2.dim("Models:")} ${modelParts.join(", ")}`);
|
|
28652
28720
|
}
|
|
28653
28721
|
}
|
|
28654
28722
|
}
|
|
28655
28723
|
return lines.join("\n");
|
|
28656
28724
|
}
|
|
28725
|
+
/** Update budget from rate limit headers */
|
|
28726
|
+
updateBudget(remaining, total, resetAt) {
|
|
28727
|
+
this._stats.budgetTokensRemaining = remaining;
|
|
28728
|
+
this._stats.budgetTokensTotal = total;
|
|
28729
|
+
this._stats.budgetResetAt = resetAt;
|
|
28730
|
+
this.emitStats();
|
|
28731
|
+
}
|
|
28732
|
+
get isPassthrough() {
|
|
28733
|
+
return this._passthrough;
|
|
28734
|
+
}
|
|
28735
|
+
get isLoadbalance() {
|
|
28736
|
+
return this._loadbalance;
|
|
28737
|
+
}
|
|
28657
28738
|
};
|
|
28658
28739
|
}
|
|
28659
28740
|
});
|
|
@@ -33519,25 +33600,44 @@ async function handleSlashCommand(input, ctx) {
|
|
|
33519
33600
|
}
|
|
33520
33601
|
return "handled";
|
|
33521
33602
|
}
|
|
33603
|
+
if (arg === "config") {
|
|
33604
|
+
await handleExposeConfig(ctx);
|
|
33605
|
+
return "handled";
|
|
33606
|
+
}
|
|
33607
|
+
if (arg?.startsWith("passthrough") || arg?.startsWith("forward")) {
|
|
33608
|
+
const ptParts = (arg ?? "").split(/\s+/);
|
|
33609
|
+
const ptLoadbalance = ptParts.includes("--loadbalance");
|
|
33610
|
+
try {
|
|
33611
|
+
const tunnelUrl = await ctx.exposeStart("passthrough", void 0, "libp2p", false, true, ptLoadbalance);
|
|
33612
|
+
if (tunnelUrl) {
|
|
33613
|
+
const info = ctx.getExposeInfo?.();
|
|
33614
|
+
if (info) {
|
|
33615
|
+
process.stdout.write("\n" + info.stats + "\n\n");
|
|
33616
|
+
}
|
|
33617
|
+
} else {
|
|
33618
|
+
renderError("Failed to start passthrough expose gateway.");
|
|
33619
|
+
}
|
|
33620
|
+
} catch (err) {
|
|
33621
|
+
renderError(`Expose passthrough error: ${err instanceof Error ? err.message : String(err)}`);
|
|
33622
|
+
}
|
|
33623
|
+
return "handled";
|
|
33624
|
+
}
|
|
33522
33625
|
if (!arg) {
|
|
33523
33626
|
const info = ctx.getExposeInfo?.();
|
|
33524
33627
|
if (info && ctx.isExposeActive?.()) {
|
|
33525
33628
|
process.stdout.write("\n" + info.stats + "\n\n");
|
|
33526
33629
|
} else {
|
|
33527
33630
|
renderInfo("Usage: /expose <backend> [options]");
|
|
33528
|
-
renderInfo(" /expose ollama
|
|
33529
|
-
renderInfo(" /expose ollama --tunnel
|
|
33530
|
-
renderInfo(" /expose
|
|
33531
|
-
renderInfo(" /expose
|
|
33532
|
-
renderInfo(" /expose
|
|
33533
|
-
renderInfo(" /expose
|
|
33534
|
-
renderInfo(" /expose stop
|
|
33535
|
-
renderInfo(" /expose
|
|
33536
|
-
renderInfo("
|
|
33537
|
-
renderInfo("
|
|
33538
|
-
renderInfo(" --key <key> Use specific auth key (tunnel mode)");
|
|
33539
|
-
renderInfo(" --key Auto-generate auth key (tunnel mode)");
|
|
33540
|
-
renderInfo(" --full Allow full Ollama API access (pull/delete/etc)");
|
|
33631
|
+
renderInfo(" /expose ollama Expose local Ollama via libp2p");
|
|
33632
|
+
renderInfo(" /expose ollama --tunnel Expose via cloudflared tunnel");
|
|
33633
|
+
renderInfo(" /expose vllm Expose local vLLM (8000)");
|
|
33634
|
+
renderInfo(" /expose passthrough --libp2p Forward /endpoint through libp2p");
|
|
33635
|
+
renderInfo(" /expose forward --loadbalance Forward with rate-limit distribution");
|
|
33636
|
+
renderInfo(" /expose config Configure expose settings");
|
|
33637
|
+
renderInfo(" /expose stop Stop all gateways");
|
|
33638
|
+
renderInfo(" /expose status Show usage stats");
|
|
33639
|
+
renderInfo(" --key <key> Use specific auth key (tunnel mode)");
|
|
33640
|
+
renderInfo(" --full Full Ollama API access");
|
|
33541
33641
|
}
|
|
33542
33642
|
return "handled";
|
|
33543
33643
|
}
|
|
@@ -34168,6 +34268,92 @@ function applyConfigChanges(ctx, changes) {
|
|
|
34168
34268
|
if (changes.commandsMode !== void 0)
|
|
34169
34269
|
ctx.setCommandsMode?.(changes.commandsMode);
|
|
34170
34270
|
}
|
|
34271
|
+
async function handleExposeConfig(ctx) {
|
|
34272
|
+
const info = ctx.getExposeInfo?.();
|
|
34273
|
+
const isActive = ctx.isExposeActive?.() ?? false;
|
|
34274
|
+
const items = [
|
|
34275
|
+
{ key: "hdr_status", label: "Status", kind: "header" },
|
|
34276
|
+
{ key: "status", label: isActive ? "Active" : "Inactive", detail: isActive ? "Gateway is running" : "No gateway active", kind: "info" }
|
|
34277
|
+
];
|
|
34278
|
+
if (isActive && info) {
|
|
34279
|
+
items.push({ key: "view_stats", label: "View Stats", detail: "Show current gateway statistics", kind: "action" });
|
|
34280
|
+
items.push({ key: "stop_all", label: "Stop All Gateways", detail: "Shut down all expose transports", kind: "action" });
|
|
34281
|
+
}
|
|
34282
|
+
items.push({ key: "hdr_start", label: "Start Gateway", kind: "header" });
|
|
34283
|
+
items.push({ key: "start_ollama", label: "Expose Ollama (libp2p)", detail: "Expose local Ollama via P2P network", kind: "action" });
|
|
34284
|
+
items.push({ key: "start_ollama_tunnel", label: "Expose Ollama (tunnel)", detail: "Expose via cloudflared public tunnel", kind: "action" });
|
|
34285
|
+
items.push({ key: "start_passthrough", label: "Passthrough /endpoint (libp2p)", detail: "Forward configured endpoint through P2P", kind: "action" });
|
|
34286
|
+
items.push({ key: "start_passthrough_lb", label: "Passthrough + Load Balance", detail: "Forward with distributed rate-limit budget", kind: "action" });
|
|
34287
|
+
items.push({ key: "start_vllm", label: "Expose vLLM (libp2p)", detail: "Expose local vLLM server (port 8000)", kind: "action" });
|
|
34288
|
+
const skipKeys = items.filter((e) => e.kind === "header" || e.kind === "info").map((e) => e.key);
|
|
34289
|
+
const result = await tuiSelect({
|
|
34290
|
+
items,
|
|
34291
|
+
title: "Expose Configuration",
|
|
34292
|
+
rl: ctx.rl,
|
|
34293
|
+
skipKeys
|
|
34294
|
+
});
|
|
34295
|
+
if (!result.confirmed || !result.key) {
|
|
34296
|
+
renderInfo("Expose config cancelled.");
|
|
34297
|
+
return;
|
|
34298
|
+
}
|
|
34299
|
+
switch (result.key) {
|
|
34300
|
+
case "view_stats": {
|
|
34301
|
+
const freshInfo = ctx.getExposeInfo?.();
|
|
34302
|
+
if (freshInfo)
|
|
34303
|
+
process.stdout.write("\n" + freshInfo.stats + "\n\n");
|
|
34304
|
+
break;
|
|
34305
|
+
}
|
|
34306
|
+
case "stop_all":
|
|
34307
|
+
await ctx.exposeStop?.();
|
|
34308
|
+
renderInfo("All expose gateways stopped.");
|
|
34309
|
+
break;
|
|
34310
|
+
case "start_ollama": {
|
|
34311
|
+
const url = await ctx.exposeStart?.("ollama", void 0, "libp2p");
|
|
34312
|
+
if (url) {
|
|
34313
|
+
const i = ctx.getExposeInfo?.();
|
|
34314
|
+
if (i)
|
|
34315
|
+
process.stdout.write("\n" + i.stats + "\n\n");
|
|
34316
|
+
}
|
|
34317
|
+
break;
|
|
34318
|
+
}
|
|
34319
|
+
case "start_ollama_tunnel": {
|
|
34320
|
+
const url = await ctx.exposeStart?.("ollama", "", "tunnel");
|
|
34321
|
+
if (url) {
|
|
34322
|
+
const i = ctx.getExposeInfo?.();
|
|
34323
|
+
if (i)
|
|
34324
|
+
process.stdout.write("\n" + i.stats + "\n\n");
|
|
34325
|
+
}
|
|
34326
|
+
break;
|
|
34327
|
+
}
|
|
34328
|
+
case "start_passthrough": {
|
|
34329
|
+
const url = await ctx.exposeStart?.("passthrough", void 0, "libp2p", false, true, false);
|
|
34330
|
+
if (url) {
|
|
34331
|
+
const i = ctx.getExposeInfo?.();
|
|
34332
|
+
if (i)
|
|
34333
|
+
process.stdout.write("\n" + i.stats + "\n\n");
|
|
34334
|
+
}
|
|
34335
|
+
break;
|
|
34336
|
+
}
|
|
34337
|
+
case "start_passthrough_lb": {
|
|
34338
|
+
const url = await ctx.exposeStart?.("passthrough", void 0, "libp2p", false, true, true);
|
|
34339
|
+
if (url) {
|
|
34340
|
+
const i = ctx.getExposeInfo?.();
|
|
34341
|
+
if (i)
|
|
34342
|
+
process.stdout.write("\n" + i.stats + "\n\n");
|
|
34343
|
+
}
|
|
34344
|
+
break;
|
|
34345
|
+
}
|
|
34346
|
+
case "start_vllm": {
|
|
34347
|
+
const url = await ctx.exposeStart?.("vllm", void 0, "libp2p");
|
|
34348
|
+
if (url) {
|
|
34349
|
+
const i = ctx.getExposeInfo?.();
|
|
34350
|
+
if (i)
|
|
34351
|
+
process.stdout.write("\n" + i.stats + "\n\n");
|
|
34352
|
+
}
|
|
34353
|
+
break;
|
|
34354
|
+
}
|
|
34355
|
+
}
|
|
34356
|
+
}
|
|
34171
34357
|
async function showModelPicker(ctx, local = false) {
|
|
34172
34358
|
try {
|
|
34173
34359
|
const models = await fetchModels(ctx.config.backendUrl, ctx.config.apiKey);
|
|
@@ -44237,14 +44423,16 @@ var init_status_bar = __esm({
|
|
|
44237
44423
|
}
|
|
44238
44424
|
}
|
|
44239
44425
|
if (this._expose) {
|
|
44426
|
+
const INTERNAL_CAPS = /* @__PURE__ */ new Set(["system_metrics", "__list_capabilities"]);
|
|
44240
44427
|
const statusEmoji = this._expose.status === "active" ? "\u{1F7E2}" : this._expose.status === "error" ? "\u{1F534}" : "\u{1F7E0}";
|
|
44241
|
-
const models = Array.from(this._expose.modelUsage.keys());
|
|
44428
|
+
const models = Array.from(this._expose.modelUsage.keys()).filter((m2) => !INTERNAL_CAPS.has(m2));
|
|
44242
44429
|
const modelParams = models.map((mdl) => {
|
|
44243
44430
|
const pm = mdl.match(/(\d+[bBmM])/);
|
|
44244
44431
|
return pm ? pm[1] : mdl.split(":")[0]?.split("/").pop() ?? mdl;
|
|
44245
44432
|
});
|
|
44246
44433
|
const modelStr = modelParams.join(",");
|
|
44247
|
-
const
|
|
44434
|
+
const visibleReqs = Array.from(this._expose.modelUsage.entries()).filter(([m2]) => !INTERNAL_CAPS.has(m2)).reduce((sum, [, n]) => sum + n, 0);
|
|
44435
|
+
const reqStr = visibleReqs > 0 ? ` ${visibleReqs}req` : "";
|
|
44248
44436
|
const connStr = this._expose.activeConnections > 0 ? ` ${this._expose.activeConnections}conn` : "";
|
|
44249
44437
|
const exposeExpanded = statusEmoji + pastel2(183, (modelStr ? " " + modelStr : "") + reqStr + connStr);
|
|
44250
44438
|
const exposeCompact = statusEmoji + (modelStr ? pastel2(183, " " + modelStr) : "");
|
|
@@ -46689,11 +46877,15 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
46689
46877
|
getCallUrl() {
|
|
46690
46878
|
return voiceSession?.tunnelUrl ?? null;
|
|
46691
46879
|
},
|
|
46692
|
-
async exposeStart(kindOrUrl, authKey, transport, fullAccess) {
|
|
46693
|
-
const knownKinds = ["ollama", "vllm", "llvm"];
|
|
46880
|
+
async exposeStart(kindOrUrl, authKey, transport, fullAccess, passthrough, loadbalance) {
|
|
46881
|
+
const knownKinds = ["ollama", "vllm", "llvm", "passthrough"];
|
|
46694
46882
|
let kind;
|
|
46695
46883
|
let targetUrl;
|
|
46696
|
-
if (
|
|
46884
|
+
if (kindOrUrl === "passthrough" || passthrough) {
|
|
46885
|
+
kind = "custom";
|
|
46886
|
+
targetUrl = config.backendUrl;
|
|
46887
|
+
passthrough = true;
|
|
46888
|
+
} else if (knownKinds.includes(kindOrUrl)) {
|
|
46697
46889
|
kind = kindOrUrl;
|
|
46698
46890
|
} else {
|
|
46699
46891
|
kind = "custom";
|
|
@@ -46706,7 +46898,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
46706
46898
|
p2pGateway = null;
|
|
46707
46899
|
}
|
|
46708
46900
|
const nexusTool = new NexusTool(repoRoot);
|
|
46709
|
-
let exposeSpinnerMsg = "Connecting to nexus P2P network...";
|
|
46901
|
+
let exposeSpinnerMsg = passthrough ? `Connecting to nexus P2P network (passthrough \u2192 ${targetUrl})...` : "Connecting to nexus P2P network...";
|
|
46710
46902
|
const exposeFrames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
46711
46903
|
let exposeFrame = 0;
|
|
46712
46904
|
const exposeSpinner = setInterval(() => {
|
|
@@ -46718,6 +46910,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
46718
46910
|
targetUrl,
|
|
46719
46911
|
authKey,
|
|
46720
46912
|
stateDir: join50(repoRoot, ".oa"),
|
|
46913
|
+
passthrough: passthrough ?? false,
|
|
46914
|
+
loadbalance: loadbalance ?? false,
|
|
46721
46915
|
onInfo: (msg) => {
|
|
46722
46916
|
exposeSpinnerMsg = msg;
|
|
46723
46917
|
},
|
package/package.json
CHANGED