open-agents-ai 0.186.16 → 0.186.18
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 +131 -41
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8895,36 +8895,13 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
8895
8895
|
const currentScriptHash = createHash("sha256").update(DAEMON_SCRIPT).digest("hex").slice(0, 16);
|
|
8896
8896
|
const existingPid = this.getDaemonPid();
|
|
8897
8897
|
if (existingPid) {
|
|
8898
|
-
|
|
8899
|
-
|
|
8900
|
-
|
|
8901
|
-
|
|
8902
|
-
|
|
8903
|
-
const diskHash = createHash("sha256").update(onDisk).digest("hex").slice(0, 16);
|
|
8904
|
-
if (diskHash === currentScriptHash) {
|
|
8905
|
-
needsRestart = false;
|
|
8906
|
-
}
|
|
8907
|
-
} catch {
|
|
8908
|
-
}
|
|
8898
|
+
let processAlive = false;
|
|
8899
|
+
try {
|
|
8900
|
+
process.kill(existingPid, 0);
|
|
8901
|
+
processAlive = true;
|
|
8902
|
+
} catch {
|
|
8909
8903
|
}
|
|
8910
|
-
if (
|
|
8911
|
-
try {
|
|
8912
|
-
process.kill(existingPid, "SIGTERM");
|
|
8913
|
-
} catch {
|
|
8914
|
-
}
|
|
8915
|
-
await new Promise((r) => setTimeout(r, 1e3));
|
|
8916
|
-
try {
|
|
8917
|
-
process.kill(existingPid, 0);
|
|
8918
|
-
process.kill(existingPid, "SIGKILL");
|
|
8919
|
-
} catch {
|
|
8920
|
-
}
|
|
8921
|
-
for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
|
|
8922
|
-
const p = join14(this.nexusDir, f);
|
|
8923
|
-
if (existsSync11(p))
|
|
8924
|
-
await unlink(p).catch(() => {
|
|
8925
|
-
});
|
|
8926
|
-
}
|
|
8927
|
-
} else {
|
|
8904
|
+
if (processAlive) {
|
|
8928
8905
|
const statusFile2 = join14(this.nexusDir, "status.json");
|
|
8929
8906
|
if (existsSync11(statusFile2)) {
|
|
8930
8907
|
try {
|
|
@@ -8933,14 +8910,46 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
8933
8910
|
await this.ensureWallet();
|
|
8934
8911
|
return `Already connected (pid: ${existingPid}, peerId: ${status.peerId})`;
|
|
8935
8912
|
}
|
|
8913
|
+
if (status.error) {
|
|
8914
|
+
try {
|
|
8915
|
+
process.kill(existingPid, "SIGTERM");
|
|
8916
|
+
} catch {
|
|
8917
|
+
}
|
|
8918
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
8919
|
+
}
|
|
8920
|
+
return await this.waitForDaemonReady(existingPid);
|
|
8936
8921
|
} catch {
|
|
8937
8922
|
}
|
|
8938
8923
|
}
|
|
8924
|
+
for (let i = 0; i < 10; i++) {
|
|
8925
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
8926
|
+
if (existsSync11(statusFile2)) {
|
|
8927
|
+
try {
|
|
8928
|
+
const status = JSON.parse(await readFile8(statusFile2, "utf8"));
|
|
8929
|
+
if (status.connected && status.peerId) {
|
|
8930
|
+
await this.ensureWallet();
|
|
8931
|
+
return `Already connected (pid: ${existingPid}, peerId: ${status.peerId})`;
|
|
8932
|
+
}
|
|
8933
|
+
} catch {
|
|
8934
|
+
}
|
|
8935
|
+
}
|
|
8936
|
+
}
|
|
8939
8937
|
try {
|
|
8940
8938
|
process.kill(existingPid, "SIGTERM");
|
|
8941
8939
|
} catch {
|
|
8942
8940
|
}
|
|
8943
8941
|
await new Promise((r) => setTimeout(r, 500));
|
|
8942
|
+
try {
|
|
8943
|
+
process.kill(existingPid, 0);
|
|
8944
|
+
process.kill(existingPid, "SIGKILL");
|
|
8945
|
+
} catch {
|
|
8946
|
+
}
|
|
8947
|
+
}
|
|
8948
|
+
for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
|
|
8949
|
+
const p = join14(this.nexusDir, f);
|
|
8950
|
+
if (existsSync11(p))
|
|
8951
|
+
await unlink(p).catch(() => {
|
|
8952
|
+
});
|
|
8944
8953
|
}
|
|
8945
8954
|
}
|
|
8946
8955
|
for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
|
|
@@ -9144,6 +9153,28 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
9144
9153
|
}
|
|
9145
9154
|
return `Daemon failed to start.${earlyError ? "\n" + earlyError : ""}${earlyOutput ? "\n" + earlyOutput : ""}`;
|
|
9146
9155
|
}
|
|
9156
|
+
/** Wait for an already-spawned daemon to write connected status (up to 20s). */
|
|
9157
|
+
async waitForDaemonReady(pid) {
|
|
9158
|
+
const statusFile = join14(this.nexusDir, "status.json");
|
|
9159
|
+
for (let i = 0; i < 40; i++) {
|
|
9160
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
9161
|
+
if (existsSync11(statusFile)) {
|
|
9162
|
+
try {
|
|
9163
|
+
const status = JSON.parse(await readFile8(statusFile, "utf8"));
|
|
9164
|
+
if (status.error)
|
|
9165
|
+
return `Nexus daemon failed: ${status.error}`;
|
|
9166
|
+
if (status.connected && status.peerId) {
|
|
9167
|
+
await this.ensureWallet();
|
|
9168
|
+
return `Connected to nexus P2P network.
|
|
9169
|
+
Peer ID: ${status.peerId}
|
|
9170
|
+
Daemon PID: ${status.pid}`;
|
|
9171
|
+
}
|
|
9172
|
+
} catch {
|
|
9173
|
+
}
|
|
9174
|
+
}
|
|
9175
|
+
}
|
|
9176
|
+
return `Daemon spawned (pid: ${pid}) but still connecting. Check status in a moment.`;
|
|
9177
|
+
}
|
|
9147
9178
|
async doDisconnect() {
|
|
9148
9179
|
const pid = this.getDaemonPid();
|
|
9149
9180
|
if (!pid)
|
|
@@ -49282,18 +49313,26 @@ import { join as join60 } from "node:path";
|
|
|
49282
49313
|
function startSponsorHeartbeat(payload, getExposeGateway) {
|
|
49283
49314
|
stopSponsorHeartbeat();
|
|
49284
49315
|
_lastRegisteredSponsorPayload = { ...payload };
|
|
49316
|
+
const _stableGetGateway = getExposeGateway;
|
|
49285
49317
|
const HEARTBEAT_MS = 5 * 60 * 1e3;
|
|
49286
49318
|
_sponsorHeartbeatTimer = setInterval(async () => {
|
|
49287
49319
|
if (!_lastRegisteredSponsorPayload)
|
|
49288
49320
|
return;
|
|
49289
49321
|
try {
|
|
49290
|
-
const gw =
|
|
49291
|
-
if (gw
|
|
49292
|
-
|
|
49322
|
+
const gw = _stableGetGateway?.();
|
|
49323
|
+
if (gw) {
|
|
49324
|
+
if (gw.tunnelUrl && gw.tunnelUrl !== _lastRegisteredSponsorPayload.tunnelUrl) {
|
|
49325
|
+
_lastRegisteredSponsorPayload.tunnelUrl = gw.tunnelUrl;
|
|
49326
|
+
}
|
|
49327
|
+
if (gw.models && Array.isArray(gw.models)) {
|
|
49328
|
+
_lastRegisteredSponsorPayload.models = gw.models;
|
|
49329
|
+
}
|
|
49293
49330
|
_lastRegisteredSponsorPayload.status = "active";
|
|
49294
49331
|
}
|
|
49295
49332
|
} catch {
|
|
49296
49333
|
}
|
|
49334
|
+
if (!_lastRegisteredSponsorPayload.tunnelUrl)
|
|
49335
|
+
return;
|
|
49297
49336
|
try {
|
|
49298
49337
|
await fetch("https://openagents.nexus/api/v1/sponsors", {
|
|
49299
49338
|
method: "POST",
|
|
@@ -51079,6 +51118,15 @@ Clone a new voice: /voice clone <wav-file> [name]`);
|
|
|
51079
51118
|
if (pauseGw && "setSponsorLimits" in pauseGw) {
|
|
51080
51119
|
pauseGw.setSponsorLimits({ maxRequestsPerMinute: 0, maxTokensPerDay: 0, maxConcurrent: 0, allowedModels: [] });
|
|
51081
51120
|
}
|
|
51121
|
+
try {
|
|
51122
|
+
await fetch("https://openagents.nexus/api/v1/sponsors", {
|
|
51123
|
+
method: "POST",
|
|
51124
|
+
headers: { "Content-Type": "application/json" },
|
|
51125
|
+
body: JSON.stringify({ name: existingConfig.header?.message || "unknown", status: "inactive", tunnelUrl: pauseGw?.tunnelUrl || "" }),
|
|
51126
|
+
signal: AbortSignal.timeout(5e3)
|
|
51127
|
+
});
|
|
51128
|
+
} catch {
|
|
51129
|
+
}
|
|
51082
51130
|
renderInfo("Sponsorship paused. Tunnel still alive for quick resume.");
|
|
51083
51131
|
renderInfo("/sponsor to resume, /sponsor remove to fully stop.");
|
|
51084
51132
|
return "handled";
|
|
@@ -51134,13 +51182,44 @@ Clone a new voice: /voice clone <wav-file> [name]`);
|
|
|
51134
51182
|
case "pause":
|
|
51135
51183
|
existingConfig.status = "paused";
|
|
51136
51184
|
saveSponsorConfig2(projectDir, existingConfig);
|
|
51185
|
+
stopSponsorHeartbeat();
|
|
51186
|
+
try {
|
|
51187
|
+
await fetch("https://openagents.nexus/api/v1/sponsors", {
|
|
51188
|
+
method: "POST",
|
|
51189
|
+
headers: { "Content-Type": "application/json" },
|
|
51190
|
+
body: JSON.stringify({ name: existingConfig.header?.message || "unknown", status: "inactive" }),
|
|
51191
|
+
signal: AbortSignal.timeout(5e3)
|
|
51192
|
+
});
|
|
51193
|
+
} catch {
|
|
51194
|
+
}
|
|
51137
51195
|
renderInfo("Sponsorship paused. /sponsor to resume.");
|
|
51138
51196
|
return "handled";
|
|
51139
|
-
case "resume":
|
|
51197
|
+
case "resume": {
|
|
51140
51198
|
existingConfig.status = "active";
|
|
51141
51199
|
saveSponsorConfig2(projectDir, existingConfig);
|
|
51142
|
-
|
|
51200
|
+
const resumeGw = ctx.getExposeGateway?.();
|
|
51201
|
+
if (resumeGw?.tunnelUrl) {
|
|
51202
|
+
const resumePayload = {
|
|
51203
|
+
name: existingConfig.header?.message || "OA Sponsor",
|
|
51204
|
+
tunnelUrl: resumeGw.tunnelUrl,
|
|
51205
|
+
authKey: resumeGw.authKey || "",
|
|
51206
|
+
models: [],
|
|
51207
|
+
status: "active"
|
|
51208
|
+
};
|
|
51209
|
+
startSponsorHeartbeat(resumePayload, ctx.getExposeGateway);
|
|
51210
|
+
try {
|
|
51211
|
+
await fetch("https://openagents.nexus/api/v1/sponsors", {
|
|
51212
|
+
method: "POST",
|
|
51213
|
+
headers: { "Content-Type": "application/json" },
|
|
51214
|
+
body: JSON.stringify(resumePayload),
|
|
51215
|
+
signal: AbortSignal.timeout(5e3)
|
|
51216
|
+
});
|
|
51217
|
+
} catch {
|
|
51218
|
+
}
|
|
51219
|
+
}
|
|
51220
|
+
renderInfo("Sponsorship resumed. Heartbeat restarted.");
|
|
51143
51221
|
return "handled";
|
|
51222
|
+
}
|
|
51144
51223
|
case "remove":
|
|
51145
51224
|
existingConfig.status = "inactive";
|
|
51146
51225
|
saveSponsorConfig2(projectDir, existingConfig);
|
|
@@ -53183,9 +53262,15 @@ async function handleSponsoredEndpoint(ctx, local) {
|
|
|
53183
53262
|
if (isConnected) {
|
|
53184
53263
|
renderInfo("Using existing nexus connection...");
|
|
53185
53264
|
} else {
|
|
53186
|
-
|
|
53187
|
-
|
|
53188
|
-
|
|
53265
|
+
const hasPid = statusResult.includes("PID:") || statusResult.includes("pid:");
|
|
53266
|
+
if (!hasPid) {
|
|
53267
|
+
renderInfo("Starting nexus daemon...");
|
|
53268
|
+
await nexusTool.execute({ action: "connect" });
|
|
53269
|
+
await new Promise((r) => setTimeout(r, 3e3));
|
|
53270
|
+
} else {
|
|
53271
|
+
renderInfo("Waiting for nexus daemon to connect...");
|
|
53272
|
+
await new Promise((r) => setTimeout(r, 5e3));
|
|
53273
|
+
}
|
|
53189
53274
|
}
|
|
53190
53275
|
renderInfo("Querying sponsors on the mesh...");
|
|
53191
53276
|
const discoverResult = await nexusTool.execute({
|
|
@@ -53315,9 +53400,14 @@ async function handleSponsoredEndpoint(ctx, local) {
|
|
|
53315
53400
|
if (sp.authKey)
|
|
53316
53401
|
headers["Authorization"] = `Bearer ${sp.authKey}`;
|
|
53317
53402
|
const resp = await fetch(`${base}/v1/models`, { headers, signal: AbortSignal.timeout(15e3) });
|
|
53403
|
+
if (resp.status === 429 || resp.status === 503)
|
|
53404
|
+
return true;
|
|
53318
53405
|
if (!resp.ok && sp.authKey) {
|
|
53319
|
-
|
|
53320
|
-
|
|
53406
|
+
if (resp.status === 401) {
|
|
53407
|
+
const noAuth = await fetch(`${base}/v1/models`, { signal: AbortSignal.timeout(1e4) });
|
|
53408
|
+
return noAuth.ok || noAuth.status === 429 || noAuth.status === 503;
|
|
53409
|
+
}
|
|
53410
|
+
return false;
|
|
53321
53411
|
}
|
|
53322
53412
|
return resp.ok;
|
|
53323
53413
|
} catch {
|
|
@@ -71763,13 +71853,13 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
71763
71853
|
if (sponsor.authKey)
|
|
71764
71854
|
headers["Authorization"] = `Bearer ${sponsor.authKey}`;
|
|
71765
71855
|
const probe = await fetch(testUrl, { headers, signal: AbortSignal.timeout(15e3) });
|
|
71766
|
-
if (probe.ok) {
|
|
71856
|
+
if (probe.ok || probe.status === 429 || probe.status === 503) {
|
|
71767
71857
|
best = sponsor;
|
|
71768
71858
|
break;
|
|
71769
71859
|
}
|
|
71770
71860
|
if (probe.status === 401 && sponsor.authKey) {
|
|
71771
71861
|
const noAuthProbe = await fetch(testUrl, { signal: AbortSignal.timeout(1e4) });
|
|
71772
|
-
if (noAuthProbe.ok) {
|
|
71862
|
+
if (noAuthProbe.ok || noAuthProbe.status === 429 || noAuthProbe.status === 503) {
|
|
71773
71863
|
best = sponsor;
|
|
71774
71864
|
bestNoAuth = true;
|
|
71775
71865
|
break;
|
package/package.json
CHANGED