@okxweb3/a2a-node 0.0.16 → 0.0.17-beta-db5dca184d-260624150845

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 (4) hide show
  1. package/README.md +40 -6
  2. package/dist/cli.js +768 -374
  3. package/dist/index.js +182 -15
  4. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -67974,6 +67974,7 @@ __export(index_exports, {
67974
67974
  detectCurrentAiProvider: () => detectCurrentAiProvider,
67975
67975
  detectGatewayInvocation: () => detectGatewayInvocation,
67976
67976
  detectRuntime: () => detectRuntime,
67977
+ ensureDaemonReady: () => ensureDaemonReady,
67977
67978
  ensureDefaultAiProvider: () => ensureDefaultAiProvider,
67978
67979
  extractAiSessionId: () => extractAiSessionId,
67979
67980
  extractXmtpSentAtMs: () => extractXmtpSentAtMs2,
@@ -68297,7 +68298,7 @@ var SessionStore = class {
68297
68298
  `);
68298
68299
  }
68299
68300
  ensurePendingGatewayDeliveriesSchema() {
68300
- const expectedKindCheck = "kind IN ('session_send', 'chat_inject', 'dispatch_user_latest', 'prompt_user_latest')";
68301
+ const expectedKindCheck = this.pendingGatewayDeliveryKindCheck();
68301
68302
  this.db.exec(`
68302
68303
  CREATE TABLE IF NOT EXISTS pending_gateway_deliveries (
68303
68304
  id TEXT PRIMARY KEY,
@@ -68308,6 +68309,9 @@ var SessionStore = class {
68308
68309
  content TEXT NOT NULL,
68309
68310
  llm_content TEXT,
68310
68311
  message_id TEXT UNIQUE,
68312
+ attention_id TEXT,
68313
+ delivery_state_json TEXT,
68314
+ payload_json TEXT,
68311
68315
  attempts INTEGER NOT NULL DEFAULT 0,
68312
68316
  last_error TEXT,
68313
68317
  created_at TEXT NOT NULL,
@@ -68315,7 +68319,7 @@ var SessionStore = class {
68315
68319
  )
68316
68320
  `);
68317
68321
  const row = this.db.prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='pending_gateway_deliveries'").get();
68318
- if (row?.sql?.includes("dispatch_user_latest")) {
68322
+ if (row?.sql?.includes("attention_id") && row.sql.includes("delivery_state_json") && row.sql.includes("payload_json")) {
68319
68323
  return;
68320
68324
  }
68321
68325
  this.db.exec("ALTER TABLE pending_gateway_deliveries RENAME TO pending_gateway_deliveries_old");
@@ -68329,6 +68333,9 @@ var SessionStore = class {
68329
68333
  content TEXT NOT NULL,
68330
68334
  llm_content TEXT,
68331
68335
  message_id TEXT UNIQUE,
68336
+ attention_id TEXT,
68337
+ delivery_state_json TEXT,
68338
+ payload_json TEXT,
68332
68339
  attempts INTEGER NOT NULL DEFAULT 0,
68333
68340
  last_error TEXT,
68334
68341
  created_at TEXT NOT NULL,
@@ -68338,15 +68345,19 @@ var SessionStore = class {
68338
68345
  this.db.exec(`
68339
68346
  INSERT INTO pending_gateway_deliveries (
68340
68347
  id, kind, provider, session_key, job_id, content, llm_content,
68341
- message_id, attempts, last_error, created_at, last_attempt_at
68348
+ message_id, attention_id, delivery_state_json, payload_json,
68349
+ attempts, last_error, created_at, last_attempt_at
68342
68350
  )
68343
68351
  SELECT
68344
68352
  id, kind, provider, session_key, job_id, content, llm_content,
68345
- message_id, attempts, last_error, created_at, last_attempt_at
68353
+ message_id, NULL, NULL, NULL, attempts, last_error, created_at, last_attempt_at
68346
68354
  FROM pending_gateway_deliveries_old
68347
68355
  `);
68348
68356
  this.db.exec("DROP TABLE pending_gateway_deliveries_old");
68349
68357
  }
68358
+ pendingGatewayDeliveryKindCheck() {
68359
+ return "kind IN ('session_send', 'chat_inject', 'dispatch_user_latest', 'prompt_user_latest')";
68360
+ }
68350
68361
  close() {
68351
68362
  this.db.close();
68352
68363
  }
@@ -69076,9 +69087,10 @@ var SessionStore = class {
69076
69087
  this.db.prepare(`
69077
69088
  INSERT INTO pending_gateway_deliveries (
69078
69089
  id, kind, provider, session_key, job_id, content, llm_content,
69079
- message_id, attempts, last_error, created_at, last_attempt_at
69090
+ message_id, attention_id, delivery_state_json, payload_json,
69091
+ attempts, last_error, created_at, last_attempt_at
69080
69092
  )
69081
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0, NULL, ?, NULL)
69093
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, NULL, ?, NULL)
69082
69094
  `).run(
69083
69095
  id,
69084
69096
  input.kind,
@@ -69088,6 +69100,9 @@ var SessionStore = class {
69088
69100
  input.content,
69089
69101
  input.llmContent ?? null,
69090
69102
  messageId,
69103
+ input.attentionId ?? null,
69104
+ input.deliveryStateJson ?? null,
69105
+ input.payloadJson ?? null,
69091
69106
  createdAt
69092
69107
  );
69093
69108
  const row = this.getPendingGatewayDelivery(id);
@@ -69365,6 +69380,9 @@ function mapPendingGatewayDeliveryRow(row) {
69365
69380
  ...row.job_id ? { jobId: row.job_id } : {},
69366
69381
  ...row.llm_content ? { llmContent: row.llm_content } : {},
69367
69382
  ...row.message_id ? { messageId: row.message_id } : {},
69383
+ ...row.attention_id ? { attentionId: row.attention_id } : {},
69384
+ ...row.delivery_state_json ? { deliveryStateJson: row.delivery_state_json } : {},
69385
+ ...row.payload_json ? { payloadJson: row.payload_json } : {},
69368
69386
  ...row.last_error ? { lastError: row.last_error } : {},
69369
69387
  ...row.last_attempt_at ? { lastAttemptAt: row.last_attempt_at } : {}
69370
69388
  };
@@ -69508,6 +69526,19 @@ async function readDaemonLock(lockPath) {
69508
69526
  const running = Number.isInteger(metadata.pid) && metadata.pid > 0 && isProcessAlive(metadata.pid);
69509
69527
  return { metadata, running, stale: !running, path: lockPath };
69510
69528
  }
69529
+ async function markDaemonReady(lockPath) {
69530
+ const current = await readDaemonLock(lockPath);
69531
+ const metadata = current.metadata;
69532
+ if (!metadata || metadata.pid !== process.pid) {
69533
+ return;
69534
+ }
69535
+ await (0, import_promises.writeFile)(ownerPath(lockPath), `${JSON.stringify({
69536
+ ...metadata,
69537
+ ready: true,
69538
+ readyAt: (/* @__PURE__ */ new Date()).toISOString()
69539
+ }, null, 2)}
69540
+ `, "utf8");
69541
+ }
69511
69542
  async function removeLock(lockPath) {
69512
69543
  await (0, import_promises.rm)(lockPath, { recursive: true, force: true });
69513
69544
  }
@@ -69518,7 +69549,8 @@ async function acquireDaemonLock(paths, entry) {
69518
69549
  cwd: process.cwd(),
69519
69550
  entry,
69520
69551
  homeDir: paths.homeDir,
69521
- capabilities: DAEMON_CAPABILITIES
69552
+ capabilities: DAEMON_CAPABILITIES,
69553
+ ready: false
69522
69554
  };
69523
69555
  ensureTaskDir(paths.runDir);
69524
69556
  for (let attempt = 0; attempt < 2; attempt += 1) {
@@ -69568,6 +69600,9 @@ async function chmodBestEffort(path, mode) {
69568
69600
  var STOP_GRACE_MS = 5e3;
69569
69601
  var FORCE_KILL_GRACE_MS = 5e3;
69570
69602
  var START_EXIT_CHECK_MS = 750;
69603
+ var DEFAULT_READY_TIMEOUT_MS = 12e4;
69604
+ var READY_POLL_MS = 250;
69605
+ var DAEMON_READY_TIMEOUT_ENV = "OKX_A2A_DAEMON_READY_TIMEOUT_MS";
69571
69606
  async function readPid(pidPath) {
69572
69607
  try {
69573
69608
  const raw = await (0, import_promises2.readFile)(pidPath, "utf8");
@@ -69627,12 +69662,17 @@ async function getDaemonStatus(homeDir) {
69627
69662
  const pid = await readPid(paths.pidPath);
69628
69663
  const lock = await readDaemonLock(paths.daemonLockPath);
69629
69664
  const lockPid = lock.metadata?.pid ?? null;
69665
+ const lockReadyStateKnown = !!lock.metadata && (typeof lock.metadata.ready === "boolean" || typeof lock.metadata.readyAt === "string");
69666
+ const lockReady = lockReadyStateKnown ? lock.metadata?.ready === true || typeof lock.metadata?.readyAt === "string" : true;
69630
69667
  if (lock.running) {
69631
69668
  return {
69632
69669
  running: true,
69633
69670
  pid: lockPid ?? pid,
69634
69671
  stale: false,
69635
69672
  capabilities: lock.metadata?.capabilities ?? [],
69673
+ ready: lockReady,
69674
+ readyAt: lock.metadata?.readyAt ?? null,
69675
+ readyStateKnown: lockReadyStateKnown,
69636
69676
  pidPath: paths.pidPath,
69637
69677
  lockPath: paths.daemonLockPath,
69638
69678
  lockPid,
@@ -69645,6 +69685,9 @@ async function getDaemonStatus(homeDir) {
69645
69685
  pid: null,
69646
69686
  stale: lock.stale,
69647
69687
  capabilities: [],
69688
+ ready: false,
69689
+ readyAt: null,
69690
+ readyStateKnown: false,
69648
69691
  pidPath: paths.pidPath,
69649
69692
  lockPath: paths.daemonLockPath,
69650
69693
  lockPid,
@@ -69657,6 +69700,9 @@ async function getDaemonStatus(homeDir) {
69657
69700
  pid,
69658
69701
  stale: !running || lock.stale,
69659
69702
  capabilities: running ? lock.metadata?.capabilities ?? [] : [],
69703
+ ready: running && !lockReadyStateKnown ? true : running && lockReady,
69704
+ readyAt: running ? lock.metadata?.readyAt ?? null : null,
69705
+ readyStateKnown: running && lockReadyStateKnown,
69660
69706
  pidPath: paths.pidPath,
69661
69707
  lockPath: paths.daemonLockPath,
69662
69708
  lockPid,
@@ -69722,6 +69768,9 @@ async function startDaemon(homeDir) {
69722
69768
  pid: child.pid ?? null,
69723
69769
  stale: false,
69724
69770
  capabilities: DAEMON_CAPABILITIES,
69771
+ ready: false,
69772
+ readyAt: null,
69773
+ readyStateKnown: true,
69725
69774
  pidPath: paths.pidPath,
69726
69775
  lockPath: paths.daemonLockPath,
69727
69776
  lockPid: child.pid ?? null,
@@ -69765,6 +69814,9 @@ async function stopDaemon(homeDir) {
69765
69814
  pid: current.pid,
69766
69815
  stale: false,
69767
69816
  capabilities: [],
69817
+ ready: false,
69818
+ readyAt: null,
69819
+ readyStateKnown: false,
69768
69820
  pidPath: paths.pidPath,
69769
69821
  lockPath: paths.daemonLockPath,
69770
69822
  lockPid: current.lockPid,
@@ -69788,6 +69840,9 @@ async function stopDaemon(homeDir) {
69788
69840
  pid: current.pid,
69789
69841
  stale: false,
69790
69842
  capabilities: exited ? [] : current.capabilities,
69843
+ ready: !exited && current.ready,
69844
+ readyAt: !exited ? current.readyAt : null,
69845
+ readyStateKnown: !exited && current.readyStateKnown,
69791
69846
  pidPath: paths.pidPath,
69792
69847
  lockPath: paths.daemonLockPath,
69793
69848
  lockPid: current.lockPid,
@@ -69796,6 +69851,115 @@ async function stopDaemon(homeDir) {
69796
69851
  forced
69797
69852
  };
69798
69853
  }
69854
+ async function ensureDaemonReady(options = {}) {
69855
+ const paths = resolveTaskPaths(options.homeDir);
69856
+ const commandName = options.commandName ?? "command";
69857
+ const timeoutMs = options.timeoutMs ?? readReadyTimeoutMs(options.env ?? process.env);
69858
+ let status = await getDaemonStatus(options.homeDir);
69859
+ let started = false;
69860
+ let logPath = paths.listenerLogPath;
69861
+ if (!status.running) {
69862
+ options.stderr?.write(`[okx-a2a] ${commandName} requires the daemon; starting daemon...
69863
+ `);
69864
+ const startResult = await startDaemon(options.homeDir);
69865
+ started = startResult.started;
69866
+ logPath = startResult.logPath;
69867
+ status = startResult;
69868
+ if (!status.running) {
69869
+ throw new Error(
69870
+ `${commandName} requires the daemon, but automatic daemon start failed. Check ${logPath} or run \`okx-a2a daemon restart\`.`
69871
+ );
69872
+ }
69873
+ status = await waitForDaemonReady({
69874
+ homeDir: options.homeDir,
69875
+ timeoutMs,
69876
+ requiredCapabilities: options.requiredCapabilities,
69877
+ requireKnownReadyState: true,
69878
+ logPath,
69879
+ commandName
69880
+ });
69881
+ options.stderr?.write(`[okx-a2a] daemon ready pid=${status.pid ?? "(unknown)"} log=${logPath}
69882
+ `);
69883
+ } else if (status.readyStateKnown && !status.ready) {
69884
+ status = await waitForDaemonReady({
69885
+ homeDir: options.homeDir,
69886
+ timeoutMs,
69887
+ requiredCapabilities: options.requiredCapabilities,
69888
+ requireKnownReadyState: false,
69889
+ logPath,
69890
+ commandName
69891
+ });
69892
+ }
69893
+ assertRequiredCapabilities(status, options.requiredCapabilities, commandName);
69894
+ return {
69895
+ ...status,
69896
+ started,
69897
+ logPath
69898
+ };
69899
+ }
69900
+ async function waitForDaemonReady(options) {
69901
+ const deadline = Date.now() + Math.max(0, options.timeoutMs);
69902
+ let lastStatus = await getDaemonStatus(options.homeDir);
69903
+ while (Date.now() <= deadline) {
69904
+ const status = await getDaemonStatus(options.homeDir);
69905
+ lastStatus = status;
69906
+ if (!status.running) {
69907
+ if (status.stale) {
69908
+ throw new Error(
69909
+ `${options.commandName} requires the daemon, but the daemon exited before becoming ready. Check ${options.logPath} or run \`okx-a2a daemon restart\`.`
69910
+ );
69911
+ }
69912
+ } else if (isReadyForCommand(status, options.requiredCapabilities, options.requireKnownReadyState)) {
69913
+ return status;
69914
+ } else if (status.ready && findMissingCapabilities(status, options.requiredCapabilities).length > 0) {
69915
+ assertRequiredCapabilities(status, options.requiredCapabilities, options.commandName);
69916
+ }
69917
+ await sleep(Math.min(READY_POLL_MS, Math.max(1, deadline - Date.now() + 1)));
69918
+ }
69919
+ const missing = findMissingCapabilities(lastStatus, options.requiredCapabilities);
69920
+ const capabilitySuffix = missing.length > 0 ? ` missingCapabilities=${missing.join(",")}` : "";
69921
+ throw new Error(
69922
+ `${options.commandName} requires the daemon, but it did not become ready within ${options.timeoutMs}ms${capabilitySuffix}. Check ${options.logPath} or run \`okx-a2a daemon restart\`.`
69923
+ );
69924
+ }
69925
+ function isReadyForCommand(status, requiredCapabilities, requireKnownReadyState = false) {
69926
+ if (!status.running) {
69927
+ return false;
69928
+ }
69929
+ if (requireKnownReadyState && !status.readyStateKnown) {
69930
+ return false;
69931
+ }
69932
+ if (status.readyStateKnown && !status.ready) {
69933
+ return false;
69934
+ }
69935
+ return findMissingCapabilities(status, requiredCapabilities).length === 0;
69936
+ }
69937
+ function assertRequiredCapabilities(status, requiredCapabilities, commandName) {
69938
+ const missing = findMissingCapabilities(status, requiredCapabilities);
69939
+ if (missing.length === 0) {
69940
+ return;
69941
+ }
69942
+ throw new Error(
69943
+ `${commandName} requires a daemon with ${missing.join(",")} support. Run \`okx-a2a daemon restart\` first.`
69944
+ );
69945
+ }
69946
+ function findMissingCapabilities(status, requiredCapabilities) {
69947
+ if (!requiredCapabilities || requiredCapabilities.length === 0) {
69948
+ return [];
69949
+ }
69950
+ return requiredCapabilities.filter((capability) => !status.capabilities.includes(capability));
69951
+ }
69952
+ function readReadyTimeoutMs(env) {
69953
+ const raw = env[DAEMON_READY_TIMEOUT_ENV]?.trim();
69954
+ if (!raw) {
69955
+ return DEFAULT_READY_TIMEOUT_MS;
69956
+ }
69957
+ const parsed = Number(raw);
69958
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_READY_TIMEOUT_MS;
69959
+ }
69960
+ function sleep(ms) {
69961
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
69962
+ }
69799
69963
 
69800
69964
  // ../core/src/log.ts
69801
69965
  function formatLogTimestamp(date = /* @__PURE__ */ new Date()) {
@@ -85915,7 +86079,7 @@ async function callOpenClawGateway(opts) {
85915
86079
  errorWithTimestamp(
85916
86080
  `${LOG_PREFIX} rpc retry method=${opts.method} attempt=${attempt + 1} delayMs=${delayMs}: ${message}`
85917
86081
  );
85918
- await sleep(delayMs);
86082
+ await sleep2(delayMs);
85919
86083
  continue;
85920
86084
  }
85921
86085
  errorWithTimestamp(
@@ -85994,7 +86158,7 @@ function isGatewayStartingError(err2) {
85994
86158
  const e = err2;
85995
86159
  return String(e?.details?.reason ?? "") === "startup-sidecars" || String(e?.message ?? "").toLowerCase().includes("gateway starting");
85996
86160
  }
85997
- async function sleep(ms) {
86161
+ async function sleep2(ms) {
85998
86162
  await new Promise((resolve4) => setTimeout(resolve4, ms));
85999
86163
  }
86000
86164
  var MinimalGatewayClient = class {
@@ -86204,7 +86368,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
86204
86368
  client: {
86205
86369
  id: "gateway-client",
86206
86370
  displayName: "okx-a2a-node",
86207
- version: "0.0.16",
86371
+ version: "0.0.17-beta-db5dca184d-260624150845",
86208
86372
  platform: "node",
86209
86373
  mode: "backend",
86210
86374
  instanceId
@@ -86215,7 +86379,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
86215
86379
  commands: [],
86216
86380
  permissions: {},
86217
86381
  locale: Intl.DateTimeFormat().resolvedOptions().locale || "en-US",
86218
- userAgent: `okx-a2a-node/${"0.0.16"}`,
86382
+ userAgent: `okx-a2a-node/${"0.0.17-beta-db5dca184d-260624150845"}`,
86219
86383
  auth: {
86220
86384
  ...config.token ? { token: config.token } : {},
86221
86385
  ...config.password ? { password: config.password } : {}
@@ -90364,7 +90528,7 @@ function userWatchEventDeliveredSentryExtra(event) {
90364
90528
  var environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
90365
90529
  var SENTRY_CONFIG = {
90366
90530
  projectName: "okx/openclaw-okx-a2a-extension",
90367
- release: "0.0.16",
90531
+ release: "0.0.17-beta-db5dca184d-260624150845",
90368
90532
  environment
90369
90533
  };
90370
90534
 
@@ -90499,12 +90663,12 @@ async function runListenerWithLock(options, paths) {
90499
90663
  }));
90500
90664
  }
90501
90665
  });
90502
- service.setPluginVersion("0.0.16");
90666
+ service.setPluginVersion("0.0.17-beta-db5dca184d-260624150845");
90503
90667
  await service.init();
90504
90668
  const pluginVersionStatus = service.pluginVersionStatus;
90505
90669
  if (pluginVersionStatus.unavailable) {
90506
90670
  throw new Error(
90507
- `@okxweb3/a2a-node v${"0.0.16"} is below the required minimum v${pluginVersionStatus.minVersion}`
90671
+ `@okxweb3/a2a-node v${"0.0.17-beta-db5dca184d-260624150845"} is below the required minimum v${pluginVersionStatus.minVersion}`
90508
90672
  );
90509
90673
  }
90510
90674
  const systemConfig = service.getSystemConfig();
@@ -90522,7 +90686,7 @@ async function runListenerWithLock(options, paths) {
90522
90686
  onchainosAgentId: "*",
90523
90687
  reason: "system-config missing sentryDsn",
90524
90688
  pluginId: "@okxweb3/a2a-node",
90525
- pluginVersion: "0.0.16"
90689
+ pluginVersion: "0.0.17-beta-db5dca184d-260624150845"
90526
90690
  });
90527
90691
  }
90528
90692
  logWithTimestamp(
@@ -90783,6 +90947,8 @@ async function runListenerWithLock(options, paths) {
90783
90947
  sessionStore,
90784
90948
  homeDir: options.homeDir
90785
90949
  });
90950
+ await markDaemonReady(paths.daemonLockPath);
90951
+ logWithTimestamp(`[okx-agent-task] daemon ready lock=${paths.daemonLockPath}`);
90786
90952
  await new Promise((resolve4) => {
90787
90953
  const shutdown = (signal) => {
90788
90954
  if (stopping) {
@@ -91085,6 +91251,7 @@ function parsePluginYamlVersion(content3) {
91085
91251
  detectCurrentAiProvider,
91086
91252
  detectGatewayInvocation,
91087
91253
  detectRuntime,
91254
+ ensureDaemonReady,
91088
91255
  ensureDefaultAiProvider,
91089
91256
  extractAiSessionId,
91090
91257
  extractXmtpSentAtMs,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@okxweb3/a2a-node",
3
- "version": "0.0.16",
3
+ "version": "0.0.17-beta-db5dca184d-260624150845",
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": {