open-agents-ai 0.186.23 → 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 +29 -21
- 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,22 +51433,24 @@ 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
|
-
if (!
|
|
51422
|
-
let daemonPeerId = "";
|
|
51436
|
+
let sponsorPeerId = tunnelGw?.peerId || "";
|
|
51437
|
+
if (!sponsorPeerId) {
|
|
51423
51438
|
try {
|
|
51424
51439
|
const nexus = new NexusTool(projectDir);
|
|
51425
51440
|
const st = String(await nexus.execute({ action: "status" }) ?? "");
|
|
51426
51441
|
const pm = st.match(/Peer ID:\s*(12D3KooW\S+)/i);
|
|
51427
51442
|
if (pm)
|
|
51428
|
-
|
|
51443
|
+
sponsorPeerId = pm[1];
|
|
51429
51444
|
} catch {
|
|
51430
51445
|
}
|
|
51431
|
-
|
|
51432
|
-
|
|
51433
|
-
|
|
51434
|
-
|
|
51435
|
-
|
|
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).");
|
|
51450
|
+
return false;
|
|
51451
|
+
}
|
|
51452
|
+
if (!sponsorUrl) {
|
|
51453
|
+
renderInfo(`P2P-only sponsor (peerId: ${sponsorPeerId.slice(0, 20)}...)`);
|
|
51436
51454
|
}
|
|
51437
51455
|
let sponsorName = (config.header.message || "").replace(/^\/+/, "").trim();
|
|
51438
51456
|
if (!sponsorName || sponsorName.length < 2) {
|
|
@@ -51446,18 +51464,8 @@ Clone a new voice: /voice clone <wav-file> [name]`);
|
|
|
51446
51464
|
if (!sponsorName)
|
|
51447
51465
|
sponsorName = "OA Sponsor";
|
|
51448
51466
|
}
|
|
51449
|
-
|
|
51450
|
-
|
|
51451
|
-
try {
|
|
51452
|
-
const nexus = new NexusTool(projectDir);
|
|
51453
|
-
const statusCheck = String(await nexus.execute({ action: "status" }) ?? "");
|
|
51454
|
-
const peerMatch = statusCheck.match(/peerId:\s*(12D3KooW\S+)/i);
|
|
51455
|
-
if (peerMatch) {
|
|
51456
|
-
stablePeerId = peerMatch[1];
|
|
51457
|
-
libp2pPeerId = peerMatch[1];
|
|
51458
|
-
}
|
|
51459
|
-
} catch {
|
|
51460
|
-
}
|
|
51467
|
+
const stablePeerId = sponsorPeerId || `oa-${Date.now()}`;
|
|
51468
|
+
const libp2pPeerId = sponsorPeerId;
|
|
51461
51469
|
const sponsorPayload = {
|
|
51462
51470
|
peerId: stablePeerId,
|
|
51463
51471
|
libp2pPeerId,
|
package/package.json
CHANGED