open-agents-ai 0.186.22 → 0.186.24
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 +36 -16
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -37389,6 +37389,8 @@ var init_expose = __esm({
|
|
|
37389
37389
|
/** Debounce tracking for tunnel restarts */
|
|
37390
37390
|
_lastRestartAttempt = 0;
|
|
37391
37391
|
_consecutiveFailures = 0;
|
|
37392
|
+
/** Cloudflare 429 cooldown — no tunnel starts before this timestamp */
|
|
37393
|
+
_cfRateLimitUntil = 0;
|
|
37392
37394
|
// ── Sponsor rate limiting ──
|
|
37393
37395
|
/** Per-IP sliding window: IP → array of request timestamps */
|
|
37394
37396
|
_rateLimitWindows = /* @__PURE__ */ new Map();
|
|
@@ -37502,6 +37504,10 @@ var init_expose = __esm({
|
|
|
37502
37504
|
let lastStartErr;
|
|
37503
37505
|
this._consecutiveFailures = 0;
|
|
37504
37506
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
37507
|
+
if (this._cfRateLimitUntil > Date.now()) {
|
|
37508
|
+
lastStartErr = new Error("Cloudflare rate limited \u2014 waiting 60s cooldown");
|
|
37509
|
+
break;
|
|
37510
|
+
}
|
|
37505
37511
|
try {
|
|
37506
37512
|
this._lastRestartAttempt = Date.now();
|
|
37507
37513
|
this._tunnelUrl = await this.startCloudflared(port);
|
|
@@ -37510,6 +37516,8 @@ var init_expose = __esm({
|
|
|
37510
37516
|
} catch (err) {
|
|
37511
37517
|
lastStartErr = err instanceof Error ? err : new Error(String(err));
|
|
37512
37518
|
this._consecutiveFailures++;
|
|
37519
|
+
if (this._cfRateLimitUntil > Date.now())
|
|
37520
|
+
break;
|
|
37513
37521
|
if (attempt < 2) {
|
|
37514
37522
|
const delaySec = Math.min(15 * Math.pow(2, attempt), 60);
|
|
37515
37523
|
this.options.onInfo?.(`Tunnel start failed \u2014 retrying in ${delaySec}s (attempt ${attempt + 2}/3)...`);
|
|
@@ -38022,6 +38030,7 @@ var init_expose = __esm({
|
|
|
38022
38030
|
if (hint.includes("address already in use")) {
|
|
38023
38031
|
reject(new Error(`Port ${port} already in use. Another expose gateway may be running. Try: /expose stop first.`));
|
|
38024
38032
|
} else if (hint.includes("429") || hint.includes("Too Many")) {
|
|
38033
|
+
this._cfRateLimitUntil = Date.now() + 6e4;
|
|
38025
38034
|
reject(new Error(`Cloudflare rate limited (429). Wait 60s or use /expose libp2p instead.`));
|
|
38026
38035
|
} else {
|
|
38027
38036
|
reject(new Error(`Cloudflared exited with code ${code}. ${hint ? "Output: " + hint : ""}`));
|
|
@@ -38043,6 +38052,13 @@ var init_expose = __esm({
|
|
|
38043
38052
|
async debouncedRestart() {
|
|
38044
38053
|
if (!this.server || this._proxyPort === 0)
|
|
38045
38054
|
return;
|
|
38055
|
+
if (this._cfRateLimitUntil > Date.now()) {
|
|
38056
|
+
const waitSec2 = Math.ceil((this._cfRateLimitUntil - Date.now()) / 1e3);
|
|
38057
|
+
this._stats.status = "standby";
|
|
38058
|
+
this.emitStats();
|
|
38059
|
+
this.options.onInfo?.(`Cloudflare rate limit active \u2014 tunnel restart paused for ${waitSec2}s. Use /expose tunnel to retry manually.`);
|
|
38060
|
+
return;
|
|
38061
|
+
}
|
|
38046
38062
|
this._consecutiveFailures++;
|
|
38047
38063
|
if (this._consecutiveFailures >= 3) {
|
|
38048
38064
|
this._stats.status = "standby";
|
|
@@ -51417,10 +51433,25 @@ Clone a new voice: /voice clone <wav-file> [name]`);
|
|
|
51417
51433
|
const enabledEps = config.endpoints.filter((e) => e.enabled);
|
|
51418
51434
|
const allModels = enabledEps.flatMap((e) => e.models || []);
|
|
51419
51435
|
const sponsorUrl = tunnelGw?.tunnelUrl || "";
|
|
51420
|
-
|
|
51421
|
-
|
|
51436
|
+
let sponsorPeerId = tunnelGw?.peerId || "";
|
|
51437
|
+
if (!sponsorPeerId) {
|
|
51438
|
+
try {
|
|
51439
|
+
const nexus = new NexusTool(projectDir);
|
|
51440
|
+
const st = String(await nexus.execute({ action: "status" }) ?? "");
|
|
51441
|
+
const pm = st.match(/Peer ID:\s*(12D3KooW\S+)/i);
|
|
51442
|
+
if (pm)
|
|
51443
|
+
sponsorPeerId = pm[1];
|
|
51444
|
+
} catch {
|
|
51445
|
+
}
|
|
51446
|
+
}
|
|
51447
|
+
if (!sponsorUrl && !sponsorPeerId) {
|
|
51448
|
+
renderWarning("No tunnel and no nexus connection \u2014 sponsor not registered.");
|
|
51449
|
+
renderInfo("Connect nexus first (/nexus) or start a tunnel (/expose tunnel).");
|
|
51422
51450
|
return false;
|
|
51423
51451
|
}
|
|
51452
|
+
if (!sponsorUrl) {
|
|
51453
|
+
renderInfo(`P2P-only sponsor (peerId: ${sponsorPeerId.slice(0, 20)}...)`);
|
|
51454
|
+
}
|
|
51424
51455
|
let sponsorName = (config.header.message || "").replace(/^\/+/, "").trim();
|
|
51425
51456
|
if (!sponsorName || sponsorName.length < 2) {
|
|
51426
51457
|
try {
|
|
@@ -51433,18 +51464,8 @@ Clone a new voice: /voice clone <wav-file> [name]`);
|
|
|
51433
51464
|
if (!sponsorName)
|
|
51434
51465
|
sponsorName = "OA Sponsor";
|
|
51435
51466
|
}
|
|
51436
|
-
|
|
51437
|
-
|
|
51438
|
-
try {
|
|
51439
|
-
const nexus = new NexusTool(projectDir);
|
|
51440
|
-
const statusCheck = String(await nexus.execute({ action: "status" }) ?? "");
|
|
51441
|
-
const peerMatch = statusCheck.match(/peerId:\s*(12D3KooW\S+)/i);
|
|
51442
|
-
if (peerMatch) {
|
|
51443
|
-
stablePeerId = peerMatch[1];
|
|
51444
|
-
libp2pPeerId = peerMatch[1];
|
|
51445
|
-
}
|
|
51446
|
-
} catch {
|
|
51447
|
-
}
|
|
51467
|
+
const stablePeerId = sponsorPeerId || `oa-${Date.now()}`;
|
|
51468
|
+
const libp2pPeerId = sponsorPeerId;
|
|
51448
51469
|
const sponsorPayload = {
|
|
51449
51470
|
peerId: stablePeerId,
|
|
51450
51471
|
libp2pPeerId,
|
|
@@ -51460,8 +51481,7 @@ Clone a new voice: /voice clone <wav-file> [name]`);
|
|
|
51460
51481
|
message: config.header.message || sponsorName,
|
|
51461
51482
|
linkUrl: config.header.linkUrl,
|
|
51462
51483
|
linkText: config.header.linkText,
|
|
51463
|
-
status: sponsorUrl ? "active" : "inactive"
|
|
51464
|
-
// don't register without a URL
|
|
51484
|
+
status: sponsorUrl || libp2pPeerId ? "active" : "inactive"
|
|
51465
51485
|
};
|
|
51466
51486
|
try {
|
|
51467
51487
|
const kvResp = await fetch("https://openagents.nexus/api/v1/sponsors", {
|
package/package.json
CHANGED