@okxweb3/a2a-node 0.0.1 → 0.0.2-beta-38940d220c-260605171631

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 +171 -59
  2. package/dist/index.js +149 -52
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -6153,11 +6153,11 @@ Sentry.init({...});
6153
6153
  */
6154
6154
  startSession(context) {
6155
6155
  const { scope: scope2, client } = this.getStackTop();
6156
- const { release, environment = constants3.DEFAULT_ENVIRONMENT } = client && client.getOptions() || {};
6156
+ const { release, environment: environment2 = constants3.DEFAULT_ENVIRONMENT } = client && client.getOptions() || {};
6157
6157
  const { userAgent } = utils.GLOBAL_OBJ.navigator || {};
6158
6158
  const session$1 = session.makeSession({
6159
6159
  release,
6160
- environment,
6160
+ environment: environment2,
6161
6161
  user: scope2.getUser(),
6162
6162
  ...userAgent && { userAgent },
6163
6163
  ...context
@@ -7995,9 +7995,9 @@ var require_prepareEvent = __commonJS({
7995
7995
  });
7996
7996
  }
7997
7997
  function applyClientOptions(event, options) {
7998
- const { environment, release, dist, maxValueLength = 250 } = options;
7998
+ const { environment: environment2, release, dist, maxValueLength = 250 } = options;
7999
7999
  if (!("environment" in event)) {
8000
- event.environment = "environment" in options ? environment : constants3.DEFAULT_ENVIRONMENT;
8000
+ event.environment = "environment" in options ? environment2 : constants3.DEFAULT_ENVIRONMENT;
8001
8001
  }
8002
8002
  if (event.release === void 0 && release !== void 0) {
8003
8003
  event.release = release;
@@ -8793,13 +8793,13 @@ var require_server_runtime_client = __commonJS({
8793
8793
  }
8794
8794
  /** Method that initialises an instance of SessionFlusher on Client */
8795
8795
  initSessionFlusher() {
8796
- const { release, environment } = this._options;
8796
+ const { release, environment: environment2 } = this._options;
8797
8797
  if (!release) {
8798
8798
  (typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && utils.logger.warn("Cannot initialise an instance of SessionFlusher if no release is provided!");
8799
8799
  } else {
8800
8800
  this._sessionFlusher = new sessionflusher.SessionFlusher(this, {
8801
8801
  release,
8802
- environment
8802
+ environment: environment2
8803
8803
  });
8804
8804
  }
8805
8805
  }
@@ -8817,13 +8817,13 @@ var require_server_runtime_client = __commonJS({
8817
8817
  return id;
8818
8818
  }
8819
8819
  const options = this.getOptions();
8820
- const { release, environment, tunnel } = options;
8820
+ const { release, environment: environment2, tunnel } = options;
8821
8821
  const serializedCheckIn = {
8822
8822
  check_in_id: id,
8823
8823
  monitor_slug: checkIn.monitorSlug,
8824
8824
  status: checkIn.status,
8825
8825
  release,
8826
- environment
8826
+ environment: environment2
8827
8827
  };
8828
8828
  if (checkIn.status !== "in_progress") {
8829
8829
  serializedCheckIn.duration = checkIn.duration;
@@ -17285,7 +17285,7 @@ function agentExtras(identity3) {
17285
17285
  onchainosAgentId: identity3.onchainosAgentId || UNKNOWN_FIELD
17286
17286
  };
17287
17287
  }
17288
- var Sentry, import_node_crypto3, FLOW_ID, SentryLogger, logger, UNKNOWN_FIELD;
17288
+ var Sentry, import_node_crypto3, FLOW_ID, SentryLogger, logger, initLogger, UNKNOWN_FIELD;
17289
17289
  var init_sentry_logger = __esm({
17290
17290
  "../core/src/sentry-logger/index.ts"() {
17291
17291
  "use strict";
@@ -17314,10 +17314,13 @@ var init_sentry_logger = __esm({
17314
17314
  dsn: config.dsn,
17315
17315
  release: config.release,
17316
17316
  environment: config.environment,
17317
+ maxBreadcrumbs: 0,
17318
+ beforeBreadcrumb: () => null,
17317
17319
  isInner: false
17318
17320
  });
17319
17321
  Sentry.setTags({
17320
- projectName: config.projectName
17322
+ projectName: config.projectName,
17323
+ agentPlatform: config.agentPlatform
17321
17324
  });
17322
17325
  this.initialized = true;
17323
17326
  this.flush();
@@ -17379,6 +17382,9 @@ var init_sentry_logger = __esm({
17379
17382
  }
17380
17383
  };
17381
17384
  logger = SentryLogger.getInstance();
17385
+ initLogger = (config) => {
17386
+ return logger.init(config);
17387
+ };
17382
17388
  UNKNOWN_FIELD = "unknown";
17383
17389
  }
17384
17390
  });
@@ -76209,7 +76215,6 @@ async function loadSystemConfigWith(dataDir, fetcher) {
76209
76215
  console.log("[xmtp-sdk] system-config fetcher not provided by host");
76210
76216
  return loadSystemConfigFromCache(dataDir);
76211
76217
  }
76212
- const cached = loadSystemConfigFromCache(dataDir);
76213
76218
  try {
76214
76219
  const config = await fetcher();
76215
76220
  console.log(
@@ -76224,6 +76229,7 @@ async function loadSystemConfigWith(dataDir, fetcher) {
76224
76229
  } catch (err2) {
76225
76230
  console.log(`[xmtp-sdk] API fetch for system-config failed:`, err2);
76226
76231
  }
76232
+ const cached = loadSystemConfigFromCache(dataDir);
76227
76233
  if (cached) {
76228
76234
  console.log(
76229
76235
  `[xmtp-sdk] using cached system-config from disk: ${Object.keys(cached).length} keys`
@@ -80403,6 +80409,28 @@ var init_envelope = __esm({
80403
80409
  }
80404
80410
  });
80405
80411
 
80412
+ // ../core/src/a2a/concurrency.ts
80413
+ async function withSharedPromise(registry, key, fn) {
80414
+ const existing = registry.get(key);
80415
+ if (existing) {
80416
+ return existing;
80417
+ }
80418
+ const run = fn();
80419
+ registry.set(key, run);
80420
+ try {
80421
+ return await run;
80422
+ } finally {
80423
+ if (registry.get(key) === run) {
80424
+ registry.delete(key);
80425
+ }
80426
+ }
80427
+ }
80428
+ var init_concurrency2 = __esm({
80429
+ "../core/src/a2a/concurrency.ts"() {
80430
+ "use strict";
80431
+ }
80432
+ });
80433
+
80406
80434
  // src/agent-message-notice.ts
80407
80435
  function shortenAddress(addr) {
80408
80436
  if (!addr) {
@@ -81096,45 +81124,53 @@ async function handleSqliteGroupSendCommand(params) {
81096
81124
  myAgentId: command.myAgentId,
81097
81125
  toAgentId: toAgentKey
81098
81126
  });
81099
- const existingMeta = sessionStore.getSession(sessionKey);
81100
- const stored = readStoredSessionFromMeta(existingMeta);
81127
+ const promiseKey = `${command.myAgentId}|${command.jobId}|${toAgentKey}`;
81101
81128
  const agent = service.getClientByAddress(myXmtpAddress);
81102
81129
  if (!agent) {
81103
81130
  throw new Error(`no XMTP client found for ${myXmtpAddress}`);
81104
81131
  }
81105
- let conversation = null;
81106
- let xmtpGroupId = stored?.xmtpGroupId ?? existingMeta?.groupId ?? null;
81107
- let created = false;
81108
- if (xmtpGroupId) {
81109
- conversation = await findGroupConversation(agent, xmtpGroupId);
81110
- }
81111
- if (!conversation) {
81112
- const toIdentifier = {
81113
- identifier: remote.toXmtpAddress,
81114
- identifierKind: 0
81115
- };
81116
- const canMessageResult = await agent.client.canMessage([toIdentifier]);
81117
- const reachable = canMessageResult.get(remote.toXmtpAddress) ?? canMessageResult.get(remote.toXmtpAddress.toLowerCase());
81118
- if (reachable === false) {
81119
- throw new Error(`${remote.toXmtpAddress} is not registered on XMTP`);
81132
+ const { conversation, created } = await withSharedPromise(
81133
+ sqliteGroupSessionPromises,
81134
+ promiseKey,
81135
+ async () => {
81136
+ const existingMeta = sessionStore.getSession(sessionKey);
81137
+ const stored = readStoredSessionFromMeta(existingMeta);
81138
+ let conversation2 = null;
81139
+ let xmtpGroupId = stored?.xmtpGroupId ?? existingMeta?.groupId ?? null;
81140
+ let created2 = false;
81141
+ if (xmtpGroupId) {
81142
+ conversation2 = await findGroupConversation(agent, xmtpGroupId);
81143
+ }
81144
+ if (!conversation2) {
81145
+ const toIdentifier = {
81146
+ identifier: remote.toXmtpAddress,
81147
+ identifierKind: 0
81148
+ };
81149
+ const canMessageResult = await agent.client.canMessage([toIdentifier]);
81150
+ const reachable = canMessageResult.get(remote.toXmtpAddress) ?? canMessageResult.get(remote.toXmtpAddress.toLowerCase());
81151
+ if (reachable === false) {
81152
+ throw new Error(`${remote.toXmtpAddress} is not registered on XMTP`);
81153
+ }
81154
+ conversation2 = await agent.client.conversations.newGroupWithIdentifiers(
81155
+ [toIdentifier],
81156
+ { groupName: `a2a-${command.jobId}` }
81157
+ );
81158
+ xmtpGroupId = conversation2.id;
81159
+ created2 = true;
81160
+ await service.allowGroup(myXmtpAddress, conversation2.id);
81161
+ }
81162
+ sessionStore.upsertSession({
81163
+ sessionKey,
81164
+ jobId: command.jobId,
81165
+ myAgentId: command.myAgentId,
81166
+ toAgentId: remote.toAgentId ?? command.toAgentId ?? null,
81167
+ groupId: xmtpGroupId,
81168
+ myAgentXmtpAddress: myXmtpAddress,
81169
+ toAgentXmtpAddress: remote.toXmtpAddress
81170
+ });
81171
+ return { conversation: conversation2, created: created2 };
81120
81172
  }
81121
- conversation = await agent.client.conversations.newGroupWithIdentifiers(
81122
- [toIdentifier],
81123
- { groupName: `a2a-${command.jobId}` }
81124
- );
81125
- xmtpGroupId = conversation.id;
81126
- created = true;
81127
- await service.allowGroup(myXmtpAddress, conversation.id);
81128
- }
81129
- sessionStore.upsertSession({
81130
- sessionKey,
81131
- jobId: command.jobId,
81132
- myAgentId: command.myAgentId,
81133
- toAgentId: remote.toAgentId ?? command.toAgentId ?? null,
81134
- groupId: xmtpGroupId,
81135
- myAgentXmtpAddress: myXmtpAddress,
81136
- toAgentXmtpAddress: remote.toXmtpAddress
81137
- });
81173
+ );
81138
81174
  const senderAgent = service.getAgentByAddress(myXmtpAddress);
81139
81175
  await assertOutboundEligible({
81140
81176
  senderAgent,
@@ -81503,19 +81539,21 @@ async function handleXmtpSendCommand(params) {
81503
81539
  });
81504
81540
  return { messageId };
81505
81541
  }
81506
- var import_node_crypto7, TASK_MIN_VERSION;
81542
+ var import_node_crypto7, TASK_MIN_VERSION, sqliteGroupSessionPromises;
81507
81543
  var init_xmtp_send = __esm({
81508
81544
  "src/xmtp-send.ts"() {
81509
81545
  "use strict";
81510
81546
  import_node_crypto7 = require("node:crypto");
81511
81547
  init_dist4();
81512
81548
  init_envelope();
81549
+ init_concurrency2();
81513
81550
  init_xmtp_sdk();
81514
81551
  init_bin();
81515
81552
  init_onchainos();
81516
81553
  init_session_store();
81517
81554
  init_agent_message_notice();
81518
81555
  TASK_MIN_VERSION = 1;
81556
+ sqliteGroupSessionPromises = /* @__PURE__ */ new Map();
81519
81557
  }
81520
81558
  });
81521
81559
 
@@ -82498,6 +82536,20 @@ var init_message_handler = __esm({
82498
82536
  }
82499
82537
  });
82500
82538
 
82539
+ // ../core/src/sentry-config.ts
82540
+ var environment, SENTRY_CONFIG;
82541
+ var init_sentry_config = __esm({
82542
+ "../core/src/sentry-config.ts"() {
82543
+ "use strict";
82544
+ environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
82545
+ SENTRY_CONFIG = {
82546
+ projectName: "okx/openclaw-okx-a2a-extension",
82547
+ release: "0.0.2-beta-38940d220c-260605171631",
82548
+ environment
82549
+ };
82550
+ }
82551
+ });
82552
+
82501
82553
  // src/listener.ts
82502
82554
  var listener_exports = {};
82503
82555
  __export(listener_exports, {
@@ -82588,13 +82640,31 @@ async function runListenerWithLock(options, paths) {
82588
82640
  }));
82589
82641
  }
82590
82642
  });
82591
- service.setPluginVersion("0.0.1");
82643
+ service.setPluginVersion("0.0.2-beta-38940d220c-260605171631");
82592
82644
  await service.init();
82593
82645
  const pluginVersionStatus = service.pluginVersionStatus;
82594
82646
  if (pluginVersionStatus.unavailable) {
82595
82647
  throw new Error(
82596
- `@okxweb3/a2a-node v${"0.0.1"} is below the required minimum v${pluginVersionStatus.minVersion}`
82648
+ `@okxweb3/a2a-node v${"0.0.2-beta-38940d220c-260605171631"} is below the required minimum v${pluginVersionStatus.minVersion}`
82649
+ );
82650
+ }
82651
+ const systemConfig = service.getSystemConfig();
82652
+ if (systemConfig.sentryDsn) {
82653
+ initLogger({
82654
+ dsn: systemConfig.sentryDsn,
82655
+ ...SENTRY_CONFIG,
82656
+ agentPlatform: "node"
82657
+ });
82658
+ } else {
82659
+ console.error(
82660
+ "[okx-agent-task] system-config did not return sentryDsn; Sentry not initialized"
82597
82661
  );
82662
+ logger.error(LogEvent.SENTRY_INIT_SKIPPED, void 0, {
82663
+ onchainosAgentId: "*",
82664
+ reason: "system-config missing sentryDsn",
82665
+ pluginId: "@okxweb3/a2a-node",
82666
+ pluginVersion: "0.0.2-beta-38940d220c-260605171631"
82667
+ });
82598
82668
  }
82599
82669
  console.log(
82600
82670
  `[okx-agent-task] listener initialized, clients=${service.getClients().size}, home=${store.homeDir}`
@@ -82638,10 +82708,47 @@ async function runListenerWithLock(options, paths) {
82638
82708
  syncInFlight = false;
82639
82709
  }
82640
82710
  };
82641
- const intervalSec = Math.max(10, service.getSystemConfig().heartbeatInterval);
82642
- const timer = setInterval(() => {
82643
- void syncTick();
82644
- }, intervalSec * 1e3);
82711
+ let intervalSec = Math.max(10, service.getSystemConfig().heartbeatInterval);
82712
+ let timer;
82713
+ let stopping = false;
82714
+ const scheduleSyncTimer = (nextIntervalSec) => {
82715
+ if (stopping) {
82716
+ return;
82717
+ }
82718
+ if (timer) {
82719
+ clearInterval(timer);
82720
+ }
82721
+ intervalSec = Math.max(10, nextIntervalSec);
82722
+ console.log(`[okx-agent-task] scheduled sync interval ${intervalSec}s`);
82723
+ timer = setInterval(() => {
82724
+ void syncTick();
82725
+ }, intervalSec * 1e3);
82726
+ };
82727
+ const refreshSystemConfigTick = async () => {
82728
+ if (stopping) {
82729
+ return;
82730
+ }
82731
+ const previousIntervalSec = intervalSec;
82732
+ try {
82733
+ await service.refreshSystemConfig();
82734
+ if (stopping) {
82735
+ return;
82736
+ }
82737
+ const nextIntervalSec = Math.max(10, service.getSystemConfig().heartbeatInterval);
82738
+ if (nextIntervalSec !== previousIntervalSec) {
82739
+ console.log(
82740
+ `[okx-agent-task] heartbeat interval changed from ${previousIntervalSec}s to ${nextIntervalSec}s; rescheduling sync timer`
82741
+ );
82742
+ scheduleSyncTimer(nextIntervalSec);
82743
+ }
82744
+ } catch (err2) {
82745
+ console.log("[okx-agent-task] system-config refresh failed:", err2);
82746
+ }
82747
+ };
82748
+ scheduleSyncTimer(intervalSec);
82749
+ const systemConfigRefreshTimer = setInterval(() => {
82750
+ void refreshSystemConfigTick();
82751
+ }, 60 * 60 * 1e3);
82645
82752
  void syncTick();
82646
82753
  const commandProcessor = startCommandProcessor({
82647
82754
  service,
@@ -82650,7 +82757,6 @@ async function runListenerWithLock(options, paths) {
82650
82757
  homeDir: options.homeDir
82651
82758
  });
82652
82759
  await new Promise((resolve4) => {
82653
- let stopping = false;
82654
82760
  const shutdown = (signal) => {
82655
82761
  if (stopping) {
82656
82762
  return;
@@ -82662,7 +82768,10 @@ async function runListenerWithLock(options, paths) {
82662
82768
  resolve4();
82663
82769
  }, SHUTDOWN_FORCE_RESOLVE_MS);
82664
82770
  void (async () => {
82665
- clearInterval(timer);
82771
+ if (timer) {
82772
+ clearInterval(timer);
82773
+ }
82774
+ clearInterval(systemConfigRefreshTimer);
82666
82775
  commandProcessor.stop();
82667
82776
  try {
82668
82777
  await userAttentionEvents?.close();
@@ -82703,6 +82812,8 @@ var init_listener = __esm({
82703
82812
  init_paths();
82704
82813
  init_user_attention_ipc();
82705
82814
  init_daemon_lock();
82815
+ init_sentry_logger();
82816
+ init_sentry_config();
82706
82817
  OFFLINE_REPLAY_SYNC_INTERVAL = 5;
82707
82818
  SHUTDOWN_FORCE_RESOLVE_MS = 5e3;
82708
82819
  }
@@ -83043,13 +83154,16 @@ Commands:
83043
83154
  decision-request --user-content <text> --llm-content <text> [--job-id <id>] [--session-key <key>] [--idempotency-key <key>] [--json]
83044
83155
  list [--include-handled] [--job-id <id>] [--limit <n>] [--json]
83045
83156
  check --todo-ids <id,id> [--json]
83046
- watch [--once] [--json] [--job-id <id>] [--timeout <seconds>] [--poll-ms <ms>] [--limit <n>] [--ignore-daemon-status]
83157
+ watch [--once] [--json] [--timeout <seconds>] [--poll-ms <ms>] [--limit <n>] [--ignore-daemon-status]
83047
83158
  `);
83048
83159
  }
83049
83160
  async function watchUserAttention(store, parsed, json) {
83050
83161
  if (parsed.flags.has("from-now")) {
83051
83162
  throw new Error("--from-now has been removed; user watch always returns existing pending items first");
83052
83163
  }
83164
+ if (parsed.options.has("job-id")) {
83165
+ throw new Error("--job-id is not supported by user watch");
83166
+ }
83053
83167
  await assertDaemonRunningForWatch(store, parsed);
83054
83168
  const once = parsed.flags.has("once") || json || !process.stdin.isTTY;
83055
83169
  if (!once) {
@@ -83079,7 +83193,6 @@ async function watchOnce(store, parsed, json) {
83079
83193
  const timeoutMs = (readNumberOption(parsed, "timeout") ?? 0) * 1e3;
83080
83194
  const pollMs = readNumberOption(parsed, "poll-ms") ?? 500;
83081
83195
  const limit = readNumberOption(parsed, "limit") ?? 10;
83082
- const jobId = parsed.options.get("job-id");
83083
83196
  const deadline = timeoutMs > 0 ? Date.now() + timeoutMs : null;
83084
83197
  const wake = createWakeSignal();
83085
83198
  const subscription = await subscribeUserAttentionEvents({
@@ -83101,7 +83214,7 @@ async function watchOnce(store, parsed, json) {
83101
83214
  }
83102
83215
  try {
83103
83216
  while (true) {
83104
- const items = store.listUserAttention({ jobId, limit });
83217
+ const items = store.listUserAttention({ limit });
83105
83218
  if (items.length > 0) {
83106
83219
  outputAttentionItems(json, items, "User attention needed");
83107
83220
  return;
@@ -83126,7 +83239,6 @@ async function watchInteractively(store, parsed) {
83126
83239
  const timeoutMs = (readNumberOption(parsed, "timeout") ?? 0) * 1e3;
83127
83240
  const pollMs = readNumberOption(parsed, "poll-ms") ?? 500;
83128
83241
  const limit = readNumberOption(parsed, "limit") ?? 10;
83129
- const jobId = parsed.options.get("job-id");
83130
83242
  const start = Date.now();
83131
83243
  const seen = /* @__PURE__ */ new Set();
83132
83244
  const wake = createWakeSignal();
@@ -83152,7 +83264,7 @@ async function watchInteractively(store, parsed) {
83152
83264
  );
83153
83265
  try {
83154
83266
  while (true) {
83155
- const items = store.listUserAttention({ jobId, limit }).filter((item) => !seen.has(item.id));
83267
+ const items = store.listUserAttention({ limit }).filter((item) => !seen.has(item.id));
83156
83268
  if (items.length === 0) {
83157
83269
  if (timeoutMs > 0 && Date.now() - start >= timeoutMs) {
83158
83270
  console.log(`Timed out after ${timeoutMs / 1e3}s waiting for user attention.`);
package/dist/index.js CHANGED
@@ -4238,11 +4238,11 @@ Sentry.init({...});
4238
4238
  */
4239
4239
  startSession(context) {
4240
4240
  const { scope: scope2, client } = this.getStackTop();
4241
- const { release, environment = constants3.DEFAULT_ENVIRONMENT } = client && client.getOptions() || {};
4241
+ const { release, environment: environment2 = constants3.DEFAULT_ENVIRONMENT } = client && client.getOptions() || {};
4242
4242
  const { userAgent } = utils.GLOBAL_OBJ.navigator || {};
4243
4243
  const session$1 = session.makeSession({
4244
4244
  release,
4245
- environment,
4245
+ environment: environment2,
4246
4246
  user: scope2.getUser(),
4247
4247
  ...userAgent && { userAgent },
4248
4248
  ...context
@@ -6080,9 +6080,9 @@ var require_prepareEvent = __commonJS({
6080
6080
  });
6081
6081
  }
6082
6082
  function applyClientOptions(event, options) {
6083
- const { environment, release, dist, maxValueLength = 250 } = options;
6083
+ const { environment: environment2, release, dist, maxValueLength = 250 } = options;
6084
6084
  if (!("environment" in event)) {
6085
- event.environment = "environment" in options ? environment : constants3.DEFAULT_ENVIRONMENT;
6085
+ event.environment = "environment" in options ? environment2 : constants3.DEFAULT_ENVIRONMENT;
6086
6086
  }
6087
6087
  if (event.release === void 0 && release !== void 0) {
6088
6088
  event.release = release;
@@ -6878,13 +6878,13 @@ var require_server_runtime_client = __commonJS({
6878
6878
  }
6879
6879
  /** Method that initialises an instance of SessionFlusher on Client */
6880
6880
  initSessionFlusher() {
6881
- const { release, environment } = this._options;
6881
+ const { release, environment: environment2 } = this._options;
6882
6882
  if (!release) {
6883
6883
  (typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && utils.logger.warn("Cannot initialise an instance of SessionFlusher if no release is provided!");
6884
6884
  } else {
6885
6885
  this._sessionFlusher = new sessionflusher.SessionFlusher(this, {
6886
6886
  release,
6887
- environment
6887
+ environment: environment2
6888
6888
  });
6889
6889
  }
6890
6890
  }
@@ -6902,13 +6902,13 @@ var require_server_runtime_client = __commonJS({
6902
6902
  return id;
6903
6903
  }
6904
6904
  const options = this.getOptions();
6905
- const { release, environment, tunnel } = options;
6905
+ const { release, environment: environment2, tunnel } = options;
6906
6906
  const serializedCheckIn = {
6907
6907
  check_in_id: id,
6908
6908
  monitor_slug: checkIn.monitorSlug,
6909
6909
  status: checkIn.status,
6910
6910
  release,
6911
- environment
6911
+ environment: environment2
6912
6912
  };
6913
6913
  if (checkIn.status !== "in_progress") {
6914
6914
  serializedCheckIn.duration = checkIn.duration;
@@ -65511,10 +65511,13 @@ var SentryLogger = class _SentryLogger {
65511
65511
  dsn: config.dsn,
65512
65512
  release: config.release,
65513
65513
  environment: config.environment,
65514
+ maxBreadcrumbs: 0,
65515
+ beforeBreadcrumb: () => null,
65514
65516
  isInner: false
65515
65517
  });
65516
65518
  Sentry.setTags({
65517
- projectName: config.projectName
65519
+ projectName: config.projectName,
65520
+ agentPlatform: config.agentPlatform
65518
65521
  });
65519
65522
  this.initialized = true;
65520
65523
  this.flush();
@@ -65576,6 +65579,9 @@ var SentryLogger = class _SentryLogger {
65576
65579
  }
65577
65580
  };
65578
65581
  var logger = SentryLogger.getInstance();
65582
+ var initLogger = (config) => {
65583
+ return logger.init(config);
65584
+ };
65579
65585
  var UNKNOWN_FIELD = "unknown";
65580
65586
  function agentExtras(identity3) {
65581
65587
  return {
@@ -77004,7 +77010,6 @@ async function loadSystemConfigWith(dataDir, fetcher) {
77004
77010
  console.log("[xmtp-sdk] system-config fetcher not provided by host");
77005
77011
  return loadSystemConfigFromCache(dataDir);
77006
77012
  }
77007
- const cached = loadSystemConfigFromCache(dataDir);
77008
77013
  try {
77009
77014
  const config = await fetcher();
77010
77015
  console.log(
@@ -77019,6 +77024,7 @@ async function loadSystemConfigWith(dataDir, fetcher) {
77019
77024
  } catch (err2) {
77020
77025
  console.log(`[xmtp-sdk] API fetch for system-config failed:`, err2);
77021
77026
  }
77027
+ const cached = loadSystemConfigFromCache(dataDir);
77022
77028
  if (cached) {
77023
77029
  console.log(
77024
77030
  `[xmtp-sdk] using cached system-config from disk: ${Object.keys(cached).length} keys`
@@ -79996,8 +80002,26 @@ function buildSendEnvelope(params) {
79996
80002
  return buildA2AEnvelope({ ...params, tips });
79997
80003
  }
79998
80004
 
80005
+ // ../core/src/a2a/concurrency.ts
80006
+ async function withSharedPromise(registry, key, fn) {
80007
+ const existing = registry.get(key);
80008
+ if (existing) {
80009
+ return existing;
80010
+ }
80011
+ const run = fn();
80012
+ registry.set(key, run);
80013
+ try {
80014
+ return await run;
80015
+ } finally {
80016
+ if (registry.get(key) === run) {
80017
+ registry.delete(key);
80018
+ }
80019
+ }
80020
+ }
80021
+
79999
80022
  // src/xmtp-send.ts
80000
80023
  var TASK_MIN_VERSION = 1;
80024
+ var sqliteGroupSessionPromises = /* @__PURE__ */ new Map();
80001
80025
  function isPlainObject2(value) {
80002
80026
  return !!value && typeof value === "object" && !Array.isArray(value);
80003
80027
  }
@@ -80531,45 +80555,53 @@ async function handleSqliteGroupSendCommand(params) {
80531
80555
  myAgentId: command.myAgentId,
80532
80556
  toAgentId: toAgentKey
80533
80557
  });
80534
- const existingMeta = sessionStore.getSession(sessionKey);
80535
- const stored = readStoredSessionFromMeta(existingMeta);
80558
+ const promiseKey = `${command.myAgentId}|${command.jobId}|${toAgentKey}`;
80536
80559
  const agent = service.getClientByAddress(myXmtpAddress);
80537
80560
  if (!agent) {
80538
80561
  throw new Error(`no XMTP client found for ${myXmtpAddress}`);
80539
80562
  }
80540
- let conversation = null;
80541
- let xmtpGroupId = stored?.xmtpGroupId ?? existingMeta?.groupId ?? null;
80542
- let created = false;
80543
- if (xmtpGroupId) {
80544
- conversation = await findGroupConversation(agent, xmtpGroupId);
80545
- }
80546
- if (!conversation) {
80547
- const toIdentifier = {
80548
- identifier: remote.toXmtpAddress,
80549
- identifierKind: 0
80550
- };
80551
- const canMessageResult = await agent.client.canMessage([toIdentifier]);
80552
- const reachable = canMessageResult.get(remote.toXmtpAddress) ?? canMessageResult.get(remote.toXmtpAddress.toLowerCase());
80553
- if (reachable === false) {
80554
- throw new Error(`${remote.toXmtpAddress} is not registered on XMTP`);
80563
+ const { conversation, created } = await withSharedPromise(
80564
+ sqliteGroupSessionPromises,
80565
+ promiseKey,
80566
+ async () => {
80567
+ const existingMeta = sessionStore.getSession(sessionKey);
80568
+ const stored = readStoredSessionFromMeta(existingMeta);
80569
+ let conversation2 = null;
80570
+ let xmtpGroupId = stored?.xmtpGroupId ?? existingMeta?.groupId ?? null;
80571
+ let created2 = false;
80572
+ if (xmtpGroupId) {
80573
+ conversation2 = await findGroupConversation(agent, xmtpGroupId);
80574
+ }
80575
+ if (!conversation2) {
80576
+ const toIdentifier = {
80577
+ identifier: remote.toXmtpAddress,
80578
+ identifierKind: 0
80579
+ };
80580
+ const canMessageResult = await agent.client.canMessage([toIdentifier]);
80581
+ const reachable = canMessageResult.get(remote.toXmtpAddress) ?? canMessageResult.get(remote.toXmtpAddress.toLowerCase());
80582
+ if (reachable === false) {
80583
+ throw new Error(`${remote.toXmtpAddress} is not registered on XMTP`);
80584
+ }
80585
+ conversation2 = await agent.client.conversations.newGroupWithIdentifiers(
80586
+ [toIdentifier],
80587
+ { groupName: `a2a-${command.jobId}` }
80588
+ );
80589
+ xmtpGroupId = conversation2.id;
80590
+ created2 = true;
80591
+ await service.allowGroup(myXmtpAddress, conversation2.id);
80592
+ }
80593
+ sessionStore.upsertSession({
80594
+ sessionKey,
80595
+ jobId: command.jobId,
80596
+ myAgentId: command.myAgentId,
80597
+ toAgentId: remote.toAgentId ?? command.toAgentId ?? null,
80598
+ groupId: xmtpGroupId,
80599
+ myAgentXmtpAddress: myXmtpAddress,
80600
+ toAgentXmtpAddress: remote.toXmtpAddress
80601
+ });
80602
+ return { conversation: conversation2, created: created2 };
80555
80603
  }
80556
- conversation = await agent.client.conversations.newGroupWithIdentifiers(
80557
- [toIdentifier],
80558
- { groupName: `a2a-${command.jobId}` }
80559
- );
80560
- xmtpGroupId = conversation.id;
80561
- created = true;
80562
- await service.allowGroup(myXmtpAddress, conversation.id);
80563
- }
80564
- sessionStore.upsertSession({
80565
- sessionKey,
80566
- jobId: command.jobId,
80567
- myAgentId: command.myAgentId,
80568
- toAgentId: remote.toAgentId ?? command.toAgentId ?? null,
80569
- groupId: xmtpGroupId,
80570
- myAgentXmtpAddress: myXmtpAddress,
80571
- toAgentXmtpAddress: remote.toXmtpAddress
80572
- });
80604
+ );
80573
80605
  const senderAgent = service.getAgentByAddress(myXmtpAddress);
80574
80606
  await assertOutboundEligible({
80575
80607
  senderAgent,
@@ -81249,6 +81281,14 @@ function trimForUser2(value) {
81249
81281
  return value.length > maxLength ? `${value.slice(0, maxLength)}...` : value;
81250
81282
  }
81251
81283
 
81284
+ // ../core/src/sentry-config.ts
81285
+ var environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
81286
+ var SENTRY_CONFIG = {
81287
+ projectName: "okx/openclaw-okx-a2a-extension",
81288
+ release: "0.0.2-beta-38940d220c-260605171631",
81289
+ environment
81290
+ };
81291
+
81252
81292
  // src/listener.ts
81253
81293
  var OFFLINE_REPLAY_SYNC_INTERVAL = 5;
81254
81294
  function shouldRunOfflineReplay(syncCount, interval = OFFLINE_REPLAY_SYNC_INTERVAL) {
@@ -81334,14 +81374,32 @@ async function runListenerWithLock(options, paths) {
81334
81374
  }));
81335
81375
  }
81336
81376
  });
81337
- service.setPluginVersion("0.0.1");
81377
+ service.setPluginVersion("0.0.2-beta-38940d220c-260605171631");
81338
81378
  await service.init();
81339
81379
  const pluginVersionStatus = service.pluginVersionStatus;
81340
81380
  if (pluginVersionStatus.unavailable) {
81341
81381
  throw new Error(
81342
- `@okxweb3/a2a-node v${"0.0.1"} is below the required minimum v${pluginVersionStatus.minVersion}`
81382
+ `@okxweb3/a2a-node v${"0.0.2-beta-38940d220c-260605171631"} is below the required minimum v${pluginVersionStatus.minVersion}`
81343
81383
  );
81344
81384
  }
81385
+ const systemConfig = service.getSystemConfig();
81386
+ if (systemConfig.sentryDsn) {
81387
+ initLogger({
81388
+ dsn: systemConfig.sentryDsn,
81389
+ ...SENTRY_CONFIG,
81390
+ agentPlatform: "node"
81391
+ });
81392
+ } else {
81393
+ console.error(
81394
+ "[okx-agent-task] system-config did not return sentryDsn; Sentry not initialized"
81395
+ );
81396
+ logger.error(LogEvent.SENTRY_INIT_SKIPPED, void 0, {
81397
+ onchainosAgentId: "*",
81398
+ reason: "system-config missing sentryDsn",
81399
+ pluginId: "@okxweb3/a2a-node",
81400
+ pluginVersion: "0.0.2-beta-38940d220c-260605171631"
81401
+ });
81402
+ }
81345
81403
  console.log(
81346
81404
  `[okx-agent-task] listener initialized, clients=${service.getClients().size}, home=${store.homeDir}`
81347
81405
  );
@@ -81384,10 +81442,47 @@ async function runListenerWithLock(options, paths) {
81384
81442
  syncInFlight = false;
81385
81443
  }
81386
81444
  };
81387
- const intervalSec = Math.max(10, service.getSystemConfig().heartbeatInterval);
81388
- const timer = setInterval(() => {
81389
- void syncTick();
81390
- }, intervalSec * 1e3);
81445
+ let intervalSec = Math.max(10, service.getSystemConfig().heartbeatInterval);
81446
+ let timer;
81447
+ let stopping = false;
81448
+ const scheduleSyncTimer = (nextIntervalSec) => {
81449
+ if (stopping) {
81450
+ return;
81451
+ }
81452
+ if (timer) {
81453
+ clearInterval(timer);
81454
+ }
81455
+ intervalSec = Math.max(10, nextIntervalSec);
81456
+ console.log(`[okx-agent-task] scheduled sync interval ${intervalSec}s`);
81457
+ timer = setInterval(() => {
81458
+ void syncTick();
81459
+ }, intervalSec * 1e3);
81460
+ };
81461
+ const refreshSystemConfigTick = async () => {
81462
+ if (stopping) {
81463
+ return;
81464
+ }
81465
+ const previousIntervalSec = intervalSec;
81466
+ try {
81467
+ await service.refreshSystemConfig();
81468
+ if (stopping) {
81469
+ return;
81470
+ }
81471
+ const nextIntervalSec = Math.max(10, service.getSystemConfig().heartbeatInterval);
81472
+ if (nextIntervalSec !== previousIntervalSec) {
81473
+ console.log(
81474
+ `[okx-agent-task] heartbeat interval changed from ${previousIntervalSec}s to ${nextIntervalSec}s; rescheduling sync timer`
81475
+ );
81476
+ scheduleSyncTimer(nextIntervalSec);
81477
+ }
81478
+ } catch (err2) {
81479
+ console.log("[okx-agent-task] system-config refresh failed:", err2);
81480
+ }
81481
+ };
81482
+ scheduleSyncTimer(intervalSec);
81483
+ const systemConfigRefreshTimer = setInterval(() => {
81484
+ void refreshSystemConfigTick();
81485
+ }, 60 * 60 * 1e3);
81391
81486
  void syncTick();
81392
81487
  const commandProcessor = startCommandProcessor({
81393
81488
  service,
@@ -81396,7 +81491,6 @@ async function runListenerWithLock(options, paths) {
81396
81491
  homeDir: options.homeDir
81397
81492
  });
81398
81493
  await new Promise((resolve3) => {
81399
- let stopping = false;
81400
81494
  const shutdown = (signal) => {
81401
81495
  if (stopping) {
81402
81496
  return;
@@ -81408,7 +81502,10 @@ async function runListenerWithLock(options, paths) {
81408
81502
  resolve3();
81409
81503
  }, SHUTDOWN_FORCE_RESOLVE_MS);
81410
81504
  void (async () => {
81411
- clearInterval(timer);
81505
+ if (timer) {
81506
+ clearInterval(timer);
81507
+ }
81508
+ clearInterval(systemConfigRefreshTimer);
81412
81509
  commandProcessor.stop();
81413
81510
  try {
81414
81511
  await userAttentionEvents?.close();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@okxweb3/a2a-node",
3
- "version": "0.0.1",
3
+ "version": "0.0.2-beta-38940d220c-260605171631",
4
4
  "description": "Host-agnostic Node CLI for E2E encrypted agent-to-agent communication via XMTP",
5
5
  "main": "dist/index.js",
6
6
  "bin": {