open-agents-ai 0.103.16 → 0.103.17
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 +372 -35
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6598,8 +6598,8 @@ async function loadTranscribeCli() {
|
|
|
6598
6598
|
const nvmBase = join16(homedir6(), ".nvm", "versions", "node");
|
|
6599
6599
|
if (existsSync13(nvmBase)) {
|
|
6600
6600
|
try {
|
|
6601
|
-
const { readdirSync:
|
|
6602
|
-
for (const ver of
|
|
6601
|
+
const { readdirSync: readdirSync16 } = await import("node:fs");
|
|
6602
|
+
for (const ver of readdirSync16(nvmBase)) {
|
|
6603
6603
|
const tcPath = join16(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
6604
6604
|
if (existsSync13(join16(tcPath, "dist", "index.js"))) {
|
|
6605
6605
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
@@ -13062,7 +13062,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13062
13062
|
result = await this.sendDaemonCmd("room_members", args);
|
|
13063
13063
|
break;
|
|
13064
13064
|
case "expose":
|
|
13065
|
-
result = await this.sendDaemonCmd("expose", args,
|
|
13065
|
+
result = await this.sendDaemonCmd("expose", args, 6e4);
|
|
13066
13066
|
break;
|
|
13067
13067
|
case "pricing_menu":
|
|
13068
13068
|
result = await this.sendDaemonCmd("pricing_menu", args);
|
|
@@ -20590,8 +20590,8 @@ var init_listen = __esm({
|
|
|
20590
20590
|
const nvmBase = join34(homedir8(), ".nvm", "versions", "node");
|
|
20591
20591
|
if (existsSync25(nvmBase)) {
|
|
20592
20592
|
try {
|
|
20593
|
-
const { readdirSync:
|
|
20594
|
-
for (const ver of
|
|
20593
|
+
const { readdirSync: readdirSync16 } = await import("node:fs");
|
|
20594
|
+
for (const ver of readdirSync16(nvmBase)) {
|
|
20595
20595
|
const tcPath = join34(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
20596
20596
|
if (existsSync25(join34(tcPath, "dist", "index.js"))) {
|
|
20597
20597
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
@@ -26203,7 +26203,7 @@ import { EventEmitter as EventEmitter3 } from "node:events";
|
|
|
26203
26203
|
import { randomBytes as randomBytes7 } from "node:crypto";
|
|
26204
26204
|
import { URL as URL2 } from "node:url";
|
|
26205
26205
|
import { loadavg, cpus, totalmem, freemem } from "node:os";
|
|
26206
|
-
import { existsSync as existsSync26, readFileSync as readFileSync18, writeFileSync as writeFileSync8, unlinkSync as unlinkSync3, mkdirSync as mkdirSync8 } from "node:fs";
|
|
26206
|
+
import { existsSync as existsSync26, readFileSync as readFileSync18, writeFileSync as writeFileSync8, unlinkSync as unlinkSync3, mkdirSync as mkdirSync8, readdirSync as readdirSync7 } from "node:fs";
|
|
26207
26207
|
import { join as join35 } from "node:path";
|
|
26208
26208
|
function cleanForwardHeaders(raw, targetHost) {
|
|
26209
26209
|
const out = {};
|
|
@@ -26313,7 +26313,7 @@ async function collectSystemMetricsAsync() {
|
|
|
26313
26313
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
26314
26314
|
};
|
|
26315
26315
|
}
|
|
26316
|
-
var HOP_BY_HOP_HEADERS, CF_HEADERS_PREFIX, DEFAULT_TARGETS, STATE_FILE_NAME, ExposeGateway;
|
|
26316
|
+
var HOP_BY_HOP_HEADERS, CF_HEADERS_PREFIX, DEFAULT_TARGETS, STATE_FILE_NAME, ExposeGateway, ExposeP2PGateway;
|
|
26317
26317
|
var init_expose = __esm({
|
|
26318
26318
|
"packages/cli/dist/tui/expose.js"() {
|
|
26319
26319
|
"use strict";
|
|
@@ -26951,6 +26951,293 @@ ${this.formatConnectionInfo()}`);
|
|
|
26951
26951
|
return lines.join("\n");
|
|
26952
26952
|
}
|
|
26953
26953
|
};
|
|
26954
|
+
ExposeP2PGateway = class extends EventEmitter3 {
|
|
26955
|
+
_nexusTool;
|
|
26956
|
+
// NexusTool instance
|
|
26957
|
+
_kind;
|
|
26958
|
+
_targetUrl;
|
|
26959
|
+
_peerId = null;
|
|
26960
|
+
_capabilities = [];
|
|
26961
|
+
_exposedModels = 0;
|
|
26962
|
+
_stateDir;
|
|
26963
|
+
_margin;
|
|
26964
|
+
_pollTimer = null;
|
|
26965
|
+
_stats = {
|
|
26966
|
+
status: "standby",
|
|
26967
|
+
totalRequests: 0,
|
|
26968
|
+
activeConnections: 0,
|
|
26969
|
+
errors: 0,
|
|
26970
|
+
totalTokensIn: 0,
|
|
26971
|
+
totalTokensOut: 0,
|
|
26972
|
+
startedAt: Date.now(),
|
|
26973
|
+
modelUsage: /* @__PURE__ */ new Map(),
|
|
26974
|
+
users: /* @__PURE__ */ new Map()
|
|
26975
|
+
};
|
|
26976
|
+
get peerId() {
|
|
26977
|
+
return this._peerId;
|
|
26978
|
+
}
|
|
26979
|
+
get stats() {
|
|
26980
|
+
return this._stats;
|
|
26981
|
+
}
|
|
26982
|
+
get kind() {
|
|
26983
|
+
return this._kind;
|
|
26984
|
+
}
|
|
26985
|
+
get isActive() {
|
|
26986
|
+
return this._stats.status === "active";
|
|
26987
|
+
}
|
|
26988
|
+
get transport() {
|
|
26989
|
+
return "libp2p";
|
|
26990
|
+
}
|
|
26991
|
+
_onInfo;
|
|
26992
|
+
_onError;
|
|
26993
|
+
constructor(options, nexusTool) {
|
|
26994
|
+
super();
|
|
26995
|
+
this._nexusTool = nexusTool;
|
|
26996
|
+
this._kind = options.kind;
|
|
26997
|
+
this._targetUrl = options.targetUrl ?? DEFAULT_TARGETS[options.kind];
|
|
26998
|
+
this._stateDir = options.stateDir ?? null;
|
|
26999
|
+
this._margin = options.margin ?? 0.5;
|
|
27000
|
+
this._onInfo = options.onInfo;
|
|
27001
|
+
this._onError = options.onError;
|
|
27002
|
+
}
|
|
27003
|
+
async start() {
|
|
27004
|
+
this._onInfo?.("Connecting to nexus P2P network...");
|
|
27005
|
+
const connectResult = await this._nexusTool.execute({
|
|
27006
|
+
action: "connect",
|
|
27007
|
+
agent_name: "open-agents-node",
|
|
27008
|
+
agent_type: "general"
|
|
27009
|
+
});
|
|
27010
|
+
if (!connectResult.success) {
|
|
27011
|
+
throw new Error(`Nexus daemon connect failed: ${connectResult.error}`);
|
|
27012
|
+
}
|
|
27013
|
+
await new Promise((r) => setTimeout(r, 2e3));
|
|
27014
|
+
this._onInfo?.("Registering inference capabilities...");
|
|
27015
|
+
let exposeResult = await this._nexusTool.execute({
|
|
27016
|
+
action: "expose",
|
|
27017
|
+
ollama_url: this._targetUrl,
|
|
27018
|
+
margin: String(this._margin)
|
|
27019
|
+
});
|
|
27020
|
+
if (!exposeResult.success && exposeResult.error?.includes("not running")) {
|
|
27021
|
+
await new Promise((r) => setTimeout(r, 3e3));
|
|
27022
|
+
exposeResult = await this._nexusTool.execute({
|
|
27023
|
+
action: "expose",
|
|
27024
|
+
ollama_url: this._targetUrl,
|
|
27025
|
+
margin: String(this._margin)
|
|
27026
|
+
});
|
|
27027
|
+
}
|
|
27028
|
+
if (!exposeResult.success) {
|
|
27029
|
+
throw new Error(`Expose failed: ${exposeResult.error}`);
|
|
27030
|
+
}
|
|
27031
|
+
const nexusDir = this._nexusTool.getNexusDir();
|
|
27032
|
+
const statusPath = join35(nexusDir, "status.json");
|
|
27033
|
+
for (let i = 0; i < 60; i++) {
|
|
27034
|
+
try {
|
|
27035
|
+
const raw = readFileSync18(statusPath, "utf8");
|
|
27036
|
+
if (raw.length > 10) {
|
|
27037
|
+
const status = JSON.parse(raw);
|
|
27038
|
+
if (status.connected && status.peerId) {
|
|
27039
|
+
this._peerId = status.peerId;
|
|
27040
|
+
this._capabilities = status.capabilities || [];
|
|
27041
|
+
this._exposedModels = status.exposedModels || 0;
|
|
27042
|
+
break;
|
|
27043
|
+
}
|
|
27044
|
+
}
|
|
27045
|
+
} catch {
|
|
27046
|
+
}
|
|
27047
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
27048
|
+
}
|
|
27049
|
+
this._stats.status = "active";
|
|
27050
|
+
this._stats.startedAt = Date.now();
|
|
27051
|
+
this.emitStats();
|
|
27052
|
+
this.startMeteringPoll(nexusDir);
|
|
27053
|
+
return this._peerId ?? "connected (peer ID pending)";
|
|
27054
|
+
}
|
|
27055
|
+
async stop() {
|
|
27056
|
+
this.stopMeteringPoll();
|
|
27057
|
+
this._stats.status = "standby";
|
|
27058
|
+
this._stats.activeConnections = 0;
|
|
27059
|
+
this.emitStats();
|
|
27060
|
+
}
|
|
27061
|
+
/** Poll the daemon's metering.jsonl and status.json for stats */
|
|
27062
|
+
startMeteringPoll(nexusDir) {
|
|
27063
|
+
this.stopMeteringPoll();
|
|
27064
|
+
let lastMeteringSize = 0;
|
|
27065
|
+
this._pollTimer = setInterval(() => {
|
|
27066
|
+
try {
|
|
27067
|
+
const statusPath = join35(nexusDir, "status.json");
|
|
27068
|
+
if (existsSync26(statusPath)) {
|
|
27069
|
+
const status = JSON.parse(readFileSync18(statusPath, "utf8"));
|
|
27070
|
+
if (status.peerId && !this._peerId) {
|
|
27071
|
+
this._peerId = status.peerId;
|
|
27072
|
+
}
|
|
27073
|
+
this._capabilities = status.capabilities || [];
|
|
27074
|
+
}
|
|
27075
|
+
} catch {
|
|
27076
|
+
}
|
|
27077
|
+
try {
|
|
27078
|
+
const invocDir = join35(nexusDir, "invocations");
|
|
27079
|
+
if (existsSync26(invocDir)) {
|
|
27080
|
+
const files = readdirSync7(invocDir);
|
|
27081
|
+
const invocCount = files.filter((f) => f.endsWith(".json")).length;
|
|
27082
|
+
if (invocCount > this._stats.totalRequests) {
|
|
27083
|
+
this._stats.totalRequests = invocCount;
|
|
27084
|
+
this.emitStats();
|
|
27085
|
+
}
|
|
27086
|
+
}
|
|
27087
|
+
} catch {
|
|
27088
|
+
}
|
|
27089
|
+
try {
|
|
27090
|
+
const meteringFile = join35(nexusDir, "metering.jsonl");
|
|
27091
|
+
if (existsSync26(meteringFile)) {
|
|
27092
|
+
const content = readFileSync18(meteringFile, "utf8");
|
|
27093
|
+
if (content.length > lastMeteringSize) {
|
|
27094
|
+
const newContent = content.slice(lastMeteringSize);
|
|
27095
|
+
lastMeteringSize = content.length;
|
|
27096
|
+
for (const line of newContent.split("\n")) {
|
|
27097
|
+
if (!line.trim())
|
|
27098
|
+
continue;
|
|
27099
|
+
try {
|
|
27100
|
+
const record = JSON.parse(line);
|
|
27101
|
+
if (record.tokens) {
|
|
27102
|
+
this._stats.totalTokensIn += record.tokens.input || 0;
|
|
27103
|
+
this._stats.totalTokensOut += record.tokens.output || 0;
|
|
27104
|
+
}
|
|
27105
|
+
const peerId = record.from || record.peerId || "unknown";
|
|
27106
|
+
const shortPeer = peerId.length > 16 ? peerId.slice(0, 16) + "..." : peerId;
|
|
27107
|
+
let user = this._stats.users.get(shortPeer);
|
|
27108
|
+
if (!user) {
|
|
27109
|
+
user = {
|
|
27110
|
+
ip: shortPeer,
|
|
27111
|
+
firstSeen: Date.now(),
|
|
27112
|
+
lastSeen: Date.now(),
|
|
27113
|
+
requests: 0,
|
|
27114
|
+
tokensIn: 0,
|
|
27115
|
+
tokensOut: 0,
|
|
27116
|
+
activeRequests: 0,
|
|
27117
|
+
models: /* @__PURE__ */ new Map()
|
|
27118
|
+
};
|
|
27119
|
+
this._stats.users.set(shortPeer, user);
|
|
27120
|
+
}
|
|
27121
|
+
user.requests++;
|
|
27122
|
+
user.lastSeen = Date.now();
|
|
27123
|
+
if (record.tokens) {
|
|
27124
|
+
user.tokensIn += record.tokens.input || 0;
|
|
27125
|
+
user.tokensOut += record.tokens.output || 0;
|
|
27126
|
+
}
|
|
27127
|
+
if (record.model || record.capability) {
|
|
27128
|
+
const modelName = record.model || record.capability.replace("inference:", "") || "unknown";
|
|
27129
|
+
this._stats.modelUsage.set(modelName, (this._stats.modelUsage.get(modelName) ?? 0) + 1);
|
|
27130
|
+
let mm = user.models.get(modelName);
|
|
27131
|
+
if (!mm) {
|
|
27132
|
+
mm = { requests: 0, tokensIn: 0, tokensOut: 0, lastUsed: Date.now() };
|
|
27133
|
+
user.models.set(modelName, mm);
|
|
27134
|
+
}
|
|
27135
|
+
mm.requests++;
|
|
27136
|
+
mm.lastUsed = Date.now();
|
|
27137
|
+
if (record.tokens) {
|
|
27138
|
+
mm.tokensIn += record.tokens.input || 0;
|
|
27139
|
+
mm.tokensOut += record.tokens.output || 0;
|
|
27140
|
+
}
|
|
27141
|
+
}
|
|
27142
|
+
} catch {
|
|
27143
|
+
}
|
|
27144
|
+
}
|
|
27145
|
+
this.emitStats();
|
|
27146
|
+
}
|
|
27147
|
+
}
|
|
27148
|
+
} catch {
|
|
27149
|
+
}
|
|
27150
|
+
}, 5e3);
|
|
27151
|
+
this._pollTimer.unref();
|
|
27152
|
+
}
|
|
27153
|
+
stopMeteringPoll() {
|
|
27154
|
+
if (this._pollTimer) {
|
|
27155
|
+
clearInterval(this._pollTimer);
|
|
27156
|
+
this._pollTimer = null;
|
|
27157
|
+
}
|
|
27158
|
+
}
|
|
27159
|
+
emitStats() {
|
|
27160
|
+
this.emit("stats", {
|
|
27161
|
+
...this._stats,
|
|
27162
|
+
modelUsage: new Map(this._stats.modelUsage),
|
|
27163
|
+
users: new Map(this._stats.users)
|
|
27164
|
+
});
|
|
27165
|
+
}
|
|
27166
|
+
/** Format connection info for display */
|
|
27167
|
+
formatConnectionInfo() {
|
|
27168
|
+
const lines = [];
|
|
27169
|
+
lines.push(` ${c2.green("\u25CF")} Expose gateway active ${c2.dim("(libp2p)")}`);
|
|
27170
|
+
lines.push(` ${c2.cyan("Backend".padEnd(12))} ${this._kind} (${this._targetUrl})`);
|
|
27171
|
+
lines.push(` ${c2.cyan("Transport".padEnd(12))} ${c2.bold("libp2p")} (DHT + mDNS + NATS relay)`);
|
|
27172
|
+
lines.push(` ${c2.cyan("Peer ID".padEnd(12))} ${c2.bold(this._peerId ?? "connecting...")}`);
|
|
27173
|
+
lines.push(` ${c2.cyan("Models".padEnd(12))} ${this._exposedModels || this._capabilities.filter((cap) => cap.startsWith("inference:")).length} exposed`);
|
|
27174
|
+
lines.push("");
|
|
27175
|
+
lines.push(` ${c2.dim("Remote peers discover your models via nexus network.")}`);
|
|
27176
|
+
lines.push(` ${c2.dim("Consumers use: /nexus invoke_capability inference:<model>")}`);
|
|
27177
|
+
const infCaps = this._capabilities.filter((cap) => cap.startsWith("inference:"));
|
|
27178
|
+
if (infCaps.length > 0) {
|
|
27179
|
+
lines.push("");
|
|
27180
|
+
lines.push(` ${c2.bold("Exposed capabilities:")}`);
|
|
27181
|
+
for (const cap of infCaps) {
|
|
27182
|
+
lines.push(` ${c2.cyan(cap)}`);
|
|
27183
|
+
}
|
|
27184
|
+
}
|
|
27185
|
+
return lines.join("\n");
|
|
27186
|
+
}
|
|
27187
|
+
/** Format usage stats for display */
|
|
27188
|
+
formatStats() {
|
|
27189
|
+
const s = this._stats;
|
|
27190
|
+
const lines = [];
|
|
27191
|
+
const uptimeSec = Math.floor((Date.now() - s.startedAt) / 1e3);
|
|
27192
|
+
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`;
|
|
27193
|
+
lines.push(` ${c2.bold("Expose Gateway Stats")} ${c2.dim("(libp2p)")}`);
|
|
27194
|
+
lines.push(` ${c2.cyan("Status".padEnd(18))} ${s.status === "active" ? c2.green("active") : s.status === "error" ? c2.red("error") : c2.yellow("standby")}`);
|
|
27195
|
+
lines.push(` ${c2.cyan("Transport".padEnd(18))} libp2p`);
|
|
27196
|
+
lines.push(` ${c2.cyan("Peer ID".padEnd(18))} ${this._peerId ?? "n/a"}`);
|
|
27197
|
+
lines.push(` ${c2.cyan("Uptime".padEnd(18))} ${uptimeStr}`);
|
|
27198
|
+
lines.push(` ${c2.cyan("Total requests".padEnd(18))} ${s.totalRequests}`);
|
|
27199
|
+
lines.push(` ${c2.cyan("Active conns".padEnd(18))} ${s.activeConnections}`);
|
|
27200
|
+
lines.push(` ${c2.cyan("Errors".padEnd(18))} ${s.errors}`);
|
|
27201
|
+
lines.push(` ${c2.cyan("Tokens in".padEnd(18))} ${fmtTokens(s.totalTokensIn)}`);
|
|
27202
|
+
lines.push(` ${c2.cyan("Tokens out".padEnd(18))} ${fmtTokens(s.totalTokensOut)}`);
|
|
27203
|
+
if (s.modelUsage.size > 0) {
|
|
27204
|
+
lines.push("");
|
|
27205
|
+
lines.push(` ${c2.bold("Models")}`);
|
|
27206
|
+
for (const [model, count] of s.modelUsage) {
|
|
27207
|
+
let mIn = 0, mOut = 0;
|
|
27208
|
+
for (const user of s.users.values()) {
|
|
27209
|
+
const mm = user.models.get(model);
|
|
27210
|
+
if (mm) {
|
|
27211
|
+
mIn += mm.tokensIn;
|
|
27212
|
+
mOut += mm.tokensOut;
|
|
27213
|
+
}
|
|
27214
|
+
}
|
|
27215
|
+
lines.push(` ${c2.cyan(model.padEnd(30))} ${count} reqs ${c2.dim(`in:${fmtTokens(mIn)} out:${fmtTokens(mOut)}`)}`);
|
|
27216
|
+
}
|
|
27217
|
+
}
|
|
27218
|
+
if (s.users.size > 0) {
|
|
27219
|
+
lines.push("");
|
|
27220
|
+
lines.push(` ${c2.bold("Active Peers")} (${s.users.size})`);
|
|
27221
|
+
for (const user of s.users.values()) {
|
|
27222
|
+
const ageSec = Math.floor((Date.now() - user.firstSeen) / 1e3);
|
|
27223
|
+
const ageStr = ageSec < 60 ? `${ageSec}s` : ageSec < 3600 ? `${Math.floor(ageSec / 60)}m` : `${Math.floor(ageSec / 3600)}h ${Math.floor(ageSec % 3600 / 60)}m`;
|
|
27224
|
+
const lastSec = Math.floor((Date.now() - user.lastSeen) / 1e3);
|
|
27225
|
+
const lastStr = lastSec < 5 ? "now" : lastSec < 60 ? `${lastSec}s ago` : `${Math.floor(lastSec / 60)}m ago`;
|
|
27226
|
+
lines.push(` ${c2.bold(user.ip)}`);
|
|
27227
|
+
lines.push(` ${c2.dim("Session:")} ${ageStr} ${c2.dim("Last seen:")} ${lastStr} ${c2.dim("Requests:")} ${user.requests}`);
|
|
27228
|
+
lines.push(` ${c2.dim("Tokens:")} in:${fmtTokens(user.tokensIn)} out:${fmtTokens(user.tokensOut)}`);
|
|
27229
|
+
if (user.models.size > 0) {
|
|
27230
|
+
const modelParts = [];
|
|
27231
|
+
for (const [m, mm] of user.models) {
|
|
27232
|
+
modelParts.push(`${m} (${mm.requests} reqs, ${fmtTokens(mm.tokensIn + mm.tokensOut)} tokens)`);
|
|
27233
|
+
}
|
|
27234
|
+
lines.push(` ${c2.dim("Models:")} ${modelParts.join(", ")}`);
|
|
27235
|
+
}
|
|
27236
|
+
}
|
|
27237
|
+
}
|
|
27238
|
+
return lines.join("\n");
|
|
27239
|
+
}
|
|
27240
|
+
};
|
|
26954
27241
|
}
|
|
26955
27242
|
});
|
|
26956
27243
|
|
|
@@ -28564,7 +28851,7 @@ var init_dist6 = __esm({
|
|
|
28564
28851
|
});
|
|
28565
28852
|
|
|
28566
28853
|
// packages/cli/dist/tui/oa-directory.js
|
|
28567
|
-
import { existsSync as existsSync29, mkdirSync as mkdirSync10, readFileSync as readFileSync21, writeFileSync as writeFileSync10, readdirSync as
|
|
28854
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync10, readFileSync as readFileSync21, writeFileSync as writeFileSync10, readdirSync as readdirSync8, statSync as statSync9, unlinkSync as unlinkSync4 } from "node:fs";
|
|
28568
28855
|
import { join as join39, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
|
|
28569
28856
|
import { homedir as homedir9 } from "node:os";
|
|
28570
28857
|
function initOaDirectory(repoRoot) {
|
|
@@ -28756,7 +29043,7 @@ function loadRecentSessions(repoRoot, limit = 5) {
|
|
|
28756
29043
|
if (!existsSync29(historyDir))
|
|
28757
29044
|
return [];
|
|
28758
29045
|
try {
|
|
28759
|
-
const files =
|
|
29046
|
+
const files = readdirSync8(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
|
|
28760
29047
|
const stat5 = statSync9(join39(historyDir, f));
|
|
28761
29048
|
return { file: f, mtime: stat5.mtimeMs };
|
|
28762
29049
|
}).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
|
|
@@ -28909,7 +29196,7 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
28909
29196
|
return "";
|
|
28910
29197
|
let result = "";
|
|
28911
29198
|
try {
|
|
28912
|
-
const entries =
|
|
29199
|
+
const entries = readdirSync8(root, { withFileTypes: true }).filter((e) => !e.name.startsWith(".") || e.name === ".github").filter((e) => !SKIP_DIRS.has(e.name)).sort((a, b) => {
|
|
28913
29200
|
if (a.isDirectory() && !b.isDirectory())
|
|
28914
29201
|
return -1;
|
|
28915
29202
|
if (!a.isDirectory() && b.isDirectory())
|
|
@@ -28924,7 +29211,7 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
28924
29211
|
if (entry.isDirectory()) {
|
|
28925
29212
|
let fileCount = 0;
|
|
28926
29213
|
try {
|
|
28927
|
-
fileCount =
|
|
29214
|
+
fileCount = readdirSync8(join39(root, entry.name)).filter((f) => !f.startsWith(".")).length;
|
|
28928
29215
|
} catch {
|
|
28929
29216
|
}
|
|
28930
29217
|
result += `${prefix}${connector}${entry.name}/ (${fileCount})
|
|
@@ -31540,15 +31827,17 @@ async function handleSlashCommand(input, ctx) {
|
|
|
31540
31827
|
if (info && ctx.isExposeActive?.()) {
|
|
31541
31828
|
process.stdout.write("\n" + info.stats + "\n\n");
|
|
31542
31829
|
} else {
|
|
31543
|
-
renderInfo("Usage: /expose <backend> [
|
|
31544
|
-
renderInfo(" /expose ollama Expose local Ollama (
|
|
31830
|
+
renderInfo("Usage: /expose <backend> [options]");
|
|
31831
|
+
renderInfo(" /expose ollama Expose local Ollama via libp2p (default)");
|
|
31832
|
+
renderInfo(" /expose ollama --tunnel Expose via cloudflared tunnel");
|
|
31833
|
+
renderInfo(" /expose ollama --libp2p Expose via libp2p (explicit)");
|
|
31545
31834
|
renderInfo(" /expose vllm Expose local vLLM (8000)");
|
|
31546
31835
|
renderInfo(" /expose llvm Expose local LLVM (8080)");
|
|
31547
31836
|
renderInfo(" /expose host:port Expose custom address");
|
|
31548
31837
|
renderInfo(" /expose stop Stop the gateway");
|
|
31549
31838
|
renderInfo(" /expose status Show usage stats");
|
|
31550
|
-
renderInfo(" --key <key> Use specific auth key");
|
|
31551
|
-
renderInfo(" --key Auto-generate auth key");
|
|
31839
|
+
renderInfo(" --key <key> Use specific auth key (tunnel mode)");
|
|
31840
|
+
renderInfo(" --key Auto-generate auth key (tunnel mode)");
|
|
31552
31841
|
}
|
|
31553
31842
|
return "handled";
|
|
31554
31843
|
}
|
|
@@ -31558,12 +31847,18 @@ async function handleSlashCommand(input, ctx) {
|
|
|
31558
31847
|
const exposeParts = arg.split(/\s+/);
|
|
31559
31848
|
const kindOrUrl = exposeParts[0];
|
|
31560
31849
|
let exposeAuthKey;
|
|
31850
|
+
let exposeTransport;
|
|
31561
31851
|
const keyIdx = exposeParts.indexOf("--key");
|
|
31562
31852
|
if (keyIdx !== -1) {
|
|
31563
31853
|
exposeAuthKey = exposeParts[keyIdx + 1] ?? "";
|
|
31564
31854
|
}
|
|
31855
|
+
if (exposeParts.includes("--tunnel")) {
|
|
31856
|
+
exposeTransport = "tunnel";
|
|
31857
|
+
} else if (exposeParts.includes("--libp2p")) {
|
|
31858
|
+
exposeTransport = "libp2p";
|
|
31859
|
+
}
|
|
31565
31860
|
try {
|
|
31566
|
-
const tunnelUrl = await ctx.exposeStart(kindOrUrl, exposeAuthKey);
|
|
31861
|
+
const tunnelUrl = await ctx.exposeStart(kindOrUrl, exposeAuthKey, exposeTransport);
|
|
31567
31862
|
if (tunnelUrl) {
|
|
31568
31863
|
const info = ctx.getExposeInfo?.();
|
|
31569
31864
|
if (info) {
|
|
@@ -32761,7 +33056,7 @@ var init_commands = __esm({
|
|
|
32761
33056
|
});
|
|
32762
33057
|
|
|
32763
33058
|
// packages/cli/dist/tui/project-context.js
|
|
32764
|
-
import { existsSync as existsSync31, readFileSync as readFileSync22, readdirSync as
|
|
33059
|
+
import { existsSync as existsSync31, readFileSync as readFileSync22, readdirSync as readdirSync9 } from "node:fs";
|
|
32765
33060
|
import { join as join41, basename as basename10 } from "node:path";
|
|
32766
33061
|
import { execSync as execSync26 } from "node:child_process";
|
|
32767
33062
|
import { homedir as homedir11, platform as platform2, release } from "node:os";
|
|
@@ -32862,7 +33157,7 @@ function loadMemoryDir(memDir, scope) {
|
|
|
32862
33157
|
return "";
|
|
32863
33158
|
const lines = [];
|
|
32864
33159
|
try {
|
|
32865
|
-
const files =
|
|
33160
|
+
const files = readdirSync9(memDir).filter((f) => f.endsWith(".json"));
|
|
32866
33161
|
for (const file of files.slice(0, 10)) {
|
|
32867
33162
|
try {
|
|
32868
33163
|
const raw = readFileSync22(join41(memDir, file), "utf-8");
|
|
@@ -33888,7 +34183,7 @@ var init_carousel = __esm({
|
|
|
33888
34183
|
});
|
|
33889
34184
|
|
|
33890
34185
|
// packages/cli/dist/tui/carousel-descriptors.js
|
|
33891
|
-
import { existsSync as existsSync32, readFileSync as readFileSync23, writeFileSync as writeFileSync12, mkdirSync as mkdirSync12, readdirSync as
|
|
34186
|
+
import { existsSync as existsSync32, readFileSync as readFileSync23, writeFileSync as writeFileSync12, mkdirSync as mkdirSync12, readdirSync as readdirSync10 } from "node:fs";
|
|
33892
34187
|
import { join as join42, basename as basename11 } from "node:path";
|
|
33893
34188
|
function loadToolProfile(repoRoot) {
|
|
33894
34189
|
const filePath = join42(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
|
|
@@ -34101,7 +34396,7 @@ function extractFromMemory(repoRoot, tags) {
|
|
|
34101
34396
|
try {
|
|
34102
34397
|
if (!existsSync32(memoryDir))
|
|
34103
34398
|
return;
|
|
34104
|
-
const files =
|
|
34399
|
+
const files = readdirSync10(memoryDir).filter((f) => f.endsWith(".json"));
|
|
34105
34400
|
for (const file of files) {
|
|
34106
34401
|
const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
|
|
34107
34402
|
tags.push(topic);
|
|
@@ -36662,7 +36957,7 @@ var init_promptLoader3 = __esm({
|
|
|
36662
36957
|
});
|
|
36663
36958
|
|
|
36664
36959
|
// packages/cli/dist/tui/dream-engine.js
|
|
36665
|
-
import { mkdirSync as mkdirSync15, writeFileSync as writeFileSync14, readFileSync as readFileSync26, existsSync as existsSync35, cpSync, rmSync, readdirSync as
|
|
36960
|
+
import { mkdirSync as mkdirSync15, writeFileSync as writeFileSync14, readFileSync as readFileSync26, existsSync as existsSync35, cpSync, rmSync, readdirSync as readdirSync11 } from "node:fs";
|
|
36666
36961
|
import { join as join46, basename as basename12 } from "node:path";
|
|
36667
36962
|
import { execSync as execSync28 } from "node:child_process";
|
|
36668
36963
|
function loadAutoresearchMemory(repoRoot) {
|
|
@@ -37868,7 +38163,7 @@ Each proposal includes implementation entrypoints and estimated effort.
|
|
|
37868
38163
|
/** Update the master proposal index */
|
|
37869
38164
|
updateProposalIndex() {
|
|
37870
38165
|
try {
|
|
37871
|
-
const files =
|
|
38166
|
+
const files = readdirSync11(this.dreamsDir).filter((f) => f.endsWith(".md") && f !== "PROPOSAL-INDEX.md" && f !== "dream-state.json").sort();
|
|
37872
38167
|
const index = `# Dream Proposals Index
|
|
37873
38168
|
|
|
37874
38169
|
**Last updated**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
@@ -38270,7 +38565,7 @@ var init_bless_engine = __esm({
|
|
|
38270
38565
|
});
|
|
38271
38566
|
|
|
38272
38567
|
// packages/cli/dist/tui/dmn-engine.js
|
|
38273
|
-
import { existsSync as existsSync36, readFileSync as readFileSync27, writeFileSync as writeFileSync15, mkdirSync as mkdirSync16, readdirSync as
|
|
38568
|
+
import { existsSync as existsSync36, readFileSync as readFileSync27, writeFileSync as writeFileSync15, mkdirSync as mkdirSync16, readdirSync as readdirSync12, unlinkSync as unlinkSync6 } from "node:fs";
|
|
38274
38569
|
import { join as join47, basename as basename13 } from "node:path";
|
|
38275
38570
|
function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
|
|
38276
38571
|
const competenceReport = competence.length > 0 ? competence.map((c3) => {
|
|
@@ -38982,7 +39277,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
38982
39277
|
if (!existsSync36(dir))
|
|
38983
39278
|
continue;
|
|
38984
39279
|
try {
|
|
38985
|
-
const files =
|
|
39280
|
+
const files = readdirSync12(dir).filter((f) => f.endsWith(".json"));
|
|
38986
39281
|
for (const f of files) {
|
|
38987
39282
|
const topic = basename13(f, ".json");
|
|
38988
39283
|
if (!topics.includes(topic))
|
|
@@ -39013,7 +39308,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
39013
39308
|
try {
|
|
39014
39309
|
const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
|
|
39015
39310
|
writeFileSync15(join47(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
|
|
39016
|
-
const files =
|
|
39311
|
+
const files = readdirSync12(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
|
|
39017
39312
|
if (files.length > 50) {
|
|
39018
39313
|
for (const old of files.slice(0, files.length - 50)) {
|
|
39019
39314
|
try {
|
|
@@ -39030,7 +39325,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
39030
39325
|
});
|
|
39031
39326
|
|
|
39032
39327
|
// packages/cli/dist/tui/snr-engine.js
|
|
39033
|
-
import { existsSync as existsSync37, readdirSync as
|
|
39328
|
+
import { existsSync as existsSync37, readdirSync as readdirSync13, readFileSync as readFileSync28 } from "node:fs";
|
|
39034
39329
|
import { join as join48, basename as basename14 } from "node:path";
|
|
39035
39330
|
function computeDPrime(signalScores, noiseScores) {
|
|
39036
39331
|
if (signalScores.length === 0 || noiseScores.length === 0)
|
|
@@ -39278,7 +39573,7 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
39278
39573
|
if (!existsSync37(dir))
|
|
39279
39574
|
continue;
|
|
39280
39575
|
try {
|
|
39281
|
-
const files =
|
|
39576
|
+
const files = readdirSync13(dir).filter((f) => f.endsWith(".json"));
|
|
39282
39577
|
for (const f of files) {
|
|
39283
39578
|
const topic = basename14(f, ".json");
|
|
39284
39579
|
if (topics.length > 0 && !topics.includes(topic))
|
|
@@ -39851,7 +40146,7 @@ var init_tool_policy = __esm({
|
|
|
39851
40146
|
});
|
|
39852
40147
|
|
|
39853
40148
|
// packages/cli/dist/tui/telegram-bridge.js
|
|
39854
|
-
import { mkdirSync as mkdirSync17, existsSync as existsSync38, unlinkSync as unlinkSync7, readdirSync as
|
|
40149
|
+
import { mkdirSync as mkdirSync17, existsSync as existsSync38, unlinkSync as unlinkSync7, readdirSync as readdirSync14, statSync as statSync10 } from "node:fs";
|
|
39855
40150
|
import { join as join49, resolve as resolve27 } from "node:path";
|
|
39856
40151
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
39857
40152
|
function convertMarkdownToTelegramHTML(md) {
|
|
@@ -42453,7 +42748,7 @@ import { cwd } from "node:process";
|
|
|
42453
42748
|
import { resolve as resolve28, join as join50, dirname as dirname17, extname as extname9 } from "node:path";
|
|
42454
42749
|
import { createRequire as createRequire2 } from "node:module";
|
|
42455
42750
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
42456
|
-
import { readFileSync as readFileSync29, writeFileSync as writeFileSync16, appendFileSync as appendFileSync3, rmSync as rmSync2, readdirSync as
|
|
42751
|
+
import { readFileSync as readFileSync29, writeFileSync as writeFileSync16, appendFileSync as appendFileSync3, rmSync as rmSync2, readdirSync as readdirSync15, mkdirSync as mkdirSync18 } from "node:fs";
|
|
42457
42752
|
import { existsSync as existsSync39 } from "node:fs";
|
|
42458
42753
|
import { homedir as homedir13 } from "node:os";
|
|
42459
42754
|
function formatTimeAgo(date) {
|
|
@@ -42692,7 +42987,7 @@ function gatherMemorySnippets(root) {
|
|
|
42692
42987
|
if (!existsSync39(dir))
|
|
42693
42988
|
continue;
|
|
42694
42989
|
try {
|
|
42695
|
-
for (const f of
|
|
42990
|
+
for (const f of readdirSync15(dir).filter((f2) => f2.endsWith(".json"))) {
|
|
42696
42991
|
const data = JSON.parse(readFileSync29(join50(dir, f), "utf-8"));
|
|
42697
42992
|
for (const val of Object.values(data)) {
|
|
42698
42993
|
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
@@ -44419,7 +44714,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
44419
44714
|
getCallUrl() {
|
|
44420
44715
|
return voiceSession?.tunnelUrl ?? null;
|
|
44421
44716
|
},
|
|
44422
|
-
async exposeStart(kindOrUrl, authKey) {
|
|
44717
|
+
async exposeStart(kindOrUrl, authKey, transport) {
|
|
44423
44718
|
const knownKinds = ["ollama", "vllm", "llvm"];
|
|
44424
44719
|
let kind;
|
|
44425
44720
|
let targetUrl;
|
|
@@ -44429,8 +44724,42 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
44429
44724
|
kind = "custom";
|
|
44430
44725
|
targetUrl = kindOrUrl.includes("://") ? kindOrUrl : `http://${kindOrUrl}`;
|
|
44431
44726
|
}
|
|
44432
|
-
|
|
44433
|
-
|
|
44727
|
+
const effectiveTransport = transport ?? "libp2p";
|
|
44728
|
+
if (effectiveTransport === "libp2p") {
|
|
44729
|
+
const nexusTool = new NexusTool(repoRoot);
|
|
44730
|
+
const p2pGateway = new ExposeP2PGateway({
|
|
44731
|
+
kind,
|
|
44732
|
+
targetUrl,
|
|
44733
|
+
stateDir: join50(repoRoot, ".oa")
|
|
44734
|
+
}, nexusTool);
|
|
44735
|
+
p2pGateway.on("stats", (stats) => {
|
|
44736
|
+
statusBar.setExposeStatus({
|
|
44737
|
+
status: stats.status,
|
|
44738
|
+
totalRequests: stats.totalRequests,
|
|
44739
|
+
activeConnections: stats.activeConnections,
|
|
44740
|
+
modelUsage: stats.modelUsage
|
|
44741
|
+
});
|
|
44742
|
+
});
|
|
44743
|
+
try {
|
|
44744
|
+
const peerId = await p2pGateway.start();
|
|
44745
|
+
exposeGateway = p2pGateway;
|
|
44746
|
+
writeContent(() => {
|
|
44747
|
+
process.stdout.write("\n" + p2pGateway.formatConnectionInfo() + "\n\n");
|
|
44748
|
+
});
|
|
44749
|
+
return peerId;
|
|
44750
|
+
} catch (err) {
|
|
44751
|
+
if (!transport) {
|
|
44752
|
+
writeContent(() => {
|
|
44753
|
+
renderWarning(`libp2p expose failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
44754
|
+
renderInfo("Falling back to cloudflared tunnel...");
|
|
44755
|
+
});
|
|
44756
|
+
} else {
|
|
44757
|
+
throw err;
|
|
44758
|
+
}
|
|
44759
|
+
}
|
|
44760
|
+
}
|
|
44761
|
+
const tunnelGateway = new ExposeGateway({ kind, targetUrl, authKey, stateDir: join50(repoRoot, ".oa") });
|
|
44762
|
+
tunnelGateway.on("stats", (stats) => {
|
|
44434
44763
|
statusBar.setExposeStatus({
|
|
44435
44764
|
status: stats.status,
|
|
44436
44765
|
totalRequests: stats.totalRequests,
|
|
@@ -44439,9 +44768,10 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
44439
44768
|
});
|
|
44440
44769
|
});
|
|
44441
44770
|
try {
|
|
44442
|
-
const url = await
|
|
44771
|
+
const url = await tunnelGateway.start();
|
|
44772
|
+
exposeGateway = tunnelGateway;
|
|
44443
44773
|
writeContent(() => {
|
|
44444
|
-
process.stdout.write("\n" +
|
|
44774
|
+
process.stdout.write("\n" + tunnelGateway.formatConnectionInfo() + "\n\n");
|
|
44445
44775
|
});
|
|
44446
44776
|
return url;
|
|
44447
44777
|
} catch (err) {
|
|
@@ -44462,6 +44792,13 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
44462
44792
|
getExposeInfo() {
|
|
44463
44793
|
if (!exposeGateway)
|
|
44464
44794
|
return null;
|
|
44795
|
+
if (exposeGateway instanceof ExposeP2PGateway) {
|
|
44796
|
+
return {
|
|
44797
|
+
tunnelUrl: exposeGateway.peerId,
|
|
44798
|
+
authKey: "",
|
|
44799
|
+
stats: exposeGateway.formatStats()
|
|
44800
|
+
};
|
|
44801
|
+
}
|
|
44465
44802
|
return {
|
|
44466
44803
|
tunnelUrl: exposeGateway.tunnelUrl,
|
|
44467
44804
|
authKey: exposeGateway.authKey,
|
package/package.json
CHANGED