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

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 +332 -144
  2. package/dist/index.js +309 -136
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -3843,14 +3843,14 @@ var require_path = __commonJS({
3843
3843
  }
3844
3844
  return root + dir;
3845
3845
  }
3846
- function basename2(path, ext) {
3846
+ function basename3(path, ext) {
3847
3847
  let f = splitPath(path)[2];
3848
3848
  if (ext && f.slice(ext.length * -1) === ext) {
3849
3849
  f = f.slice(0, f.length - ext.length);
3850
3850
  }
3851
3851
  return f;
3852
3852
  }
3853
- exports2.basename = basename2;
3853
+ exports2.basename = basename3;
3854
3854
  exports2.dirname = dirname4;
3855
3855
  exports2.isAbsolute = isAbsolute2;
3856
3856
  exports2.join = join15;
@@ -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;
@@ -13648,10 +13648,10 @@ var require_module = __commonJS({
13648
13648
  return;
13649
13649
  }
13650
13650
  const normalizedFilename = normalizeWindowsPathSeparator ? normalizeWindowsPath(filename) : filename;
13651
- let { root, dir, base: basename2, ext } = path.posix.parse(normalizedFilename);
13651
+ let { root, dir, base: basename3, ext } = path.posix.parse(normalizedFilename);
13652
13652
  const base3 = require && require.main && require.main.filename && dir || global.process.cwd();
13653
13653
  const normalizedBase = `${base3}/`;
13654
- let file = basename2;
13654
+ let file = basename3;
13655
13655
  if (ext === ".js" || ext === ".mjs" || ext === ".cjs") {
13656
13656
  file = file.slice(0, ext.length * -1);
13657
13657
  }
@@ -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, SENTRY_EXTRA_BLOCKLIST, SentryLogger, logger, initLogger, UNKNOWN_FIELD;
17289
17289
  var init_sentry_logger = __esm({
17290
17290
  "../core/src/sentry-logger/index.ts"() {
17291
17291
  "use strict";
@@ -17293,6 +17293,44 @@ var init_sentry_logger = __esm({
17293
17293
  import_node_crypto3 = require("node:crypto");
17294
17294
  init_events();
17295
17295
  FLOW_ID = (0, import_node_crypto3.randomUUID)();
17296
+ SENTRY_EXTRA_BLOCKLIST = /* @__PURE__ */ new Set([
17297
+ "args",
17298
+ "argv",
17299
+ "body",
17300
+ "cache",
17301
+ "command",
17302
+ "content",
17303
+ "cwd",
17304
+ "data",
17305
+ "error",
17306
+ "failures",
17307
+ "filename",
17308
+ "file_name",
17309
+ "filepath",
17310
+ "file_path",
17311
+ "headers",
17312
+ "input",
17313
+ "logpath",
17314
+ "message",
17315
+ "output",
17316
+ "params",
17317
+ "path",
17318
+ "payload",
17319
+ "prompt",
17320
+ "raw",
17321
+ "rawevent",
17322
+ "rawtext",
17323
+ "request",
17324
+ "response",
17325
+ "digest",
17326
+ "nonce",
17327
+ "salt",
17328
+ "secret",
17329
+ "stderr",
17330
+ "stdout",
17331
+ "title",
17332
+ "tooloutput"
17333
+ ]);
17296
17334
  SentryLogger = class _SentryLogger {
17297
17335
  static instance;
17298
17336
  initialized = false;
@@ -17314,16 +17352,19 @@ var init_sentry_logger = __esm({
17314
17352
  dsn: config.dsn,
17315
17353
  release: config.release,
17316
17354
  environment: config.environment,
17355
+ maxBreadcrumbs: 0,
17356
+ beforeBreadcrumb: () => null,
17317
17357
  isInner: false
17318
17358
  });
17319
17359
  Sentry.setTags({
17320
- projectName: config.projectName
17360
+ projectName: config.projectName,
17361
+ agentPlatform: config.agentPlatform
17321
17362
  });
17322
17363
  this.initialized = true;
17323
17364
  this.flush();
17324
17365
  }
17325
17366
  info(message, extra) {
17326
- const extraWithFlow = { flowId: FLOW_ID, ...extra ?? {} };
17367
+ const extraWithFlow = _SentryLogger.sanitizeExtra({ flowId: FLOW_ID, ...extra ?? {} });
17327
17368
  if (!this.initialized) {
17328
17369
  this.buffer.push({ level: "info", message, extra: extraWithFlow });
17329
17370
  return;
@@ -17335,7 +17376,7 @@ var init_sentry_logger = __esm({
17335
17376
  });
17336
17377
  }
17337
17378
  error(message, error, extra) {
17338
- const extraWithFlow = { flowId: FLOW_ID, ...extra ?? {} };
17379
+ const extraWithFlow = _SentryLogger.sanitizeExtra({ flowId: FLOW_ID, ...extra ?? {} });
17339
17380
  if (!this.initialized) {
17340
17381
  this.buffer.push({
17341
17382
  level: "error",
@@ -17349,7 +17390,12 @@ var init_sentry_logger = __esm({
17349
17390
  scope.setLevel("error");
17350
17391
  scope.setContext("report", { info: JSON.stringify(extraWithFlow) });
17351
17392
  Sentry.captureException(_SentryLogger.createSentryEvent(message, error), {
17352
- extra: error ? { ...extraWithFlow, message } : extraWithFlow
17393
+ extra: error ? {
17394
+ ...extraWithFlow,
17395
+ eventName: message,
17396
+ errorName: error.name,
17397
+ errorMessageLength: String(error.message.length)
17398
+ } : extraWithFlow
17353
17399
  });
17354
17400
  });
17355
17401
  }
@@ -17366,19 +17412,30 @@ var init_sentry_logger = __esm({
17366
17412
  }
17367
17413
  }
17368
17414
  }
17415
+ static sanitizeExtra(extra) {
17416
+ return Object.fromEntries(
17417
+ Object.entries(extra).filter(([key]) => !SENTRY_EXTRA_BLOCKLIST.has(key.toLowerCase()))
17418
+ );
17419
+ }
17369
17420
  static toPascalCase(str) {
17370
17421
  return str.split(/[\s:]+/).filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
17371
17422
  }
17372
17423
  static createSentryEvent(eventName, cause) {
17373
- const err2 = new Error(cause?.message ?? eventName);
17424
+ const err2 = new Error(eventName);
17374
17425
  err2.name = _SentryLogger.toPascalCase(eventName);
17375
17426
  if (cause?.stack) {
17376
- err2.stack = cause.stack;
17427
+ err2.stack = [
17428
+ `${err2.name}: ${eventName}`,
17429
+ ...cause.stack.split("\n").slice(1)
17430
+ ].join("\n");
17377
17431
  }
17378
17432
  return err2;
17379
17433
  }
17380
17434
  };
17381
17435
  logger = SentryLogger.getInstance();
17436
+ initLogger = (config) => {
17437
+ return logger.init(config);
17438
+ };
17382
17439
  UNKNOWN_FIELD = "unknown";
17383
17440
  }
17384
17441
  });
@@ -17432,9 +17489,33 @@ function isExecutable2(path) {
17432
17489
  return false;
17433
17490
  }
17434
17491
  }
17492
+ function redactArgsForLog(args) {
17493
+ const redacted = [];
17494
+ let redactNext = false;
17495
+ for (const arg of args) {
17496
+ if (redactNext) {
17497
+ redacted.push("<redacted>");
17498
+ redactNext = false;
17499
+ continue;
17500
+ }
17501
+ const inlineFlag = [...REDACTED_VALUE_FLAGS].find((flag) => arg.startsWith(`${flag}=`));
17502
+ if (inlineFlag) {
17503
+ redacted.push(`${inlineFlag}=<redacted>`);
17504
+ continue;
17505
+ }
17506
+ redacted.push(arg);
17507
+ if (REDACTED_VALUE_FLAGS.has(arg)) {
17508
+ redactNext = true;
17509
+ }
17510
+ }
17511
+ return redacted;
17512
+ }
17513
+ function commandForLog(bin, args) {
17514
+ return `${bin} ${redactArgsForLog(args).join(" ")}`;
17515
+ }
17435
17516
  async function exec(args) {
17436
17517
  const bin = await resolve2();
17437
- const cmd = `${bin} ${args.join(" ")}`;
17518
+ const cmd = commandForLog(bin, args);
17438
17519
  console.log(`[onchainos] exec: ${cmd}`);
17439
17520
  const t0 = Date.now();
17440
17521
  try {
@@ -17449,22 +17530,24 @@ async function exec(args) {
17449
17530
  );
17450
17531
  logger.error(
17451
17532
  LogEvent.ONCHAINOS_CLI_ERROR,
17452
- err2 instanceof Error ? err2 : new Error(String(err2?.message ?? err2)),
17533
+ new Error("onchainos command failed"),
17453
17534
  {
17454
- args: args.join(" ").slice(0, 1e3),
17535
+ operation: redactArgsForLog(args).slice(0, 3).join(" "),
17536
+ argCount: String(args.length),
17455
17537
  exitCode: String(err2?.code ?? ""),
17456
17538
  signal: String(err2?.signal ?? ""),
17457
17539
  killed: String(err2?.killed ?? ""),
17458
- stderr: String(err2?.stderr ?? "").slice(0, 500),
17459
- stdout: String(err2?.stdout ?? "").slice(0, 500),
17460
- message: String(err2?.message ?? "").slice(0, 500),
17540
+ stderrBytes: String(Buffer.byteLength(String(err2?.stderr ?? ""), "utf8")),
17541
+ stdoutBytes: String(Buffer.byteLength(String(err2?.stdout ?? ""), "utf8")),
17542
+ cliErrorName: err2 instanceof Error ? err2.name : "",
17543
+ cliErrorMessageLength: String(String(err2?.message ?? "").length),
17461
17544
  durationMs: String(Date.now() - t0)
17462
17545
  }
17463
17546
  );
17464
17547
  throw err2;
17465
17548
  }
17466
17549
  }
17467
- var import_node_fs5, import_node_child_process2, import_node_util, execFileAsync, resolvedBin;
17550
+ var import_node_fs5, import_node_child_process2, import_node_util, execFileAsync, resolvedBin, REDACTED_VALUE_FLAGS;
17468
17551
  var init_bin = __esm({
17469
17552
  "../core/src/xmtp-sdk/onchainos/bin.ts"() {
17470
17553
  "use strict";
@@ -17474,6 +17557,7 @@ var init_bin = __esm({
17474
17557
  init_sentry_logger();
17475
17558
  execFileAsync = (0, import_node_util.promisify)(import_node_child_process2.execFile);
17476
17559
  resolvedBin = null;
17560
+ REDACTED_VALUE_FLAGS = /* @__PURE__ */ new Set(["--message"]);
17477
17561
  }
17478
17562
  });
17479
17563
 
@@ -19598,7 +19682,7 @@ var require_parseParams = __commonJS({
19598
19682
  var require_basename = __commonJS({
19599
19683
  "../../node_modules/@fastify/busboy/lib/utils/basename.js"(exports2, module2) {
19600
19684
  "use strict";
19601
- module2.exports = function basename2(path) {
19685
+ module2.exports = function basename3(path) {
19602
19686
  if (typeof path !== "string") {
19603
19687
  return "";
19604
19688
  }
@@ -19625,7 +19709,7 @@ var require_multipart = __commonJS({
19625
19709
  var Dicer = require_Dicer();
19626
19710
  var parseParams = require_parseParams();
19627
19711
  var decodeText = require_decodeText();
19628
- var basename2 = require_basename();
19712
+ var basename3 = require_basename();
19629
19713
  var getLimit = require_getLimit();
19630
19714
  var RE_BOUNDARY = /^boundary$/i;
19631
19715
  var RE_FIELD = /^form-data$/i;
@@ -19742,7 +19826,7 @@ var require_multipart = __commonJS({
19742
19826
  } else if (RE_FILENAME.test(parsed[i][0])) {
19743
19827
  filename = parsed[i][1];
19744
19828
  if (!preservePath) {
19745
- filename = basename2(filename);
19829
+ filename = basename3(filename);
19746
19830
  }
19747
19831
  }
19748
19832
  }
@@ -76209,7 +76293,6 @@ async function loadSystemConfigWith(dataDir, fetcher) {
76209
76293
  console.log("[xmtp-sdk] system-config fetcher not provided by host");
76210
76294
  return loadSystemConfigFromCache(dataDir);
76211
76295
  }
76212
- const cached = loadSystemConfigFromCache(dataDir);
76213
76296
  try {
76214
76297
  const config = await fetcher();
76215
76298
  console.log(
@@ -76224,6 +76307,7 @@ async function loadSystemConfigWith(dataDir, fetcher) {
76224
76307
  } catch (err2) {
76225
76308
  console.log(`[xmtp-sdk] API fetch for system-config failed:`, err2);
76226
76309
  }
76310
+ const cached = loadSystemConfigFromCache(dataDir);
76227
76311
  if (cached) {
76228
76312
  console.log(
76229
76313
  `[xmtp-sdk] using cached system-config from disk: ${Object.keys(cached).length} keys`
@@ -77754,12 +77838,25 @@ function normalizeAgentPage(raw) {
77754
77838
  }
77755
77839
  return { list, page: raw.page, pageSize: raw.pageSize, total: raw.total };
77756
77840
  }
77841
+ function cliResponseExtras(stdout) {
77842
+ let responseJson = "0";
77843
+ try {
77844
+ JSON.parse(stdout);
77845
+ responseJson = "1";
77846
+ } catch {
77847
+ responseJson = "0";
77848
+ }
77849
+ return {
77850
+ responseBytes: String(Buffer.byteLength(stdout, "utf8")),
77851
+ responseJson
77852
+ };
77853
+ }
77757
77854
  function cliOkFalseExtras(stdout, command, extra) {
77758
77855
  return {
77759
- command,
77856
+ operation: command,
77760
77857
  reason: CliErrorReason.OK_FALSE,
77761
- ...extra,
77762
- response: stdout.slice(0, 500)
77858
+ ...cliResponseExtras(stdout),
77859
+ ...extra
77763
77860
  };
77764
77861
  }
77765
77862
  function parseCliJson(stdout, command, extras = {}) {
@@ -77768,10 +77865,10 @@ function parseCliJson(stdout, command, extras = {}) {
77768
77865
  } catch (err2) {
77769
77866
  const parseErr = err2 instanceof Error ? err2 : new Error(String(err2));
77770
77867
  logger.error(LogEvent.ONCHAINOS_CLI_ERROR, parseErr, {
77771
- command,
77868
+ operation: command,
77772
77869
  reason: CliErrorReason.JSON_PARSE_FAILED,
77773
- ...extras,
77774
- response: stdout.slice(0, 500)
77870
+ ...cliResponseExtras(stdout),
77871
+ ...extras
77775
77872
  });
77776
77873
  throw parseErr;
77777
77874
  }
@@ -77842,7 +77939,7 @@ async function fetchAgentPage(page) {
77842
77939
  );
77843
77940
  if (!res.ok) {
77844
77941
  guardSessionExpired(stdout, "list-agents");
77845
- const parseErr = new Error(`onchainos agent get failed: ${stdout}`);
77942
+ const parseErr = new Error("onchainos agent get failed");
77846
77943
  logger.error(
77847
77944
  LogEvent.ONCHAINOS_CLI_ERROR,
77848
77945
  parseErr,
@@ -77884,9 +77981,7 @@ async function fetchAgentsByIds(agentIds) {
77884
77981
  );
77885
77982
  if (!res.ok) {
77886
77983
  guardSessionExpired(stdout, "get-agents-by-ids");
77887
- const parseErr = new Error(
77888
- `onchainos agent get --agent-ids failed: ${stdout}`
77889
- );
77984
+ const parseErr = new Error("onchainos agent get --agent-ids failed");
77890
77985
  logger.error(
77891
77986
  LogEvent.ONCHAINOS_CLI_ERROR,
77892
77987
  parseErr,
@@ -77938,9 +78033,7 @@ async function fetchAgentByAddress(communicationAddress) {
77938
78033
  );
77939
78034
  if (!res.ok) {
77940
78035
  guardSessionExpired(stdout, "get-agent-by-address");
77941
- const parseErr = new Error(
77942
- `onchainos agent get-by-address failed: ${stdout}`
77943
- );
78036
+ const parseErr = new Error("onchainos agent get-by-address failed");
77944
78037
  logger.error(
77945
78038
  LogEvent.ONCHAINOS_CLI_ERROR,
77946
78039
  parseErr,
@@ -78048,16 +78141,7 @@ async function sendHeartbeat(chainIndex) {
78048
78141
  throw err2;
78049
78142
  }
78050
78143
  }
78051
- function shouldBypassMessageEligibleForMockIntegration() {
78052
- return true;
78053
- }
78054
78144
  async function checkMessageEligible(params) {
78055
- if (shouldBypassMessageEligibleForMockIntegration()) {
78056
- console.log(
78057
- `[onchainos] message-eligible temporarily bypassed: job=${params.jobId} direction=${params.direction}`
78058
- );
78059
- return { eligible: true, reason: "temporarily-bypassed-for-mock-integration" };
78060
- }
78061
78145
  console.log(
78062
78146
  `[onchainos] checking message-eligible: job=${params.jobId} direction=${params.direction} providerSecurityRate=${params.providerSecurityRate}`
78063
78147
  );
@@ -78088,29 +78172,34 @@ async function checkMessageEligible(params) {
78088
78172
  ]));
78089
78173
  } catch (err2) {
78090
78174
  guardCatchSessionExpired(err2, "message-eligible");
78091
- return { eligible: true };
78175
+ return { eligible: false, reason: "message-eligible-cli-error" };
78092
78176
  }
78093
78177
  if (stderr) {
78094
78178
  console.log(`[onchainos] stderr (message-eligible): ${stderr}`);
78095
78179
  }
78096
- const res = parseCliJson(stdout, "message-eligible", {
78097
- onchainosAgentId: params.agentId,
78098
- clientAgentId: params.clientAgentId,
78099
- providerAgentId: params.providerAgentId,
78100
- clientCommunicationAddress: params.clientCommunicationAddress,
78101
- providerCommunicationAddress: params.providerCommunicationAddress,
78102
- jobId: params.jobId,
78103
- groupId: params.groupId,
78104
- direction: params.direction,
78105
- providerSecurityRate: String(params.providerSecurityRate)
78106
- });
78180
+ let res;
78181
+ try {
78182
+ res = parseCliJson(stdout, "message-eligible", {
78183
+ onchainosAgentId: params.agentId,
78184
+ clientAgentId: params.clientAgentId,
78185
+ providerAgentId: params.providerAgentId,
78186
+ clientCommunicationAddress: params.clientCommunicationAddress,
78187
+ providerCommunicationAddress: params.providerCommunicationAddress,
78188
+ jobId: params.jobId,
78189
+ groupId: params.groupId,
78190
+ direction: params.direction,
78191
+ providerSecurityRate: String(params.providerSecurityRate)
78192
+ });
78193
+ } catch {
78194
+ return { eligible: false, reason: "message-eligible-json-parse-failed" };
78195
+ }
78107
78196
  if (!res.ok) {
78108
78197
  guardSessionExpired(stdout, "message-eligible");
78109
78198
  console.warn(
78110
- `[onchainos] message-eligible ok=false, letting message through: ${stdout.slice(0, 200)}`
78199
+ `[onchainos] message-eligible ok=false, blocking message: ${stdout.slice(0, 200)}`
78111
78200
  );
78112
78201
  logger.error(
78113
- LogEvent.INBOUND_ELIGIBILITY_BYPASSED,
78202
+ LogEvent.ONCHAINOS_CLI_ERROR,
78114
78203
  new Error("message-eligible ok=false"),
78115
78204
  cliOkFalseExtras(stdout, "message-eligible", {
78116
78205
  onchainosAgentId: params.agentId,
@@ -78126,7 +78215,7 @@ async function checkMessageEligible(params) {
78126
78215
  reason: "ok=false"
78127
78216
  })
78128
78217
  );
78129
- return { eligible: true };
78218
+ return { eligible: false, reason: "message-eligible-ok-false" };
78130
78219
  }
78131
78220
  console.log(
78132
78221
  `[onchainos] message-eligible result: eligible=${res.data.eligible}`
@@ -78262,7 +78351,7 @@ async function onchainosSign(agentId, keyUuid, walletAddress, message) {
78262
78351
  if (isSessionExpired(stdout)) {
78263
78352
  notifySessionExpired("xmtp-sign");
78264
78353
  }
78265
- const signErr = new Error(`onchainos xmtp-sign failed: ${stdout}`);
78354
+ const signErr = new Error("onchainos xmtp-sign failed");
78266
78355
  logger.error(
78267
78356
  LogEvent.ONCHAINOS_CLI_ERROR,
78268
78357
  signErr,
@@ -78819,10 +78908,6 @@ function truncateForError(text, max = 500) {
78819
78908
  const normalized = text.replace(/\s+/g, " ").trim();
78820
78909
  return normalized.length > max ? `${normalized.slice(0, max)}...` : normalized;
78821
78910
  }
78822
- function trimForSentry(text, max = 1200) {
78823
- const normalized = text.replace(/\s+/g, " ").trim();
78824
- return normalized.length > max ? `${normalized.slice(0, max)}...` : normalized;
78825
- }
78826
78911
  function createAiToolFailureTracker(provider) {
78827
78912
  const failures = [];
78828
78913
  const claudeToolCommands = /* @__PURE__ */ new Map();
@@ -80275,17 +80360,17 @@ var init_ai_runner = __esm({
80275
80360
  provider: failure.provider,
80276
80361
  tool: failure.tool,
80277
80362
  errorType: failure.errorType,
80278
- command: trimForSentry(failure.command ?? ""),
80363
+ commandLength: String(failure.command?.length ?? 0),
80279
80364
  toolExitCode: failure.exitCode === void 0 || failure.exitCode === null ? "" : String(failure.exitCode),
80280
80365
  toolStatus: failure.status ?? "",
80281
- toolOutput: trimForSentry(failure.output),
80282
- rawEvent: trimForSentry(failure.rawEvent),
80366
+ toolOutputBytes: String(Buffer.byteLength(failure.output, "utf8")),
80367
+ rawEventBytes: String(Buffer.byteLength(failure.rawEvent, "utf8")),
80283
80368
  sessionKey: context.sessionKey,
80284
80369
  taskId: context.jobId ?? "",
80285
80370
  agentId: context.agentId ?? "",
80286
80371
  messageId: context.messageId ?? "",
80287
- logPath: context.logPath,
80288
- cwd: context.cwd,
80372
+ logFileName: context.logPath ? (0, import_node_path13.basename)(context.logPath) : "",
80373
+ cwdName: context.cwd ? (0, import_node_path13.basename)(context.cwd) : "",
80289
80374
  providerExitCode: context.exitCode === null ? "" : String(context.exitCode),
80290
80375
  closeSignal: context.closeSignal ?? "",
80291
80376
  aiSessionId: context.aiSessionId ?? "",
@@ -80403,6 +80488,28 @@ var init_envelope = __esm({
80403
80488
  }
80404
80489
  });
80405
80490
 
80491
+ // ../core/src/a2a/concurrency.ts
80492
+ async function withSharedPromise(registry, key, fn) {
80493
+ const existing = registry.get(key);
80494
+ if (existing) {
80495
+ return existing;
80496
+ }
80497
+ const run = fn();
80498
+ registry.set(key, run);
80499
+ try {
80500
+ return await run;
80501
+ } finally {
80502
+ if (registry.get(key) === run) {
80503
+ registry.delete(key);
80504
+ }
80505
+ }
80506
+ }
80507
+ var init_concurrency2 = __esm({
80508
+ "../core/src/a2a/concurrency.ts"() {
80509
+ "use strict";
80510
+ }
80511
+ });
80512
+
80406
80513
  // src/agent-message-notice.ts
80407
80514
  function shortenAddress(addr) {
80408
80515
  if (!addr) {
@@ -80774,10 +80881,10 @@ async function assertOutboundEligible(params) {
80774
80881
  });
80775
80882
  } catch (err2) {
80776
80883
  console.log(
80777
- `[okx-agent-task] outbound message-eligible call failed, letting message through: senderAgentId=${senderAgent.agentId} receiverAgentId=${receiverAgent.agentId} job=${jobId} group=${groupId}`,
80884
+ `[okx-agent-task] outbound message-eligible call failed, blocking send: senderAgentId=${senderAgent.agentId} receiverAgentId=${receiverAgent.agentId} job=${jobId} group=${groupId}`,
80778
80885
  err2
80779
80886
  );
80780
- return;
80887
+ throw new Error("unable to verify message eligibility for this task/group");
80781
80888
  }
80782
80889
  console.log(
80783
80890
  `[okx-agent-task] outbound message-eligible: senderAgentId=${senderAgent.agentId} receiverAgentId=${receiverAgent.agentId} job=${jobId} group=${groupId} result=${JSON.stringify(result)}`
@@ -81096,45 +81203,53 @@ async function handleSqliteGroupSendCommand(params) {
81096
81203
  myAgentId: command.myAgentId,
81097
81204
  toAgentId: toAgentKey
81098
81205
  });
81099
- const existingMeta = sessionStore.getSession(sessionKey);
81100
- const stored = readStoredSessionFromMeta(existingMeta);
81206
+ const promiseKey = `${command.myAgentId}|${command.jobId}|${toAgentKey}`;
81101
81207
  const agent = service.getClientByAddress(myXmtpAddress);
81102
81208
  if (!agent) {
81103
81209
  throw new Error(`no XMTP client found for ${myXmtpAddress}`);
81104
81210
  }
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`);
81211
+ const { conversation, created } = await withSharedPromise(
81212
+ sqliteGroupSessionPromises,
81213
+ promiseKey,
81214
+ async () => {
81215
+ const existingMeta = sessionStore.getSession(sessionKey);
81216
+ const stored = readStoredSessionFromMeta(existingMeta);
81217
+ let conversation2 = null;
81218
+ let xmtpGroupId = stored?.xmtpGroupId ?? existingMeta?.groupId ?? null;
81219
+ let created2 = false;
81220
+ if (xmtpGroupId) {
81221
+ conversation2 = await findGroupConversation(agent, xmtpGroupId);
81222
+ }
81223
+ if (!conversation2) {
81224
+ const toIdentifier = {
81225
+ identifier: remote.toXmtpAddress,
81226
+ identifierKind: 0
81227
+ };
81228
+ const canMessageResult = await agent.client.canMessage([toIdentifier]);
81229
+ const reachable = canMessageResult.get(remote.toXmtpAddress) ?? canMessageResult.get(remote.toXmtpAddress.toLowerCase());
81230
+ if (reachable === false) {
81231
+ throw new Error(`${remote.toXmtpAddress} is not registered on XMTP`);
81232
+ }
81233
+ conversation2 = await agent.client.conversations.newGroupWithIdentifiers(
81234
+ [toIdentifier],
81235
+ { groupName: `a2a-${command.jobId}` }
81236
+ );
81237
+ xmtpGroupId = conversation2.id;
81238
+ created2 = true;
81239
+ await service.allowGroup(myXmtpAddress, conversation2.id);
81240
+ }
81241
+ sessionStore.upsertSession({
81242
+ sessionKey,
81243
+ jobId: command.jobId,
81244
+ myAgentId: command.myAgentId,
81245
+ toAgentId: remote.toAgentId ?? command.toAgentId ?? null,
81246
+ groupId: xmtpGroupId,
81247
+ myAgentXmtpAddress: myXmtpAddress,
81248
+ toAgentXmtpAddress: remote.toXmtpAddress
81249
+ });
81250
+ return { conversation: conversation2, created: created2 };
81120
81251
  }
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
- });
81252
+ );
81138
81253
  const senderAgent = service.getAgentByAddress(myXmtpAddress);
81139
81254
  await assertOutboundEligible({
81140
81255
  senderAgent,
@@ -81503,19 +81618,21 @@ async function handleXmtpSendCommand(params) {
81503
81618
  });
81504
81619
  return { messageId };
81505
81620
  }
81506
- var import_node_crypto7, TASK_MIN_VERSION;
81621
+ var import_node_crypto7, TASK_MIN_VERSION, sqliteGroupSessionPromises;
81507
81622
  var init_xmtp_send = __esm({
81508
81623
  "src/xmtp-send.ts"() {
81509
81624
  "use strict";
81510
81625
  import_node_crypto7 = require("node:crypto");
81511
81626
  init_dist4();
81512
81627
  init_envelope();
81628
+ init_concurrency2();
81513
81629
  init_xmtp_sdk();
81514
81630
  init_bin();
81515
81631
  init_onchainos();
81516
81632
  init_session_store();
81517
81633
  init_agent_message_notice();
81518
81634
  TASK_MIN_VERSION = 1;
81635
+ sqliteGroupSessionPromises = /* @__PURE__ */ new Map();
81519
81636
  }
81520
81637
  });
81521
81638
 
@@ -82200,25 +82317,22 @@ async function verifyInboundA2AGroupMessage(params) {
82200
82317
  }
82201
82318
  } catch (err2) {
82202
82319
  console.log(
82203
- `[okx-agent-task:${myXmtpAddress}] message-eligible call failed, letting message through:`,
82320
+ `[okx-agent-task:${myXmtpAddress}] message-eligible call failed, dropping:`,
82204
82321
  err2
82205
82322
  );
82206
- logger.error(
82207
- LogEvent.INBOUND_ELIGIBILITY_BYPASSED,
82208
- err2 instanceof Error ? err2 : new Error(String(err2)),
82209
- {
82210
- ...agentExtras({ walletAddress: myXmtpAddress, onchainosAgentId: myAgent.agentId }),
82211
- peerWalletAddress: senderAddress,
82212
- peerInboxId: senderInboxId,
82213
- peerAgentId: senderAgentId,
82214
- taskId: jobId,
82215
- conversationId: groupId,
82216
- messageId,
82217
- direction: isSenderClient ? "client_to_provider" : "provider_to_client",
82218
- providerSecurityRate: String(providerSecurityRate),
82219
- reason: "exception"
82220
- }
82221
- );
82323
+ logger.info(LogEvent.INBOUND_BLOCKED_INELIGIBLE, {
82324
+ ...agentExtras({ walletAddress: myXmtpAddress, onchainosAgentId: myAgent.agentId }),
82325
+ peerWalletAddress: senderAddress,
82326
+ peerInboxId: senderInboxId,
82327
+ peerAgentId: senderAgentId,
82328
+ taskId: jobId,
82329
+ conversationId: groupId,
82330
+ messageId,
82331
+ direction: isSenderClient ? "client_to_provider" : "provider_to_client",
82332
+ providerSecurityRate: String(providerSecurityRate),
82333
+ reason: "exception"
82334
+ });
82335
+ return false;
82222
82336
  }
82223
82337
  return true;
82224
82338
  }
@@ -82498,6 +82612,20 @@ var init_message_handler = __esm({
82498
82612
  }
82499
82613
  });
82500
82614
 
82615
+ // ../core/src/sentry-config.ts
82616
+ var environment, SENTRY_CONFIG;
82617
+ var init_sentry_config = __esm({
82618
+ "../core/src/sentry-config.ts"() {
82619
+ "use strict";
82620
+ environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
82621
+ SENTRY_CONFIG = {
82622
+ projectName: "okx/openclaw-okx-a2a-extension",
82623
+ release: "0.0.2-beta-38940d220c-260605180610",
82624
+ environment
82625
+ };
82626
+ }
82627
+ });
82628
+
82501
82629
  // src/listener.ts
82502
82630
  var listener_exports = {};
82503
82631
  __export(listener_exports, {
@@ -82588,13 +82716,31 @@ async function runListenerWithLock(options, paths) {
82588
82716
  }));
82589
82717
  }
82590
82718
  });
82591
- service.setPluginVersion("0.0.1");
82719
+ service.setPluginVersion("0.0.2-beta-38940d220c-260605180610");
82592
82720
  await service.init();
82593
82721
  const pluginVersionStatus = service.pluginVersionStatus;
82594
82722
  if (pluginVersionStatus.unavailable) {
82595
82723
  throw new Error(
82596
- `@okxweb3/a2a-node v${"0.0.1"} is below the required minimum v${pluginVersionStatus.minVersion}`
82724
+ `@okxweb3/a2a-node v${"0.0.2-beta-38940d220c-260605180610"} is below the required minimum v${pluginVersionStatus.minVersion}`
82725
+ );
82726
+ }
82727
+ const systemConfig = service.getSystemConfig();
82728
+ if (systemConfig.sentryDsn) {
82729
+ initLogger({
82730
+ dsn: systemConfig.sentryDsn,
82731
+ ...SENTRY_CONFIG,
82732
+ agentPlatform: "node"
82733
+ });
82734
+ } else {
82735
+ console.error(
82736
+ "[okx-agent-task] system-config did not return sentryDsn; Sentry not initialized"
82597
82737
  );
82738
+ logger.error(LogEvent.SENTRY_INIT_SKIPPED, void 0, {
82739
+ onchainosAgentId: "*",
82740
+ reason: "system-config missing sentryDsn",
82741
+ pluginId: "@okxweb3/a2a-node",
82742
+ pluginVersion: "0.0.2-beta-38940d220c-260605180610"
82743
+ });
82598
82744
  }
82599
82745
  console.log(
82600
82746
  `[okx-agent-task] listener initialized, clients=${service.getClients().size}, home=${store.homeDir}`
@@ -82638,10 +82784,47 @@ async function runListenerWithLock(options, paths) {
82638
82784
  syncInFlight = false;
82639
82785
  }
82640
82786
  };
82641
- const intervalSec = Math.max(10, service.getSystemConfig().heartbeatInterval);
82642
- const timer = setInterval(() => {
82643
- void syncTick();
82644
- }, intervalSec * 1e3);
82787
+ let intervalSec = Math.max(10, service.getSystemConfig().heartbeatInterval);
82788
+ let timer;
82789
+ let stopping = false;
82790
+ const scheduleSyncTimer = (nextIntervalSec) => {
82791
+ if (stopping) {
82792
+ return;
82793
+ }
82794
+ if (timer) {
82795
+ clearInterval(timer);
82796
+ }
82797
+ intervalSec = Math.max(10, nextIntervalSec);
82798
+ console.log(`[okx-agent-task] scheduled sync interval ${intervalSec}s`);
82799
+ timer = setInterval(() => {
82800
+ void syncTick();
82801
+ }, intervalSec * 1e3);
82802
+ };
82803
+ const refreshSystemConfigTick = async () => {
82804
+ if (stopping) {
82805
+ return;
82806
+ }
82807
+ const previousIntervalSec = intervalSec;
82808
+ try {
82809
+ await service.refreshSystemConfig();
82810
+ if (stopping) {
82811
+ return;
82812
+ }
82813
+ const nextIntervalSec = Math.max(10, service.getSystemConfig().heartbeatInterval);
82814
+ if (nextIntervalSec !== previousIntervalSec) {
82815
+ console.log(
82816
+ `[okx-agent-task] heartbeat interval changed from ${previousIntervalSec}s to ${nextIntervalSec}s; rescheduling sync timer`
82817
+ );
82818
+ scheduleSyncTimer(nextIntervalSec);
82819
+ }
82820
+ } catch (err2) {
82821
+ console.log("[okx-agent-task] system-config refresh failed:", err2);
82822
+ }
82823
+ };
82824
+ scheduleSyncTimer(intervalSec);
82825
+ const systemConfigRefreshTimer = setInterval(() => {
82826
+ void refreshSystemConfigTick();
82827
+ }, 60 * 60 * 1e3);
82645
82828
  void syncTick();
82646
82829
  const commandProcessor = startCommandProcessor({
82647
82830
  service,
@@ -82650,7 +82833,6 @@ async function runListenerWithLock(options, paths) {
82650
82833
  homeDir: options.homeDir
82651
82834
  });
82652
82835
  await new Promise((resolve4) => {
82653
- let stopping = false;
82654
82836
  const shutdown = (signal) => {
82655
82837
  if (stopping) {
82656
82838
  return;
@@ -82662,7 +82844,10 @@ async function runListenerWithLock(options, paths) {
82662
82844
  resolve4();
82663
82845
  }, SHUTDOWN_FORCE_RESOLVE_MS);
82664
82846
  void (async () => {
82665
- clearInterval(timer);
82847
+ if (timer) {
82848
+ clearInterval(timer);
82849
+ }
82850
+ clearInterval(systemConfigRefreshTimer);
82666
82851
  commandProcessor.stop();
82667
82852
  try {
82668
82853
  await userAttentionEvents?.close();
@@ -82703,6 +82888,8 @@ var init_listener = __esm({
82703
82888
  init_paths();
82704
82889
  init_user_attention_ipc();
82705
82890
  init_daemon_lock();
82891
+ init_sentry_logger();
82892
+ init_sentry_config();
82706
82893
  OFFLINE_REPLAY_SYNC_INTERVAL = 5;
82707
82894
  SHUTDOWN_FORCE_RESOLVE_MS = 5e3;
82708
82895
  }
@@ -83043,13 +83230,16 @@ Commands:
83043
83230
  decision-request --user-content <text> --llm-content <text> [--job-id <id>] [--session-key <key>] [--idempotency-key <key>] [--json]
83044
83231
  list [--include-handled] [--job-id <id>] [--limit <n>] [--json]
83045
83232
  check --todo-ids <id,id> [--json]
83046
- watch [--once] [--json] [--job-id <id>] [--timeout <seconds>] [--poll-ms <ms>] [--limit <n>] [--ignore-daemon-status]
83233
+ watch [--once] [--json] [--timeout <seconds>] [--poll-ms <ms>] [--limit <n>] [--ignore-daemon-status]
83047
83234
  `);
83048
83235
  }
83049
83236
  async function watchUserAttention(store, parsed, json) {
83050
83237
  if (parsed.flags.has("from-now")) {
83051
83238
  throw new Error("--from-now has been removed; user watch always returns existing pending items first");
83052
83239
  }
83240
+ if (parsed.options.has("job-id")) {
83241
+ throw new Error("--job-id is not supported by user watch");
83242
+ }
83053
83243
  await assertDaemonRunningForWatch(store, parsed);
83054
83244
  const once = parsed.flags.has("once") || json || !process.stdin.isTTY;
83055
83245
  if (!once) {
@@ -83079,7 +83269,6 @@ async function watchOnce(store, parsed, json) {
83079
83269
  const timeoutMs = (readNumberOption(parsed, "timeout") ?? 0) * 1e3;
83080
83270
  const pollMs = readNumberOption(parsed, "poll-ms") ?? 500;
83081
83271
  const limit = readNumberOption(parsed, "limit") ?? 10;
83082
- const jobId = parsed.options.get("job-id");
83083
83272
  const deadline = timeoutMs > 0 ? Date.now() + timeoutMs : null;
83084
83273
  const wake = createWakeSignal();
83085
83274
  const subscription = await subscribeUserAttentionEvents({
@@ -83101,7 +83290,7 @@ async function watchOnce(store, parsed, json) {
83101
83290
  }
83102
83291
  try {
83103
83292
  while (true) {
83104
- const items = store.listUserAttention({ jobId, limit });
83293
+ const items = store.listUserAttention({ limit });
83105
83294
  if (items.length > 0) {
83106
83295
  outputAttentionItems(json, items, "User attention needed");
83107
83296
  return;
@@ -83126,7 +83315,6 @@ async function watchInteractively(store, parsed) {
83126
83315
  const timeoutMs = (readNumberOption(parsed, "timeout") ?? 0) * 1e3;
83127
83316
  const pollMs = readNumberOption(parsed, "poll-ms") ?? 500;
83128
83317
  const limit = readNumberOption(parsed, "limit") ?? 10;
83129
- const jobId = parsed.options.get("job-id");
83130
83318
  const start = Date.now();
83131
83319
  const seen = /* @__PURE__ */ new Set();
83132
83320
  const wake = createWakeSignal();
@@ -83152,7 +83340,7 @@ async function watchInteractively(store, parsed) {
83152
83340
  );
83153
83341
  try {
83154
83342
  while (true) {
83155
- const items = store.listUserAttention({ jobId, limit }).filter((item) => !seen.has(item.id));
83343
+ const items = store.listUserAttention({ limit }).filter((item) => !seen.has(item.id));
83156
83344
  if (items.length === 0) {
83157
83345
  if (timeoutMs > 0 && Date.now() - start >= timeoutMs) {
83158
83346
  console.log(`Timed out after ${timeoutMs / 1e3}s waiting for user attention.`);