@okxweb3/a2a-node 0.2.16 → 0.2.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.
Files changed (3) hide show
  1. package/dist/cli.js +393 -69
  2. package/dist/index.js +400 -70
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4256,8 +4256,8 @@ var require_worldwide = __commonJS({
4256
4256
  function getGlobalSingleton(name, creator, obj) {
4257
4257
  const gbl = obj || GLOBAL_OBJ;
4258
4258
  const __SENTRY__ = gbl.__SENTRY__ = gbl.__SENTRY__ || {};
4259
- const singleton2 = __SENTRY__[name] || (__SENTRY__[name] = creator());
4260
- return singleton2;
4259
+ const singleton3 = __SENTRY__[name] || (__SENTRY__[name] = creator());
4260
+ return singleton3;
4261
4261
  }
4262
4262
  exports2.GLOBAL_OBJ = GLOBAL_OBJ;
4263
4263
  exports2.getGlobalObject = getGlobalObject;
@@ -19302,6 +19302,14 @@ var init_events = __esm({
19302
19302
  SYSTEM_NOTIFICATION_ROUTED: "System notification routed",
19303
19303
  HERMES_SESSION_ROUTE_BINDING: "Hermes session route binding",
19304
19304
  DOCTOR_REPORT: "Doctor report",
19305
+ // XMTP creation rate-limit cooldown (DEXMARKET-9116). All four are logger.info,
19306
+ // so each one must also be listed in SENTRY_INFO_ALLOWLIST (index.ts) or info()
19307
+ // drops it silently. Extras are bounded tokens/ints/bools only — never raw SDK
19308
+ // error text (no-content-leak invariant).
19309
+ XMTP_RATE_LIMIT_COOLDOWN_STARTED: "XMTP rate limit cooldown started",
19310
+ XMTP_RATE_LIMIT_CREATE_SUPPRESSED: "XMTP rate limit create suppressed",
19311
+ XMTP_RATE_LIMIT_PROBE: "XMTP rate limit probe",
19312
+ XMTP_RATE_LIMIT_RECOVERED: "XMTP rate limit recovered",
19305
19313
  // ── error ─────────────────────────────────────────────────────
19306
19314
  XMTP_CONNECTION_FAILED: "XMTP connection failed",
19307
19315
  CONVERSATIONS_STREAM_FAILED: "conversations.stream failed",
@@ -19367,7 +19375,10 @@ var init_events = __esm({
19367
19375
  AGENT_DB_DIR_CREATE_FAILED: "Agent DB dir create failed",
19368
19376
  AGENT_INSTALLATION_LIMIT_NEAR: "Agent installation limit near",
19369
19377
  XMTP_HISTORY_SYNC_REQUEST_FAILED: "XMTP history sync request failed",
19370
- XMTP_DEBUG_SYNC_FAILED: "XMTP debug sync failed"
19378
+ XMTP_DEBUG_SYNC_FAILED: "XMTP debug sync failed",
19379
+ // Underlying XMTP SDK client close failed during recycle/removal/shutdown
19380
+ // (DEXMARKET-9116). Error-level → NOT added to SENTRY_INFO_ALLOWLIST.
19381
+ XMTP_CLIENT_CLOSE_FAILED: "XMTP client close failed"
19371
19382
  };
19372
19383
  }
19373
19384
  });
@@ -20212,7 +20223,13 @@ var init_sentry_logger = __esm({
20212
20223
  LogEvent.PENDING_LIST_QUERIED,
20213
20224
  LogEvent.SESSION_KEY_DERIVED,
20214
20225
  LogEvent.SESSIONS_QUERIED,
20215
- LogEvent.SYNC_TICK_COMPLETED
20226
+ LogEvent.SYNC_TICK_COMPLETED,
20227
+ // XMTP creation rate-limit cooldown checkpoints (DEXMARKET-9116). info() drops
20228
+ // any event not listed here, so these must stay registered.
20229
+ LogEvent.XMTP_RATE_LIMIT_COOLDOWN_STARTED,
20230
+ LogEvent.XMTP_RATE_LIMIT_CREATE_SUPPRESSED,
20231
+ LogEvent.XMTP_RATE_LIMIT_PROBE,
20232
+ LogEvent.XMTP_RATE_LIMIT_RECOVERED
20216
20233
  ]);
20217
20234
  MAX_EXTRA_STRING_LENGTH = 256;
20218
20235
  MAX_TAG_VALUE_LENGTH = 128;
@@ -32448,7 +32465,7 @@ var init_sentry_config = __esm({
32448
32465
  environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
32449
32466
  SENTRY_CONFIG = {
32450
32467
  projectName: "okx/openclaw-okx-a2a-extension",
32451
- release: "0.2.16",
32468
+ release: "0.2.17",
32452
32469
  environment,
32453
32470
  runtimeContainer: normalizeRuntimeContainer(process.env.OKX_A2A_RUNTIME_CONTAINER)
32454
32471
  };
@@ -33404,7 +33421,7 @@ async function getCurrentNodeCliVersion() {
33404
33421
  return await getGlobalNpmPackageVersion(UPDATE_PACKAGES.node) ?? getBundledNodeCliVersion();
33405
33422
  }
33406
33423
  function getBundledNodeCliVersion() {
33407
- return true ? "0.2.16" : null;
33424
+ return true ? "0.2.17" : null;
33408
33425
  }
33409
33426
  function readConfiguredAiProvider() {
33410
33427
  const explicit = process.env.OKX_A2A_AI_PROVIDER || process.env.OKX_AGENT_TASK_AI_CLI;
@@ -33614,7 +33631,7 @@ async function updateHermes(release, options) {
33614
33631
  }
33615
33632
  }
33616
33633
  async function installGatewayPluginForDoctor(target) {
33617
- const release = isPrereleaseVersion("0.2.16") ? "beta" : "latest";
33634
+ const release = isPrereleaseVersion("0.2.17") ? "beta" : "latest";
33618
33635
  const insideTargetGateway = detectGatewayInvocation() === target;
33619
33636
  const options = {
33620
33637
  restart: !insideTargetGateway,
@@ -44359,6 +44376,9 @@ __export(index_exports, {
44359
44376
  UserCancelledAiProviderSelectionError: () => UserCancelledAiProviderSelectionError,
44360
44377
  WALLET_STATUS_TIMEOUT_MS: () => WALLET_STATUS_TIMEOUT_MS,
44361
44378
  XMTP_CLIENT_RECYCLE_INTERVAL_ENV: () => XMTP_CLIENT_RECYCLE_INTERVAL_ENV,
44379
+ XMTP_CREATION_COOLDOWN_MS: () => XMTP_CREATION_COOLDOWN_MS,
44380
+ XmtpCreationCooldown: () => XmtpCreationCooldown,
44381
+ XmtpCreationCooldownSkipError: () => XmtpCreationCooldownSkipError,
44362
44382
  XmtpDm: () => Dm,
44363
44383
  XmtpGroup: () => Group,
44364
44384
  XmtpService: () => XmtpService,
@@ -44439,6 +44459,7 @@ __export(index_exports, {
44439
44459
  exportDiagnosticLogs: () => exportDiagnosticLogs,
44440
44460
  extractAiSessionId: () => extractAiSessionId,
44441
44461
  extractDirectToUserNotification: () => extractDirectToUserNotification,
44462
+ extractRateLimitEndpoint: () => extractRateLimitEndpoint,
44442
44463
  extractXmtpSentAtMs: () => extractXmtpSentAtMs2,
44443
44464
  findWindowsNativeOkxA2aExe: () => findWindowsNativeOkxA2aExe,
44444
44465
  followFile: () => followFile,
@@ -44449,6 +44470,7 @@ __export(index_exports, {
44449
44470
  getResolvedOnchainosBinForTests: () => getResolvedOnchainosBinForTests,
44450
44471
  getRuntimeMetadata: () => getRuntimeMetadata,
44451
44472
  getSessionBusyTracker: () => getSessionBusyTracker,
44473
+ getXmtpCreationCooldown: () => getXmtpCreationCooldown,
44452
44474
  handleCapabilitiesCommand: () => handleCapabilitiesCommand,
44453
44475
  handleDoctorCommand: () => handleDoctorCommand,
44454
44476
  handleXmtpDebugCommand: () => handleXmtpDebugCommand,
@@ -44479,6 +44501,7 @@ __export(index_exports, {
44479
44501
  isTagKey: () => isTagKey,
44480
44502
  isValidExternalJobId: () => isValidExternalJobId,
44481
44503
  isWindowsElevated: () => isWindowsElevated,
44504
+ isXmtpRateLimitError: () => isXmtpRateLimitError,
44482
44505
  killProcessTree: () => killProcessTree,
44483
44506
  launchdPlistHasCurrentRestartPolicy: () => launchdPlistHasCurrentRestartPolicy,
44484
44507
  listAllAgentsWithMetadata: () => listAllAgentsWithMetadata,
@@ -44528,6 +44551,7 @@ __export(index_exports, {
44528
44551
  reportUserNotificationFailure: () => reportUserNotificationFailure,
44529
44552
  resetMessageEligibleOfflineReplayCapabilityForTests: () => resetMessageEligibleOfflineReplayCapabilityForTests,
44530
44553
  resetResolvedOnchainosBinForTests: () => resetResolvedOnchainosBinForTests,
44554
+ resetXmtpCreationCooldownForTests: () => resetXmtpCreationCooldownForTests,
44531
44555
  resolveAiPermissionPreset: () => resolveAiPermissionPreset,
44532
44556
  resolveAiProviderCommand: () => resolveAiProviderCommand,
44533
44557
  resolveAiProviderCommandWithSource: () => resolveAiProviderCommandWithSource,
@@ -44575,6 +44599,7 @@ __export(index_exports, {
44575
44599
  startDaemonRespectingSupervisor: () => startDaemonRespectingSupervisor,
44576
44600
  startUserAttentionEventServer: () => startUserAttentionEventServer,
44577
44601
  startUserAttentionWatcherCoordinator: () => startUserAttentionWatcherCoordinator,
44602
+ stopAndCloseXmtpClient: () => stopAndCloseXmtpClient,
44578
44603
  stopDaemon: () => stopDaemon,
44579
44604
  stopOpenClawGateway: () => stopOpenClawGateway,
44580
44605
  stopSystemdAutostart: () => stopSystemdAutostart,
@@ -56467,6 +56492,188 @@ function reportSessionExpired(command) {
56467
56492
  );
56468
56493
  }
56469
56494
 
56495
+ // ../core/src/xmtp-sdk/rate-limit-cooldown.ts
56496
+ var MAX_CAUSE_DEPTH2 = 4;
56497
+ var XMTP_CREATION_COOLDOWN_MS = 33e4;
56498
+ var RATE_LIMIT_PATTERNS = [
56499
+ /some resource has been exhausted/i,
56500
+ /exceeds rate limit/i,
56501
+ /resource_exhausted/i
56502
+ ];
56503
+ var KNOWN_RATE_LIMIT_ENDPOINTS = [
56504
+ /\bGetInboxIds\b/i,
56505
+ /\bGetIdentityUpdates\b/i
56506
+ ];
56507
+ function asErrorLike2(value) {
56508
+ return value instanceof Error ? value : void 0;
56509
+ }
56510
+ function causeChain2(err) {
56511
+ const chain = [];
56512
+ const seen = /* @__PURE__ */ new Set();
56513
+ let current = err;
56514
+ while (chain.length < MAX_CAUSE_DEPTH2) {
56515
+ chain.push(current);
56516
+ const errorLike = asErrorLike2(current);
56517
+ if (!errorLike || seen.has(errorLike)) {
56518
+ break;
56519
+ }
56520
+ seen.add(errorLike);
56521
+ current = errorLike.cause;
56522
+ if (current === void 0) {
56523
+ break;
56524
+ }
56525
+ }
56526
+ return chain;
56527
+ }
56528
+ function messageOf(node) {
56529
+ return (node instanceof Error ? node.message : String(node)).toLowerCase();
56530
+ }
56531
+ function isXmtpRateLimitError(err) {
56532
+ if (err === void 0 || err === null) {
56533
+ return false;
56534
+ }
56535
+ const chain = causeChain2(err);
56536
+ return chain.some(
56537
+ (node) => RATE_LIMIT_PATTERNS.some((pattern) => pattern.test(messageOf(node)))
56538
+ );
56539
+ }
56540
+ function extractRateLimitEndpoint(err) {
56541
+ if (err === void 0 || err === null) {
56542
+ return void 0;
56543
+ }
56544
+ const chain = causeChain2(err);
56545
+ for (const node of chain) {
56546
+ const message = messageOf(node);
56547
+ for (const pattern of KNOWN_RATE_LIMIT_ENDPOINTS) {
56548
+ const match = pattern.exec(message);
56549
+ if (match) {
56550
+ return /GetInboxIds/i.test(match[0]) ? "GetInboxIds" : "GetIdentityUpdates";
56551
+ }
56552
+ }
56553
+ }
56554
+ return void 0;
56555
+ }
56556
+ var XmtpCreationCooldownSkipError = class extends Error {
56557
+ remainingMs;
56558
+ address;
56559
+ agentId;
56560
+ constructor(remainingMs, address, agentId) {
56561
+ super("xmtp creation suppressed during rate-limit cooldown");
56562
+ this.name = "XmtpCreationCooldownSkipError";
56563
+ this.remainingMs = remainingMs;
56564
+ this.address = address;
56565
+ this.agentId = agentId;
56566
+ }
56567
+ };
56568
+ var XmtpCreationCooldown = class {
56569
+ cooldownUntilMs = null;
56570
+ probeInFlight = false;
56571
+ suppressedCreateCount = 0;
56572
+ rateLimitHitCount = 0;
56573
+ probeCount = 0;
56574
+ inFlightCreateCount = 0;
56575
+ beginCreateAttempt(nowMs = Date.now()) {
56576
+ if (this.cooldownUntilMs === null) {
56577
+ this.inFlightCreateCount++;
56578
+ return { allowed: true, mode: "normal" };
56579
+ }
56580
+ if (nowMs < this.cooldownUntilMs) {
56581
+ this.suppressedCreateCount++;
56582
+ return {
56583
+ allowed: false,
56584
+ mode: "blocked",
56585
+ remainingMs: Math.max(0, this.cooldownUntilMs - nowMs)
56586
+ };
56587
+ }
56588
+ if (this.probeInFlight) {
56589
+ this.suppressedCreateCount++;
56590
+ return { allowed: false, mode: "blocked", remainingMs: 0 };
56591
+ }
56592
+ this.probeInFlight = true;
56593
+ this.inFlightCreateCount++;
56594
+ this.probeCount++;
56595
+ return { allowed: true, mode: "probe" };
56596
+ }
56597
+ recordCreateSuccess(decision, _nowMs = Date.now()) {
56598
+ this.inFlightCreateCount = Math.max(0, this.inFlightCreateCount - 1);
56599
+ if (decision.mode === "probe") {
56600
+ this.cooldownUntilMs = null;
56601
+ this.probeInFlight = false;
56602
+ }
56603
+ }
56604
+ recordRateLimit(decision, nowMs = Date.now()) {
56605
+ this.inFlightCreateCount = Math.max(0, this.inFlightCreateCount - 1);
56606
+ this.cooldownUntilMs = nowMs + XMTP_CREATION_COOLDOWN_MS;
56607
+ this.rateLimitHitCount++;
56608
+ this.probeInFlight = false;
56609
+ void decision;
56610
+ }
56611
+ recordCreateFailure(decision, nowMs = Date.now()) {
56612
+ this.inFlightCreateCount = Math.max(0, this.inFlightCreateCount - 1);
56613
+ if (decision.mode === "probe") {
56614
+ this.cooldownUntilMs = nowMs + XMTP_CREATION_COOLDOWN_MS;
56615
+ this.probeInFlight = false;
56616
+ }
56617
+ }
56618
+ isCoolingDown(nowMs = Date.now()) {
56619
+ return this.cooldownUntilMs !== null && nowMs < this.cooldownUntilMs;
56620
+ }
56621
+ remainingMs(nowMs = Date.now()) {
56622
+ return this.cooldownUntilMs === null ? 0 : Math.max(0, this.cooldownUntilMs - nowMs);
56623
+ }
56624
+ snapshot(nowMs = Date.now()) {
56625
+ return {
56626
+ coolingDown: this.isCoolingDown(nowMs),
56627
+ cooldownUntilMs: this.cooldownUntilMs,
56628
+ remainingMs: this.remainingMs(nowMs),
56629
+ probeInFlight: this.probeInFlight,
56630
+ suppressedCreateCount: this.suppressedCreateCount,
56631
+ rateLimitHitCount: this.rateLimitHitCount,
56632
+ probeCount: this.probeCount,
56633
+ inFlightCreateCount: this.inFlightCreateCount
56634
+ };
56635
+ }
56636
+ resetForTests() {
56637
+ this.cooldownUntilMs = null;
56638
+ this.probeInFlight = false;
56639
+ this.suppressedCreateCount = 0;
56640
+ this.rateLimitHitCount = 0;
56641
+ this.probeCount = 0;
56642
+ this.inFlightCreateCount = 0;
56643
+ }
56644
+ };
56645
+ var singleton;
56646
+ function getXmtpCreationCooldown() {
56647
+ if (!singleton) {
56648
+ singleton = new XmtpCreationCooldown();
56649
+ }
56650
+ return singleton;
56651
+ }
56652
+ function resetXmtpCreationCooldownForTests() {
56653
+ getXmtpCreationCooldown().resetForTests();
56654
+ }
56655
+
56656
+ // ../core/src/xmtp-sdk/client-lifecycle.ts
56657
+ async function stopAndCloseXmtpClient(agent, ctx) {
56658
+ let stopped = true;
56659
+ try {
56660
+ await Promise.resolve(agent.stop());
56661
+ } catch {
56662
+ stopped = false;
56663
+ }
56664
+ const close2 = agent.client?.close;
56665
+ if (typeof close2 !== "function") {
56666
+ return { stopped, closed: false, closeFailed: false };
56667
+ }
56668
+ try {
56669
+ await Promise.resolve(close2.call(agent.client));
56670
+ return { stopped, closed: true, closeFailed: false };
56671
+ } catch (err) {
56672
+ ctx.onCloseError?.(err);
56673
+ return { stopped, closed: false, closeFailed: true };
56674
+ }
56675
+ }
56676
+
56470
56677
  // ../core/src/xmtp-sdk/index.ts
56471
56678
  var DEFAULT_DATA_DIR = resolveA2aTaskPaths().xmtpDir;
56472
56679
  var XMTP_INSTALLATION_WARNING_THRESHOLD = 2;
@@ -57150,21 +57357,78 @@ var XmtpService = class _XmtpService {
57150
57357
  }
57151
57358
  async createClientForAgent(agentInfo, options = {}) {
57152
57359
  const address = agentInfo.communicationAddress;
57153
- const signer = this.tools.createSigner(agentInfo);
57154
- const dbPath = (inboxId2) => `${this.dataDir}/${inboxId2}-${this.env}.db3`;
57155
- const agent = await createAgentWithInstallationPrune(signer, {
57156
- dbPath,
57157
- env: this.env
57158
- }, {
57159
- address,
57160
- agentId: agentInfo.agentId,
57161
- logPrefix: options.logPrefix
57162
- });
57163
- const inboxId = agent.client?.inboxId ?? "";
57164
- logWithTimestamp(
57165
- `[xmtp-sdk] xmtp_client_ready agentId=${agentInfo.agentId} address=${address} inboxId=${inboxId} dbPath=${inboxId ? dbPath(inboxId) : "(unknown)"} lastSync=${formatLogTimestamp2(this.syncByAddress.get(address))}`
57166
- );
57167
- return { address, agent, agentInfo };
57360
+ const phase = options.logPrefix ?? "[xmtp-sdk]";
57361
+ const cooldown = getXmtpCreationCooldown();
57362
+ const decision = cooldown.beginCreateAttempt();
57363
+ if (!decision.allowed) {
57364
+ logger.info(LogEvent.XMTP_RATE_LIMIT_CREATE_SUPPRESSED, {
57365
+ onchainosAgentId: agentInfo.agentId,
57366
+ walletAddress: address,
57367
+ cooldownRemainingMs: String(decision.remainingMs ?? 0),
57368
+ phase
57369
+ });
57370
+ throw new XmtpCreationCooldownSkipError(
57371
+ decision.remainingMs ?? 0,
57372
+ address,
57373
+ agentInfo.agentId
57374
+ );
57375
+ }
57376
+ if (decision.mode === "probe") {
57377
+ logger.info(LogEvent.XMTP_RATE_LIMIT_PROBE, {
57378
+ onchainosAgentId: agentInfo.agentId,
57379
+ walletAddress: address,
57380
+ phase: "probe-start",
57381
+ probeCount: String(cooldown.snapshot().probeCount)
57382
+ });
57383
+ }
57384
+ try {
57385
+ const signer = this.tools.createSigner(agentInfo);
57386
+ const dbPath = (inboxId2) => `${this.dataDir}/${inboxId2}-${this.env}.db3`;
57387
+ const agent = await createAgentWithInstallationPrune(signer, {
57388
+ dbPath,
57389
+ env: this.env
57390
+ }, {
57391
+ address,
57392
+ agentId: agentInfo.agentId,
57393
+ logPrefix: options.logPrefix
57394
+ });
57395
+ cooldown.recordCreateSuccess(decision);
57396
+ if (decision.mode === "probe") {
57397
+ logger.info(LogEvent.XMTP_RATE_LIMIT_RECOVERED, {
57398
+ onchainosAgentId: agentInfo.agentId,
57399
+ walletAddress: address,
57400
+ phase: "probe-success"
57401
+ });
57402
+ }
57403
+ const inboxId = agent.client?.inboxId ?? "";
57404
+ logWithTimestamp(
57405
+ `[xmtp-sdk] xmtp_client_ready agentId=${agentInfo.agentId} address=${address} inboxId=${inboxId} dbPath=${inboxId ? dbPath(inboxId) : "(unknown)"} lastSync=${formatLogTimestamp2(this.syncByAddress.get(address))}`
57406
+ );
57407
+ return { address, agent, agentInfo };
57408
+ } catch (err) {
57409
+ if (isXmtpRateLimitError(err)) {
57410
+ cooldown.recordRateLimit(decision);
57411
+ logger.info(LogEvent.XMTP_RATE_LIMIT_COOLDOWN_STARTED, {
57412
+ ...agentExtras({ walletAddress: address, onchainosAgentId: agentInfo.agentId }),
57413
+ rateLimitIdentified: "true",
57414
+ endpoint: extractRateLimitEndpoint(err) ?? "unknown",
57415
+ cooldownMs: String(XMTP_CREATION_COOLDOWN_MS),
57416
+ cooldownExpiresAtMs: String(cooldown.snapshot().cooldownUntilMs ?? ""),
57417
+ inFlightCreateCount: String(cooldown.snapshot().inFlightCreateCount),
57418
+ probe: String(decision.mode === "probe")
57419
+ });
57420
+ } else {
57421
+ cooldown.recordCreateFailure(decision);
57422
+ if (decision.mode === "probe") {
57423
+ logger.info(LogEvent.XMTP_RATE_LIMIT_PROBE, {
57424
+ onchainosAgentId: agentInfo.agentId,
57425
+ walletAddress: address,
57426
+ phase: "probe-failed-nonratelimit"
57427
+ });
57428
+ }
57429
+ }
57430
+ throw err;
57431
+ }
57168
57432
  }
57169
57433
  async recordInstallationHealth(params) {
57170
57434
  const { address, agent, agentInfo, phase, attempt } = params;
@@ -57315,22 +57579,28 @@ var XmtpService = class _XmtpService {
57315
57579
  });
57316
57580
  } else {
57317
57581
  failedAgents.push(agents[i]);
57318
- logWithTimestamp(
57319
- `[xmtp-sdk] identity init failed: ${agents[i].communicationAddress} (agentId=${agents[i].agentId})`,
57320
- r.reason
57321
- );
57322
- logger.error(
57323
- LogEvent.XMTP_CONNECTION_FAILED,
57324
- r.reason instanceof Error ? r.reason : new Error(String(r.reason)),
57325
- {
57326
- walletAddress: agents[i].communicationAddress,
57327
- onchainosAgentId: agents[i].agentId,
57328
- attempt: "1"
57329
- }
57330
- );
57582
+ if (r.reason instanceof XmtpCreationCooldownSkipError) {
57583
+ logWithTimestamp(
57584
+ `[xmtp-sdk] identity init suppressed (rate-limit cooldown): ${agents[i].communicationAddress} (agentId=${agents[i].agentId})`
57585
+ );
57586
+ } else {
57587
+ logWithTimestamp(
57588
+ `[xmtp-sdk] identity init failed: ${agents[i].communicationAddress} (agentId=${agents[i].agentId})`,
57589
+ r.reason
57590
+ );
57591
+ logger.error(
57592
+ LogEvent.XMTP_CONNECTION_FAILED,
57593
+ r.reason instanceof Error ? r.reason : new Error(String(r.reason)),
57594
+ {
57595
+ walletAddress: agents[i].communicationAddress,
57596
+ onchainosAgentId: agents[i].agentId,
57597
+ attempt: "1"
57598
+ }
57599
+ );
57600
+ }
57331
57601
  }
57332
57602
  }
57333
- if (failedAgents.length > 0) {
57603
+ if (failedAgents.length > 0 && !getXmtpCreationCooldown().isCoolingDown()) {
57334
57604
  logWithTimestamp(
57335
57605
  `[xmtp-sdk] ${failedAgents.length} client(s) failed to initialize, retrying in 1s...`
57336
57606
  );
@@ -57370,6 +57640,11 @@ var XmtpService = class _XmtpService {
57370
57640
  phase: "init",
57371
57641
  attempt: "2"
57372
57642
  });
57643
+ } else if (r.reason instanceof XmtpCreationCooldownSkipError) {
57644
+ const info = failedAgents[i];
57645
+ logWithTimestamp(
57646
+ `[xmtp-sdk] retry suppressed (rate-limit cooldown): ${info.communicationAddress} (agentId=${info.agentId})`
57647
+ );
57373
57648
  } else {
57374
57649
  const info = failedAgents[i];
57375
57650
  logWithTimestamp(
@@ -57465,7 +57740,16 @@ var XmtpService = class _XmtpService {
57465
57740
  try {
57466
57741
  this.cancelStreamRecoveryForAddress(address);
57467
57742
  this.stoppedAddresses.add(address.toLowerCase());
57468
- client.stop();
57743
+ await stopAndCloseXmtpClient(client, {
57744
+ address,
57745
+ agentId: agentInfo.agentId,
57746
+ phase: "refresh/remove",
57747
+ onCloseError: (err) => logger.error(
57748
+ LogEvent.XMTP_CLIENT_CLOSE_FAILED,
57749
+ err instanceof Error ? err : new Error(String(err)),
57750
+ { walletAddress: address, onchainosAgentId: agentInfo.agentId, phase: "refresh/remove" }
57751
+ )
57752
+ });
57469
57753
  logWithTimestamp(
57470
57754
  `[xmtp-sdk] refresh: stopped client: ${address} (agentId=${agentInfo.agentId})`
57471
57755
  );
@@ -57552,23 +57836,29 @@ var XmtpService = class _XmtpService {
57552
57836
  });
57553
57837
  } else {
57554
57838
  failedAgents.push(added[i]);
57555
- logWithTimestamp(
57556
- `[xmtp-sdk] refresh: identity init failed: ${added[i].communicationAddress} (agentId=${added[i].agentId})`,
57557
- r.reason
57558
- );
57559
- logger.error(
57560
- LogEvent.XMTP_CONNECTION_FAILED,
57561
- r.reason instanceof Error ? r.reason : new Error(String(r.reason)),
57562
- {
57563
- walletAddress: added[i].communicationAddress,
57564
- onchainosAgentId: added[i].agentId,
57565
- phase: "refresh",
57566
- attempt: "1"
57567
- }
57568
- );
57839
+ if (r.reason instanceof XmtpCreationCooldownSkipError) {
57840
+ logWithTimestamp(
57841
+ `[xmtp-sdk] refresh: identity init suppressed (rate-limit cooldown): ${added[i].communicationAddress} (agentId=${added[i].agentId})`
57842
+ );
57843
+ } else {
57844
+ logWithTimestamp(
57845
+ `[xmtp-sdk] refresh: identity init failed: ${added[i].communicationAddress} (agentId=${added[i].agentId})`,
57846
+ r.reason
57847
+ );
57848
+ logger.error(
57849
+ LogEvent.XMTP_CONNECTION_FAILED,
57850
+ r.reason instanceof Error ? r.reason : new Error(String(r.reason)),
57851
+ {
57852
+ walletAddress: added[i].communicationAddress,
57853
+ onchainosAgentId: added[i].agentId,
57854
+ phase: "refresh",
57855
+ attempt: "1"
57856
+ }
57857
+ );
57858
+ }
57569
57859
  }
57570
57860
  }
57571
- if (failedAgents.length > 0) {
57861
+ if (failedAgents.length > 0 && !getXmtpCreationCooldown().isCoolingDown()) {
57572
57862
  logWithTimestamp(
57573
57863
  `[xmtp-sdk] refresh: ${failedAgents.length} client(s) failed to initialize, retrying in 1s...`
57574
57864
  );
@@ -57611,6 +57901,11 @@ var XmtpService = class _XmtpService {
57611
57901
  phase: "refresh",
57612
57902
  attempt: "2"
57613
57903
  });
57904
+ } else if (r.reason instanceof XmtpCreationCooldownSkipError) {
57905
+ const info = failedAgents[i];
57906
+ logWithTimestamp(
57907
+ `[xmtp-sdk] refresh: retry suppressed (rate-limit cooldown): ${info.communicationAddress} (agentId=${info.agentId})`
57908
+ );
57614
57909
  } else {
57615
57910
  const info = failedAgents[i];
57616
57911
  logWithTimestamp(
@@ -57674,6 +57969,18 @@ var XmtpService = class _XmtpService {
57674
57969
  async recycleXmtpClients() {
57675
57970
  await this._backupReady;
57676
57971
  const startedAt = Date.now();
57972
+ if (getXmtpCreationCooldown().isCoolingDown()) {
57973
+ logWithTimestamp("[xmtp-sdk] recycle skipped \u2014 rate-limit cooldown active");
57974
+ return {
57975
+ clients: this.clients.size,
57976
+ recycled: 0,
57977
+ failed: 0,
57978
+ replayed: 0,
57979
+ skipped: 0,
57980
+ durationMs: Date.now() - startedAt,
57981
+ addresses: []
57982
+ };
57983
+ }
57677
57984
  const addresses = [];
57678
57985
  let recycled = 0;
57679
57986
  let failed = 0;
@@ -57692,7 +57999,16 @@ var XmtpService = class _XmtpService {
57692
57999
  try {
57693
58000
  this.cancelStreamRecoveryForAddress(address);
57694
58001
  this.stoppedAddresses.add(addressKey);
57695
- await Promise.resolve(oldClient.stop());
58002
+ await stopAndCloseXmtpClient(oldClient, {
58003
+ address,
58004
+ agentId: agentInfo.agentId,
58005
+ phase: "recycle",
58006
+ onCloseError: (err) => logger.error(
58007
+ LogEvent.XMTP_CLIENT_CLOSE_FAILED,
58008
+ err instanceof Error ? err : new Error(String(err)),
58009
+ { walletAddress: address, onchainosAgentId: agentInfo.agentId, phase: "recycle" }
58010
+ )
58011
+ });
57696
58012
  this.clients.delete(address);
57697
58013
  this.inboundReplayGates.delete(addressKey);
57698
58014
  this.replayScanFailuresByAddress.delete(addressKey);
@@ -57779,6 +58095,12 @@ var XmtpService = class _XmtpService {
57779
58095
  phase: "recycle/create-client"
57780
58096
  }
57781
58097
  );
58098
+ if (isXmtpRateLimitError(err)) {
58099
+ logWithTimestamp(
58100
+ "[xmtp-sdk] recycle: rate-limit on recreate \u2014 stopping remaining recycles"
58101
+ );
58102
+ break;
58103
+ }
57782
58104
  }
57783
58105
  }
57784
58106
  return {
@@ -60854,12 +61176,12 @@ var SessionBusyTracker = class {
60854
61176
  }
60855
61177
  }
60856
61178
  };
60857
- var singleton = null;
61179
+ var singleton2 = null;
60858
61180
  function getSessionBusyTracker() {
60859
- if (!singleton) {
60860
- singleton = new SessionBusyTracker();
61181
+ if (!singleton2) {
61182
+ singleton2 = new SessionBusyTracker();
60861
61183
  }
60862
- return singleton;
61184
+ return singleton2;
60863
61185
  }
60864
61186
 
60865
61187
  // src/openclaw-gateway.ts
@@ -61394,7 +61716,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
61394
61716
  client: {
61395
61717
  id: "gateway-client",
61396
61718
  displayName: "okx-a2a-node",
61397
- version: "0.2.16",
61719
+ version: "0.2.17",
61398
61720
  platform: "node",
61399
61721
  mode: "backend",
61400
61722
  instanceId
@@ -61405,7 +61727,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
61405
61727
  commands: [],
61406
61728
  permissions: {},
61407
61729
  locale: Intl.DateTimeFormat().resolvedOptions().locale || "en-US",
61408
- userAgent: `okx-a2a-node/${"0.2.16"}`,
61730
+ userAgent: `okx-a2a-node/${"0.2.17"}`,
61409
61731
  auth: {
61410
61732
  ...config.token ? { token: config.token } : {},
61411
61733
  ...config.password ? { password: config.password } : {}
@@ -67600,12 +67922,12 @@ function parseYamlInlineEnabledList(line) {
67600
67922
  var SHUTDOWN_FORCE_RESOLVE_MS = 5e3;
67601
67923
  function stopClients(service) {
67602
67924
  for (const [address, client] of service.getClients()) {
67603
- try {
67604
- client.stop();
67605
- logWithTimestamp(`[okx-agent-task] stopped XMTP client ${address}`);
67606
- } catch (err) {
67607
- logWithTimestamp(`[okx-agent-task] failed to stop XMTP client ${address}:`, err);
67608
- }
67925
+ void stopAndCloseXmtpClient(client, {
67926
+ address,
67927
+ agentId: "",
67928
+ phase: "shutdown",
67929
+ onCloseError: (err) => logWithTimestamp(`[okx-agent-task] failed to close XMTP client ${address}:`, err)
67930
+ }).then(() => logWithTimestamp(`[okx-agent-task] stopped XMTP client ${address}`)).catch((err) => logWithTimestamp(`[okx-agent-task] failed to stop XMTP client ${address}:`, err));
67609
67931
  }
67610
67932
  }
67611
67933
  async function runListener(options = {}) {
@@ -67745,12 +68067,12 @@ async function runListenerWithLock(options, paths) {
67745
68067
  });
67746
68068
  }
67747
68069
  });
67748
- service.setPluginVersion("0.2.16");
68070
+ service.setPluginVersion("0.2.17");
67749
68071
  await service.init();
67750
68072
  const pluginVersionStatus = service.pluginVersionStatus;
67751
68073
  if (pluginVersionStatus.unavailable) {
67752
68074
  throw new Error(
67753
- `@okxweb3/a2a-node v${"0.2.16"} is below the required minimum v${pluginVersionStatus.minVersion}`
68075
+ `@okxweb3/a2a-node v${"0.2.17"} is below the required minimum v${pluginVersionStatus.minVersion}`
67754
68076
  );
67755
68077
  }
67756
68078
  const systemConfig = service.getSystemConfig();
@@ -67778,7 +68100,7 @@ async function runListenerWithLock(options, paths) {
67778
68100
  onchainosAgentId: "*",
67779
68101
  reason: "system-config missing sentryDsn",
67780
68102
  pluginId: "@okxweb3/a2a-node",
67781
- pluginVersion: "0.2.16"
68103
+ pluginVersion: "0.2.17"
67782
68104
  });
67783
68105
  }
67784
68106
  logWithTimestamp(
@@ -70551,7 +70873,7 @@ async function exportDiagnosticLogs(options) {
70551
70873
  node: process.version,
70552
70874
  platform: process.platform,
70553
70875
  arch: process.arch,
70554
- packageVersion: true ? "0.2.16" : "unknown",
70876
+ packageVersion: true ? "0.2.17" : "unknown",
70555
70877
  sensitiveContentIncluded: options.includeSensitiveContent,
70556
70878
  listenerAndLlmContentIncluded: true,
70557
70879
  credentialsAlwaysRedacted: true,
@@ -72463,7 +72785,7 @@ async function runDoctor(options = {}) {
72463
72785
  platform: options.platform ?? process.platform,
72464
72786
  env: options.env ?? process.env,
72465
72787
  target: options.target ?? resolveDoctorTarget(options.env ?? process.env),
72466
- cliVersion: options.cliVersion ?? (true ? "0.2.16" : "0.0.0"),
72788
+ cliVersion: options.cliVersion ?? (true ? "0.2.17" : "0.0.0"),
72467
72789
  fixMode: options.fix === true,
72468
72790
  nonInteractive: options.nonInteractive === true,
72469
72791
  packageChanged: false,
@@ -72733,6 +73055,9 @@ init_autostart_windows();
72733
73055
  UserCancelledAiProviderSelectionError,
72734
73056
  WALLET_STATUS_TIMEOUT_MS,
72735
73057
  XMTP_CLIENT_RECYCLE_INTERVAL_ENV,
73058
+ XMTP_CREATION_COOLDOWN_MS,
73059
+ XmtpCreationCooldown,
73060
+ XmtpCreationCooldownSkipError,
72736
73061
  XmtpDm,
72737
73062
  XmtpGroup,
72738
73063
  XmtpService,
@@ -72813,6 +73138,7 @@ init_autostart_windows();
72813
73138
  exportDiagnosticLogs,
72814
73139
  extractAiSessionId,
72815
73140
  extractDirectToUserNotification,
73141
+ extractRateLimitEndpoint,
72816
73142
  extractXmtpSentAtMs,
72817
73143
  findWindowsNativeOkxA2aExe,
72818
73144
  followFile,
@@ -72823,6 +73149,7 @@ init_autostart_windows();
72823
73149
  getResolvedOnchainosBinForTests,
72824
73150
  getRuntimeMetadata,
72825
73151
  getSessionBusyTracker,
73152
+ getXmtpCreationCooldown,
72826
73153
  handleCapabilitiesCommand,
72827
73154
  handleDoctorCommand,
72828
73155
  handleXmtpDebugCommand,
@@ -72853,6 +73180,7 @@ init_autostart_windows();
72853
73180
  isTagKey,
72854
73181
  isValidExternalJobId,
72855
73182
  isWindowsElevated,
73183
+ isXmtpRateLimitError,
72856
73184
  killProcessTree,
72857
73185
  launchdPlistHasCurrentRestartPolicy,
72858
73186
  listAllAgentsWithMetadata,
@@ -72902,6 +73230,7 @@ init_autostart_windows();
72902
73230
  reportUserNotificationFailure,
72903
73231
  resetMessageEligibleOfflineReplayCapabilityForTests,
72904
73232
  resetResolvedOnchainosBinForTests,
73233
+ resetXmtpCreationCooldownForTests,
72905
73234
  resolveAiPermissionPreset,
72906
73235
  resolveAiProviderCommand,
72907
73236
  resolveAiProviderCommandWithSource,
@@ -72949,6 +73278,7 @@ init_autostart_windows();
72949
73278
  startDaemonRespectingSupervisor,
72950
73279
  startUserAttentionEventServer,
72951
73280
  startUserAttentionWatcherCoordinator,
73281
+ stopAndCloseXmtpClient,
72952
73282
  stopDaemon,
72953
73283
  stopOpenClawGateway,
72954
73284
  stopSystemdAutostart,