@okxweb3/a2a-node 0.2.4-beta-e7a52faf6f-260812154627 → 0.2.4

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 +267 -169
  2. package/dist/index.js +224 -168
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -32104,7 +32104,7 @@ var init_sentry_config = __esm({
32104
32104
  environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
32105
32105
  SENTRY_CONFIG = {
32106
32106
  projectName: "okx/openclaw-okx-a2a-extension",
32107
- release: "0.2.4-beta-e7a52faf6f-260812154627",
32107
+ release: "0.2.4",
32108
32108
  environment,
32109
32109
  runtimeContainer: normalizeRuntimeContainer(process.env.OKX_A2A_RUNTIME_CONTAINER)
32110
32110
  };
@@ -33045,7 +33045,7 @@ async function getCurrentNodeCliVersion() {
33045
33045
  return await getGlobalNpmPackageVersion(UPDATE_PACKAGES.node) ?? getBundledNodeCliVersion();
33046
33046
  }
33047
33047
  function getBundledNodeCliVersion() {
33048
- return true ? "0.2.4-beta-e7a52faf6f-260812154627" : null;
33048
+ return true ? "0.2.4" : null;
33049
33049
  }
33050
33050
  function readConfiguredAiProvider() {
33051
33051
  const explicit = process.env.OKX_A2A_AI_PROVIDER || process.env.OKX_AGENT_TASK_AI_CLI;
@@ -33255,7 +33255,7 @@ async function updateHermes(release, options) {
33255
33255
  }
33256
33256
  }
33257
33257
  async function installGatewayPluginForDoctor(target) {
33258
- const release = isPrereleaseVersion("0.2.4-beta-e7a52faf6f-260812154627") ? "beta" : "latest";
33258
+ const release = isPrereleaseVersion("0.2.4") ? "beta" : "latest";
33259
33259
  const insideTargetGateway = detectGatewayInvocation() === target;
33260
33260
  const options = {
33261
33261
  restart: !insideTargetGateway,
@@ -44020,7 +44020,6 @@ __export(index_exports, {
44020
44020
  buildLaunchdPlist: () => buildLaunchdPlist,
44021
44021
  buildLauncherEntryJs: () => buildLauncherEntryJs,
44022
44022
  buildMessageEligibleArgs: () => buildMessageEligibleArgs,
44023
- buildPendingConversationBackupDispatch: () => buildPendingConversationBackupDispatch,
44024
44023
  buildSchtasksCreateArgs: () => buildSchtasksCreateArgs,
44025
44024
  buildSchtasksDeleteArgs: () => buildSchtasksDeleteArgs,
44026
44025
  buildSchtasksEndArgs: () => buildSchtasksEndArgs,
@@ -44176,7 +44175,6 @@ __export(index_exports, {
44176
44175
  scanUserAttentionWatchers: () => scanUserAttentionWatchers,
44177
44176
  setOpenClawWebSocketFactoryForTests: () => setOpenClawWebSocketFactoryForTests,
44178
44177
  shouldDelegateToSupervisor: () => shouldDelegateToSupervisor,
44179
- shouldKeepInboundGroupPendingForBuyer: () => shouldKeepInboundGroupPendingForBuyer,
44180
44178
  shouldRouteThroughWindowsShell: () => shouldRouteThroughWindowsShell,
44181
44179
  spawnCompat: () => spawnCompat,
44182
44180
  spawnSyncCompat: () => spawnSyncCompat,
@@ -55414,6 +55412,7 @@ var StreamRecoveryTelemetry = class {
55414
55412
  }
55415
55413
  markError(nowMs = Date.now()) {
55416
55414
  if (this.activeRecovery) {
55415
+ this.activeRecovery.candidateStartedAtMs = void 0;
55417
55416
  return {
55418
55417
  recoverySequence: this.activeRecovery.sequence,
55419
55418
  alreadyRecovering: true
@@ -55427,9 +55426,26 @@ var StreamRecoveryTelemetry = class {
55427
55426
  if (!this.activeRecovery) {
55428
55427
  return void 0;
55429
55428
  }
55429
+ this.activeRecovery.candidateStartedAtMs = nowMs;
55430
+ return {
55431
+ recoverySequence: this.activeRecovery.sequence,
55432
+ candidateStartedAtMs: nowMs
55433
+ };
55434
+ }
55435
+ markStable(nowMs = Date.now()) {
55436
+ if (this.activeRecovery?.candidateStartedAtMs === void 0) {
55437
+ return void 0;
55438
+ }
55430
55439
  const completed = {
55431
55440
  recoverySequence: this.activeRecovery.sequence,
55432
- recoveryDurationMs: Math.max(0, nowMs - this.activeRecovery.startedAtMs)
55441
+ recoveryDurationMs: Math.max(
55442
+ 0,
55443
+ this.activeRecovery.candidateStartedAtMs - this.activeRecovery.startedAtMs
55444
+ ),
55445
+ recoveryConfirmationDurationMs: Math.max(
55446
+ 0,
55447
+ nowMs - this.activeRecovery.startedAtMs
55448
+ )
55433
55449
  };
55434
55450
  this.activeRecovery = void 0;
55435
55451
  return completed;
@@ -55438,9 +55454,12 @@ var StreamRecoveryTelemetry = class {
55438
55454
  this.activeRecovery = void 0;
55439
55455
  }
55440
55456
  };
55457
+ function replayFlightDiscriminator(clientGeneration, isOfflineReplay) {
55458
+ return isOfflineReplay ? `startup_offline:${clientGeneration}` : `online_repair:${clientGeneration}`;
55459
+ }
55441
55460
  var KeyedSingleFlight = class {
55442
55461
  inFlight = /* @__PURE__ */ new Map();
55443
- run(key, discriminator, operation) {
55462
+ run(key, discriminator, operation, options = {}) {
55444
55463
  const normalizedKey = key.toLowerCase();
55445
55464
  const state = this.inFlight.get(normalizedKey);
55446
55465
  if (!state) {
@@ -55450,7 +55469,22 @@ var KeyedSingleFlight = class {
55450
55469
  return active.promise;
55451
55470
  }
55452
55471
  if (state.active.discriminator === discriminator) {
55453
- return state.active.promise;
55472
+ if (!options.queueBehindActive) {
55473
+ return state.active.promise;
55474
+ }
55475
+ const queued2 = state.queued.find(
55476
+ (flight3) => flight3.discriminator === discriminator
55477
+ );
55478
+ if (queued2) {
55479
+ return queued2.promise;
55480
+ }
55481
+ const flight2 = createKeyedFlight(
55482
+ discriminator,
55483
+ operation,
55484
+ options.shouldRunAfterActive
55485
+ );
55486
+ state.queued.push(flight2);
55487
+ return flight2.promise;
55454
55488
  }
55455
55489
  const queued = state.queued.find(
55456
55490
  (flight2) => flight2.discriminator === discriminator
@@ -55466,15 +55500,33 @@ var KeyedSingleFlight = class {
55466
55500
  void Promise.resolve().then(flight.operation).then(
55467
55501
  (value) => {
55468
55502
  flight.resolve(value);
55469
- this.advance(key, flight);
55503
+ this.advanceAfterSuccess(key, flight, value);
55470
55504
  },
55471
55505
  (error) => {
55472
55506
  flight.reject(error);
55473
- this.advance(key, flight);
55507
+ this.advanceAfterFailure(key, flight, error);
55474
55508
  }
55475
55509
  );
55476
55510
  }
55477
- advance(key, completed) {
55511
+ advanceAfterSuccess(key, completed, value) {
55512
+ const state = this.inFlight.get(key);
55513
+ if (state?.active !== completed) {
55514
+ return;
55515
+ }
55516
+ const next = state.queued.shift();
55517
+ if (!next) {
55518
+ this.inFlight.delete(key);
55519
+ return;
55520
+ }
55521
+ if (next.shouldRunAfterActive && !next.shouldRunAfterActive(value)) {
55522
+ next.resolve(value);
55523
+ this.advanceAfterSuccess(key, completed, value);
55524
+ return;
55525
+ }
55526
+ state.active = next;
55527
+ this.execute(key, next);
55528
+ }
55529
+ advanceAfterFailure(key, completed, error) {
55478
55530
  const state = this.inFlight.get(key);
55479
55531
  if (state?.active !== completed) {
55480
55532
  return;
@@ -55484,18 +55536,30 @@ var KeyedSingleFlight = class {
55484
55536
  this.inFlight.delete(key);
55485
55537
  return;
55486
55538
  }
55539
+ if (next.shouldRunAfterActive) {
55540
+ next.reject(error);
55541
+ this.advanceAfterFailure(key, completed, error);
55542
+ return;
55543
+ }
55487
55544
  state.active = next;
55488
55545
  this.execute(key, next);
55489
55546
  }
55490
55547
  };
55491
- function createKeyedFlight(discriminator, operation) {
55548
+ function createKeyedFlight(discriminator, operation, shouldRunAfterActive) {
55492
55549
  let resolve11;
55493
55550
  let reject;
55494
55551
  const promise = new Promise((resolvePromise, rejectPromise) => {
55495
55552
  resolve11 = resolvePromise;
55496
55553
  reject = rejectPromise;
55497
55554
  });
55498
- return { discriminator, operation, promise, resolve: resolve11, reject };
55555
+ return {
55556
+ discriminator,
55557
+ operation,
55558
+ promise,
55559
+ resolve: resolve11,
55560
+ reject,
55561
+ shouldRunAfterActive
55562
+ };
55499
55563
  }
55500
55564
 
55501
55565
  // ../core/src/xmtp-sdk/extract-job-id.ts
@@ -56225,6 +56289,7 @@ var SYSTEM_CONFIG_DEFAULTS = {
56225
56289
  }
56226
56290
  };
56227
56291
  var STREAM_RECOVERY_ALERT_THRESHOLD_MS = 3e4;
56292
+ var STREAM_RECOVERY_STABILITY_WINDOW_MS = 1e4;
56228
56293
  var REPLAY_GATE_DRAIN_MAX_ATTEMPTS = 3;
56229
56294
  var REPLAY_GATE_DRAIN_RETRY_DELAY_MS = 100;
56230
56295
  var SEMVER_RE = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*)?$/;
@@ -56417,11 +56482,11 @@ function replayScanBackoffMs(consecutiveFailures) {
56417
56482
  function isOfflineReplayForTrigger(trigger) {
56418
56483
  return trigger === "startup";
56419
56484
  }
56420
- function replaySingleFlightDiscriminator(trigger, clientGeneration, recoveryIdentity) {
56421
- if (trigger === "stream_recovery") {
56422
- return `stream_recovery:${clientGeneration}:${recoveryIdentity ?? "unknown"}`;
56423
- }
56424
- return isOfflineReplayForTrigger(trigger) ? `startup_offline:${clientGeneration}` : `online_repair:${clientGeneration}`;
56485
+ function replaySingleFlightDiscriminator(trigger, clientGeneration) {
56486
+ return replayFlightDiscriminator(
56487
+ clientGeneration,
56488
+ isOfflineReplayForTrigger(trigger)
56489
+ );
56425
56490
  }
56426
56491
  var XmtpService = class _XmtpService {
56427
56492
  static instance = null;
@@ -56456,6 +56521,9 @@ var XmtpService = class _XmtpService {
56456
56521
  replayScanClearTimeout = (timer) => clearTimeout(timer);
56457
56522
  inboundReplayGates = /* @__PURE__ */ new Map();
56458
56523
  streamRecoveryCleanupByAddress = /* @__PURE__ */ new Map();
56524
+ streamRecoverySetTimeout = (callback, delayMs) => setTimeout(callback, delayMs);
56525
+ streamRecoveryClearTimeout = (timer) => clearTimeout(timer);
56526
+ streamStartSetTimeout = (callback, delayMs) => setTimeout(callback, delayMs);
56459
56527
  nextClientGeneration = 1;
56460
56528
  clientGenerationByClient = /* @__PURE__ */ new WeakMap();
56461
56529
  resolveStartupReplayCompletion;
@@ -57908,10 +57976,14 @@ var XmtpService = class _XmtpService {
57908
57976
  }
57909
57977
  const delay = BASE_DELAY_MS * 2 ** attempt;
57910
57978
  logWithTimestamp(`${tag} reconnecting in ${delay}ms (attempt=${attempt + 1})`);
57911
- setTimeout(() => void startWithRetry(attempt + 1), delay);
57979
+ this.streamStartSetTimeout(
57980
+ () => void startWithRetry(attempt + 1),
57981
+ delay
57982
+ );
57912
57983
  };
57913
57984
  const streamRecovery = new StreamRecoveryTelemetry();
57914
57985
  let recoveryTimeout;
57986
+ let recoveryStabilityTimeout;
57915
57987
  let pendingRecoveryGate;
57916
57988
  let recoveryDisposed = false;
57917
57989
  this.cancelStreamRecoveryForAddress(address);
@@ -57919,9 +57991,13 @@ var XmtpService = class _XmtpService {
57919
57991
  recoveryDisposed = true;
57920
57992
  streamRecovery.cancel();
57921
57993
  if (recoveryTimeout) {
57922
- clearTimeout(recoveryTimeout);
57994
+ this.streamRecoveryClearTimeout(recoveryTimeout);
57923
57995
  recoveryTimeout = void 0;
57924
57996
  }
57997
+ if (recoveryStabilityTimeout) {
57998
+ this.streamRecoveryClearTimeout(recoveryStabilityTimeout);
57999
+ recoveryStabilityTimeout = void 0;
58000
+ }
57925
58001
  };
57926
58002
  this.streamRecoveryCleanupByAddress.set(
57927
58003
  addressKey,
@@ -57936,6 +58012,10 @@ var XmtpService = class _XmtpService {
57936
58012
  logger.error(LogEvent.AGENT_UNHANDLED_ERROR, err, agentExtras(identity));
57937
58013
  return;
57938
58014
  }
58015
+ if (recoveryStabilityTimeout) {
58016
+ this.streamRecoveryClearTimeout(recoveryStabilityTimeout);
58017
+ recoveryStabilityTimeout = void 0;
58018
+ }
57939
58019
  const recovery = streamRecovery.markError();
57940
58020
  const errorTelemetry = extractStreamErrorTelemetry(err);
57941
58021
  if (!recovery.alreadyRecovering) {
@@ -57950,10 +58030,11 @@ var XmtpService = class _XmtpService {
57950
58030
  recoveryAlreadyActive: String(recovery.alreadyRecovering)
57951
58031
  });
57952
58032
  if (!recovery.alreadyRecovering) {
57953
- recoveryTimeout = setTimeout(() => {
58033
+ recoveryTimeout = this.streamRecoverySetTimeout(() => {
57954
58034
  if (recoveryDisposed || this.clients.get(address) !== agent || this.stoppedAddresses.has(addressKey) || streamRecovery.activeSequence !== recovery.recoverySequence) {
57955
58035
  return;
57956
58036
  }
58037
+ recoveryTimeout = void 0;
57957
58038
  logger.error(LogEvent.AGENT_STREAM_RECOVERY_TIMEOUT, void 0, {
57958
58039
  ...agentExtras(identity),
57959
58040
  ...errorTelemetry,
@@ -57962,6 +58043,22 @@ var XmtpService = class _XmtpService {
57962
58043
  recoveryDurationMs: String(STREAM_RECOVERY_ALERT_THRESHOLD_MS),
57963
58044
  thresholdMs: String(STREAM_RECOVERY_ALERT_THRESHOLD_MS)
57964
58045
  });
58046
+ const timedOutGate = pendingRecoveryGate;
58047
+ pendingRecoveryGate = void 0;
58048
+ void this.drainInboundReplayGate(address, timedOutGate).catch(
58049
+ (drainError) => {
58050
+ logger.error(
58051
+ LogEvent.OFFLINE_REPLAY_FAILED,
58052
+ drainError instanceof Error ? drainError : new Error(String(drainError)),
58053
+ {
58054
+ ...agentExtras(identity),
58055
+ clientGeneration: String(clientGeneration),
58056
+ recoverySequence: String(recovery.recoverySequence),
58057
+ stage: "streamRecovery/timeout-drain-gate"
58058
+ }
58059
+ );
58060
+ }
58061
+ );
57965
58062
  }, STREAM_RECOVERY_ALERT_THRESHOLD_MS);
57966
58063
  }
57967
58064
  });
@@ -57969,60 +58066,61 @@ var XmtpService = class _XmtpService {
57969
58066
  if (recoveryDisposed || this.clients.get(address) !== agent || this.stoppedAddresses.has(addressKey)) {
57970
58067
  return;
57971
58068
  }
57972
- const recovery = streamRecovery.markStarted();
57973
- if (recoveryTimeout) {
57974
- clearTimeout(recoveryTimeout);
57975
- recoveryTimeout = void 0;
57976
- }
58069
+ const candidate = streamRecovery.markStarted();
57977
58070
  logWithTimestamp(
57978
58071
  `${tag} agent stream started agentId=${identity.onchainosAgentId ?? "(unknown)"} inboxId=${identity.inboxId ?? "(unknown)"} role=${identity.role ?? "(unknown)"} consentStates=Allowed,Unknown lastSync=${formatLogTimestamp2(this.syncByAddress.get(address))}`
57979
58072
  );
57980
- if (recovery) {
57981
- const recoveryGate = pendingRecoveryGate;
57982
- pendingRecoveryGate = void 0;
57983
- logger.info(LogEvent.AGENT_STREAM_RECOVERED, {
57984
- ...agentExtras(identity),
57985
- clientGeneration: String(clientGeneration),
57986
- recoverySequence: String(recovery.recoverySequence),
57987
- recoveryDurationMs: String(recovery.recoveryDurationMs)
57988
- });
57989
- void (async () => {
57990
- try {
57991
- const summary = await this.replayOfflineMessagesForStreamRecovery(
57992
- address,
57993
- String(recovery.recoverySequence),
57994
- agent
57995
- );
57996
- if (summary.outcome === "completed" && !recoveryDisposed && this.clients.get(address) === agent) {
57997
- logger.info(LogEvent.AGENT_STREAM_RECOVERY_REPLAY_COMPLETED, {
57998
- ...agentExtras(identity),
57999
- clientGeneration: String(clientGeneration),
58000
- recoverySequence: String(recovery.recoverySequence),
58001
- replayed: String(summary.replayed),
58002
- skipped: String(summary.skipped),
58003
- conversationCount: String(summary.conversations),
58004
- replayDurationMs: String(summary.durationMs),
58005
- outcome: "success",
58006
- replayOutcome: summary.outcome
58007
- });
58008
- }
58009
- } catch (err) {
58010
- logWithTimestamp(`${tag} recovery offline replay failed:`, err);
58011
- logger.error(
58012
- LogEvent.OFFLINE_REPLAY_FAILED,
58013
- err instanceof Error ? err : new Error(String(err)),
58014
- {
58015
- ...agentExtras(identity),
58016
- clientGeneration: String(clientGeneration),
58017
- recoverySequence: String(recovery.recoverySequence),
58018
- stage: "streamRecovery/replay"
58019
- }
58020
- );
58021
- } finally {
58073
+ if (candidate) {
58074
+ if (recoveryStabilityTimeout) {
58075
+ this.streamRecoveryClearTimeout(recoveryStabilityTimeout);
58076
+ }
58077
+ recoveryStabilityTimeout = this.streamRecoverySetTimeout(() => {
58078
+ recoveryStabilityTimeout = void 0;
58079
+ if (recoveryDisposed || this.clients.get(address) !== agent || this.stoppedAddresses.has(addressKey) || streamRecovery.activeSequence !== candidate.recoverySequence) {
58080
+ return;
58081
+ }
58082
+ const recovery = streamRecovery.markStable();
58083
+ if (!recovery) {
58084
+ return;
58085
+ }
58086
+ if (recoveryTimeout) {
58087
+ this.streamRecoveryClearTimeout(recoveryTimeout);
58088
+ recoveryTimeout = void 0;
58089
+ }
58090
+ const recoveryGate = pendingRecoveryGate;
58091
+ pendingRecoveryGate = void 0;
58092
+ logger.info(LogEvent.AGENT_STREAM_RECOVERED, {
58093
+ ...agentExtras(identity),
58094
+ clientGeneration: String(clientGeneration),
58095
+ recoverySequence: String(recovery.recoverySequence),
58096
+ recoveryDurationMs: String(recovery.recoveryDurationMs),
58097
+ recoveryConfirmationDurationMs: String(
58098
+ recovery.recoveryConfirmationDurationMs
58099
+ ),
58100
+ stabilityWindowMs: String(STREAM_RECOVERY_STABILITY_WINDOW_MS)
58101
+ });
58102
+ void (async () => {
58022
58103
  try {
58023
- await this.drainInboundReplayGate(address, recoveryGate);
58104
+ const summary = await this.replayOfflineMessagesForStreamRecovery(
58105
+ address,
58106
+ String(recovery.recoverySequence),
58107
+ agent
58108
+ );
58109
+ if (summary.outcome === "completed" && !recoveryDisposed && this.clients.get(address) === agent) {
58110
+ logger.info(LogEvent.AGENT_STREAM_RECOVERY_REPLAY_COMPLETED, {
58111
+ ...agentExtras(identity),
58112
+ clientGeneration: String(clientGeneration),
58113
+ recoverySequence: String(recovery.recoverySequence),
58114
+ replayed: String(summary.replayed),
58115
+ skipped: String(summary.skipped),
58116
+ conversationCount: String(summary.conversations),
58117
+ replayDurationMs: String(summary.durationMs),
58118
+ outcome: "success",
58119
+ replayOutcome: summary.outcome
58120
+ });
58121
+ }
58024
58122
  } catch (err) {
58025
- logWithTimestamp(`${tag} recovery replay gate drain failed:`, err);
58123
+ logWithTimestamp(`${tag} recovery offline replay failed:`, err);
58026
58124
  logger.error(
58027
58125
  LogEvent.OFFLINE_REPLAY_FAILED,
58028
58126
  err instanceof Error ? err : new Error(String(err)),
@@ -58030,12 +58128,28 @@ var XmtpService = class _XmtpService {
58030
58128
  ...agentExtras(identity),
58031
58129
  clientGeneration: String(clientGeneration),
58032
58130
  recoverySequence: String(recovery.recoverySequence),
58033
- stage: "streamRecovery/drain-gate"
58131
+ stage: "streamRecovery/replay"
58034
58132
  }
58035
58133
  );
58134
+ } finally {
58135
+ try {
58136
+ await this.drainInboundReplayGate(address, recoveryGate);
58137
+ } catch (err) {
58138
+ logWithTimestamp(`${tag} recovery replay gate drain failed:`, err);
58139
+ logger.error(
58140
+ LogEvent.OFFLINE_REPLAY_FAILED,
58141
+ err instanceof Error ? err : new Error(String(err)),
58142
+ {
58143
+ ...agentExtras(identity),
58144
+ clientGeneration: String(clientGeneration),
58145
+ recoverySequence: String(recovery.recoverySequence),
58146
+ stage: "streamRecovery/drain-gate"
58147
+ }
58148
+ );
58149
+ }
58036
58150
  }
58037
- }
58038
- })();
58151
+ })();
58152
+ }, STREAM_RECOVERY_STABILITY_WINDOW_MS);
58039
58153
  }
58040
58154
  if (process.env.XMTP_FORCE_DEBUG === "true") {
58041
58155
  void logDetails(agent).catch((err) => {
@@ -58054,7 +58168,7 @@ var XmtpService = class _XmtpService {
58054
58168
  logWithTimestamp(`${tag} message listener started`);
58055
58169
  });
58056
58170
  }
58057
- async replayOfflineMessagesForAddress(address, expectedClient, trigger = "periodic_repair") {
58171
+ async replayOfflineMessagesForAddress(address, expectedClient, trigger = "periodic_repair", recoveryIdentity) {
58058
58172
  const addressReplayStartedAt = Date.now();
58059
58173
  const summary = createOfflineReplayAddressSummary(address);
58060
58174
  const isOfflineReplay = isOfflineReplayForTrigger(trigger);
@@ -58154,6 +58268,8 @@ var XmtpService = class _XmtpService {
58154
58268
  walletAddress: address,
58155
58269
  stage: `offlineReplay/${stage}`,
58156
58270
  trigger,
58271
+ clientGeneration: String(clientGeneration),
58272
+ ...recoveryIdentity ? { recoverySequence: recoveryIdentity } : {},
58157
58273
  outcome: "failed",
58158
58274
  replayOutcome: summary.outcome,
58159
58275
  consecutiveFailures: String(consecutiveFailures),
@@ -58348,8 +58464,7 @@ var XmtpService = class _XmtpService {
58348
58464
  const clientGeneration = expectedClient ? this.getClientGeneration(expectedClient) : "missing";
58349
58465
  const eligibilityClass = replaySingleFlightDiscriminator(
58350
58466
  trigger,
58351
- clientGeneration,
58352
- recoveryIdentity
58467
+ clientGeneration
58353
58468
  );
58354
58469
  return this.offlineReplaySingleFlight.run(
58355
58470
  address,
@@ -58359,9 +58474,14 @@ var XmtpService = class _XmtpService {
58359
58474
  return this.replayOfflineMessagesForAddress(
58360
58475
  address,
58361
58476
  expectedClient,
58362
- trigger
58477
+ trigger,
58478
+ recoveryIdentity
58363
58479
  );
58364
- }
58480
+ },
58481
+ trigger === "stream_recovery" ? {
58482
+ queueBehindActive: true,
58483
+ shouldRunAfterActive: (summary) => summary.outcome === "completed"
58484
+ } : void 0
58365
58485
  );
58366
58486
  }
58367
58487
  async replayOfflineMessagesForStreamRecovery(address, recoveryIdentity, expectedClient) {
@@ -58419,12 +58539,6 @@ function createOfflineReplayAddressSummary(address) {
58419
58539
  };
58420
58540
  }
58421
58541
 
58422
- // ../core/src/a2a/pending-conversation.ts
58423
- var PENDING_CONVERSATION_BACKUP_NOTICE_TEMPLATE = "[event:provider_conversation][jobId:${jobId}] There are new conversation requests pending.";
58424
- function buildPendingConversationBackupNotice(jobId) {
58425
- return PENDING_CONVERSATION_BACKUP_NOTICE_TEMPLATE.replace("${jobId}", jobId);
58426
- }
58427
-
58428
58542
  // ../core/src/a2a/index.ts
58429
58543
  var A2A_MESSAGE_TYPE = "a2a-agent-chat";
58430
58544
 
@@ -60281,7 +60395,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
60281
60395
  client: {
60282
60396
  id: "gateway-client",
60283
60397
  displayName: "okx-a2a-node",
60284
- version: "0.2.4-beta-e7a52faf6f-260812154627",
60398
+ version: "0.2.4",
60285
60399
  platform: "node",
60286
60400
  mode: "backend",
60287
60401
  instanceId
@@ -60292,7 +60406,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
60292
60406
  commands: [],
60293
60407
  permissions: {},
60294
60408
  locale: Intl.DateTimeFormat().resolvedOptions().locale || "en-US",
60295
- userAgent: `okx-a2a-node/${"0.2.4-beta-e7a52faf6f-260812154627"}`,
60409
+ userAgent: `okx-a2a-node/${"0.2.4"}`,
60296
60410
  auth: {
60297
60411
  ...config.token ? { token: config.token } : {},
60298
60412
  ...config.password ? { password: config.password } : {}
@@ -64571,17 +64685,22 @@ async function maybeAllowProviderGroup(deps, chatType, conversationId) {
64571
64685
  );
64572
64686
  }
64573
64687
  }
64574
- function shouldKeepInboundGroupPendingForBuyer(input) {
64575
- return input.consentState === import_node_bindings2.ConsentState.Unknown && !input.hasExistingSession && (input.localAgentRole === 1 /* CLIENT */ || input.localAgentRole == null);
64576
- }
64577
- function buildPendingConversationBackupDispatch(input) {
64578
- return {
64579
- sessionKey: buildBackupJobSessionKey(input.jobId),
64580
- content: buildPendingConversationBackupNotice(input.jobId),
64581
- messageId: `pending-conversation:${input.messageId}`,
64688
+ function ensureInboundGroupSession(deps, input) {
64689
+ const sessionKey = buildSessionKey({
64582
64690
  jobId: input.jobId,
64583
- agentId: null
64584
- };
64691
+ myAgentId: input.myAgentId,
64692
+ toAgentId: input.toAgentId
64693
+ });
64694
+ deps.sessionStore?.upsertSession({
64695
+ sessionKey,
64696
+ jobId: input.jobId,
64697
+ myAgentId: input.myAgentId,
64698
+ toAgentId: input.toAgentId,
64699
+ groupId: input.groupId,
64700
+ myAgentXmtpAddress: deps.myXmtpAddress,
64701
+ toAgentXmtpAddress: input.toAgentXmtpAddress
64702
+ });
64703
+ return sessionKey;
64585
64704
  }
64586
64705
  var INBOUND_TRANSPORT = "xmtp";
64587
64706
  var INBOUND_EVENT_FAMILY = "inbound";
@@ -64647,30 +64766,6 @@ function buildInboundTerminalExtras(input) {
64647
64766
  })
64648
64767
  };
64649
64768
  }
64650
- function notifyPendingConversationToBackup(params) {
64651
- const event = buildPendingConversationBackupDispatch({
64652
- jobId: params.jobId,
64653
- messageId: params.messageId
64654
- });
64655
- void Promise.resolve(params.deps.onSessionMessage?.(event)).catch((err) => {
64656
- logWithTimestamp(`[okx-agent-task:${params.deps.myXmtpAddress}] pending conversation backup dispatch failed:`, err);
64657
- logger.error(LogEvent.INBOUND_DISPATCH_FAILED, toLoggableError(err), {
64658
- ...buildInboundTerminalExtras({
64659
- terminalState: "dispatch_failed",
64660
- myXmtpAddress: params.deps.myXmtpAddress,
64661
- messageId: event.messageId,
64662
- jobId: params.jobId,
64663
- sessionKey: event.sessionKey,
64664
- route: "backup",
64665
- reason: "pending_backup_dispatch_failed"
64666
- }),
64667
- // Each fire-and-forget dispatch overrides the generic checkpoint with the
64668
- // `_failed` twin of its own success checkpoint, so the four paths stay
64669
- // distinguishable in the funnel.
64670
- checkpoint: "inbound/pending_backup_dispatch_failed"
64671
- });
64672
- });
64673
- }
64674
64769
  function maybeNotifyInboundAgentMessage(params) {
64675
64770
  if (params.chatType === "dm") {
64676
64771
  return;
@@ -65478,7 +65573,7 @@ async function processFileMessage(ctx, deps, options = {}) {
65478
65573
  }
65479
65574
  const sender = isPlainObject3(payloadObject?.sender) ? payloadObject.sender : null;
65480
65575
  const localAgent = service.getAgentByAddress(deps.myXmtpAddress);
65481
- const myAgentId = localAgent?.agentId ?? sessionAgentId ?? null;
65576
+ const myAgentId = localAgent?.agentId ?? readString3(payloadObject?.receiverAgentId) ?? sessionAgentId ?? null;
65482
65577
  const toAgentId = readString3(sender?.agentId);
65483
65578
  const accepted = await verifyInboundA2AGroupMessage({
65484
65579
  payload: parsed.parsed ? parsed.payload : null,
@@ -65496,50 +65591,13 @@ async function processFileMessage(ctx, deps, options = {}) {
65496
65591
  if (!accepted) {
65497
65592
  return true;
65498
65593
  }
65499
- const sessionKey = buildSessionKey({
65500
- jobId: route.jobId,
65501
- myAgentId,
65502
- toAgentId
65503
- });
65504
- const existingSession = deps.sessionStore?.getSession(sessionKey) ?? null;
65505
65594
  const routedMessageId = messageId || `group-${(0, import_node_crypto12.randomUUID)()}`;
65506
- const consentState = ctx.conversation instanceof Group ? ctx.conversation.consentState() : void 0;
65507
- if (shouldKeepInboundGroupPendingForBuyer({
65508
- consentState,
65509
- localAgentRole: localAgent?.role ?? null,
65510
- hasExistingSession: !!existingSession
65511
- })) {
65512
- logWithTimestamp(
65513
- `[okx-agent-task:${deps.myXmtpAddress}] buyer inbound group kept pending: session=${sessionKey} job=${shortenLogValue(route.jobId)} group=${conversationId} consent=${String(consentState)} message=${shortenLogValue(routedMessageId)}`
65514
- );
65515
- logger.info(LogEvent.INBOUND_BUYER_PENDING, {
65516
- ...agentExtras({ walletAddress: deps.myXmtpAddress, onchainosAgentId: localAgent?.agentId }),
65517
- peerWalletAddress: senderAddress,
65518
- peerInboxId: ctx.message.senderInboxId ?? "",
65519
- peerAgentId: toAgentId ?? "",
65520
- taskId: route.jobId,
65521
- conversationId,
65522
- messageId: routedMessageId,
65523
- consentState: String(consentState),
65524
- ...inboundStageExtras("inbound/buyer_pending", "pending"),
65525
- reason: "unknown_group_without_session",
65526
- ...timing.extras()
65527
- });
65528
- notifyPendingConversationToBackup({
65529
- deps,
65530
- jobId: route.jobId,
65531
- messageId: routedMessageId
65532
- });
65533
- return true;
65534
- }
65535
- deps.sessionStore?.upsertSession({
65536
- sessionKey,
65595
+ const sessionKey = ensureInboundGroupSession(deps, {
65537
65596
  jobId: route.jobId,
65538
65597
  myAgentId,
65539
65598
  toAgentId,
65540
- groupId: conversationId || null,
65541
- myAgentXmtpAddress: deps.myXmtpAddress,
65542
- toAgentXmtpAddress: senderAddress || null
65599
+ groupId: conversationId,
65600
+ toAgentXmtpAddress: senderAddress || readString3(payloadObject?.fromXmtpAddress)
65543
65601
  });
65544
65602
  const dispatchStartedAt = Date.now();
65545
65603
  void Promise.resolve(deps.onSessionMessage?.({
@@ -66507,12 +66565,12 @@ async function runListenerWithLock(options, paths) {
66507
66565
  });
66508
66566
  }
66509
66567
  });
66510
- service.setPluginVersion("0.2.4-beta-e7a52faf6f-260812154627");
66568
+ service.setPluginVersion("0.2.4");
66511
66569
  await service.init();
66512
66570
  const pluginVersionStatus = service.pluginVersionStatus;
66513
66571
  if (pluginVersionStatus.unavailable) {
66514
66572
  throw new Error(
66515
- `@okxweb3/a2a-node v${"0.2.4-beta-e7a52faf6f-260812154627"} is below the required minimum v${pluginVersionStatus.minVersion}`
66573
+ `@okxweb3/a2a-node v${"0.2.4"} is below the required minimum v${pluginVersionStatus.minVersion}`
66516
66574
  );
66517
66575
  }
66518
66576
  const systemConfig = service.getSystemConfig();
@@ -66530,7 +66588,7 @@ async function runListenerWithLock(options, paths) {
66530
66588
  onchainosAgentId: "*",
66531
66589
  reason: "system-config missing sentryDsn",
66532
66590
  pluginId: "@okxweb3/a2a-node",
66533
- pluginVersion: "0.2.4-beta-e7a52faf6f-260812154627"
66591
+ pluginVersion: "0.2.4"
66534
66592
  });
66535
66593
  }
66536
66594
  logWithTimestamp(
@@ -69228,7 +69286,7 @@ async function exportDiagnosticLogs(options) {
69228
69286
  node: process.version,
69229
69287
  platform: process.platform,
69230
69288
  arch: process.arch,
69231
- packageVersion: true ? "0.2.4-beta-e7a52faf6f-260812154627" : "unknown",
69289
+ packageVersion: true ? "0.2.4" : "unknown",
69232
69290
  sensitiveContentIncluded: options.includeSensitiveContent,
69233
69291
  listenerAndLlmContentIncluded: true,
69234
69292
  credentialsAlwaysRedacted: true,
@@ -71064,7 +71122,7 @@ async function runDoctor(options = {}) {
71064
71122
  platform: options.platform ?? process.platform,
71065
71123
  env: options.env ?? process.env,
71066
71124
  target: options.target ?? resolveDoctorTarget(options.env ?? process.env),
71067
- cliVersion: options.cliVersion ?? (true ? "0.2.4-beta-e7a52faf6f-260812154627" : "0.0.0"),
71125
+ cliVersion: options.cliVersion ?? (true ? "0.2.4" : "0.0.0"),
71068
71126
  fixMode: options.fix === true,
71069
71127
  nonInteractive: options.nonInteractive === true,
71070
71128
  packageChanged: false,
@@ -71361,7 +71419,6 @@ init_autostart_windows();
71361
71419
  buildLaunchdPlist,
71362
71420
  buildLauncherEntryJs,
71363
71421
  buildMessageEligibleArgs,
71364
- buildPendingConversationBackupDispatch,
71365
71422
  buildSchtasksCreateArgs,
71366
71423
  buildSchtasksDeleteArgs,
71367
71424
  buildSchtasksEndArgs,
@@ -71517,7 +71574,6 @@ init_autostart_windows();
71517
71574
  scanUserAttentionWatchers,
71518
71575
  setOpenClawWebSocketFactoryForTests,
71519
71576
  shouldDelegateToSupervisor,
71520
- shouldKeepInboundGroupPendingForBuyer,
71521
71577
  shouldRouteThroughWindowsShell,
71522
71578
  spawnCompat,
71523
71579
  spawnSyncCompat,