@okxweb3/a2a-node 0.2.16 → 0.2.17-beta-a72a480b58-261013200517

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/cli.js CHANGED
@@ -4935,8 +4935,8 @@ var require_worldwide = __commonJS({
4935
4935
  function getGlobalSingleton(name, creator, obj) {
4936
4936
  const gbl = obj || GLOBAL_OBJ;
4937
4937
  const __SENTRY__ = gbl.__SENTRY__ = gbl.__SENTRY__ || {};
4938
- const singleton2 = __SENTRY__[name] || (__SENTRY__[name] = creator());
4939
- return singleton2;
4938
+ const singleton3 = __SENTRY__[name] || (__SENTRY__[name] = creator());
4939
+ return singleton3;
4940
4940
  }
4941
4941
  exports2.GLOBAL_OBJ = GLOBAL_OBJ;
4942
4942
  exports2.getGlobalObject = getGlobalObject;
@@ -19981,6 +19981,14 @@ var init_events = __esm({
19981
19981
  SYSTEM_NOTIFICATION_ROUTED: "System notification routed",
19982
19982
  HERMES_SESSION_ROUTE_BINDING: "Hermes session route binding",
19983
19983
  DOCTOR_REPORT: "Doctor report",
19984
+ // XMTP creation rate-limit cooldown (DEXMARKET-9116). All four are logger.info,
19985
+ // so each one must also be listed in SENTRY_INFO_ALLOWLIST (index.ts) or info()
19986
+ // drops it silently. Extras are bounded tokens/ints/bools only — never raw SDK
19987
+ // error text (no-content-leak invariant).
19988
+ XMTP_RATE_LIMIT_COOLDOWN_STARTED: "XMTP rate limit cooldown started",
19989
+ XMTP_RATE_LIMIT_CREATE_SUPPRESSED: "XMTP rate limit create suppressed",
19990
+ XMTP_RATE_LIMIT_PROBE: "XMTP rate limit probe",
19991
+ XMTP_RATE_LIMIT_RECOVERED: "XMTP rate limit recovered",
19984
19992
  // ── error ─────────────────────────────────────────────────────
19985
19993
  XMTP_CONNECTION_FAILED: "XMTP connection failed",
19986
19994
  CONVERSATIONS_STREAM_FAILED: "conversations.stream failed",
@@ -20046,7 +20054,10 @@ var init_events = __esm({
20046
20054
  AGENT_DB_DIR_CREATE_FAILED: "Agent DB dir create failed",
20047
20055
  AGENT_INSTALLATION_LIMIT_NEAR: "Agent installation limit near",
20048
20056
  XMTP_HISTORY_SYNC_REQUEST_FAILED: "XMTP history sync request failed",
20049
- XMTP_DEBUG_SYNC_FAILED: "XMTP debug sync failed"
20057
+ XMTP_DEBUG_SYNC_FAILED: "XMTP debug sync failed",
20058
+ // Underlying XMTP SDK client close failed during recycle/removal/shutdown
20059
+ // (DEXMARKET-9116). Error-level → NOT added to SENTRY_INFO_ALLOWLIST.
20060
+ XMTP_CLIENT_CLOSE_FAILED: "XMTP client close failed"
20050
20061
  };
20051
20062
  }
20052
20063
  });
@@ -20885,7 +20896,13 @@ var init_sentry_logger = __esm({
20885
20896
  LogEvent.PENDING_LIST_QUERIED,
20886
20897
  LogEvent.SESSION_KEY_DERIVED,
20887
20898
  LogEvent.SESSIONS_QUERIED,
20888
- LogEvent.SYNC_TICK_COMPLETED
20899
+ LogEvent.SYNC_TICK_COMPLETED,
20900
+ // XMTP creation rate-limit cooldown checkpoints (DEXMARKET-9116). info() drops
20901
+ // any event not listed here, so these must stay registered.
20902
+ LogEvent.XMTP_RATE_LIMIT_COOLDOWN_STARTED,
20903
+ LogEvent.XMTP_RATE_LIMIT_CREATE_SUPPRESSED,
20904
+ LogEvent.XMTP_RATE_LIMIT_PROBE,
20905
+ LogEvent.XMTP_RATE_LIMIT_RECOVERED
20889
20906
  ]);
20890
20907
  MAX_EXTRA_STRING_LENGTH = 256;
20891
20908
  MAX_TAG_VALUE_LENGTH = 128;
@@ -27001,7 +27018,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
27001
27018
  client: {
27002
27019
  id: "gateway-client",
27003
27020
  displayName: "okx-a2a-node",
27004
- version: "0.2.16",
27021
+ version: "0.2.17-beta-a72a480b58-261013200517",
27005
27022
  platform: "node",
27006
27023
  mode: "backend",
27007
27024
  instanceId
@@ -27012,7 +27029,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
27012
27029
  commands: [],
27013
27030
  permissions: {},
27014
27031
  locale: Intl.DateTimeFormat().resolvedOptions().locale || "en-US",
27015
- userAgent: `okx-a2a-node/${"0.2.16"}`,
27032
+ userAgent: `okx-a2a-node/${"0.2.17-beta-a72a480b58-261013200517"}`,
27016
27033
  auth: {
27017
27034
  ...config.token ? { token: config.token } : {},
27018
27035
  ...config.password ? { password: config.password } : {}
@@ -29072,7 +29089,7 @@ var init_sentry_config = __esm({
29072
29089
  environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
29073
29090
  SENTRY_CONFIG = {
29074
29091
  projectName: "okx/openclaw-okx-a2a-extension",
29075
- release: "0.2.16",
29092
+ release: "0.2.17-beta-a72a480b58-261013200517",
29076
29093
  environment,
29077
29094
  runtimeContainer: normalizeRuntimeContainer(process.env.OKX_A2A_RUNTIME_CONTAINER)
29078
29095
  };
@@ -40242,7 +40259,7 @@ async function exportDiagnosticLogs(options) {
40242
40259
  node: process.version,
40243
40260
  platform: process.platform,
40244
40261
  arch: process.arch,
40245
- packageVersion: true ? "0.2.16" : "unknown",
40262
+ packageVersion: true ? "0.2.17-beta-a72a480b58-261013200517" : "unknown",
40246
40263
  sensitiveContentIncluded: options.includeSensitiveContent,
40247
40264
  listenerAndLlmContentIncluded: true,
40248
40265
  credentialsAlwaysRedacted: true,
@@ -42221,6 +42238,32 @@ var init_trade_records_cli = __esm({
42221
42238
  }
42222
42239
  });
42223
42240
 
42241
+ // ../core/src/xmtp-sdk/client-lifecycle.ts
42242
+ async function stopAndCloseXmtpClient(agent, ctx) {
42243
+ let stopped = true;
42244
+ try {
42245
+ await Promise.resolve(agent.stop());
42246
+ } catch {
42247
+ stopped = false;
42248
+ }
42249
+ const close2 = agent.client?.close;
42250
+ if (typeof close2 !== "function") {
42251
+ return { stopped, closed: false, closeFailed: false };
42252
+ }
42253
+ try {
42254
+ await Promise.resolve(close2.call(agent.client));
42255
+ return { stopped, closed: true, closeFailed: false };
42256
+ } catch (err2) {
42257
+ ctx.onCloseError?.(err2);
42258
+ return { stopped, closed: false, closeFailed: true };
42259
+ }
42260
+ }
42261
+ var init_client_lifecycle = __esm({
42262
+ "../core/src/xmtp-sdk/client-lifecycle.ts"() {
42263
+ "use strict";
42264
+ }
42265
+ });
42266
+
42224
42267
  // ../core/src/xmtp-sdk/onchainos/bin.ts
42225
42268
  async function refreshOnchainosVersionMetadata(options = {}) {
42226
42269
  const now = options.now ?? Date.now;
@@ -58261,6 +58304,169 @@ var init_session_expired = __esm({
58261
58304
  }
58262
58305
  });
58263
58306
 
58307
+ // ../core/src/xmtp-sdk/rate-limit-cooldown.ts
58308
+ function asErrorLike2(value) {
58309
+ return value instanceof Error ? value : void 0;
58310
+ }
58311
+ function causeChain2(err2) {
58312
+ const chain = [];
58313
+ const seen = /* @__PURE__ */ new Set();
58314
+ let current = err2;
58315
+ while (chain.length < MAX_CAUSE_DEPTH2) {
58316
+ chain.push(current);
58317
+ const errorLike = asErrorLike2(current);
58318
+ if (!errorLike || seen.has(errorLike)) {
58319
+ break;
58320
+ }
58321
+ seen.add(errorLike);
58322
+ current = errorLike.cause;
58323
+ if (current === void 0) {
58324
+ break;
58325
+ }
58326
+ }
58327
+ return chain;
58328
+ }
58329
+ function messageOf(node) {
58330
+ return (node instanceof Error ? node.message : String(node)).toLowerCase();
58331
+ }
58332
+ function isXmtpRateLimitError(err2) {
58333
+ if (err2 === void 0 || err2 === null) {
58334
+ return false;
58335
+ }
58336
+ const chain = causeChain2(err2);
58337
+ return chain.some(
58338
+ (node) => RATE_LIMIT_PATTERNS.some((pattern) => pattern.test(messageOf(node)))
58339
+ );
58340
+ }
58341
+ function extractRateLimitEndpoint(err2) {
58342
+ if (err2 === void 0 || err2 === null) {
58343
+ return void 0;
58344
+ }
58345
+ const chain = causeChain2(err2);
58346
+ for (const node of chain) {
58347
+ const message = messageOf(node);
58348
+ for (const pattern of KNOWN_RATE_LIMIT_ENDPOINTS) {
58349
+ const match = pattern.exec(message);
58350
+ if (match) {
58351
+ return /GetInboxIds/i.test(match[0]) ? "GetInboxIds" : "GetIdentityUpdates";
58352
+ }
58353
+ }
58354
+ }
58355
+ return void 0;
58356
+ }
58357
+ function getXmtpCreationCooldown() {
58358
+ if (!singleton2) {
58359
+ singleton2 = new XmtpCreationCooldown();
58360
+ }
58361
+ return singleton2;
58362
+ }
58363
+ var MAX_CAUSE_DEPTH2, XMTP_CREATION_COOLDOWN_MS, RATE_LIMIT_PATTERNS, KNOWN_RATE_LIMIT_ENDPOINTS, XmtpCreationCooldownSkipError, XmtpCreationCooldown, singleton2;
58364
+ var init_rate_limit_cooldown = __esm({
58365
+ "../core/src/xmtp-sdk/rate-limit-cooldown.ts"() {
58366
+ "use strict";
58367
+ MAX_CAUSE_DEPTH2 = 4;
58368
+ XMTP_CREATION_COOLDOWN_MS = 33e4;
58369
+ RATE_LIMIT_PATTERNS = [
58370
+ /some resource has been exhausted/i,
58371
+ /exceeds rate limit/i,
58372
+ /resource_exhausted/i
58373
+ ];
58374
+ KNOWN_RATE_LIMIT_ENDPOINTS = [
58375
+ /\bGetInboxIds\b/i,
58376
+ /\bGetIdentityUpdates\b/i
58377
+ ];
58378
+ XmtpCreationCooldownSkipError = class extends Error {
58379
+ remainingMs;
58380
+ address;
58381
+ agentId;
58382
+ constructor(remainingMs, address, agentId) {
58383
+ super("xmtp creation suppressed during rate-limit cooldown");
58384
+ this.name = "XmtpCreationCooldownSkipError";
58385
+ this.remainingMs = remainingMs;
58386
+ this.address = address;
58387
+ this.agentId = agentId;
58388
+ }
58389
+ };
58390
+ XmtpCreationCooldown = class {
58391
+ cooldownUntilMs = null;
58392
+ probeInFlight = false;
58393
+ suppressedCreateCount = 0;
58394
+ rateLimitHitCount = 0;
58395
+ probeCount = 0;
58396
+ inFlightCreateCount = 0;
58397
+ beginCreateAttempt(nowMs = Date.now()) {
58398
+ if (this.cooldownUntilMs === null) {
58399
+ this.inFlightCreateCount++;
58400
+ return { allowed: true, mode: "normal" };
58401
+ }
58402
+ if (nowMs < this.cooldownUntilMs) {
58403
+ this.suppressedCreateCount++;
58404
+ return {
58405
+ allowed: false,
58406
+ mode: "blocked",
58407
+ remainingMs: Math.max(0, this.cooldownUntilMs - nowMs)
58408
+ };
58409
+ }
58410
+ if (this.probeInFlight) {
58411
+ this.suppressedCreateCount++;
58412
+ return { allowed: false, mode: "blocked", remainingMs: 0 };
58413
+ }
58414
+ this.probeInFlight = true;
58415
+ this.inFlightCreateCount++;
58416
+ this.probeCount++;
58417
+ return { allowed: true, mode: "probe" };
58418
+ }
58419
+ recordCreateSuccess(decision, _nowMs = Date.now()) {
58420
+ this.inFlightCreateCount = Math.max(0, this.inFlightCreateCount - 1);
58421
+ if (decision.mode === "probe") {
58422
+ this.cooldownUntilMs = null;
58423
+ this.probeInFlight = false;
58424
+ }
58425
+ }
58426
+ recordRateLimit(decision, nowMs = Date.now()) {
58427
+ this.inFlightCreateCount = Math.max(0, this.inFlightCreateCount - 1);
58428
+ this.cooldownUntilMs = nowMs + XMTP_CREATION_COOLDOWN_MS;
58429
+ this.rateLimitHitCount++;
58430
+ this.probeInFlight = false;
58431
+ void decision;
58432
+ }
58433
+ recordCreateFailure(decision, nowMs = Date.now()) {
58434
+ this.inFlightCreateCount = Math.max(0, this.inFlightCreateCount - 1);
58435
+ if (decision.mode === "probe") {
58436
+ this.cooldownUntilMs = nowMs + XMTP_CREATION_COOLDOWN_MS;
58437
+ this.probeInFlight = false;
58438
+ }
58439
+ }
58440
+ isCoolingDown(nowMs = Date.now()) {
58441
+ return this.cooldownUntilMs !== null && nowMs < this.cooldownUntilMs;
58442
+ }
58443
+ remainingMs(nowMs = Date.now()) {
58444
+ return this.cooldownUntilMs === null ? 0 : Math.max(0, this.cooldownUntilMs - nowMs);
58445
+ }
58446
+ snapshot(nowMs = Date.now()) {
58447
+ return {
58448
+ coolingDown: this.isCoolingDown(nowMs),
58449
+ cooldownUntilMs: this.cooldownUntilMs,
58450
+ remainingMs: this.remainingMs(nowMs),
58451
+ probeInFlight: this.probeInFlight,
58452
+ suppressedCreateCount: this.suppressedCreateCount,
58453
+ rateLimitHitCount: this.rateLimitHitCount,
58454
+ probeCount: this.probeCount,
58455
+ inFlightCreateCount: this.inFlightCreateCount
58456
+ };
58457
+ }
58458
+ resetForTests() {
58459
+ this.cooldownUntilMs = null;
58460
+ this.probeInFlight = false;
58461
+ this.suppressedCreateCount = 0;
58462
+ this.rateLimitHitCount = 0;
58463
+ this.probeCount = 0;
58464
+ this.inFlightCreateCount = 0;
58465
+ }
58466
+ };
58467
+ }
58468
+ });
58469
+
58264
58470
  // ../core/src/xmtp-sdk/index.ts
58265
58471
  function cachePath(dataDir, fileName) {
58266
58472
  return (0, import_node_path28.join)(dataDir, fileName);
@@ -58690,6 +58896,8 @@ var init_xmtp_sdk = __esm({
58690
58896
  init_a2a_paths();
58691
58897
  init_installation_prune();
58692
58898
  init_session_expired();
58899
+ init_rate_limit_cooldown();
58900
+ init_client_lifecycle();
58693
58901
  DEFAULT_DATA_DIR = resolveA2aTaskPaths().xmtpDir;
58694
58902
  XMTP_INSTALLATION_WARNING_THRESHOLD = 2;
58695
58903
  XMTP_INSTALLATION_NEAR_LIMIT_THRESHOLD = 8;
@@ -58987,21 +59195,78 @@ var init_xmtp_sdk = __esm({
58987
59195
  }
58988
59196
  async createClientForAgent(agentInfo, options = {}) {
58989
59197
  const address = agentInfo.communicationAddress;
58990
- const signer = this.tools.createSigner(agentInfo);
58991
- const dbPath = (inboxId2) => `${this.dataDir}/${inboxId2}-${this.env}.db3`;
58992
- const agent = await createAgentWithInstallationPrune(signer, {
58993
- dbPath,
58994
- env: this.env
58995
- }, {
58996
- address,
58997
- agentId: agentInfo.agentId,
58998
- logPrefix: options.logPrefix
58999
- });
59000
- const inboxId = agent.client?.inboxId ?? "";
59001
- logWithTimestamp(
59002
- `[xmtp-sdk] xmtp_client_ready agentId=${agentInfo.agentId} address=${address} inboxId=${inboxId} dbPath=${inboxId ? dbPath(inboxId) : "(unknown)"} lastSync=${formatLogTimestamp2(this.syncByAddress.get(address))}`
59003
- );
59004
- return { address, agent, agentInfo };
59198
+ const phase = options.logPrefix ?? "[xmtp-sdk]";
59199
+ const cooldown = getXmtpCreationCooldown();
59200
+ const decision = cooldown.beginCreateAttempt();
59201
+ if (!decision.allowed) {
59202
+ logger.info(LogEvent.XMTP_RATE_LIMIT_CREATE_SUPPRESSED, {
59203
+ onchainosAgentId: agentInfo.agentId,
59204
+ walletAddress: address,
59205
+ cooldownRemainingMs: String(decision.remainingMs ?? 0),
59206
+ phase
59207
+ });
59208
+ throw new XmtpCreationCooldownSkipError(
59209
+ decision.remainingMs ?? 0,
59210
+ address,
59211
+ agentInfo.agentId
59212
+ );
59213
+ }
59214
+ if (decision.mode === "probe") {
59215
+ logger.info(LogEvent.XMTP_RATE_LIMIT_PROBE, {
59216
+ onchainosAgentId: agentInfo.agentId,
59217
+ walletAddress: address,
59218
+ phase: "probe-start",
59219
+ probeCount: String(cooldown.snapshot().probeCount)
59220
+ });
59221
+ }
59222
+ try {
59223
+ const signer = this.tools.createSigner(agentInfo);
59224
+ const dbPath = (inboxId2) => `${this.dataDir}/${inboxId2}-${this.env}.db3`;
59225
+ const agent = await createAgentWithInstallationPrune(signer, {
59226
+ dbPath,
59227
+ env: this.env
59228
+ }, {
59229
+ address,
59230
+ agentId: agentInfo.agentId,
59231
+ logPrefix: options.logPrefix
59232
+ });
59233
+ cooldown.recordCreateSuccess(decision);
59234
+ if (decision.mode === "probe") {
59235
+ logger.info(LogEvent.XMTP_RATE_LIMIT_RECOVERED, {
59236
+ onchainosAgentId: agentInfo.agentId,
59237
+ walletAddress: address,
59238
+ phase: "probe-success"
59239
+ });
59240
+ }
59241
+ const inboxId = agent.client?.inboxId ?? "";
59242
+ logWithTimestamp(
59243
+ `[xmtp-sdk] xmtp_client_ready agentId=${agentInfo.agentId} address=${address} inboxId=${inboxId} dbPath=${inboxId ? dbPath(inboxId) : "(unknown)"} lastSync=${formatLogTimestamp2(this.syncByAddress.get(address))}`
59244
+ );
59245
+ return { address, agent, agentInfo };
59246
+ } catch (err2) {
59247
+ if (isXmtpRateLimitError(err2)) {
59248
+ cooldown.recordRateLimit(decision);
59249
+ logger.info(LogEvent.XMTP_RATE_LIMIT_COOLDOWN_STARTED, {
59250
+ ...agentExtras({ walletAddress: address, onchainosAgentId: agentInfo.agentId }),
59251
+ rateLimitIdentified: "true",
59252
+ endpoint: extractRateLimitEndpoint(err2) ?? "unknown",
59253
+ cooldownMs: String(XMTP_CREATION_COOLDOWN_MS),
59254
+ cooldownExpiresAtMs: String(cooldown.snapshot().cooldownUntilMs ?? ""),
59255
+ inFlightCreateCount: String(cooldown.snapshot().inFlightCreateCount),
59256
+ probe: String(decision.mode === "probe")
59257
+ });
59258
+ } else {
59259
+ cooldown.recordCreateFailure(decision);
59260
+ if (decision.mode === "probe") {
59261
+ logger.info(LogEvent.XMTP_RATE_LIMIT_PROBE, {
59262
+ onchainosAgentId: agentInfo.agentId,
59263
+ walletAddress: address,
59264
+ phase: "probe-failed-nonratelimit"
59265
+ });
59266
+ }
59267
+ }
59268
+ throw err2;
59269
+ }
59005
59270
  }
59006
59271
  async recordInstallationHealth(params) {
59007
59272
  const { address, agent, agentInfo, phase, attempt } = params;
@@ -59152,22 +59417,28 @@ var init_xmtp_sdk = __esm({
59152
59417
  });
59153
59418
  } else {
59154
59419
  failedAgents.push(agents[i]);
59155
- logWithTimestamp(
59156
- `[xmtp-sdk] identity init failed: ${agents[i].communicationAddress} (agentId=${agents[i].agentId})`,
59157
- r.reason
59158
- );
59159
- logger.error(
59160
- LogEvent.XMTP_CONNECTION_FAILED,
59161
- r.reason instanceof Error ? r.reason : new Error(String(r.reason)),
59162
- {
59163
- walletAddress: agents[i].communicationAddress,
59164
- onchainosAgentId: agents[i].agentId,
59165
- attempt: "1"
59166
- }
59167
- );
59420
+ if (r.reason instanceof XmtpCreationCooldownSkipError) {
59421
+ logWithTimestamp(
59422
+ `[xmtp-sdk] identity init suppressed (rate-limit cooldown): ${agents[i].communicationAddress} (agentId=${agents[i].agentId})`
59423
+ );
59424
+ } else {
59425
+ logWithTimestamp(
59426
+ `[xmtp-sdk] identity init failed: ${agents[i].communicationAddress} (agentId=${agents[i].agentId})`,
59427
+ r.reason
59428
+ );
59429
+ logger.error(
59430
+ LogEvent.XMTP_CONNECTION_FAILED,
59431
+ r.reason instanceof Error ? r.reason : new Error(String(r.reason)),
59432
+ {
59433
+ walletAddress: agents[i].communicationAddress,
59434
+ onchainosAgentId: agents[i].agentId,
59435
+ attempt: "1"
59436
+ }
59437
+ );
59438
+ }
59168
59439
  }
59169
59440
  }
59170
- if (failedAgents.length > 0) {
59441
+ if (failedAgents.length > 0 && !getXmtpCreationCooldown().isCoolingDown()) {
59171
59442
  logWithTimestamp(
59172
59443
  `[xmtp-sdk] ${failedAgents.length} client(s) failed to initialize, retrying in 1s...`
59173
59444
  );
@@ -59207,6 +59478,11 @@ var init_xmtp_sdk = __esm({
59207
59478
  phase: "init",
59208
59479
  attempt: "2"
59209
59480
  });
59481
+ } else if (r.reason instanceof XmtpCreationCooldownSkipError) {
59482
+ const info = failedAgents[i];
59483
+ logWithTimestamp(
59484
+ `[xmtp-sdk] retry suppressed (rate-limit cooldown): ${info.communicationAddress} (agentId=${info.agentId})`
59485
+ );
59210
59486
  } else {
59211
59487
  const info = failedAgents[i];
59212
59488
  logWithTimestamp(
@@ -59302,7 +59578,16 @@ var init_xmtp_sdk = __esm({
59302
59578
  try {
59303
59579
  this.cancelStreamRecoveryForAddress(address);
59304
59580
  this.stoppedAddresses.add(address.toLowerCase());
59305
- client.stop();
59581
+ await stopAndCloseXmtpClient(client, {
59582
+ address,
59583
+ agentId: agentInfo.agentId,
59584
+ phase: "refresh/remove",
59585
+ onCloseError: (err2) => logger.error(
59586
+ LogEvent.XMTP_CLIENT_CLOSE_FAILED,
59587
+ err2 instanceof Error ? err2 : new Error(String(err2)),
59588
+ { walletAddress: address, onchainosAgentId: agentInfo.agentId, phase: "refresh/remove" }
59589
+ )
59590
+ });
59306
59591
  logWithTimestamp(
59307
59592
  `[xmtp-sdk] refresh: stopped client: ${address} (agentId=${agentInfo.agentId})`
59308
59593
  );
@@ -59389,23 +59674,29 @@ var init_xmtp_sdk = __esm({
59389
59674
  });
59390
59675
  } else {
59391
59676
  failedAgents.push(added[i]);
59392
- logWithTimestamp(
59393
- `[xmtp-sdk] refresh: identity init failed: ${added[i].communicationAddress} (agentId=${added[i].agentId})`,
59394
- r.reason
59395
- );
59396
- logger.error(
59397
- LogEvent.XMTP_CONNECTION_FAILED,
59398
- r.reason instanceof Error ? r.reason : new Error(String(r.reason)),
59399
- {
59400
- walletAddress: added[i].communicationAddress,
59401
- onchainosAgentId: added[i].agentId,
59402
- phase: "refresh",
59403
- attempt: "1"
59404
- }
59405
- );
59677
+ if (r.reason instanceof XmtpCreationCooldownSkipError) {
59678
+ logWithTimestamp(
59679
+ `[xmtp-sdk] refresh: identity init suppressed (rate-limit cooldown): ${added[i].communicationAddress} (agentId=${added[i].agentId})`
59680
+ );
59681
+ } else {
59682
+ logWithTimestamp(
59683
+ `[xmtp-sdk] refresh: identity init failed: ${added[i].communicationAddress} (agentId=${added[i].agentId})`,
59684
+ r.reason
59685
+ );
59686
+ logger.error(
59687
+ LogEvent.XMTP_CONNECTION_FAILED,
59688
+ r.reason instanceof Error ? r.reason : new Error(String(r.reason)),
59689
+ {
59690
+ walletAddress: added[i].communicationAddress,
59691
+ onchainosAgentId: added[i].agentId,
59692
+ phase: "refresh",
59693
+ attempt: "1"
59694
+ }
59695
+ );
59696
+ }
59406
59697
  }
59407
59698
  }
59408
- if (failedAgents.length > 0) {
59699
+ if (failedAgents.length > 0 && !getXmtpCreationCooldown().isCoolingDown()) {
59409
59700
  logWithTimestamp(
59410
59701
  `[xmtp-sdk] refresh: ${failedAgents.length} client(s) failed to initialize, retrying in 1s...`
59411
59702
  );
@@ -59448,6 +59739,11 @@ var init_xmtp_sdk = __esm({
59448
59739
  phase: "refresh",
59449
59740
  attempt: "2"
59450
59741
  });
59742
+ } else if (r.reason instanceof XmtpCreationCooldownSkipError) {
59743
+ const info = failedAgents[i];
59744
+ logWithTimestamp(
59745
+ `[xmtp-sdk] refresh: retry suppressed (rate-limit cooldown): ${info.communicationAddress} (agentId=${info.agentId})`
59746
+ );
59451
59747
  } else {
59452
59748
  const info = failedAgents[i];
59453
59749
  logWithTimestamp(
@@ -59511,6 +59807,18 @@ var init_xmtp_sdk = __esm({
59511
59807
  async recycleXmtpClients() {
59512
59808
  await this._backupReady;
59513
59809
  const startedAt = Date.now();
59810
+ if (getXmtpCreationCooldown().isCoolingDown()) {
59811
+ logWithTimestamp("[xmtp-sdk] recycle skipped \u2014 rate-limit cooldown active");
59812
+ return {
59813
+ clients: this.clients.size,
59814
+ recycled: 0,
59815
+ failed: 0,
59816
+ replayed: 0,
59817
+ skipped: 0,
59818
+ durationMs: Date.now() - startedAt,
59819
+ addresses: []
59820
+ };
59821
+ }
59514
59822
  const addresses = [];
59515
59823
  let recycled = 0;
59516
59824
  let failed = 0;
@@ -59529,7 +59837,16 @@ var init_xmtp_sdk = __esm({
59529
59837
  try {
59530
59838
  this.cancelStreamRecoveryForAddress(address);
59531
59839
  this.stoppedAddresses.add(addressKey);
59532
- await Promise.resolve(oldClient.stop());
59840
+ await stopAndCloseXmtpClient(oldClient, {
59841
+ address,
59842
+ agentId: agentInfo.agentId,
59843
+ phase: "recycle",
59844
+ onCloseError: (err2) => logger.error(
59845
+ LogEvent.XMTP_CLIENT_CLOSE_FAILED,
59846
+ err2 instanceof Error ? err2 : new Error(String(err2)),
59847
+ { walletAddress: address, onchainosAgentId: agentInfo.agentId, phase: "recycle" }
59848
+ )
59849
+ });
59533
59850
  this.clients.delete(address);
59534
59851
  this.inboundReplayGates.delete(addressKey);
59535
59852
  this.replayScanFailuresByAddress.delete(addressKey);
@@ -59616,6 +59933,12 @@ var init_xmtp_sdk = __esm({
59616
59933
  phase: "recycle/create-client"
59617
59934
  }
59618
59935
  );
59936
+ if (isXmtpRateLimitError(err2)) {
59937
+ logWithTimestamp(
59938
+ "[xmtp-sdk] recycle: rate-limit on recreate \u2014 stopping remaining recycles"
59939
+ );
59940
+ break;
59941
+ }
59619
59942
  }
59620
59943
  }
59621
59944
  return {
@@ -69603,12 +69926,12 @@ function parseYamlInlineEnabledList(line) {
69603
69926
  }
69604
69927
  function stopClients(service) {
69605
69928
  for (const [address, client] of service.getClients()) {
69606
- try {
69607
- client.stop();
69608
- logWithTimestamp(`[okx-agent-task] stopped XMTP client ${address}`);
69609
- } catch (err2) {
69610
- logWithTimestamp(`[okx-agent-task] failed to stop XMTP client ${address}:`, err2);
69611
- }
69929
+ void stopAndCloseXmtpClient(client, {
69930
+ address,
69931
+ agentId: "",
69932
+ phase: "shutdown",
69933
+ onCloseError: (err2) => logWithTimestamp(`[okx-agent-task] failed to close XMTP client ${address}:`, err2)
69934
+ }).then(() => logWithTimestamp(`[okx-agent-task] stopped XMTP client ${address}`)).catch((err2) => logWithTimestamp(`[okx-agent-task] failed to stop XMTP client ${address}:`, err2));
69612
69935
  }
69613
69936
  }
69614
69937
  async function runListener(options = {}) {
@@ -69748,12 +70071,12 @@ async function runListenerWithLock(options, paths) {
69748
70071
  });
69749
70072
  }
69750
70073
  });
69751
- service.setPluginVersion("0.2.16");
70074
+ service.setPluginVersion("0.2.17-beta-a72a480b58-261013200517");
69752
70075
  await service.init();
69753
70076
  const pluginVersionStatus = service.pluginVersionStatus;
69754
70077
  if (pluginVersionStatus.unavailable) {
69755
70078
  throw new Error(
69756
- `@okxweb3/a2a-node v${"0.2.16"} is below the required minimum v${pluginVersionStatus.minVersion}`
70079
+ `@okxweb3/a2a-node v${"0.2.17-beta-a72a480b58-261013200517"} is below the required minimum v${pluginVersionStatus.minVersion}`
69757
70080
  );
69758
70081
  }
69759
70082
  const systemConfig = service.getSystemConfig();
@@ -69781,7 +70104,7 @@ async function runListenerWithLock(options, paths) {
69781
70104
  onchainosAgentId: "*",
69782
70105
  reason: "system-config missing sentryDsn",
69783
70106
  pluginId: "@okxweb3/a2a-node",
69784
- pluginVersion: "0.2.16"
70107
+ pluginVersion: "0.2.17-beta-a72a480b58-261013200517"
69785
70108
  });
69786
70109
  }
69787
70110
  logWithTimestamp(
@@ -70136,6 +70459,7 @@ var init_listener = __esm({
70136
70459
  "src/listener.ts"() {
70137
70460
  "use strict";
70138
70461
  init_log();
70462
+ init_client_lifecycle();
70139
70463
  import_node_fs27 = require("node:fs");
70140
70464
  import_promises13 = require("node:fs/promises");
70141
70465
  import_node_os10 = require("node:os");
@@ -118123,7 +118447,7 @@ async function getCurrentNodeCliVersion() {
118123
118447
  return await getGlobalNpmPackageVersion(UPDATE_PACKAGES.node) ?? getBundledNodeCliVersion();
118124
118448
  }
118125
118449
  function getBundledNodeCliVersion() {
118126
- return true ? "0.2.16" : null;
118450
+ return true ? "0.2.17-beta-a72a480b58-261013200517" : null;
118127
118451
  }
118128
118452
  function readConfiguredAiProvider() {
118129
118453
  const explicit = process.env.OKX_A2A_AI_PROVIDER || process.env.OKX_AGENT_TASK_AI_CLI;
@@ -118333,7 +118657,7 @@ async function updateHermes(release, options) {
118333
118657
  }
118334
118658
  }
118335
118659
  async function installGatewayPluginForDoctor(target) {
118336
- const release = isPrereleaseVersion("0.2.16") ? "beta" : "latest";
118660
+ const release = isPrereleaseVersion("0.2.17-beta-a72a480b58-261013200517") ? "beta" : "latest";
118337
118661
  const insideTargetGateway = detectGatewayInvocation() === target;
118338
118662
  const options = {
118339
118663
  restart: !insideTargetGateway,
@@ -119386,7 +119710,7 @@ async function runDoctor(options = {}) {
119386
119710
  platform: options.platform ?? process.platform,
119387
119711
  env: options.env ?? process.env,
119388
119712
  target: options.target ?? resolveDoctorTarget(options.env ?? process.env),
119389
- cliVersion: options.cliVersion ?? (true ? "0.2.16" : "0.0.0"),
119713
+ cliVersion: options.cliVersion ?? (true ? "0.2.17-beta-a72a480b58-261013200517" : "0.0.0"),
119390
119714
  fixMode: options.fix === true,
119391
119715
  nonInteractive: options.nonInteractive === true,
119392
119716
  packageChanged: false,
@@ -120493,7 +120817,7 @@ init_sentry_config();
120493
120817
  init_runtime_metadata();
120494
120818
  var CURRENT_GATEWAY_SESSION_KEYS_ENV4 = "OKX_A2A_CURRENT_GATEWAY_SESSION_KEYS";
120495
120819
  function printUsage3() {
120496
- console.log(`okx-a2a ${"0.2.16"}
120820
+ console.log(`okx-a2a ${"0.2.17-beta-a72a480b58-261013200517"}
120497
120821
 
120498
120822
  Usage:
120499
120823
  okx-a2a <command> [options]
@@ -120535,7 +120859,7 @@ Run \`okx-a2a <command> -h\` for command-specific help.
120535
120859
  `);
120536
120860
  }
120537
120861
  function printVersion() {
120538
- console.log("0.2.16");
120862
+ console.log("0.2.17-beta-a72a480b58-261013200517");
120539
120863
  }
120540
120864
  function printDaemonUsage() {
120541
120865
  console.log(`Usage: okx-a2a daemon <start|restart|stop|status|autostart> [options]
@@ -122030,7 +122354,7 @@ async function main() {
122030
122354
  if (command === "xmtp-test") {
122031
122355
  const { handleXmtpTestCommand: handleXmtpTestCommand2 } = await Promise.resolve().then(() => (init_xmtp_test_cli(), xmtp_test_cli_exports));
122032
122356
  await handleXmtpTestCommand2(process.argv.slice(3), {
122033
- packageVersion: "0.2.16",
122357
+ packageVersion: "0.2.17-beta-a72a480b58-261013200517",
122034
122358
  agentSdkVersion: "2.3.0",
122035
122359
  nodeSdkVersion: "6.1.0",
122036
122360
  nodeBindingsVersion: "1.11.0"