@okxweb3/a2a-node 0.1.6 → 0.1.7-beta-482acfaf84-260707171501

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 +213 -49
  2. package/dist/index.js +215 -47
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -593,7 +593,7 @@ function readTextArray(value) {
593
593
  });
594
594
  return normalizeGatewayRouteAliases(values);
595
595
  }
596
- var import_node_crypto, import_node_fs2, import_node_path3, DatabaseSync, SYSTEM_NOTIFICATION_SESSION_KEY, AI_PROVIDER_COMMAND_SETTING_PREFIX, SessionStore;
596
+ var import_node_crypto, import_node_fs2, import_node_path3, DatabaseSync, SYSTEM_NOTIFICATION_SESSION_KEY, NOTIFICATION_ATTENTION_KINDS, PROMPT_ATTENTION_KINDS, AI_PROVIDER_COMMAND_SETTING_PREFIX, SessionStore;
597
597
  var init_session_store = __esm({
598
598
  "src/session-store.ts"() {
599
599
  "use strict";
@@ -603,6 +603,8 @@ var init_session_store = __esm({
603
603
  init_paths();
604
604
  ({ DatabaseSync } = loadSqlite());
605
605
  SYSTEM_NOTIFICATION_SESSION_KEY = "system-notification";
606
+ NOTIFICATION_ATTENTION_KINDS = ["notification", "system_notification"];
607
+ PROMPT_ATTENTION_KINDS = ["decision_request", "system_prompt"];
606
608
  AI_PROVIDER_COMMAND_SETTING_PREFIX = "ai_provider_command_";
607
609
  SessionStore = class {
608
610
  homeDir;
@@ -664,34 +666,11 @@ var init_session_store = __esm({
664
666
  CREATE INDEX IF NOT EXISTS idx_session_metadata_job_agents
665
667
  ON session_metadata(job_id, my_agent_id, to_agent_id)
666
668
  `);
667
- this.db.exec(`
668
- CREATE TABLE IF NOT EXISTS user_attention (
669
- id TEXT PRIMARY KEY,
670
- kind TEXT NOT NULL CHECK (kind IN ('notification', 'decision_request')),
671
- provider TEXT CHECK (provider IN ('codex', 'claude', 'hermes', 'openclaw') OR provider IS NULL),
672
- status TEXT NOT NULL CHECK (status IN ('pending', 'handled')),
673
- job_id TEXT,
674
- session_key TEXT,
675
- llm_content TEXT,
676
- choices_json TEXT,
677
- user_content TEXT NOT NULL,
678
- idempotency_key TEXT UNIQUE,
679
- expire_time INTEGER,
680
- created_at TEXT NOT NULL,
681
- handled_at TEXT,
682
- deleted_at TEXT,
683
- seen INTEGER NOT NULL DEFAULT 0 CHECK (seen IN (0, 1))
684
- )
685
- `);
669
+ this.ensureUserAttentionSchema();
686
670
  this.db.exec(`
687
671
  CREATE INDEX IF NOT EXISTS idx_user_attention_status_created
688
672
  ON user_attention(status, created_at)
689
673
  `);
690
- this.ensureColumn("user_attention", "choices_json", "TEXT");
691
- this.ensureColumn("user_attention", "deleted_at", "TEXT");
692
- this.ensureColumn("user_attention", "seen", "INTEGER NOT NULL DEFAULT 0");
693
- this.ensureColumn("user_attention", "provider", "TEXT CHECK (provider IN ('codex', 'claude', 'hermes', 'openclaw') OR provider IS NULL)");
694
- this.ensureColumn("user_attention", "expire_time", "INTEGER");
695
674
  this.db.exec(`
696
675
  CREATE INDEX IF NOT EXISTS idx_user_attention_provider_status_created
697
676
  ON user_attention(provider, status, created_at)
@@ -757,6 +736,58 @@ var init_session_store = __esm({
757
736
  CREATE INDEX IF NOT EXISTS idx_pending_gateway_deliveries_provider_created
758
737
  ON pending_gateway_deliveries(provider, created_at)
759
738
  `);
739
+ }
740
+ ensureUserAttentionSchema() {
741
+ this.db.exec(`
742
+ CREATE TABLE IF NOT EXISTS user_attention (
743
+ ${this.userAttentionTableColumnsSql()}
744
+ )
745
+ `);
746
+ this.ensureColumn("user_attention", "choices_json", "TEXT");
747
+ this.ensureColumn("user_attention", "deleted_at", "TEXT");
748
+ this.ensureColumn("user_attention", "seen", "INTEGER NOT NULL DEFAULT 0");
749
+ this.ensureColumn("user_attention", "provider", "TEXT CHECK (provider IN ('codex', 'claude', 'hermes', 'openclaw') OR provider IS NULL)");
750
+ this.ensureColumn("user_attention", "expire_time", "INTEGER");
751
+ const row = this.db.prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='user_attention'").get();
752
+ if (row?.sql?.includes("system_notification") && row.sql.includes("system_prompt")) {
753
+ return;
754
+ }
755
+ this.db.exec("ALTER TABLE user_attention RENAME TO user_attention_old");
756
+ this.db.exec(`
757
+ CREATE TABLE user_attention (
758
+ ${this.userAttentionTableColumnsSql()}
759
+ )
760
+ `);
761
+ this.db.exec(`
762
+ INSERT INTO user_attention (
763
+ id, kind, provider, status, job_id, session_key, llm_content, choices_json,
764
+ user_content, idempotency_key, expire_time, created_at, handled_at, deleted_at, seen
765
+ )
766
+ SELECT
767
+ id, kind, provider, status, job_id, session_key, llm_content, choices_json,
768
+ user_content, idempotency_key, expire_time, created_at, handled_at, deleted_at, seen
769
+ FROM user_attention_old
770
+ `);
771
+ this.db.exec("DROP TABLE user_attention_old");
772
+ }
773
+ userAttentionTableColumnsSql() {
774
+ return `
775
+ id TEXT PRIMARY KEY,
776
+ kind TEXT NOT NULL CHECK (kind IN ('notification', 'decision_request', 'system_notification', 'system_prompt')),
777
+ provider TEXT CHECK (provider IN ('codex', 'claude', 'hermes', 'openclaw') OR provider IS NULL),
778
+ status TEXT NOT NULL CHECK (status IN ('pending', 'handled')),
779
+ job_id TEXT,
780
+ session_key TEXT,
781
+ llm_content TEXT,
782
+ choices_json TEXT,
783
+ user_content TEXT NOT NULL,
784
+ idempotency_key TEXT UNIQUE,
785
+ expire_time INTEGER,
786
+ created_at TEXT NOT NULL,
787
+ handled_at TEXT,
788
+ deleted_at TEXT,
789
+ seen INTEGER NOT NULL DEFAULT 0 CHECK (seen IN (0, 1))
790
+ `;
760
791
  }
761
792
  ensurePendingGatewayDeliveriesSchema() {
762
793
  const expectedKindCheck = this.pendingGatewayDeliveryKindCheck();
@@ -1101,11 +1132,11 @@ var init_session_store = __esm({
1101
1132
  return rows.map(mapJobProviderBindingRow);
1102
1133
  }
1103
1134
  createUserAttention(input) {
1104
- if (input.kind !== "notification" && input.kind !== "decision_request") {
1135
+ if (!NOTIFICATION_ATTENTION_KINDS.includes(input.kind) && !PROMPT_ATTENTION_KINDS.includes(input.kind)) {
1105
1136
  throw new Error(`Unsupported user_attention kind: ${String(input.kind)}`);
1106
1137
  }
1107
1138
  assertNonEmpty(input.userContent, "userContent");
1108
- if (input.kind === "decision_request") {
1139
+ if (PROMPT_ATTENTION_KINDS.includes(input.kind)) {
1109
1140
  assertNonEmpty(input.llmContent ?? "", "llmContent");
1110
1141
  }
1111
1142
  const provider = normalizeOptionalProvider(input.provider);
@@ -1120,8 +1151,8 @@ var init_session_store = __esm({
1120
1151
  }
1121
1152
  const id = this.idFactory();
1122
1153
  const createdAt = this.timestamp();
1123
- if (input.kind === "decision_request" && input.jobId) {
1124
- this.softDeleteDecisionRequestsForJob(input.jobId, createdAt);
1154
+ if (PROMPT_ATTENTION_KINDS.includes(input.kind) && input.jobId) {
1155
+ this.softDeletePromptAttentionForJob(input.jobId, createdAt);
1125
1156
  }
1126
1157
  const statement = input.idempotencyKey ? this.db.prepare(`
1127
1158
  INSERT OR IGNORE INTO user_attention (
@@ -1221,7 +1252,7 @@ var init_session_store = __esm({
1221
1252
  const watchFilter = buildWatchAttentionFilter(options);
1222
1253
  const decision = this.db.prepare(`
1223
1254
  SELECT * FROM user_attention
1224
- WHERE kind = 'decision_request'
1255
+ WHERE kind IN ('decision_request', 'system_prompt')
1225
1256
  AND status = 'pending'
1226
1257
  AND seen = 0
1227
1258
  AND deleted_at IS NULL
@@ -1232,7 +1263,7 @@ var init_session_store = __esm({
1232
1263
  `).get(this.currentUnixSeconds(), ...watchFilter.values);
1233
1264
  const notifications = this.db.prepare(`
1234
1265
  SELECT * FROM user_attention
1235
- WHERE kind = 'notification'
1266
+ WHERE kind IN ('notification', 'system_notification')
1236
1267
  AND status = 'pending'
1237
1268
  AND seen = 0
1238
1269
  AND deleted_at IS NULL
@@ -1463,7 +1494,7 @@ var init_session_store = __esm({
1463
1494
  const providerFilter = conditions.length > 0 ? `AND ${conditions.join(" AND ")}` : "";
1464
1495
  const rows = this.db.prepare(`
1465
1496
  SELECT * FROM user_attention
1466
- WHERE kind = 'decision_request'
1497
+ WHERE kind IN ('decision_request', 'system_prompt')
1467
1498
  AND status = 'pending'
1468
1499
  AND seen = 1
1469
1500
  AND deleted_at IS NULL
@@ -1641,11 +1672,14 @@ var init_session_store = __esm({
1641
1672
  const row = this.db.prepare("SELECT * FROM user_attention WHERE id = ?").get(id);
1642
1673
  return row ? mapAttentionRow(row) : null;
1643
1674
  }
1644
- softDeleteDecisionRequestsForJob(jobId, deletedAt) {
1675
+ // The task state machine allows at most one live action per job, so a new
1676
+ // prompt-kind item (decision_request / system_prompt) supersedes every
1677
+ // pending prompt for that job regardless of which side produced it.
1678
+ softDeletePromptAttentionForJob(jobId, deletedAt) {
1645
1679
  this.db.prepare(`
1646
1680
  UPDATE user_attention
1647
1681
  SET deleted_at = ?, idempotency_key = NULL
1648
- WHERE kind = 'decision_request'
1682
+ WHERE kind IN ('decision_request', 'system_prompt')
1649
1683
  AND job_id = ?
1650
1684
  AND deleted_at IS NULL
1651
1685
  `).run(deletedAt, jobId);
@@ -8300,7 +8334,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
8300
8334
  client: {
8301
8335
  id: "gateway-client",
8302
8336
  displayName: "okx-a2a-node",
8303
- version: "0.1.6",
8337
+ version: "0.1.7-beta-482acfaf84-260707171501",
8304
8338
  platform: "node",
8305
8339
  mode: "backend",
8306
8340
  instanceId
@@ -8311,7 +8345,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
8311
8345
  commands: [],
8312
8346
  permissions: {},
8313
8347
  locale: Intl.DateTimeFormat().resolvedOptions().locale || "en-US",
8314
- userAgent: `okx-a2a-node/${"0.1.6"}`,
8348
+ userAgent: `okx-a2a-node/${"0.1.7-beta-482acfaf84-260707171501"}`,
8315
8349
  auth: {
8316
8350
  ...config.token ? { token: config.token } : {},
8317
8351
  ...config.password ? { password: config.password } : {}
@@ -24920,7 +24954,7 @@ var init_outbound_behavior = __esm({
24920
24954
  }
24921
24955
  async dispatchUser(input) {
24922
24956
  const item = this.store.createUserAttention({
24923
- kind: "notification",
24957
+ kind: input.kind ?? "notification",
24924
24958
  provider: this.provider,
24925
24959
  userContent: input.userContent,
24926
24960
  jobId: input.jobId ?? null,
@@ -24933,7 +24967,7 @@ var init_outbound_behavior = __esm({
24933
24967
  }
24934
24968
  async promptUser(input) {
24935
24969
  const item = this.store.createUserAttention({
24936
- kind: "decision_request",
24970
+ kind: input.kind ?? "decision_request",
24937
24971
  provider: this.provider,
24938
24972
  userContent: input.userContent,
24939
24973
  llmContent: input.llmContent,
@@ -25568,7 +25602,7 @@ var init_sentry_config = __esm({
25568
25602
  environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
25569
25603
  SENTRY_CONFIG = {
25570
25604
  projectName: "okx/openclaw-okx-a2a-extension",
25571
- release: "0.1.6",
25605
+ release: "0.1.7-beta-482acfaf84-260707171501",
25572
25606
  environment
25573
25607
  };
25574
25608
  }
@@ -88078,6 +88112,45 @@ async function notifySystemMessageToUser(input) {
88078
88112
  ownedStore?.close();
88079
88113
  }
88080
88114
  }
88115
+ async function notifyDirectSystemMessageToUser(input) {
88116
+ const ownedStore = input.store ? null : new SessionStore();
88117
+ const store = input.store ?? ownedStore;
88118
+ const idempotencyKey = input.idempotencyKey ?? buildDirectSystemMessageIdempotencyKey(input);
88119
+ const llmContent = input.llmContent?.trim() || null;
88120
+ try {
88121
+ const provider = resolveOutboundProvider(store, {
88122
+ jobId: input.jobId,
88123
+ override: input.provider
88124
+ });
88125
+ const behavior = createOutboundBehavior(provider, { store });
88126
+ const item = llmContent ? await behavior.promptUser({
88127
+ kind: "system_prompt",
88128
+ userContent: input.userContent,
88129
+ llmContent,
88130
+ jobId: input.jobId ?? null,
88131
+ idempotencyKey
88132
+ }) : await behavior.dispatchUser({
88133
+ kind: "system_notification",
88134
+ userContent: input.userContent,
88135
+ jobId: input.jobId ?? null,
88136
+ idempotencyKey
88137
+ });
88138
+ logWithTimestamp(
88139
+ `[notifyDirectSystemMessageToUser] provider=${provider} kind=${llmContent ? "system_prompt" : "system_notification"} job=${input.jobId ?? "(none)"} item=${item?.id ?? "(gateway)"}`
88140
+ );
88141
+ return item;
88142
+ } finally {
88143
+ ownedStore?.close();
88144
+ }
88145
+ }
88146
+ function buildDirectSystemMessageIdempotencyKey(input) {
88147
+ const identity3 = input.messageId || stableHash([
88148
+ input.jobId ?? "",
88149
+ input.userContent,
88150
+ input.llmContent ?? ""
88151
+ ].join("\n"));
88152
+ return `system-direct:${identity3}`;
88153
+ }
88081
88154
  function buildAgentMessageIdempotencyKey(input) {
88082
88155
  const identity3 = input.messageId || stableHash([
88083
88156
  input.direction,
@@ -92603,7 +92676,8 @@ function extractSystemNotification(payload) {
92603
92676
  }
92604
92677
  const message = isPlainObject3(payload.message) ? payload.message : null;
92605
92678
  const isDirectCommunication = message?.isDirectCommunication === true;
92606
- if (message?.source !== "system" && !isDirectCommunication) {
92679
+ const isDirectToUser = message?.isDirectToUser === true;
92680
+ if (message?.source !== "system" && !isDirectCommunication && !isDirectToUser) {
92607
92681
  return null;
92608
92682
  }
92609
92683
  return {
@@ -92612,7 +92686,10 @@ function extractSystemNotification(payload) {
92612
92686
  providerAgentId: readString3(message.providerAgentId),
92613
92687
  clientAgentId: readString3(message.clientAgentId),
92614
92688
  event: readString3(message.event),
92615
- isDirectCommunication
92689
+ isDirectCommunication,
92690
+ isDirectToUser,
92691
+ userContent: readString3(message.userContent),
92692
+ llmContent: readString3(message.llmContent)
92616
92693
  };
92617
92694
  }
92618
92695
  function resolveDirectCommunicationSessionTarget(notification) {
@@ -93219,6 +93296,85 @@ ${failureMessage}`,
93219
93296
  }
93220
93297
  return true;
93221
93298
  }
93299
+ function processDirectToUserSystemNotification(params) {
93300
+ const { deps, notification, messageId, timing } = params;
93301
+ const notificationAgentId = notification.agentId ?? void 0;
93302
+ const attentionKind = notification.llmContent ? "system_prompt" : "system_notification";
93303
+ if (!notification.userContent) {
93304
+ logger.info(LogEvent.DM_FALLBACK_TO_BACKUP, {
93305
+ ...agentExtras({ walletAddress: deps.myXmtpAddress, onchainosAgentId: notificationAgentId }),
93306
+ taskId: notification.jobId ?? "",
93307
+ messageId,
93308
+ systemEvent: notification.event ?? "",
93309
+ stage: "inbound/payload_parse",
93310
+ reason: "direct_to_user_missing_user_content"
93311
+ });
93312
+ logWithTimestamp(
93313
+ `[okx-agent-task:${deps.myXmtpAddress}] direct-to-user system DM missing userContent, falling back to AI session routing message=${shortenLogValue(messageId)}`
93314
+ );
93315
+ return false;
93316
+ }
93317
+ const userContent = notification.userContent;
93318
+ const providerBindStartedAt = Date.now();
93319
+ const providerGate = bindMessageJobProviderToCurrentDefault(deps, notification.jobId, "system-direct-user");
93320
+ timing.mark("providerBind", providerBindStartedAt);
93321
+ if (!providerGate.allowed) {
93322
+ return true;
93323
+ }
93324
+ logger.info(LogEvent.SYSTEM_NOTIFICATION_RECEIVED, {
93325
+ ...agentExtras({ walletAddress: deps.myXmtpAddress, onchainosAgentId: notificationAgentId }),
93326
+ taskId: notification.jobId ?? "",
93327
+ agentId: notification.agentId ?? "",
93328
+ providerAgentId: notification.providerAgentId ?? "",
93329
+ clientAgentId: notification.clientAgentId ?? "",
93330
+ messageId,
93331
+ systemEvent: notification.event ?? "",
93332
+ stage: "inbound/system_notification_received",
93333
+ isDirectToUser: "true",
93334
+ attentionKind,
93335
+ providerBinding: providerGate.provider ?? "",
93336
+ providerBindingCreated: String(providerGate.created)
93337
+ });
93338
+ const dispatchStartedAt = Date.now();
93339
+ void notifyDirectSystemMessageToUser({
93340
+ userContent,
93341
+ llmContent: notification.llmContent ?? null,
93342
+ jobId: notification.jobId ?? null,
93343
+ messageId,
93344
+ store: deps.sessionStore
93345
+ }).then(() => {
93346
+ timing.mark("userDispatch", dispatchStartedAt);
93347
+ logger.info(LogEvent.SYSTEM_NOTIFICATION_ROUTED, timing.extras({
93348
+ ...agentExtras({ walletAddress: deps.myXmtpAddress, onchainosAgentId: notificationAgentId }),
93349
+ taskId: notification.jobId ?? "",
93350
+ agentId: notification.agentId ?? "",
93351
+ messageId,
93352
+ route: "system/direct-user",
93353
+ systemEvent: notification.event ?? "",
93354
+ stage: "inbound/system_direct_user_delivered",
93355
+ isDirectToUser: "true",
93356
+ attentionKind
93357
+ }));
93358
+ }).catch((err2) => {
93359
+ logger.error(LogEvent.USER_DISPATCH_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), {
93360
+ ...agentExtras({ walletAddress: deps.myXmtpAddress, onchainosAgentId: notificationAgentId }),
93361
+ taskId: notification.jobId ?? "",
93362
+ messageId,
93363
+ systemEvent: notification.event ?? "",
93364
+ stage: "inbound/system_direct_user_delivery",
93365
+ isDirectToUser: "true",
93366
+ attentionKind
93367
+ });
93368
+ logWithTimestamp(
93369
+ `[okx-agent-task:${deps.myXmtpAddress}] direct-to-user delivery failed message=${shortenLogValue(messageId)}:`,
93370
+ err2
93371
+ );
93372
+ });
93373
+ logWithTimestamp(
93374
+ `[okx-agent-task:${deps.myXmtpAddress}] direct-to-user delivery queued kind=${attentionKind} job=${shortenLogValue(notification.jobId ?? "(none)")} message=${shortenLogValue(messageId)}`
93375
+ );
93376
+ return true;
93377
+ }
93222
93378
  async function processFileMessage(ctx, deps, options = {}) {
93223
93379
  const messageId = ctx.message.id ?? "";
93224
93380
  const timing = createInboundTimingTracker(extractXmtpSentAtMs2(ctx.message));
@@ -93271,6 +93427,14 @@ async function processFileMessage(ctx, deps, options = {}) {
93271
93427
  );
93272
93428
  return true;
93273
93429
  }
93430
+ if (systemNotification.isDirectToUser && processDirectToUserSystemNotification({
93431
+ deps,
93432
+ notification: systemNotification,
93433
+ messageId: systemMessageId,
93434
+ timing
93435
+ })) {
93436
+ return true;
93437
+ }
93274
93438
  const directTarget = resolveDirectCommunicationSessionTarget(systemNotification);
93275
93439
  if (systemNotification.isDirectCommunication && !directTarget) {
93276
93440
  logger.error(
@@ -94086,12 +94250,12 @@ async function runListenerWithLock(options, paths) {
94086
94250
  }));
94087
94251
  }
94088
94252
  });
94089
- service.setPluginVersion("0.1.6");
94253
+ service.setPluginVersion("0.1.7-beta-482acfaf84-260707171501");
94090
94254
  await service.init();
94091
94255
  const pluginVersionStatus = service.pluginVersionStatus;
94092
94256
  if (pluginVersionStatus.unavailable) {
94093
94257
  throw new Error(
94094
- `@okxweb3/a2a-node v${"0.1.6"} is below the required minimum v${pluginVersionStatus.minVersion}`
94258
+ `@okxweb3/a2a-node v${"0.1.7-beta-482acfaf84-260707171501"} is below the required minimum v${pluginVersionStatus.minVersion}`
94095
94259
  );
94096
94260
  }
94097
94261
  const systemConfig = service.getSystemConfig();
@@ -94109,7 +94273,7 @@ async function runListenerWithLock(options, paths) {
94109
94273
  onchainosAgentId: "*",
94110
94274
  reason: "system-config missing sentryDsn",
94111
94275
  pluginId: "@okxweb3/a2a-node",
94112
- pluginVersion: "0.1.6"
94276
+ pluginVersion: "0.1.7-beta-482acfaf84-260707171501"
94113
94277
  });
94114
94278
  }
94115
94279
  logWithTimestamp(
@@ -98130,7 +98294,7 @@ async function getCurrentNodeCliVersion() {
98130
98294
  return await getGlobalNpmPackageVersion(UPDATE_PACKAGES.node) ?? getBundledNodeCliVersion();
98131
98295
  }
98132
98296
  function getBundledNodeCliVersion() {
98133
- return true ? "0.1.6" : null;
98297
+ return true ? "0.1.7-beta-482acfaf84-260707171501" : null;
98134
98298
  }
98135
98299
  function readConfiguredAiProvider() {
98136
98300
  const explicit = process.env.OKX_A2A_AI_PROVIDER || process.env.OKX_AGENT_TASK_AI_CLI;
@@ -98340,7 +98504,7 @@ async function updateHermes(release, options) {
98340
98504
  }
98341
98505
  }
98342
98506
  async function installGatewayPluginForDoctor(target) {
98343
- const release = isPrereleaseVersion("0.1.6") ? "beta" : "latest";
98507
+ const release = isPrereleaseVersion("0.1.7-beta-482acfaf84-260707171501") ? "beta" : "latest";
98344
98508
  const insideTargetGateway = detectGatewayInvocation() === target;
98345
98509
  const options = {
98346
98510
  restart: !insideTargetGateway,
@@ -99225,7 +99389,7 @@ async function runDoctor(options = {}) {
99225
99389
  platform: options.platform ?? process.platform,
99226
99390
  env: options.env ?? process.env,
99227
99391
  target: options.target ?? resolveDoctorTarget(options.env ?? process.env),
99228
- cliVersion: options.cliVersion ?? (true ? "0.1.6" : "0.0.0"),
99392
+ cliVersion: options.cliVersion ?? (true ? "0.1.7-beta-482acfaf84-260707171501" : "0.0.0"),
99229
99393
  fixMode: options.fix === true,
99230
99394
  nonInteractive: options.nonInteractive === true,
99231
99395
  packageChanged: false
@@ -100318,7 +100482,7 @@ init_sentry_logger();
100318
100482
  init_sentry_config();
100319
100483
  var CURRENT_GATEWAY_SESSION_KEYS_ENV4 = "OKX_A2A_CURRENT_GATEWAY_SESSION_KEYS";
100320
100484
  function printUsage2() {
100321
- console.log(`okx-a2a ${"0.1.6"}
100485
+ console.log(`okx-a2a ${"0.1.7-beta-482acfaf84-260707171501"}
100322
100486
 
100323
100487
  Usage:
100324
100488
  okx-a2a <command> [options]
@@ -100356,7 +100520,7 @@ Run \`okx-a2a <command> -h\` for command-specific help.
100356
100520
  `);
100357
100521
  }
100358
100522
  function printVersion() {
100359
- console.log("0.1.6");
100523
+ console.log("0.1.7-beta-482acfaf84-260707171501");
100360
100524
  }
100361
100525
  function printDaemonUsage() {
100362
100526
  console.log(`Usage: okx-a2a daemon <start|restart|stop|status|autostart> [options]
package/dist/index.js CHANGED
@@ -593,7 +593,7 @@ function readTextArray(value) {
593
593
  });
594
594
  return normalizeGatewayRouteAliases(values);
595
595
  }
596
- var import_node_crypto, import_node_fs2, import_node_path3, DatabaseSync, SYSTEM_NOTIFICATION_SESSION_KEY, AI_PROVIDER_COMMAND_SETTING_PREFIX, SessionStore;
596
+ var import_node_crypto, import_node_fs2, import_node_path3, DatabaseSync, SYSTEM_NOTIFICATION_SESSION_KEY, NOTIFICATION_ATTENTION_KINDS, PROMPT_ATTENTION_KINDS, AI_PROVIDER_COMMAND_SETTING_PREFIX, SessionStore;
597
597
  var init_session_store = __esm({
598
598
  "src/session-store.ts"() {
599
599
  "use strict";
@@ -603,6 +603,8 @@ var init_session_store = __esm({
603
603
  init_paths();
604
604
  ({ DatabaseSync } = loadSqlite());
605
605
  SYSTEM_NOTIFICATION_SESSION_KEY = "system-notification";
606
+ NOTIFICATION_ATTENTION_KINDS = ["notification", "system_notification"];
607
+ PROMPT_ATTENTION_KINDS = ["decision_request", "system_prompt"];
606
608
  AI_PROVIDER_COMMAND_SETTING_PREFIX = "ai_provider_command_";
607
609
  SessionStore = class {
608
610
  homeDir;
@@ -664,34 +666,11 @@ var init_session_store = __esm({
664
666
  CREATE INDEX IF NOT EXISTS idx_session_metadata_job_agents
665
667
  ON session_metadata(job_id, my_agent_id, to_agent_id)
666
668
  `);
667
- this.db.exec(`
668
- CREATE TABLE IF NOT EXISTS user_attention (
669
- id TEXT PRIMARY KEY,
670
- kind TEXT NOT NULL CHECK (kind IN ('notification', 'decision_request')),
671
- provider TEXT CHECK (provider IN ('codex', 'claude', 'hermes', 'openclaw') OR provider IS NULL),
672
- status TEXT NOT NULL CHECK (status IN ('pending', 'handled')),
673
- job_id TEXT,
674
- session_key TEXT,
675
- llm_content TEXT,
676
- choices_json TEXT,
677
- user_content TEXT NOT NULL,
678
- idempotency_key TEXT UNIQUE,
679
- expire_time INTEGER,
680
- created_at TEXT NOT NULL,
681
- handled_at TEXT,
682
- deleted_at TEXT,
683
- seen INTEGER NOT NULL DEFAULT 0 CHECK (seen IN (0, 1))
684
- )
685
- `);
669
+ this.ensureUserAttentionSchema();
686
670
  this.db.exec(`
687
671
  CREATE INDEX IF NOT EXISTS idx_user_attention_status_created
688
672
  ON user_attention(status, created_at)
689
673
  `);
690
- this.ensureColumn("user_attention", "choices_json", "TEXT");
691
- this.ensureColumn("user_attention", "deleted_at", "TEXT");
692
- this.ensureColumn("user_attention", "seen", "INTEGER NOT NULL DEFAULT 0");
693
- this.ensureColumn("user_attention", "provider", "TEXT CHECK (provider IN ('codex', 'claude', 'hermes', 'openclaw') OR provider IS NULL)");
694
- this.ensureColumn("user_attention", "expire_time", "INTEGER");
695
674
  this.db.exec(`
696
675
  CREATE INDEX IF NOT EXISTS idx_user_attention_provider_status_created
697
676
  ON user_attention(provider, status, created_at)
@@ -757,6 +736,58 @@ var init_session_store = __esm({
757
736
  CREATE INDEX IF NOT EXISTS idx_pending_gateway_deliveries_provider_created
758
737
  ON pending_gateway_deliveries(provider, created_at)
759
738
  `);
739
+ }
740
+ ensureUserAttentionSchema() {
741
+ this.db.exec(`
742
+ CREATE TABLE IF NOT EXISTS user_attention (
743
+ ${this.userAttentionTableColumnsSql()}
744
+ )
745
+ `);
746
+ this.ensureColumn("user_attention", "choices_json", "TEXT");
747
+ this.ensureColumn("user_attention", "deleted_at", "TEXT");
748
+ this.ensureColumn("user_attention", "seen", "INTEGER NOT NULL DEFAULT 0");
749
+ this.ensureColumn("user_attention", "provider", "TEXT CHECK (provider IN ('codex', 'claude', 'hermes', 'openclaw') OR provider IS NULL)");
750
+ this.ensureColumn("user_attention", "expire_time", "INTEGER");
751
+ const row = this.db.prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='user_attention'").get();
752
+ if (row?.sql?.includes("system_notification") && row.sql.includes("system_prompt")) {
753
+ return;
754
+ }
755
+ this.db.exec("ALTER TABLE user_attention RENAME TO user_attention_old");
756
+ this.db.exec(`
757
+ CREATE TABLE user_attention (
758
+ ${this.userAttentionTableColumnsSql()}
759
+ )
760
+ `);
761
+ this.db.exec(`
762
+ INSERT INTO user_attention (
763
+ id, kind, provider, status, job_id, session_key, llm_content, choices_json,
764
+ user_content, idempotency_key, expire_time, created_at, handled_at, deleted_at, seen
765
+ )
766
+ SELECT
767
+ id, kind, provider, status, job_id, session_key, llm_content, choices_json,
768
+ user_content, idempotency_key, expire_time, created_at, handled_at, deleted_at, seen
769
+ FROM user_attention_old
770
+ `);
771
+ this.db.exec("DROP TABLE user_attention_old");
772
+ }
773
+ userAttentionTableColumnsSql() {
774
+ return `
775
+ id TEXT PRIMARY KEY,
776
+ kind TEXT NOT NULL CHECK (kind IN ('notification', 'decision_request', 'system_notification', 'system_prompt')),
777
+ provider TEXT CHECK (provider IN ('codex', 'claude', 'hermes', 'openclaw') OR provider IS NULL),
778
+ status TEXT NOT NULL CHECK (status IN ('pending', 'handled')),
779
+ job_id TEXT,
780
+ session_key TEXT,
781
+ llm_content TEXT,
782
+ choices_json TEXT,
783
+ user_content TEXT NOT NULL,
784
+ idempotency_key TEXT UNIQUE,
785
+ expire_time INTEGER,
786
+ created_at TEXT NOT NULL,
787
+ handled_at TEXT,
788
+ deleted_at TEXT,
789
+ seen INTEGER NOT NULL DEFAULT 0 CHECK (seen IN (0, 1))
790
+ `;
760
791
  }
761
792
  ensurePendingGatewayDeliveriesSchema() {
762
793
  const expectedKindCheck = this.pendingGatewayDeliveryKindCheck();
@@ -1101,11 +1132,11 @@ var init_session_store = __esm({
1101
1132
  return rows.map(mapJobProviderBindingRow);
1102
1133
  }
1103
1134
  createUserAttention(input) {
1104
- if (input.kind !== "notification" && input.kind !== "decision_request") {
1135
+ if (!NOTIFICATION_ATTENTION_KINDS.includes(input.kind) && !PROMPT_ATTENTION_KINDS.includes(input.kind)) {
1105
1136
  throw new Error(`Unsupported user_attention kind: ${String(input.kind)}`);
1106
1137
  }
1107
1138
  assertNonEmpty(input.userContent, "userContent");
1108
- if (input.kind === "decision_request") {
1139
+ if (PROMPT_ATTENTION_KINDS.includes(input.kind)) {
1109
1140
  assertNonEmpty(input.llmContent ?? "", "llmContent");
1110
1141
  }
1111
1142
  const provider = normalizeOptionalProvider(input.provider);
@@ -1120,8 +1151,8 @@ var init_session_store = __esm({
1120
1151
  }
1121
1152
  const id = this.idFactory();
1122
1153
  const createdAt = this.timestamp();
1123
- if (input.kind === "decision_request" && input.jobId) {
1124
- this.softDeleteDecisionRequestsForJob(input.jobId, createdAt);
1154
+ if (PROMPT_ATTENTION_KINDS.includes(input.kind) && input.jobId) {
1155
+ this.softDeletePromptAttentionForJob(input.jobId, createdAt);
1125
1156
  }
1126
1157
  const statement = input.idempotencyKey ? this.db.prepare(`
1127
1158
  INSERT OR IGNORE INTO user_attention (
@@ -1221,7 +1252,7 @@ var init_session_store = __esm({
1221
1252
  const watchFilter = buildWatchAttentionFilter(options);
1222
1253
  const decision = this.db.prepare(`
1223
1254
  SELECT * FROM user_attention
1224
- WHERE kind = 'decision_request'
1255
+ WHERE kind IN ('decision_request', 'system_prompt')
1225
1256
  AND status = 'pending'
1226
1257
  AND seen = 0
1227
1258
  AND deleted_at IS NULL
@@ -1232,7 +1263,7 @@ var init_session_store = __esm({
1232
1263
  `).get(this.currentUnixSeconds(), ...watchFilter.values);
1233
1264
  const notifications = this.db.prepare(`
1234
1265
  SELECT * FROM user_attention
1235
- WHERE kind = 'notification'
1266
+ WHERE kind IN ('notification', 'system_notification')
1236
1267
  AND status = 'pending'
1237
1268
  AND seen = 0
1238
1269
  AND deleted_at IS NULL
@@ -1463,7 +1494,7 @@ var init_session_store = __esm({
1463
1494
  const providerFilter = conditions.length > 0 ? `AND ${conditions.join(" AND ")}` : "";
1464
1495
  const rows = this.db.prepare(`
1465
1496
  SELECT * FROM user_attention
1466
- WHERE kind = 'decision_request'
1497
+ WHERE kind IN ('decision_request', 'system_prompt')
1467
1498
  AND status = 'pending'
1468
1499
  AND seen = 1
1469
1500
  AND deleted_at IS NULL
@@ -1641,11 +1672,14 @@ var init_session_store = __esm({
1641
1672
  const row = this.db.prepare("SELECT * FROM user_attention WHERE id = ?").get(id);
1642
1673
  return row ? mapAttentionRow(row) : null;
1643
1674
  }
1644
- softDeleteDecisionRequestsForJob(jobId, deletedAt) {
1675
+ // The task state machine allows at most one live action per job, so a new
1676
+ // prompt-kind item (decision_request / system_prompt) supersedes every
1677
+ // pending prompt for that job regardless of which side produced it.
1678
+ softDeletePromptAttentionForJob(jobId, deletedAt) {
1645
1679
  this.db.prepare(`
1646
1680
  UPDATE user_attention
1647
1681
  SET deleted_at = ?, idempotency_key = NULL
1648
- WHERE kind = 'decision_request'
1682
+ WHERE kind IN ('decision_request', 'system_prompt')
1649
1683
  AND job_id = ?
1650
1684
  AND deleted_at IS NULL
1651
1685
  `).run(deletedAt, jobId);
@@ -72344,7 +72378,7 @@ async function getCurrentNodeCliVersion() {
72344
72378
  return await getGlobalNpmPackageVersion(UPDATE_PACKAGES.node) ?? getBundledNodeCliVersion();
72345
72379
  }
72346
72380
  function getBundledNodeCliVersion() {
72347
- return true ? "0.1.6" : null;
72381
+ return true ? "0.1.7-beta-482acfaf84-260707171501" : null;
72348
72382
  }
72349
72383
  function readConfiguredAiProvider() {
72350
72384
  const explicit = process.env.OKX_A2A_AI_PROVIDER || process.env.OKX_AGENT_TASK_AI_CLI;
@@ -72554,7 +72588,7 @@ async function updateHermes(release, options) {
72554
72588
  }
72555
72589
  }
72556
72590
  async function installGatewayPluginForDoctor(target) {
72557
- const release = isPrereleaseVersion("0.1.6") ? "beta" : "latest";
72591
+ const release = isPrereleaseVersion("0.1.7-beta-482acfaf84-260707171501") ? "beta" : "latest";
72558
72592
  const insideTargetGateway = detectGatewayInvocation() === target;
72559
72593
  const options = {
72560
72594
  restart: !insideTargetGateway,
@@ -73422,12 +73456,14 @@ __export(index_exports, {
73422
73456
  normalizeAiProvider: () => normalizeAiProvider,
73423
73457
  normalizeHermesOkxA2aPluginConfig: () => normalizeHermesOkxA2aPluginConfig,
73424
73458
  notifyAgentMessageToUserAttention: () => notifyAgentMessageToUserAttention,
73459
+ notifyDirectSystemMessageToUser: () => notifyDirectSystemMessageToUser,
73425
73460
  notifySystemMessageToUser: () => notifySystemMessageToUser,
73426
73461
  notifyUserAttentionChanged: () => notifyUserAttentionChanged,
73427
73462
  parsePluginYamlVersion: () => parsePluginYamlVersion,
73428
73463
  parseWindowsParentProcessJson: () => parseWindowsParentProcessJson,
73429
73464
  performRuntimeSwitch: () => performRuntimeSwitch,
73430
73465
  pickOnchainosWin32Candidate: () => pickOnchainosWin32Candidate,
73466
+ processDirectToUserSystemNotification: () => processDirectToUserSystemNotification,
73431
73467
  processFileMessage: () => processFileMessage,
73432
73468
  readAiProviderTimeoutMs: () => readAiProviderTimeoutMs,
73433
73469
  readLastLines: () => readLastLines,
@@ -89404,7 +89440,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
89404
89440
  client: {
89405
89441
  id: "gateway-client",
89406
89442
  displayName: "okx-a2a-node",
89407
- version: "0.1.6",
89443
+ version: "0.1.7-beta-482acfaf84-260707171501",
89408
89444
  platform: "node",
89409
89445
  mode: "backend",
89410
89446
  instanceId
@@ -89415,7 +89451,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
89415
89451
  commands: [],
89416
89452
  permissions: {},
89417
89453
  locale: Intl.DateTimeFormat().resolvedOptions().locale || "en-US",
89418
- userAgent: `okx-a2a-node/${"0.1.6"}`,
89454
+ userAgent: `okx-a2a-node/${"0.1.7-beta-482acfaf84-260707171501"}`,
89419
89455
  auth: {
89420
89456
  ...config.token ? { token: config.token } : {},
89421
89457
  ...config.password ? { password: config.password } : {}
@@ -89971,7 +90007,7 @@ var SqliteOutboundBehavior = class {
89971
90007
  }
89972
90008
  async dispatchUser(input) {
89973
90009
  const item = this.store.createUserAttention({
89974
- kind: "notification",
90010
+ kind: input.kind ?? "notification",
89975
90011
  provider: this.provider,
89976
90012
  userContent: input.userContent,
89977
90013
  jobId: input.jobId ?? null,
@@ -89984,7 +90020,7 @@ var SqliteOutboundBehavior = class {
89984
90020
  }
89985
90021
  async promptUser(input) {
89986
90022
  const item = this.store.createUserAttention({
89987
- kind: "decision_request",
90023
+ kind: input.kind ?? "decision_request",
89988
90024
  provider: this.provider,
89989
90025
  userContent: input.userContent,
89990
90026
  llmContent: input.llmContent,
@@ -90681,6 +90717,45 @@ async function notifySystemMessageToUser(input) {
90681
90717
  ownedStore?.close();
90682
90718
  }
90683
90719
  }
90720
+ async function notifyDirectSystemMessageToUser(input) {
90721
+ const ownedStore = input.store ? null : new SessionStore();
90722
+ const store = input.store ?? ownedStore;
90723
+ const idempotencyKey = input.idempotencyKey ?? buildDirectSystemMessageIdempotencyKey(input);
90724
+ const llmContent = input.llmContent?.trim() || null;
90725
+ try {
90726
+ const provider = resolveOutboundProvider(store, {
90727
+ jobId: input.jobId,
90728
+ override: input.provider
90729
+ });
90730
+ const behavior = createOutboundBehavior(provider, { store });
90731
+ const item = llmContent ? await behavior.promptUser({
90732
+ kind: "system_prompt",
90733
+ userContent: input.userContent,
90734
+ llmContent,
90735
+ jobId: input.jobId ?? null,
90736
+ idempotencyKey
90737
+ }) : await behavior.dispatchUser({
90738
+ kind: "system_notification",
90739
+ userContent: input.userContent,
90740
+ jobId: input.jobId ?? null,
90741
+ idempotencyKey
90742
+ });
90743
+ logWithTimestamp(
90744
+ `[notifyDirectSystemMessageToUser] provider=${provider} kind=${llmContent ? "system_prompt" : "system_notification"} job=${input.jobId ?? "(none)"} item=${item?.id ?? "(gateway)"}`
90745
+ );
90746
+ return item;
90747
+ } finally {
90748
+ ownedStore?.close();
90749
+ }
90750
+ }
90751
+ function buildDirectSystemMessageIdempotencyKey(input) {
90752
+ const identity3 = input.messageId || stableHash2([
90753
+ input.jobId ?? "",
90754
+ input.userContent,
90755
+ input.llmContent ?? ""
90756
+ ].join("\n"));
90757
+ return `system-direct:${identity3}`;
90758
+ }
90684
90759
  function buildAgentMessageIdempotencyKey(input) {
90685
90760
  const identity3 = input.messageId || stableHash2([
90686
90761
  input.direction,
@@ -92526,7 +92601,8 @@ function extractSystemNotification(payload) {
92526
92601
  }
92527
92602
  const message = isPlainObject3(payload.message) ? payload.message : null;
92528
92603
  const isDirectCommunication = message?.isDirectCommunication === true;
92529
- if (message?.source !== "system" && !isDirectCommunication) {
92604
+ const isDirectToUser = message?.isDirectToUser === true;
92605
+ if (message?.source !== "system" && !isDirectCommunication && !isDirectToUser) {
92530
92606
  return null;
92531
92607
  }
92532
92608
  return {
@@ -92535,7 +92611,10 @@ function extractSystemNotification(payload) {
92535
92611
  providerAgentId: readString3(message.providerAgentId),
92536
92612
  clientAgentId: readString3(message.clientAgentId),
92537
92613
  event: readString3(message.event),
92538
- isDirectCommunication
92614
+ isDirectCommunication,
92615
+ isDirectToUser,
92616
+ userContent: readString3(message.userContent),
92617
+ llmContent: readString3(message.llmContent)
92539
92618
  };
92540
92619
  }
92541
92620
  function resolveDirectCommunicationSessionTarget(notification) {
@@ -93142,6 +93221,85 @@ ${failureMessage}`,
93142
93221
  }
93143
93222
  return true;
93144
93223
  }
93224
+ function processDirectToUserSystemNotification(params) {
93225
+ const { deps, notification, messageId, timing } = params;
93226
+ const notificationAgentId = notification.agentId ?? void 0;
93227
+ const attentionKind = notification.llmContent ? "system_prompt" : "system_notification";
93228
+ if (!notification.userContent) {
93229
+ logger.info(LogEvent.DM_FALLBACK_TO_BACKUP, {
93230
+ ...agentExtras({ walletAddress: deps.myXmtpAddress, onchainosAgentId: notificationAgentId }),
93231
+ taskId: notification.jobId ?? "",
93232
+ messageId,
93233
+ systemEvent: notification.event ?? "",
93234
+ stage: "inbound/payload_parse",
93235
+ reason: "direct_to_user_missing_user_content"
93236
+ });
93237
+ logWithTimestamp(
93238
+ `[okx-agent-task:${deps.myXmtpAddress}] direct-to-user system DM missing userContent, falling back to AI session routing message=${shortenLogValue(messageId)}`
93239
+ );
93240
+ return false;
93241
+ }
93242
+ const userContent = notification.userContent;
93243
+ const providerBindStartedAt = Date.now();
93244
+ const providerGate = bindMessageJobProviderToCurrentDefault(deps, notification.jobId, "system-direct-user");
93245
+ timing.mark("providerBind", providerBindStartedAt);
93246
+ if (!providerGate.allowed) {
93247
+ return true;
93248
+ }
93249
+ logger.info(LogEvent.SYSTEM_NOTIFICATION_RECEIVED, {
93250
+ ...agentExtras({ walletAddress: deps.myXmtpAddress, onchainosAgentId: notificationAgentId }),
93251
+ taskId: notification.jobId ?? "",
93252
+ agentId: notification.agentId ?? "",
93253
+ providerAgentId: notification.providerAgentId ?? "",
93254
+ clientAgentId: notification.clientAgentId ?? "",
93255
+ messageId,
93256
+ systemEvent: notification.event ?? "",
93257
+ stage: "inbound/system_notification_received",
93258
+ isDirectToUser: "true",
93259
+ attentionKind,
93260
+ providerBinding: providerGate.provider ?? "",
93261
+ providerBindingCreated: String(providerGate.created)
93262
+ });
93263
+ const dispatchStartedAt = Date.now();
93264
+ void notifyDirectSystemMessageToUser({
93265
+ userContent,
93266
+ llmContent: notification.llmContent ?? null,
93267
+ jobId: notification.jobId ?? null,
93268
+ messageId,
93269
+ store: deps.sessionStore
93270
+ }).then(() => {
93271
+ timing.mark("userDispatch", dispatchStartedAt);
93272
+ logger.info(LogEvent.SYSTEM_NOTIFICATION_ROUTED, timing.extras({
93273
+ ...agentExtras({ walletAddress: deps.myXmtpAddress, onchainosAgentId: notificationAgentId }),
93274
+ taskId: notification.jobId ?? "",
93275
+ agentId: notification.agentId ?? "",
93276
+ messageId,
93277
+ route: "system/direct-user",
93278
+ systemEvent: notification.event ?? "",
93279
+ stage: "inbound/system_direct_user_delivered",
93280
+ isDirectToUser: "true",
93281
+ attentionKind
93282
+ }));
93283
+ }).catch((err2) => {
93284
+ logger.error(LogEvent.USER_DISPATCH_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), {
93285
+ ...agentExtras({ walletAddress: deps.myXmtpAddress, onchainosAgentId: notificationAgentId }),
93286
+ taskId: notification.jobId ?? "",
93287
+ messageId,
93288
+ systemEvent: notification.event ?? "",
93289
+ stage: "inbound/system_direct_user_delivery",
93290
+ isDirectToUser: "true",
93291
+ attentionKind
93292
+ });
93293
+ logWithTimestamp(
93294
+ `[okx-agent-task:${deps.myXmtpAddress}] direct-to-user delivery failed message=${shortenLogValue(messageId)}:`,
93295
+ err2
93296
+ );
93297
+ });
93298
+ logWithTimestamp(
93299
+ `[okx-agent-task:${deps.myXmtpAddress}] direct-to-user delivery queued kind=${attentionKind} job=${shortenLogValue(notification.jobId ?? "(none)")} message=${shortenLogValue(messageId)}`
93300
+ );
93301
+ return true;
93302
+ }
93145
93303
  async function processFileMessage(ctx, deps, options = {}) {
93146
93304
  const messageId = ctx.message.id ?? "";
93147
93305
  const timing = createInboundTimingTracker(extractXmtpSentAtMs2(ctx.message));
@@ -93194,6 +93352,14 @@ async function processFileMessage(ctx, deps, options = {}) {
93194
93352
  );
93195
93353
  return true;
93196
93354
  }
93355
+ if (systemNotification.isDirectToUser && processDirectToUserSystemNotification({
93356
+ deps,
93357
+ notification: systemNotification,
93358
+ messageId: systemMessageId,
93359
+ timing
93360
+ })) {
93361
+ return true;
93362
+ }
93197
93363
  const directTarget = resolveDirectCommunicationSessionTarget(systemNotification);
93198
93364
  if (systemNotification.isDirectCommunication && !directTarget) {
93199
93365
  logger.error(
@@ -93886,7 +94052,7 @@ init_ai_provider();
93886
94052
  var environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
93887
94053
  var SENTRY_CONFIG = {
93888
94054
  projectName: "okx/openclaw-okx-a2a-extension",
93889
- release: "0.1.6",
94055
+ release: "0.1.7-beta-482acfaf84-260707171501",
93890
94056
  environment
93891
94057
  };
93892
94058
 
@@ -94124,12 +94290,12 @@ async function runListenerWithLock(options, paths) {
94124
94290
  }));
94125
94291
  }
94126
94292
  });
94127
- service.setPluginVersion("0.1.6");
94293
+ service.setPluginVersion("0.1.7-beta-482acfaf84-260707171501");
94128
94294
  await service.init();
94129
94295
  const pluginVersionStatus = service.pluginVersionStatus;
94130
94296
  if (pluginVersionStatus.unavailable) {
94131
94297
  throw new Error(
94132
- `@okxweb3/a2a-node v${"0.1.6"} is below the required minimum v${pluginVersionStatus.minVersion}`
94298
+ `@okxweb3/a2a-node v${"0.1.7-beta-482acfaf84-260707171501"} is below the required minimum v${pluginVersionStatus.minVersion}`
94133
94299
  );
94134
94300
  }
94135
94301
  const systemConfig = service.getSystemConfig();
@@ -94147,7 +94313,7 @@ async function runListenerWithLock(options, paths) {
94147
94313
  onchainosAgentId: "*",
94148
94314
  reason: "system-config missing sentryDsn",
94149
94315
  pluginId: "@okxweb3/a2a-node",
94150
- pluginVersion: "0.1.6"
94316
+ pluginVersion: "0.1.7-beta-482acfaf84-260707171501"
94151
94317
  });
94152
94318
  }
94153
94319
  logWithTimestamp(
@@ -95884,7 +96050,7 @@ async function runDoctor(options = {}) {
95884
96050
  platform: options.platform ?? process.platform,
95885
96051
  env: options.env ?? process.env,
95886
96052
  target: options.target ?? resolveDoctorTarget(options.env ?? process.env),
95887
- cliVersion: options.cliVersion ?? (true ? "0.1.6" : "0.0.0"),
96053
+ cliVersion: options.cliVersion ?? (true ? "0.1.7-beta-482acfaf84-260707171501" : "0.0.0"),
95888
96054
  fixMode: options.fix === true,
95889
96055
  nonInteractive: options.nonInteractive === true,
95890
96056
  packageChanged: false
@@ -96192,12 +96358,14 @@ init_win_native_launcher();
96192
96358
  normalizeAiProvider,
96193
96359
  normalizeHermesOkxA2aPluginConfig,
96194
96360
  notifyAgentMessageToUserAttention,
96361
+ notifyDirectSystemMessageToUser,
96195
96362
  notifySystemMessageToUser,
96196
96363
  notifyUserAttentionChanged,
96197
96364
  parsePluginYamlVersion,
96198
96365
  parseWindowsParentProcessJson,
96199
96366
  performRuntimeSwitch,
96200
96367
  pickOnchainosWin32Candidate,
96368
+ processDirectToUserSystemNotification,
96201
96369
  processFileMessage,
96202
96370
  readAiProviderTimeoutMs,
96203
96371
  readLastLines,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@okxweb3/a2a-node",
3
- "version": "0.1.6",
3
+ "version": "0.1.7-beta-482acfaf84-260707171501",
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": {