@okxweb3/a2a-node 0.1.6 → 0.1.7

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 +234 -26
  2. package/dist/index.js +808 -556
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -18764,6 +18764,547 @@ var require_cjs4 = __commonJS({
18764
18764
  }
18765
18765
  });
18766
18766
 
18767
+ // ../core/src/sentry-logger/events.ts
18768
+ var LogEvent;
18769
+ var init_events = __esm({
18770
+ "../core/src/sentry-logger/events.ts"() {
18771
+ "use strict";
18772
+ LogEvent = {
18773
+ // ── info ──────────────────────────────────────────────────────
18774
+ GATEWAY_STARTED: "Gateway started",
18775
+ GATEWAY_STOPPED: "Gateway stopped",
18776
+ BOOTSTRAP_APPLIED: "Bootstrap applied",
18777
+ CHANNEL_READY: "Channel ready",
18778
+ CONVERSATION_STARTED: "Conversation started",
18779
+ EVALUATE_CONVERSATION_STARTED: "Evaluate conversation started",
18780
+ CONVERSATION_DELETED: "Conversation deleted",
18781
+ PENDING_CONVERSATION_DENIED: "Pending conversation denied",
18782
+ AGENTS_REFRESHED: "Agents refreshed",
18783
+ USER_DISPATCHED: "User dispatched",
18784
+ SESSION_DISPATCHED: "Session dispatched",
18785
+ SYNC_TICK_COMPLETED: "Sync tick completed",
18786
+ INBOUND_HANDLER_ENTERED: "Inbound handler entered",
18787
+ MESSAGE_RECEIVED: "Message received",
18788
+ MESSAGE_SENT: "Message sent",
18789
+ INBOUND_BUYER_PENDING: "Inbound buyer: no session, group still Unknown (pending)",
18790
+ INBOUND_BUYER_SESSION_AUTO_RECOVERED: "Inbound buyer: session missing for Allowed group, auto-recovered",
18791
+ INBOUND_BLOCKED_SENSITIVE: "Inbound blocked: sensitive word; reply sent",
18792
+ INBOUND_BLOCKED_ADDRESS_MISMATCH: "Inbound blocked: address mismatch",
18793
+ INBOUND_BLOCKED_INELIGIBLE: "Inbound blocked: message-eligible check failed",
18794
+ INBOUND_DROP_EMPTY_CONTENT: "Inbound drop: empty content",
18795
+ INBOUND_DROP_MISSING_JOBID: "Inbound drop: missing jobId",
18796
+ INBOUND_DROP_UNSUPPORTED_MSGTYPE: "Inbound drop: unsupported msgType",
18797
+ INBOUND_DROP_DM_NON_SYSTEM: "Inbound drop: DM sender not in system whitelist",
18798
+ INBOUND_DROP_DM_INVALID_PAYLOAD: "Inbound drop: DM payload invalid",
18799
+ INBOUND_DROP_DM_UNKNOWN_AGENT: "Inbound drop: DM target agent not local",
18800
+ DM_FALLBACK_TO_BACKUP: "DM fallback to backup session",
18801
+ DM_WHITELIST_FAIL_OPEN: "DM whitelist fail-open (empty system accounts)",
18802
+ FILE_UPLOADED: "File uploaded",
18803
+ FILE_DOWNLOADED: "File downloaded",
18804
+ PENDING_LIST_QUERIED: "Pending list queried",
18805
+ AGENT_LIST_QUERIED: "Agent list queried",
18806
+ SESSION_KEY_DERIVED: "Session key derived",
18807
+ CONVERSATION_HISTORY_QUERIED: "Conversation history queried",
18808
+ SESSIONS_QUERIED: "Sessions queried",
18809
+ GROUP_CONSENT_CHANGED: "Group consent changed",
18810
+ SESSION_CREATED: "Session created",
18811
+ SESSION_DELETED: "Session deleted",
18812
+ SESSION_AUTO_RECOVERED: "Session auto-recovered",
18813
+ INBOUND_DELIVERED: "Inbound delivered to session",
18814
+ DM_DELIVERED: "DM delivered to session",
18815
+ OUTBOUND_ELIGIBILITY_CHECKED: "Outbound eligibility checked",
18816
+ AGENT_CLIENT_CREATED: "Agent client created",
18817
+ AGENT_CLIENT_REMOVED: "Agent client removed",
18818
+ ADDRESS_SYNC_COMPLETED: "Address sync completed",
18819
+ AGENT_REFRESH_SESSION_EXPIRED: "Agent refresh aborted: onchainos session expired, local clients taken offline",
18820
+ OFFLINE_REPLAY_MESSAGE_REPLAYED: "Offline replay message replayed",
18821
+ AGENTS_WAKEUP_NOTIFIED: "Agents wakeup notified",
18822
+ CONFIG_SENSITIVE_WORDS_REFRESHED: "Sensitive words config refreshed",
18823
+ CONFIG_SYSTEM_REFRESHED: "System config refreshed",
18824
+ GATEWAY_DISCONNECTED: "Gateway disconnected",
18825
+ GATEWAY_REQUEST: "Gateway request",
18826
+ GATEWAY_DELIVERY_BUFFERED: "Gateway delivery buffered",
18827
+ DAEMON_LIFECYCLE_SKIPPED: "Daemon lifecycle skipped",
18828
+ DAEMON_LIFECYCLE_REQUESTED: "Daemon lifecycle requested",
18829
+ PROMPT_USER_CHECKPOINT: "Prompt user checkpoint",
18830
+ USER_WATCH_STARTED: "User watch started",
18831
+ USER_WATCH_EVENT_DELIVERED: "User watch event delivered",
18832
+ INBOUND_DM_RAW: "Inbound DM raw",
18833
+ INBOUND_GROUP_RAW: "Inbound group raw",
18834
+ SYSTEM_NOTIFICATION_RECEIVED: "System notification received",
18835
+ SYSTEM_NOTIFICATION_ROUTED: "System notification routed",
18836
+ HERMES_SESSION_ROUTE_BINDING: "Hermes session route binding",
18837
+ DOCTOR_REPORT: "Doctor report",
18838
+ // ── error ─────────────────────────────────────────────────────
18839
+ XMTP_CONNECTION_FAILED: "XMTP connection failed",
18840
+ CONVERSATIONS_STREAM_FAILED: "conversations.stream failed",
18841
+ AGENT_START_FAILED: "agent.start failed",
18842
+ AGENT_STREAM_ERROR: "agent stream error",
18843
+ BOOTSTRAP_FAILED: "Bootstrap failed",
18844
+ ONCHAINOS_SESSION_EXPIRED: "Onchainos session expired",
18845
+ ONCHAINOS_CLI_ERROR: "Onchainos CLI error",
18846
+ HEARTBEAT_FAILED: "Heartbeat failed",
18847
+ HEARTBEAT_SKIPPED: "Heartbeat skipped",
18848
+ HEARTBEAT_GATEWAY_CHECK_FAILED: "Heartbeat gateway check failed",
18849
+ MESSAGE_PARSE_FAILED: "Message parse failed",
18850
+ MESSAGE_HANDLER_ERROR: "Message handler error",
18851
+ OFFLINE_REPLAY_FAILED: "Offline replay failed",
18852
+ INBOUND_ROUTING_FAILED: "Inbound routing failed",
18853
+ CONVERSATION_NOT_FOUND: "Conversation not found for send",
18854
+ XMTP_SEND_FAILED: "XMTP send failed",
18855
+ AGENT_REFRESH_FAILED: "Agent refresh failed",
18856
+ GROUP_CONSENT_UPDATE_FAILED: "Group consent update failed",
18857
+ TOOL_EXECUTE_FAILED: "Tool execute failed",
18858
+ AGENT_RESOLUTION_FAILED: "Agent resolution failed",
18859
+ USER_DISPATCH_FAILED: "User dispatch failed",
18860
+ INBOUND_ELIGIBILITY_BYPASSED: "Inbound eligibility bypassed",
18861
+ INBOUND_ADDRESS_CHECK_FAILED: "Inbound address check failed",
18862
+ INBOUND_ADDRESS_CHECK_BYPASSED: "Inbound address check bypassed",
18863
+ INBOUND_SENSITIVE_CHECK_FAILED: "Inbound sensitive check failed",
18864
+ FILE_UPLOAD_FAILED: "File upload failed",
18865
+ FILE_DOWNLOAD_FAILED: "File download failed",
18866
+ OFFLINE_REPLAY_MESSAGE_FAILED: "Offline replay message failed",
18867
+ PENDING_NOTIFICATION_FAILED: "Pending notification failed",
18868
+ GATEWAY_CONNECT_FAILED: "Gateway connect failed",
18869
+ GATEWAY_REQUEST_FAILED: "Gateway request failed",
18870
+ PROMPT_USER_FAILED: "Prompt user failed",
18871
+ DAEMON_COMMAND_FAILED: "Daemon command failed",
18872
+ DAEMON_COMMAND_TIMEOUT: "Daemon command timeout",
18873
+ DAEMON_COMMAND_STALE: "Daemon command stale",
18874
+ DAEMON_LIFECYCLE_FAILED: "Daemon lifecycle failed",
18875
+ DAEMON_TICK_FAILED: "Daemon tick failed",
18876
+ DIRECT_CLI_FAILED: "Direct CLI failed",
18877
+ DOCTOR_NOT_READY: "Doctor not ready",
18878
+ DOCTOR_CRASHED: "Doctor crashed",
18879
+ AI_RUN_FAILED: "AI run failed",
18880
+ AI_RUN_TIMEOUT: "AI run timeout",
18881
+ AI_RUN_TOOL_FAILED: "AI run tool failed",
18882
+ IPC_FAILED: "IPC failed",
18883
+ NOTIFY_AGENTS_WAKEUP_FAILED: "Notify agents wakeup failed",
18884
+ OUTBOUND_AGENT_LOOKUP_FAILED: "Outbound agent lookup failed",
18885
+ OUTBOUND_ELIGIBILITY_CHECK_FAILED: "Outbound eligibility check failed",
18886
+ OUTBOUND_ELIGIBILITY_BYPASSED: "Outbound eligibility bypassed",
18887
+ OUTBOUND_BLOCKED_INELIGIBLE: "Outbound blocked: message-eligible check failed",
18888
+ CACHE_LOAD_FAILED: "Cache load failed",
18889
+ CACHE_WRITE_FAILED: "Cache write failed",
18890
+ CONFIG_LOAD_FAILED: "Config load failed",
18891
+ SENTRY_INIT_SKIPPED: "Sentry init skipped",
18892
+ AGENT_DB_DIR_CREATE_FAILED: "Agent DB dir create failed"
18893
+ };
18894
+ }
18895
+ });
18896
+
18897
+ // ../core/src/sentry-logger/index.ts
18898
+ function agentExtras(identity3) {
18899
+ return {
18900
+ walletAddress: identity3.walletAddress || UNKNOWN_FIELD,
18901
+ inboxId: identity3.inboxId || UNKNOWN_FIELD,
18902
+ onchainosAgentId: identity3.onchainosAgentId || UNKNOWN_FIELD,
18903
+ role: identity3.role != null && identity3.role !== "" ? String(identity3.role) : UNKNOWN_FIELD
18904
+ };
18905
+ }
18906
+ var Sentry, import_node_crypto2, FLOW_ID, SENTRY_EXTRA_BLOCKLIST, SENTRY_EXTRA_BLOCKED_KEY_PARTS, SENTRY_FULL_STRING_EXTRA_KEYS, SENTRY_TAG_KEYS, SENTRY_FINGERPRINT_KEYS, SENTRY_INFO_ALLOWLIST, MAX_EXTRA_STRING_LENGTH, MAX_TAG_VALUE_LENGTH, SentryLogger, logger, initLogger, shutdown, UNKNOWN_FIELD;
18907
+ var init_sentry_logger = __esm({
18908
+ "../core/src/sentry-logger/index.ts"() {
18909
+ "use strict";
18910
+ init_log();
18911
+ Sentry = __toESM(require_cjs4());
18912
+ import_node_crypto2 = require("node:crypto");
18913
+ init_events();
18914
+ init_events();
18915
+ FLOW_ID = (0, import_node_crypto2.randomUUID)();
18916
+ SENTRY_EXTRA_BLOCKLIST = /* @__PURE__ */ new Set([
18917
+ "args",
18918
+ "apikey",
18919
+ "argv",
18920
+ "auth",
18921
+ "authorization",
18922
+ "authtoken",
18923
+ "bearer",
18924
+ "body",
18925
+ "cache",
18926
+ "command",
18927
+ "content",
18928
+ "credential",
18929
+ "credentials",
18930
+ "cwd",
18931
+ "data",
18932
+ "error",
18933
+ "failures",
18934
+ "filename",
18935
+ "file_name",
18936
+ "filepath",
18937
+ "file_path",
18938
+ "headers",
18939
+ "input",
18940
+ "logpath",
18941
+ "message",
18942
+ "output",
18943
+ "password",
18944
+ "params",
18945
+ "path",
18946
+ "payload",
18947
+ "privatekey",
18948
+ "prompt",
18949
+ "raw",
18950
+ "rawevent",
18951
+ "rawtext",
18952
+ "request",
18953
+ "response",
18954
+ "accesstoken",
18955
+ "refreshtoken",
18956
+ "digest",
18957
+ "nonce",
18958
+ "salt",
18959
+ "secret",
18960
+ "token",
18961
+ "stderr",
18962
+ "stdout",
18963
+ "title",
18964
+ "tooloutput"
18965
+ ]);
18966
+ SENTRY_EXTRA_BLOCKED_KEY_PARTS = [
18967
+ "accesstoken",
18968
+ "apikey",
18969
+ "authorization",
18970
+ "authtoken",
18971
+ "content",
18972
+ "credential",
18973
+ "filepath",
18974
+ "logpath",
18975
+ "outputpath",
18976
+ "password",
18977
+ "payload",
18978
+ "privatekey",
18979
+ "prompt",
18980
+ "rawevent",
18981
+ "rawtext",
18982
+ "refreshtoken",
18983
+ "requestbody",
18984
+ "responsebody",
18985
+ "secret",
18986
+ "stderr",
18987
+ "stdout",
18988
+ "token",
18989
+ "tooloutput"
18990
+ ];
18991
+ SENTRY_FULL_STRING_EXTRA_KEYS = /* @__PURE__ */ new Set([
18992
+ "onchainosagentlistresultjson",
18993
+ "onchainosagentlistdiagnostictext"
18994
+ ]);
18995
+ SENTRY_TAG_KEYS = /* @__PURE__ */ new Set([
18996
+ "agentPlatform",
18997
+ "cacheName",
18998
+ "checkpoint",
18999
+ "code",
19000
+ "communicationClass",
19001
+ "component",
19002
+ "eventName",
19003
+ "exitCode",
19004
+ "kind",
19005
+ "method",
19006
+ "onchainosAgentId",
19007
+ "operation",
19008
+ "phase",
19009
+ "platform",
19010
+ "provider",
19011
+ "reason",
19012
+ "role",
19013
+ "source",
19014
+ "stage",
19015
+ "status",
19016
+ "subcommand",
19017
+ "taskId",
19018
+ "type"
19019
+ ]);
19020
+ SENTRY_FINGERPRINT_KEYS = [
19021
+ "eventName",
19022
+ "cacheName",
19023
+ "checkpoint",
19024
+ "component",
19025
+ "method",
19026
+ "operation",
19027
+ "phase",
19028
+ "reason",
19029
+ "code",
19030
+ "provider",
19031
+ "type",
19032
+ "kind",
19033
+ "status",
19034
+ "subcommand"
19035
+ ];
19036
+ SENTRY_INFO_ALLOWLIST = /* @__PURE__ */ new Set([
19037
+ LogEvent.GATEWAY_STARTED,
19038
+ LogEvent.GATEWAY_STOPPED,
19039
+ LogEvent.GATEWAY_DISCONNECTED,
19040
+ LogEvent.GATEWAY_REQUEST,
19041
+ LogEvent.GATEWAY_DELIVERY_BUFFERED,
19042
+ LogEvent.DAEMON_LIFECYCLE_SKIPPED,
19043
+ LogEvent.DAEMON_LIFECYCLE_REQUESTED,
19044
+ LogEvent.PROMPT_USER_CHECKPOINT,
19045
+ LogEvent.USER_WATCH_STARTED,
19046
+ LogEvent.USER_WATCH_EVENT_DELIVERED,
19047
+ LogEvent.CHANNEL_READY,
19048
+ LogEvent.CONVERSATION_STARTED,
19049
+ LogEvent.EVALUATE_CONVERSATION_STARTED,
19050
+ LogEvent.CONVERSATION_DELETED,
19051
+ LogEvent.USER_DISPATCHED,
19052
+ LogEvent.SESSION_DISPATCHED,
19053
+ LogEvent.SESSION_CREATED,
19054
+ LogEvent.SESSION_DELETED,
19055
+ LogEvent.SESSION_AUTO_RECOVERED,
19056
+ LogEvent.INBOUND_DELIVERED,
19057
+ LogEvent.INBOUND_DM_RAW,
19058
+ LogEvent.INBOUND_GROUP_RAW,
19059
+ LogEvent.SYSTEM_NOTIFICATION_RECEIVED,
19060
+ LogEvent.SYSTEM_NOTIFICATION_ROUTED,
19061
+ LogEvent.HERMES_SESSION_ROUTE_BINDING,
19062
+ LogEvent.INBOUND_BLOCKED_ADDRESS_MISMATCH,
19063
+ LogEvent.INBOUND_BLOCKED_INELIGIBLE,
19064
+ LogEvent.INBOUND_BLOCKED_SENSITIVE,
19065
+ LogEvent.INBOUND_DROP_DM_INVALID_PAYLOAD,
19066
+ LogEvent.INBOUND_DROP_DM_NON_SYSTEM,
19067
+ LogEvent.INBOUND_DROP_DM_UNKNOWN_AGENT,
19068
+ LogEvent.INBOUND_DROP_EMPTY_CONTENT,
19069
+ LogEvent.INBOUND_DROP_MISSING_JOBID,
19070
+ LogEvent.INBOUND_DROP_UNSUPPORTED_MSGTYPE,
19071
+ LogEvent.DM_DELIVERED,
19072
+ LogEvent.DM_FALLBACK_TO_BACKUP,
19073
+ LogEvent.DM_WHITELIST_FAIL_OPEN,
19074
+ LogEvent.INBOUND_BUYER_PENDING,
19075
+ LogEvent.INBOUND_BUYER_SESSION_AUTO_RECOVERED,
19076
+ LogEvent.MESSAGE_SENT,
19077
+ LogEvent.AGENT_CLIENT_CREATED,
19078
+ LogEvent.AGENT_CLIENT_REMOVED,
19079
+ LogEvent.ADDRESS_SYNC_COMPLETED,
19080
+ LogEvent.AGENTS_REFRESHED,
19081
+ LogEvent.AGENTS_WAKEUP_NOTIFIED,
19082
+ LogEvent.AGENT_LIST_QUERIED,
19083
+ LogEvent.BOOTSTRAP_APPLIED,
19084
+ LogEvent.CONFIG_SENSITIVE_WORDS_REFRESHED,
19085
+ LogEvent.CONFIG_SYSTEM_REFRESHED,
19086
+ LogEvent.CONVERSATION_HISTORY_QUERIED,
19087
+ LogEvent.FILE_DOWNLOADED,
19088
+ LogEvent.FILE_UPLOADED,
19089
+ LogEvent.GROUP_CONSENT_CHANGED,
19090
+ LogEvent.INBOUND_HANDLER_ENTERED,
19091
+ LogEvent.MESSAGE_RECEIVED,
19092
+ LogEvent.OFFLINE_REPLAY_MESSAGE_REPLAYED,
19093
+ LogEvent.AGENT_REFRESH_SESSION_EXPIRED,
19094
+ LogEvent.OUTBOUND_ELIGIBILITY_CHECKED,
19095
+ LogEvent.OUTBOUND_BLOCKED_INELIGIBLE,
19096
+ LogEvent.PENDING_CONVERSATION_DENIED,
19097
+ LogEvent.PENDING_LIST_QUERIED,
19098
+ LogEvent.SESSION_KEY_DERIVED,
19099
+ LogEvent.SESSIONS_QUERIED,
19100
+ LogEvent.SYNC_TICK_COMPLETED
19101
+ ]);
19102
+ MAX_EXTRA_STRING_LENGTH = 256;
19103
+ MAX_TAG_VALUE_LENGTH = 128;
19104
+ SentryLogger = class _SentryLogger {
19105
+ static instance;
19106
+ initialized = false;
19107
+ buffer = [];
19108
+ constructor() {
19109
+ }
19110
+ static getInstance() {
19111
+ if (!_SentryLogger.instance) {
19112
+ _SentryLogger.instance = new _SentryLogger();
19113
+ }
19114
+ return _SentryLogger.instance;
19115
+ }
19116
+ init(config) {
19117
+ if (this.initialized) {
19118
+ warnWithTimestamp("[logger] Already initialized, skipping.");
19119
+ return;
19120
+ }
19121
+ try {
19122
+ Sentry.init({
19123
+ dsn: config.dsn,
19124
+ release: config.release,
19125
+ environment: config.environment,
19126
+ maxBreadcrumbs: 0,
19127
+ beforeBreadcrumb: () => null,
19128
+ isInner: false
19129
+ });
19130
+ Sentry.setTags({
19131
+ projectName: config.projectName,
19132
+ agentPlatform: config.agentPlatform
19133
+ });
19134
+ } catch {
19135
+ return;
19136
+ }
19137
+ this.initialized = true;
19138
+ this.flush();
19139
+ }
19140
+ info(message, extra) {
19141
+ const extraWithFlow = _SentryLogger.sanitizeExtra({ flowId: FLOW_ID, ...extra ?? {} });
19142
+ if (!SENTRY_INFO_ALLOWLIST.has(message)) {
19143
+ return;
19144
+ }
19145
+ if (!this.initialized) {
19146
+ this.buffer.push({ level: "info", message, extra: extraWithFlow });
19147
+ return;
19148
+ }
19149
+ try {
19150
+ Sentry.withScope((scope) => {
19151
+ _SentryLogger.applyDiagnostics(scope, message, extraWithFlow);
19152
+ Sentry.captureEvent({
19153
+ level: "info",
19154
+ message,
19155
+ extra: {
19156
+ ...extraWithFlow,
19157
+ eventName: message
19158
+ }
19159
+ });
19160
+ });
19161
+ } catch {
19162
+ }
19163
+ }
19164
+ error(message, error, extra) {
19165
+ const extraWithFlow = _SentryLogger.sanitizeExtra({ flowId: FLOW_ID, ...extra ?? {} });
19166
+ if (!this.initialized) {
19167
+ this.buffer.push({
19168
+ level: "error",
19169
+ message,
19170
+ error,
19171
+ extra: extraWithFlow
19172
+ });
19173
+ return;
19174
+ }
19175
+ try {
19176
+ Sentry.withScope((scope) => {
19177
+ scope.setLevel("error");
19178
+ _SentryLogger.applyDiagnostics(scope, message, extraWithFlow);
19179
+ Sentry.captureException(_SentryLogger.createSentryEvent(message), {
19180
+ extra: error ? {
19181
+ ...extraWithFlow,
19182
+ eventName: message,
19183
+ errorName: error.name,
19184
+ errorMessageLength: String(error.message.length)
19185
+ } : extraWithFlow
19186
+ });
19187
+ });
19188
+ } catch {
19189
+ }
19190
+ }
19191
+ async shutdown() {
19192
+ try {
19193
+ await Sentry.close(5e3);
19194
+ } catch {
19195
+ await Sentry.flush(5e3);
19196
+ }
19197
+ }
19198
+ flush() {
19199
+ while (this.buffer.length > 0) {
19200
+ const entry = this.buffer.shift();
19201
+ if (entry.level === "info") {
19202
+ this.info(entry.message, entry.extra);
19203
+ } else {
19204
+ this.error(entry.message, entry.error, entry.extra);
19205
+ }
19206
+ }
19207
+ }
19208
+ static sanitizeExtra(extra) {
19209
+ return Object.fromEntries(
19210
+ Object.entries(extra).filter(([, value]) => value !== void 0).filter(([key]) => !_SentryLogger.isBlockedExtraKey(key)).map(([key, value]) => [key, _SentryLogger.safeValueForKey(key, value)])
19211
+ );
19212
+ }
19213
+ static isBlockedExtraKey(key) {
19214
+ const lower = key.toLowerCase();
19215
+ const normalized = _SentryLogger.normalizeSensitiveKey(key);
19216
+ if (SENTRY_EXTRA_BLOCKLIST.has(lower) || SENTRY_EXTRA_BLOCKLIST.has(normalized)) {
19217
+ return true;
19218
+ }
19219
+ if (_SentryLogger.isSafeMetricKey(normalized)) {
19220
+ return false;
19221
+ }
19222
+ return SENTRY_EXTRA_BLOCKED_KEY_PARTS.some((needle) => normalized.includes(needle));
19223
+ }
19224
+ static isSafeMetricKey(normalized) {
19225
+ return /(bytes|count|length|ms|size)$/.test(normalized);
19226
+ }
19227
+ static safeValueForKey(key, value) {
19228
+ if (typeof value === "string" && SENTRY_FULL_STRING_EXTRA_KEYS.has(_SentryLogger.normalizeSensitiveKey(key))) {
19229
+ return value;
19230
+ }
19231
+ return _SentryLogger.safeValue(value);
19232
+ }
19233
+ static normalizeSensitiveKey(key) {
19234
+ return key.toLowerCase().replace(/[^a-z0-9]/g, "");
19235
+ }
19236
+ static safeValue(value) {
19237
+ if (typeof value === "string") {
19238
+ return value.length <= MAX_EXTRA_STRING_LENGTH ? value : `${value.slice(0, MAX_EXTRA_STRING_LENGTH)}...`;
19239
+ }
19240
+ if (value === null || value === void 0 || typeof value === "number" || typeof value === "boolean") {
19241
+ return value;
19242
+ }
19243
+ if (typeof value === "bigint") {
19244
+ return value.toString();
19245
+ }
19246
+ if (value instanceof Error) {
19247
+ return {
19248
+ name: value.name,
19249
+ messageLength: value.message.length
19250
+ };
19251
+ }
19252
+ if (Array.isArray(value)) {
19253
+ return value.slice(0, 20).map((item) => _SentryLogger.safeValue(item));
19254
+ }
19255
+ if (typeof value === "object") {
19256
+ return Object.fromEntries(
19257
+ Object.entries(value).slice(0, 50).filter(([, item]) => item !== void 0).filter(([key]) => !_SentryLogger.isBlockedExtraKey(key)).map(([key, item]) => [key, _SentryLogger.safeValueForKey(key, item)])
19258
+ );
19259
+ }
19260
+ const text = String(value);
19261
+ return text.length <= MAX_EXTRA_STRING_LENGTH ? text : `${text.slice(0, MAX_EXTRA_STRING_LENGTH)}...`;
19262
+ }
19263
+ static tagValue(value) {
19264
+ const text = String(value);
19265
+ return text.length <= MAX_TAG_VALUE_LENGTH ? text : `${text.slice(0, MAX_TAG_VALUE_LENGTH)}...`;
19266
+ }
19267
+ static normalizeTagKey(key) {
19268
+ return key.replace(/[^A-Za-z0-9_.:-]+/g, "_").slice(0, 32) || "unknown";
19269
+ }
19270
+ static applyDiagnostics(scope, eventName, extra) {
19271
+ const enriched = { eventName, ...extra };
19272
+ for (const [key, value] of Object.entries(enriched)) {
19273
+ if (!SENTRY_TAG_KEYS.has(key)) {
19274
+ continue;
19275
+ }
19276
+ scope.setTag(_SentryLogger.normalizeTagKey(key), _SentryLogger.tagValue(value));
19277
+ }
19278
+ const fingerprint = ["a2a", eventName];
19279
+ for (const key of SENTRY_FINGERPRINT_KEYS) {
19280
+ const value = enriched[key];
19281
+ if (value) {
19282
+ fingerprint.push(`${key}:${_SentryLogger.tagValue(value)}`);
19283
+ }
19284
+ }
19285
+ scope.setFingerprint(fingerprint);
19286
+ }
19287
+ static toPascalCase(str) {
19288
+ return str.split(/[\s:]+/).filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
19289
+ }
19290
+ static createSentryEvent(eventName) {
19291
+ const err2 = new Error(eventName);
19292
+ err2.name = _SentryLogger.toPascalCase(eventName);
19293
+ err2.stack = `${err2.name}: ${eventName}`;
19294
+ return err2;
19295
+ }
19296
+ };
19297
+ logger = SentryLogger.getInstance();
19298
+ initLogger = (config) => {
19299
+ return logger.init(config);
19300
+ };
19301
+ shutdown = () => {
19302
+ return logger.shutdown();
19303
+ };
19304
+ UNKNOWN_FIELD = "unknown";
19305
+ }
19306
+ });
19307
+
18767
19308
  // ../../node_modules/undici/lib/core/symbols.js
18768
19309
  var require_symbols = __commonJS({
18769
19310
  "../../node_modules/undici/lib/core/symbols.js"(exports2, module2) {
@@ -71422,6 +71963,21 @@ var require_ws = __commonJS({
71422
71963
  }
71423
71964
  });
71424
71965
 
71966
+ // ../core/src/sentry-config.ts
71967
+ var environment, SENTRY_CONFIG, FALLBACK_SENTRY_DSN;
71968
+ var init_sentry_config = __esm({
71969
+ "../core/src/sentry-config.ts"() {
71970
+ "use strict";
71971
+ environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
71972
+ SENTRY_CONFIG = {
71973
+ projectName: "okx/openclaw-okx-a2a-extension",
71974
+ release: "0.1.7",
71975
+ environment
71976
+ };
71977
+ FALLBACK_SENTRY_DSN = "https://e20ff987c945887733de9ec6cca87aba@sentry.coinall.ltd/apmfe/70295";
71978
+ }
71979
+ });
71980
+
71425
71981
  // src/win-native-launcher.ts
71426
71982
  var win_native_launcher_exports = {};
71427
71983
  __export(win_native_launcher_exports, {
@@ -72344,7 +72900,7 @@ async function getCurrentNodeCliVersion() {
72344
72900
  return await getGlobalNpmPackageVersion(UPDATE_PACKAGES.node) ?? getBundledNodeCliVersion();
72345
72901
  }
72346
72902
  function getBundledNodeCliVersion() {
72347
- return true ? "0.1.6" : null;
72903
+ return true ? "0.1.7" : null;
72348
72904
  }
72349
72905
  function readConfiguredAiProvider() {
72350
72906
  const explicit = process.env.OKX_A2A_AI_PROVIDER || process.env.OKX_AGENT_TASK_AI_CLI;
@@ -72554,7 +73110,7 @@ async function updateHermes(release, options) {
72554
73110
  }
72555
73111
  }
72556
73112
  async function installGatewayPluginForDoctor(target) {
72557
- const release = isPrereleaseVersion("0.1.6") ? "beta" : "latest";
73113
+ const release = isPrereleaseVersion("0.1.7") ? "beta" : "latest";
72558
73114
  const insideTargetGateway = detectGatewayInvocation() === target;
72559
73115
  const options = {
72560
73116
  restart: !insideTargetGateway,
@@ -73319,6 +73875,106 @@ var init_update_cli = __esm({
73319
73875
  }
73320
73876
  });
73321
73877
 
73878
+ // src/doctor-sentry.ts
73879
+ var doctor_sentry_exports = {};
73880
+ __export(doctor_sentry_exports, {
73881
+ buildDoctorSentryExtra: () => buildDoctorSentryExtra,
73882
+ reportDoctorCrashToSentry: () => reportDoctorCrashToSentry,
73883
+ reportDoctorRunToSentry: () => reportDoctorRunToSentry
73884
+ });
73885
+ function initDoctorSentry() {
73886
+ if (sentryReady) {
73887
+ return true;
73888
+ }
73889
+ try {
73890
+ const dsn = process.env.OKX_A2A_SENTRY_DSN?.trim() || process.env.SENTRY_DSN?.trim() || FALLBACK_SENTRY_DSN;
73891
+ initLogger({
73892
+ dsn,
73893
+ ...SENTRY_CONFIG,
73894
+ agentPlatform: "node"
73895
+ });
73896
+ sentryReady = true;
73897
+ return true;
73898
+ } catch {
73899
+ return false;
73900
+ }
73901
+ }
73902
+ function buildDoctorSentryExtra(report, meta) {
73903
+ const failedDetails = report.checks.filter((check) => check.status === "fail").map((check) => `${check.id}: ${check.detail}`.slice(0, 160)).join(" | ").slice(0, 900);
73904
+ return {
73905
+ component: "node_direct_cli",
73906
+ source: "direct_cli",
73907
+ operation: "doctor",
73908
+ communicationClass: "node_cli_or_daemon_issue",
73909
+ fixMode: String(meta.fix),
73910
+ nonInteractive: String(meta.nonInteractive),
73911
+ durationMs: String(meta.durationMs),
73912
+ ready: String(report.ready),
73913
+ state: report.state,
73914
+ target: report.target,
73915
+ platform: report.platform,
73916
+ cliVersion: report.cliVersion,
73917
+ blockingFailures: String(report.blockingFailures),
73918
+ checks: report.checks.map((check) => `${check.id}=${check.status}`).join(";"),
73919
+ fixesApplied: report.fixesApplied.map((fixEntry) => `${fixEntry.checkId}=${fixEntry.applied}`).join(";"),
73920
+ ...failedDetails ? { failedDetails } : {},
73921
+ ...report.upgraded ? { upgradedFrom: report.upgraded.from, upgradedTo: report.upgraded.to } : {}
73922
+ };
73923
+ }
73924
+ async function reportDoctorRunToSentry(report, meta) {
73925
+ try {
73926
+ if (!initDoctorSentry()) {
73927
+ return;
73928
+ }
73929
+ const extra = buildDoctorSentryExtra(report, meta);
73930
+ logger.info(LogEvent.DOCTOR_REPORT, extra);
73931
+ if (!report.ready) {
73932
+ const blocking = report.checks.filter((check) => check.status === "fail" && check.severity !== "recommended").map((check) => check.id).join(",");
73933
+ logger.error(
73934
+ LogEvent.DOCTOR_NOT_READY,
73935
+ new Error(`doctor not ready: ${blocking || report.state}`),
73936
+ extra
73937
+ );
73938
+ }
73939
+ await flushBounded();
73940
+ } catch {
73941
+ }
73942
+ }
73943
+ async function reportDoctorCrashToSentry(error, meta) {
73944
+ try {
73945
+ if (!initDoctorSentry()) {
73946
+ return;
73947
+ }
73948
+ logger.error(LogEvent.DOCTOR_CRASHED, error instanceof Error ? error : new Error(String(error)), {
73949
+ component: "node_direct_cli",
73950
+ source: "direct_cli",
73951
+ operation: "doctor",
73952
+ communicationClass: "node_cli_or_daemon_issue",
73953
+ fixMode: String(meta.fix),
73954
+ nonInteractive: String(meta.nonInteractive),
73955
+ durationMs: String(meta.durationMs)
73956
+ });
73957
+ await flushBounded();
73958
+ } catch {
73959
+ }
73960
+ }
73961
+ async function flushBounded() {
73962
+ const timeout = new Promise((resolvePromise) => {
73963
+ const timer = setTimeout(() => resolvePromise(), 1500);
73964
+ timer.unref?.();
73965
+ });
73966
+ await Promise.race([shutdown().then(() => void 0), timeout]);
73967
+ }
73968
+ var sentryReady;
73969
+ var init_doctor_sentry = __esm({
73970
+ "src/doctor-sentry.ts"() {
73971
+ "use strict";
73972
+ init_sentry_config();
73973
+ init_sentry_logger();
73974
+ sentryReady = false;
73975
+ }
73976
+ });
73977
+
73322
73978
  // src/index.ts
73323
73979
  var index_exports = {};
73324
73980
  __export(index_exports, {
@@ -73359,6 +74015,7 @@ __export(index_exports, {
73359
74015
  buildAutostartVbs: () => buildAutostartVbs,
73360
74016
  buildBackupJobSessionKey: () => buildBackupJobSessionKey,
73361
74017
  buildDispatchSessionKey: () => buildDispatchSessionKey,
74018
+ buildDoctorSentryExtra: () => buildDoctorSentryExtra,
73362
74019
  buildExternalCommandInvocation: () => buildExternalCommandInvocation,
73363
74020
  buildLauncherEntryJs: () => buildLauncherEntryJs,
73364
74021
  buildPendingConversationBackupDispatch: () => buildPendingConversationBackupDispatch,
@@ -73436,6 +74093,7 @@ __export(index_exports, {
73436
74093
  refreshAgentsAndWait: () => refreshAgentsAndWait,
73437
74094
  registerUserAttentionWatcher: () => registerUserAttentionWatcher,
73438
74095
  removeUserAttentionWatcher: () => removeUserAttentionWatcher,
74096
+ reportDoctorRunToSentry: () => reportDoctorRunToSentry,
73439
74097
  resolveAiPermissionPreset: () => resolveAiPermissionPreset,
73440
74098
  resolveAiProviderCommand: () => resolveAiProviderCommand,
73441
74099
  resolveAiProviderForDispatch: () => resolveAiProviderForDispatch,
@@ -73885,529 +74543,8 @@ function escapeRegExp(value) {
73885
74543
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
73886
74544
  }
73887
74545
 
73888
- // ../core/src/sentry-logger/index.ts
73889
- init_log();
73890
- var Sentry = __toESM(require_cjs4());
73891
- var import_node_crypto2 = require("node:crypto");
73892
-
73893
- // ../core/src/sentry-logger/events.ts
73894
- var LogEvent = {
73895
- // ── info ──────────────────────────────────────────────────────
73896
- GATEWAY_STARTED: "Gateway started",
73897
- GATEWAY_STOPPED: "Gateway stopped",
73898
- BOOTSTRAP_APPLIED: "Bootstrap applied",
73899
- CHANNEL_READY: "Channel ready",
73900
- CONVERSATION_STARTED: "Conversation started",
73901
- EVALUATE_CONVERSATION_STARTED: "Evaluate conversation started",
73902
- CONVERSATION_DELETED: "Conversation deleted",
73903
- PENDING_CONVERSATION_DENIED: "Pending conversation denied",
73904
- AGENTS_REFRESHED: "Agents refreshed",
73905
- USER_DISPATCHED: "User dispatched",
73906
- SESSION_DISPATCHED: "Session dispatched",
73907
- SYNC_TICK_COMPLETED: "Sync tick completed",
73908
- INBOUND_HANDLER_ENTERED: "Inbound handler entered",
73909
- MESSAGE_RECEIVED: "Message received",
73910
- MESSAGE_SENT: "Message sent",
73911
- INBOUND_BUYER_PENDING: "Inbound buyer: no session, group still Unknown (pending)",
73912
- INBOUND_BUYER_SESSION_AUTO_RECOVERED: "Inbound buyer: session missing for Allowed group, auto-recovered",
73913
- INBOUND_BLOCKED_SENSITIVE: "Inbound blocked: sensitive word; reply sent",
73914
- INBOUND_BLOCKED_ADDRESS_MISMATCH: "Inbound blocked: address mismatch",
73915
- INBOUND_BLOCKED_INELIGIBLE: "Inbound blocked: message-eligible check failed",
73916
- INBOUND_DROP_EMPTY_CONTENT: "Inbound drop: empty content",
73917
- INBOUND_DROP_MISSING_JOBID: "Inbound drop: missing jobId",
73918
- INBOUND_DROP_UNSUPPORTED_MSGTYPE: "Inbound drop: unsupported msgType",
73919
- INBOUND_DROP_DM_NON_SYSTEM: "Inbound drop: DM sender not in system whitelist",
73920
- INBOUND_DROP_DM_INVALID_PAYLOAD: "Inbound drop: DM payload invalid",
73921
- INBOUND_DROP_DM_UNKNOWN_AGENT: "Inbound drop: DM target agent not local",
73922
- DM_FALLBACK_TO_BACKUP: "DM fallback to backup session",
73923
- DM_WHITELIST_FAIL_OPEN: "DM whitelist fail-open (empty system accounts)",
73924
- FILE_UPLOADED: "File uploaded",
73925
- FILE_DOWNLOADED: "File downloaded",
73926
- PENDING_LIST_QUERIED: "Pending list queried",
73927
- AGENT_LIST_QUERIED: "Agent list queried",
73928
- SESSION_KEY_DERIVED: "Session key derived",
73929
- CONVERSATION_HISTORY_QUERIED: "Conversation history queried",
73930
- SESSIONS_QUERIED: "Sessions queried",
73931
- GROUP_CONSENT_CHANGED: "Group consent changed",
73932
- SESSION_CREATED: "Session created",
73933
- SESSION_DELETED: "Session deleted",
73934
- SESSION_AUTO_RECOVERED: "Session auto-recovered",
73935
- INBOUND_DELIVERED: "Inbound delivered to session",
73936
- DM_DELIVERED: "DM delivered to session",
73937
- OUTBOUND_ELIGIBILITY_CHECKED: "Outbound eligibility checked",
73938
- AGENT_CLIENT_CREATED: "Agent client created",
73939
- AGENT_CLIENT_REMOVED: "Agent client removed",
73940
- ADDRESS_SYNC_COMPLETED: "Address sync completed",
73941
- AGENT_REFRESH_SESSION_EXPIRED: "Agent refresh aborted: onchainos session expired, local clients taken offline",
73942
- OFFLINE_REPLAY_MESSAGE_REPLAYED: "Offline replay message replayed",
73943
- AGENTS_WAKEUP_NOTIFIED: "Agents wakeup notified",
73944
- CONFIG_SENSITIVE_WORDS_REFRESHED: "Sensitive words config refreshed",
73945
- CONFIG_SYSTEM_REFRESHED: "System config refreshed",
73946
- GATEWAY_DISCONNECTED: "Gateway disconnected",
73947
- GATEWAY_REQUEST: "Gateway request",
73948
- GATEWAY_DELIVERY_BUFFERED: "Gateway delivery buffered",
73949
- DAEMON_LIFECYCLE_SKIPPED: "Daemon lifecycle skipped",
73950
- DAEMON_LIFECYCLE_REQUESTED: "Daemon lifecycle requested",
73951
- PROMPT_USER_CHECKPOINT: "Prompt user checkpoint",
73952
- USER_WATCH_STARTED: "User watch started",
73953
- USER_WATCH_EVENT_DELIVERED: "User watch event delivered",
73954
- INBOUND_DM_RAW: "Inbound DM raw",
73955
- INBOUND_GROUP_RAW: "Inbound group raw",
73956
- SYSTEM_NOTIFICATION_RECEIVED: "System notification received",
73957
- SYSTEM_NOTIFICATION_ROUTED: "System notification routed",
73958
- HERMES_SESSION_ROUTE_BINDING: "Hermes session route binding",
73959
- // ── error ─────────────────────────────────────────────────────
73960
- XMTP_CONNECTION_FAILED: "XMTP connection failed",
73961
- CONVERSATIONS_STREAM_FAILED: "conversations.stream failed",
73962
- AGENT_START_FAILED: "agent.start failed",
73963
- AGENT_STREAM_ERROR: "agent stream error",
73964
- BOOTSTRAP_FAILED: "Bootstrap failed",
73965
- ONCHAINOS_SESSION_EXPIRED: "Onchainos session expired",
73966
- ONCHAINOS_CLI_ERROR: "Onchainos CLI error",
73967
- HEARTBEAT_FAILED: "Heartbeat failed",
73968
- HEARTBEAT_SKIPPED: "Heartbeat skipped",
73969
- HEARTBEAT_GATEWAY_CHECK_FAILED: "Heartbeat gateway check failed",
73970
- MESSAGE_PARSE_FAILED: "Message parse failed",
73971
- MESSAGE_HANDLER_ERROR: "Message handler error",
73972
- OFFLINE_REPLAY_FAILED: "Offline replay failed",
73973
- INBOUND_ROUTING_FAILED: "Inbound routing failed",
73974
- CONVERSATION_NOT_FOUND: "Conversation not found for send",
73975
- XMTP_SEND_FAILED: "XMTP send failed",
73976
- AGENT_REFRESH_FAILED: "Agent refresh failed",
73977
- GROUP_CONSENT_UPDATE_FAILED: "Group consent update failed",
73978
- TOOL_EXECUTE_FAILED: "Tool execute failed",
73979
- AGENT_RESOLUTION_FAILED: "Agent resolution failed",
73980
- USER_DISPATCH_FAILED: "User dispatch failed",
73981
- INBOUND_ELIGIBILITY_BYPASSED: "Inbound eligibility bypassed",
73982
- INBOUND_ADDRESS_CHECK_FAILED: "Inbound address check failed",
73983
- INBOUND_ADDRESS_CHECK_BYPASSED: "Inbound address check bypassed",
73984
- INBOUND_SENSITIVE_CHECK_FAILED: "Inbound sensitive check failed",
73985
- FILE_UPLOAD_FAILED: "File upload failed",
73986
- FILE_DOWNLOAD_FAILED: "File download failed",
73987
- OFFLINE_REPLAY_MESSAGE_FAILED: "Offline replay message failed",
73988
- PENDING_NOTIFICATION_FAILED: "Pending notification failed",
73989
- GATEWAY_CONNECT_FAILED: "Gateway connect failed",
73990
- GATEWAY_REQUEST_FAILED: "Gateway request failed",
73991
- PROMPT_USER_FAILED: "Prompt user failed",
73992
- DAEMON_COMMAND_FAILED: "Daemon command failed",
73993
- DAEMON_COMMAND_TIMEOUT: "Daemon command timeout",
73994
- DAEMON_COMMAND_STALE: "Daemon command stale",
73995
- DAEMON_LIFECYCLE_FAILED: "Daemon lifecycle failed",
73996
- DAEMON_TICK_FAILED: "Daemon tick failed",
73997
- DIRECT_CLI_FAILED: "Direct CLI failed",
73998
- AI_RUN_FAILED: "AI run failed",
73999
- AI_RUN_TIMEOUT: "AI run timeout",
74000
- AI_RUN_TOOL_FAILED: "AI run tool failed",
74001
- IPC_FAILED: "IPC failed",
74002
- NOTIFY_AGENTS_WAKEUP_FAILED: "Notify agents wakeup failed",
74003
- OUTBOUND_AGENT_LOOKUP_FAILED: "Outbound agent lookup failed",
74004
- OUTBOUND_ELIGIBILITY_CHECK_FAILED: "Outbound eligibility check failed",
74005
- OUTBOUND_ELIGIBILITY_BYPASSED: "Outbound eligibility bypassed",
74006
- OUTBOUND_BLOCKED_INELIGIBLE: "Outbound blocked: message-eligible check failed",
74007
- CACHE_LOAD_FAILED: "Cache load failed",
74008
- CACHE_WRITE_FAILED: "Cache write failed",
74009
- CONFIG_LOAD_FAILED: "Config load failed",
74010
- SENTRY_INIT_SKIPPED: "Sentry init skipped",
74011
- AGENT_DB_DIR_CREATE_FAILED: "Agent DB dir create failed"
74012
- };
74013
-
74014
- // ../core/src/sentry-logger/index.ts
74015
- var FLOW_ID = (0, import_node_crypto2.randomUUID)();
74016
- var SENTRY_EXTRA_BLOCKLIST = /* @__PURE__ */ new Set([
74017
- "args",
74018
- "apikey",
74019
- "argv",
74020
- "auth",
74021
- "authorization",
74022
- "authtoken",
74023
- "bearer",
74024
- "body",
74025
- "cache",
74026
- "command",
74027
- "content",
74028
- "credential",
74029
- "credentials",
74030
- "cwd",
74031
- "data",
74032
- "error",
74033
- "failures",
74034
- "filename",
74035
- "file_name",
74036
- "filepath",
74037
- "file_path",
74038
- "headers",
74039
- "input",
74040
- "logpath",
74041
- "message",
74042
- "output",
74043
- "password",
74044
- "params",
74045
- "path",
74046
- "payload",
74047
- "privatekey",
74048
- "prompt",
74049
- "raw",
74050
- "rawevent",
74051
- "rawtext",
74052
- "request",
74053
- "response",
74054
- "accesstoken",
74055
- "refreshtoken",
74056
- "digest",
74057
- "nonce",
74058
- "salt",
74059
- "secret",
74060
- "token",
74061
- "stderr",
74062
- "stdout",
74063
- "title",
74064
- "tooloutput"
74065
- ]);
74066
- var SENTRY_EXTRA_BLOCKED_KEY_PARTS = [
74067
- "accesstoken",
74068
- "apikey",
74069
- "authorization",
74070
- "authtoken",
74071
- "content",
74072
- "credential",
74073
- "filepath",
74074
- "logpath",
74075
- "outputpath",
74076
- "password",
74077
- "payload",
74078
- "privatekey",
74079
- "prompt",
74080
- "rawevent",
74081
- "rawtext",
74082
- "refreshtoken",
74083
- "requestbody",
74084
- "responsebody",
74085
- "secret",
74086
- "stderr",
74087
- "stdout",
74088
- "token",
74089
- "tooloutput"
74090
- ];
74091
- var SENTRY_FULL_STRING_EXTRA_KEYS = /* @__PURE__ */ new Set([
74092
- "onchainosagentlistresultjson",
74093
- "onchainosagentlistdiagnostictext"
74094
- ]);
74095
- var SENTRY_TAG_KEYS = /* @__PURE__ */ new Set([
74096
- "agentPlatform",
74097
- "cacheName",
74098
- "checkpoint",
74099
- "code",
74100
- "communicationClass",
74101
- "component",
74102
- "eventName",
74103
- "exitCode",
74104
- "kind",
74105
- "method",
74106
- "onchainosAgentId",
74107
- "operation",
74108
- "phase",
74109
- "platform",
74110
- "provider",
74111
- "reason",
74112
- "role",
74113
- "source",
74114
- "stage",
74115
- "status",
74116
- "subcommand",
74117
- "taskId",
74118
- "type"
74119
- ]);
74120
- var SENTRY_FINGERPRINT_KEYS = [
74121
- "eventName",
74122
- "cacheName",
74123
- "checkpoint",
74124
- "component",
74125
- "method",
74126
- "operation",
74127
- "phase",
74128
- "reason",
74129
- "code",
74130
- "provider",
74131
- "type",
74132
- "kind",
74133
- "status",
74134
- "subcommand"
74135
- ];
74136
- var SENTRY_INFO_ALLOWLIST = /* @__PURE__ */ new Set([
74137
- LogEvent.GATEWAY_STARTED,
74138
- LogEvent.GATEWAY_STOPPED,
74139
- LogEvent.GATEWAY_DISCONNECTED,
74140
- LogEvent.GATEWAY_REQUEST,
74141
- LogEvent.GATEWAY_DELIVERY_BUFFERED,
74142
- LogEvent.DAEMON_LIFECYCLE_SKIPPED,
74143
- LogEvent.DAEMON_LIFECYCLE_REQUESTED,
74144
- LogEvent.PROMPT_USER_CHECKPOINT,
74145
- LogEvent.USER_WATCH_STARTED,
74146
- LogEvent.USER_WATCH_EVENT_DELIVERED,
74147
- LogEvent.CHANNEL_READY,
74148
- LogEvent.CONVERSATION_STARTED,
74149
- LogEvent.EVALUATE_CONVERSATION_STARTED,
74150
- LogEvent.CONVERSATION_DELETED,
74151
- LogEvent.USER_DISPATCHED,
74152
- LogEvent.SESSION_DISPATCHED,
74153
- LogEvent.SESSION_CREATED,
74154
- LogEvent.SESSION_DELETED,
74155
- LogEvent.SESSION_AUTO_RECOVERED,
74156
- LogEvent.INBOUND_DELIVERED,
74157
- LogEvent.INBOUND_DM_RAW,
74158
- LogEvent.INBOUND_GROUP_RAW,
74159
- LogEvent.SYSTEM_NOTIFICATION_RECEIVED,
74160
- LogEvent.SYSTEM_NOTIFICATION_ROUTED,
74161
- LogEvent.HERMES_SESSION_ROUTE_BINDING,
74162
- LogEvent.INBOUND_BLOCKED_ADDRESS_MISMATCH,
74163
- LogEvent.INBOUND_BLOCKED_INELIGIBLE,
74164
- LogEvent.INBOUND_BLOCKED_SENSITIVE,
74165
- LogEvent.INBOUND_DROP_DM_INVALID_PAYLOAD,
74166
- LogEvent.INBOUND_DROP_DM_NON_SYSTEM,
74167
- LogEvent.INBOUND_DROP_DM_UNKNOWN_AGENT,
74168
- LogEvent.INBOUND_DROP_EMPTY_CONTENT,
74169
- LogEvent.INBOUND_DROP_MISSING_JOBID,
74170
- LogEvent.INBOUND_DROP_UNSUPPORTED_MSGTYPE,
74171
- LogEvent.DM_DELIVERED,
74172
- LogEvent.DM_FALLBACK_TO_BACKUP,
74173
- LogEvent.DM_WHITELIST_FAIL_OPEN,
74174
- LogEvent.INBOUND_BUYER_PENDING,
74175
- LogEvent.INBOUND_BUYER_SESSION_AUTO_RECOVERED,
74176
- LogEvent.MESSAGE_SENT,
74177
- LogEvent.AGENT_CLIENT_CREATED,
74178
- LogEvent.AGENT_CLIENT_REMOVED,
74179
- LogEvent.ADDRESS_SYNC_COMPLETED,
74180
- LogEvent.AGENTS_REFRESHED,
74181
- LogEvent.AGENTS_WAKEUP_NOTIFIED,
74182
- LogEvent.AGENT_LIST_QUERIED,
74183
- LogEvent.BOOTSTRAP_APPLIED,
74184
- LogEvent.CONFIG_SENSITIVE_WORDS_REFRESHED,
74185
- LogEvent.CONFIG_SYSTEM_REFRESHED,
74186
- LogEvent.CONVERSATION_HISTORY_QUERIED,
74187
- LogEvent.FILE_DOWNLOADED,
74188
- LogEvent.FILE_UPLOADED,
74189
- LogEvent.GROUP_CONSENT_CHANGED,
74190
- LogEvent.INBOUND_HANDLER_ENTERED,
74191
- LogEvent.MESSAGE_RECEIVED,
74192
- LogEvent.OFFLINE_REPLAY_MESSAGE_REPLAYED,
74193
- LogEvent.AGENT_REFRESH_SESSION_EXPIRED,
74194
- LogEvent.OUTBOUND_ELIGIBILITY_CHECKED,
74195
- LogEvent.OUTBOUND_BLOCKED_INELIGIBLE,
74196
- LogEvent.PENDING_CONVERSATION_DENIED,
74197
- LogEvent.PENDING_LIST_QUERIED,
74198
- LogEvent.SESSION_KEY_DERIVED,
74199
- LogEvent.SESSIONS_QUERIED,
74200
- LogEvent.SYNC_TICK_COMPLETED
74201
- ]);
74202
- var MAX_EXTRA_STRING_LENGTH = 256;
74203
- var MAX_TAG_VALUE_LENGTH = 128;
74204
- var SentryLogger = class _SentryLogger {
74205
- static instance;
74206
- initialized = false;
74207
- buffer = [];
74208
- constructor() {
74209
- }
74210
- static getInstance() {
74211
- if (!_SentryLogger.instance) {
74212
- _SentryLogger.instance = new _SentryLogger();
74213
- }
74214
- return _SentryLogger.instance;
74215
- }
74216
- init(config) {
74217
- if (this.initialized) {
74218
- warnWithTimestamp("[logger] Already initialized, skipping.");
74219
- return;
74220
- }
74221
- try {
74222
- Sentry.init({
74223
- dsn: config.dsn,
74224
- release: config.release,
74225
- environment: config.environment,
74226
- maxBreadcrumbs: 0,
74227
- beforeBreadcrumb: () => null,
74228
- isInner: false
74229
- });
74230
- Sentry.setTags({
74231
- projectName: config.projectName,
74232
- agentPlatform: config.agentPlatform
74233
- });
74234
- } catch {
74235
- return;
74236
- }
74237
- this.initialized = true;
74238
- this.flush();
74239
- }
74240
- info(message, extra) {
74241
- const extraWithFlow = _SentryLogger.sanitizeExtra({ flowId: FLOW_ID, ...extra ?? {} });
74242
- if (!SENTRY_INFO_ALLOWLIST.has(message)) {
74243
- return;
74244
- }
74245
- if (!this.initialized) {
74246
- this.buffer.push({ level: "info", message, extra: extraWithFlow });
74247
- return;
74248
- }
74249
- try {
74250
- Sentry.withScope((scope) => {
74251
- _SentryLogger.applyDiagnostics(scope, message, extraWithFlow);
74252
- Sentry.captureEvent({
74253
- level: "info",
74254
- message,
74255
- extra: {
74256
- ...extraWithFlow,
74257
- eventName: message
74258
- }
74259
- });
74260
- });
74261
- } catch {
74262
- }
74263
- }
74264
- error(message, error, extra) {
74265
- const extraWithFlow = _SentryLogger.sanitizeExtra({ flowId: FLOW_ID, ...extra ?? {} });
74266
- if (!this.initialized) {
74267
- this.buffer.push({
74268
- level: "error",
74269
- message,
74270
- error,
74271
- extra: extraWithFlow
74272
- });
74273
- return;
74274
- }
74275
- try {
74276
- Sentry.withScope((scope) => {
74277
- scope.setLevel("error");
74278
- _SentryLogger.applyDiagnostics(scope, message, extraWithFlow);
74279
- Sentry.captureException(_SentryLogger.createSentryEvent(message), {
74280
- extra: error ? {
74281
- ...extraWithFlow,
74282
- eventName: message,
74283
- errorName: error.name,
74284
- errorMessageLength: String(error.message.length)
74285
- } : extraWithFlow
74286
- });
74287
- });
74288
- } catch {
74289
- }
74290
- }
74291
- async shutdown() {
74292
- try {
74293
- await Sentry.close(5e3);
74294
- } catch {
74295
- await Sentry.flush(5e3);
74296
- }
74297
- }
74298
- flush() {
74299
- while (this.buffer.length > 0) {
74300
- const entry = this.buffer.shift();
74301
- if (entry.level === "info") {
74302
- this.info(entry.message, entry.extra);
74303
- } else {
74304
- this.error(entry.message, entry.error, entry.extra);
74305
- }
74306
- }
74307
- }
74308
- static sanitizeExtra(extra) {
74309
- return Object.fromEntries(
74310
- Object.entries(extra).filter(([, value]) => value !== void 0).filter(([key]) => !_SentryLogger.isBlockedExtraKey(key)).map(([key, value]) => [key, _SentryLogger.safeValueForKey(key, value)])
74311
- );
74312
- }
74313
- static isBlockedExtraKey(key) {
74314
- const lower = key.toLowerCase();
74315
- const normalized = _SentryLogger.normalizeSensitiveKey(key);
74316
- if (SENTRY_EXTRA_BLOCKLIST.has(lower) || SENTRY_EXTRA_BLOCKLIST.has(normalized)) {
74317
- return true;
74318
- }
74319
- if (_SentryLogger.isSafeMetricKey(normalized)) {
74320
- return false;
74321
- }
74322
- return SENTRY_EXTRA_BLOCKED_KEY_PARTS.some((needle) => normalized.includes(needle));
74323
- }
74324
- static isSafeMetricKey(normalized) {
74325
- return /(bytes|count|length|ms|size)$/.test(normalized);
74326
- }
74327
- static safeValueForKey(key, value) {
74328
- if (typeof value === "string" && SENTRY_FULL_STRING_EXTRA_KEYS.has(_SentryLogger.normalizeSensitiveKey(key))) {
74329
- return value;
74330
- }
74331
- return _SentryLogger.safeValue(value);
74332
- }
74333
- static normalizeSensitiveKey(key) {
74334
- return key.toLowerCase().replace(/[^a-z0-9]/g, "");
74335
- }
74336
- static safeValue(value) {
74337
- if (typeof value === "string") {
74338
- return value.length <= MAX_EXTRA_STRING_LENGTH ? value : `${value.slice(0, MAX_EXTRA_STRING_LENGTH)}...`;
74339
- }
74340
- if (value === null || value === void 0 || typeof value === "number" || typeof value === "boolean") {
74341
- return value;
74342
- }
74343
- if (typeof value === "bigint") {
74344
- return value.toString();
74345
- }
74346
- if (value instanceof Error) {
74347
- return {
74348
- name: value.name,
74349
- messageLength: value.message.length
74350
- };
74351
- }
74352
- if (Array.isArray(value)) {
74353
- return value.slice(0, 20).map((item) => _SentryLogger.safeValue(item));
74354
- }
74355
- if (typeof value === "object") {
74356
- return Object.fromEntries(
74357
- Object.entries(value).slice(0, 50).filter(([, item]) => item !== void 0).filter(([key]) => !_SentryLogger.isBlockedExtraKey(key)).map(([key, item]) => [key, _SentryLogger.safeValueForKey(key, item)])
74358
- );
74359
- }
74360
- const text = String(value);
74361
- return text.length <= MAX_EXTRA_STRING_LENGTH ? text : `${text.slice(0, MAX_EXTRA_STRING_LENGTH)}...`;
74362
- }
74363
- static tagValue(value) {
74364
- const text = String(value);
74365
- return text.length <= MAX_TAG_VALUE_LENGTH ? text : `${text.slice(0, MAX_TAG_VALUE_LENGTH)}...`;
74366
- }
74367
- static normalizeTagKey(key) {
74368
- return key.replace(/[^A-Za-z0-9_.:-]+/g, "_").slice(0, 32) || "unknown";
74369
- }
74370
- static applyDiagnostics(scope, eventName, extra) {
74371
- const enriched = { eventName, ...extra };
74372
- for (const [key, value] of Object.entries(enriched)) {
74373
- if (!SENTRY_TAG_KEYS.has(key)) {
74374
- continue;
74375
- }
74376
- scope.setTag(_SentryLogger.normalizeTagKey(key), _SentryLogger.tagValue(value));
74377
- }
74378
- const fingerprint = ["a2a", eventName];
74379
- for (const key of SENTRY_FINGERPRINT_KEYS) {
74380
- const value = enriched[key];
74381
- if (value) {
74382
- fingerprint.push(`${key}:${_SentryLogger.tagValue(value)}`);
74383
- }
74384
- }
74385
- scope.setFingerprint(fingerprint);
74386
- }
74387
- static toPascalCase(str) {
74388
- return str.split(/[\s:]+/).filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
74389
- }
74390
- static createSentryEvent(eventName) {
74391
- const err2 = new Error(eventName);
74392
- err2.name = _SentryLogger.toPascalCase(eventName);
74393
- err2.stack = `${err2.name}: ${eventName}`;
74394
- return err2;
74395
- }
74396
- };
74397
- var logger = SentryLogger.getInstance();
74398
- var initLogger = (config) => {
74399
- return logger.init(config);
74400
- };
74401
- var UNKNOWN_FIELD = "unknown";
74402
- function agentExtras(identity3) {
74403
- return {
74404
- walletAddress: identity3.walletAddress || UNKNOWN_FIELD,
74405
- inboxId: identity3.inboxId || UNKNOWN_FIELD,
74406
- onchainosAgentId: identity3.onchainosAgentId || UNKNOWN_FIELD
74407
- };
74408
- }
74409
-
74410
74546
  // src/ai-adapter.ts
74547
+ init_sentry_logger();
74411
74548
  init_win_spawn();
74412
74549
  var CLAUDE_ALLOWED_TOOLS = [
74413
74550
  "Read",
@@ -74996,6 +75133,7 @@ function isChangedEventLine(line) {
74996
75133
  }
74997
75134
 
74998
75135
  // src/ai-runner.ts
75136
+ init_sentry_logger();
74999
75137
  function aiRunSentryExtra(input) {
75000
75138
  const entries = Object.entries({
75001
75139
  component: "node_ai_runner",
@@ -79761,6 +79899,9 @@ var Client = class _Client {
79761
79899
  }
79762
79900
  };
79763
79901
 
79902
+ // ../core/src/xmtp-sdk/index.ts
79903
+ init_sentry_logger();
79904
+
79764
79905
  // ../core/src/xmtp-sdk/extract-job-id.ts
79765
79906
  function extractJobIdFromContent(content3) {
79766
79907
  const raw = typeof content3 === "string" ? content3 : JSON.stringify(content3) ?? "";
@@ -79808,6 +79949,7 @@ function selfFilterMiddleware() {
79808
79949
 
79809
79950
  // ../core/src/xmtp-sdk/middleware/logging.ts
79810
79951
  init_log();
79952
+ init_sentry_logger();
79811
79953
 
79812
79954
  // ../core/src/xmtp-sdk/inbound-timing.ts
79813
79955
  function createInboundTimingTracker(xmtpSentAtMs, xmtpReceivedAtMs = Date.now()) {
@@ -87658,7 +87800,8 @@ var XmtpService = class _XmtpService {
87658
87800
  const identity3 = {
87659
87801
  walletAddress: address,
87660
87802
  inboxId: agent.client?.inboxId,
87661
- onchainosAgentId: onchainosAgent?.agentId
87803
+ onchainosAgentId: onchainosAgent?.agentId,
87804
+ role: onchainosAgent?.role
87662
87805
  };
87663
87806
  try {
87664
87807
  await agent.client.conversations.syncAll([
@@ -87889,12 +88032,16 @@ var XmtpService = class _XmtpService {
87889
88032
  ...agentExtras({
87890
88033
  walletAddress: address,
87891
88034
  inboxId: agent.client?.inboxId,
87892
- onchainosAgentId: this.getAgentByAddress(address)?.agentId
88035
+ onchainosAgentId: this.getAgentByAddress(address)?.agentId,
88036
+ role: this.getAgentByAddress(address)?.role
87893
88037
  }),
87894
88038
  ...jobIdExtras(msg.content),
87895
88039
  messageId: msg.id,
87896
88040
  conversationId: conv.id,
87897
- stage: "offlineReplay/handleMessage"
88041
+ stage: "offlineReplay/handleMessage",
88042
+ xmtpSentAtMs: String(msgSentMs),
88043
+ replayLagMs: String(Math.max(0, Date.now() - msgSentMs)),
88044
+ handleMs: String(handleMs)
87898
88045
  });
87899
88046
  } else {
87900
88047
  summary.skipped++;
@@ -88035,6 +88182,7 @@ function buildSendEnvelope(params) {
88035
88182
 
88036
88183
  // src/xmtp-send.ts
88037
88184
  init_log();
88185
+ init_sentry_logger();
88038
88186
  var import_node_crypto9 = require("node:crypto");
88039
88187
 
88040
88188
  // ../core/src/a2a/concurrency.ts
@@ -88063,6 +88211,7 @@ var import_node_fs12 = require("node:fs");
88063
88211
  var import_node_child_process4 = require("node:child_process");
88064
88212
  var import_node_path18 = require("node:path");
88065
88213
  var import_node_util = require("node:util");
88214
+ init_sentry_logger();
88066
88215
  init_win_compat();
88067
88216
  var execFileAsync = (0, import_node_util.promisify)(import_node_child_process4.execFile);
88068
88217
  var resolvedBin = null;
@@ -88312,7 +88461,11 @@ async function exec(args) {
88312
88461
  }
88313
88462
  }
88314
88463
 
88464
+ // ../core/src/xmtp-sdk/onchainos/index.ts
88465
+ init_sentry_logger();
88466
+
88315
88467
  // ../core/src/xmtp-sdk/onchainos/cli-response.ts
88468
+ init_sentry_logger();
88316
88469
  var CliErrorReason = {
88317
88470
  OK_FALSE: "ok_false",
88318
88471
  JSON_PARSE_FAILED: "json_parse_failed"
@@ -88362,6 +88515,7 @@ function parseCliJson(stdout, command, extras = {}) {
88362
88515
  }
88363
88516
 
88364
88517
  // ../core/src/xmtp-sdk/onchainos/session-expired.ts
88518
+ init_sentry_logger();
88365
88519
  var SESSION_EXPIRED_RE2 = /session expired/i;
88366
88520
  function isSessionExpired(stdout) {
88367
88521
  try {
@@ -88389,6 +88543,7 @@ function reportSessionExpired(command) {
88389
88543
 
88390
88544
  // ../core/src/xmtp-sdk/onchainos/system-config.ts
88391
88545
  init_log();
88546
+ init_sentry_logger();
88392
88547
  function notifyExpired(command, options) {
88393
88548
  if (options?.notifySessionExpired) {
88394
88549
  options.notifySessionExpired(command);
@@ -89404,7 +89559,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
89404
89559
  client: {
89405
89560
  id: "gateway-client",
89406
89561
  displayName: "okx-a2a-node",
89407
- version: "0.1.6",
89562
+ version: "0.1.7",
89408
89563
  platform: "node",
89409
89564
  mode: "backend",
89410
89565
  instanceId
@@ -89415,7 +89570,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
89415
89570
  commands: [],
89416
89571
  permissions: {},
89417
89572
  locale: Intl.DateTimeFormat().resolvedOptions().locale || "en-US",
89418
- userAgent: `okx-a2a-node/${"0.1.6"}`,
89573
+ userAgent: `okx-a2a-node/${"0.1.7"}`,
89419
89574
  auth: {
89420
89575
  ...config.token ? { token: config.token } : {},
89421
89576
  ...config.password ? { password: config.password } : {}
@@ -89934,6 +90089,7 @@ function safeDecode2(value) {
89934
90089
  }
89935
90090
 
89936
90091
  // src/outbound-behavior.ts
90092
+ init_sentry_logger();
89937
90093
  var SqliteOutboundBehavior = class {
89938
90094
  provider;
89939
90095
  store;
@@ -90710,6 +90866,23 @@ function stableHash2(value) {
90710
90866
  // src/xmtp-send.ts
90711
90867
  var TASK_MIN_VERSION = 1;
90712
90868
  var sqliteGroupSessionPromises = /* @__PURE__ */ new Map();
90869
+ function logXmtpMessageSent(params) {
90870
+ logger.info(LogEvent.MESSAGE_SENT, {
90871
+ component: params.component,
90872
+ stage: "outbound/xmtp_send",
90873
+ taskId: params.jobId,
90874
+ messageId: typeof params.xmtpMessageId === "string" && params.xmtpMessageId.length > 0 ? params.xmtpMessageId : "unknown",
90875
+ conversationId: params.conversationId,
90876
+ chatType: params.chatType,
90877
+ walletAddress: params.myXmtpAddress,
90878
+ toXmtpAddress: params.toXmtpAddress ?? "unknown",
90879
+ senderAgentId: params.senderAgentId ?? "unknown",
90880
+ toAgentId: params.toAgentId ?? "unknown",
90881
+ role: params.role != null && params.role !== "" ? String(params.role) : "unknown",
90882
+ xmtpSentAtMs: String(Date.now()),
90883
+ sendDurationMs: String(params.sendDurationMs)
90884
+ });
90885
+ }
90713
90886
  function isPlainObject(value) {
90714
90887
  return !!value && typeof value === "object" && !Array.isArray(value);
90715
90888
  }
@@ -91209,7 +91382,21 @@ async function handleSqliteGroupSendCommand(params) {
91209
91382
  payload: resolveEnvelopePayload(command, command.replyToMessageId)
91210
91383
  });
91211
91384
  logWithTimestamp(`[okx-agent-task] xmtp envelope ${rawText}`);
91212
- await conversation.send(rawText);
91385
+ const sendStartMs = Date.now();
91386
+ const xmtpMessageId = await conversation.send(rawText);
91387
+ logXmtpMessageSent({
91388
+ xmtpMessageId,
91389
+ conversationId: conversation.id,
91390
+ jobId: command.jobId,
91391
+ chatType: "group",
91392
+ component: "node_xmtp_send",
91393
+ myXmtpAddress,
91394
+ toXmtpAddress: remote.toXmtpAddress,
91395
+ senderAgentId: senderAgent?.agentId ?? command.myAgentId,
91396
+ toAgentId: remote.remoteAgent?.agentId ?? remote.toAgentId ?? command.toAgentId,
91397
+ role: senderAgent?.role,
91398
+ sendDurationMs: Date.now() - sendStartMs
91399
+ });
91213
91400
  const messageId = `outbound-${(0, import_node_crypto9.randomUUID)()}`;
91214
91401
  await notifyAgentMessageToUserAttention({
91215
91402
  direction: "outbound" /* OUTBOUND */,
@@ -91346,7 +91533,21 @@ async function handleGroupSendCommand(params) {
91346
91533
  payload: resolveEnvelopePayload(command, command.replyToMessageId)
91347
91534
  });
91348
91535
  logWithTimestamp(`[okx-agent-task] xmtp envelope ${rawText}`);
91349
- await conversation.send(rawText);
91536
+ const sendStartMs = Date.now();
91537
+ const xmtpMessageId = await conversation.send(rawText);
91538
+ logXmtpMessageSent({
91539
+ xmtpMessageId,
91540
+ conversationId: session.xmtpGroupId,
91541
+ jobId: command.jobId,
91542
+ chatType: "group",
91543
+ component: "node_xmtp_send",
91544
+ myXmtpAddress: session.myXmtpAddress,
91545
+ toXmtpAddress: session.toXmtpAddress,
91546
+ senderAgentId: senderAgent?.agentId ?? session.myAgentId,
91547
+ toAgentId: remoteAgent?.agentId ?? session.toAgentId,
91548
+ role: senderAgent?.role,
91549
+ sendDurationMs: Date.now() - sendStartMs
91550
+ });
91350
91551
  const now = Date.now();
91351
91552
  const messageId = `outbound-${(0, import_node_crypto9.randomUUID)()}`;
91352
91553
  const stored = {
@@ -91555,7 +91756,20 @@ async function handleXmtpSendCommand(params) {
91555
91756
  }
91556
91757
  const localAgent = service.getAgentByAddress(target.myXmtpAddress);
91557
91758
  const rawText = target.chatType === "group" ? buildGroupReplyRaw(command, target, target.myXmtpAddress, localAgent) : buildDmReplyRaw(command, target, localAgent?.agentId ?? null);
91558
- await conversation.send(rawText);
91759
+ const sendStartMs = Date.now();
91760
+ const xmtpMessageId = await conversation.send(rawText);
91761
+ logXmtpMessageSent({
91762
+ xmtpMessageId,
91763
+ conversationId: target.conversationId,
91764
+ jobId: command.jobId,
91765
+ chatType: target.chatType,
91766
+ component: "node_xmtp_send",
91767
+ myXmtpAddress: target.myXmtpAddress,
91768
+ toXmtpAddress: target.senderAddress,
91769
+ senderAgentId: localAgent?.agentId,
91770
+ role: localAgent?.role,
91771
+ sendDurationMs: Date.now() - sendStartMs
91772
+ });
91559
91773
  const now = Date.now();
91560
91774
  const messageId = `outbound-${(0, import_node_crypto9.randomUUID)()}`;
91561
91775
  const stored = {
@@ -91607,6 +91821,7 @@ async function handleXmtpSendCommand(params) {
91607
91821
  // src/command-processor.ts
91608
91822
  init_session_store();
91609
91823
  init_ai_provider();
91824
+ init_sentry_logger();
91610
91825
  var DEFAULT_COMMAND_EXECUTION_TIMEOUT_MS = 5e4;
91611
91826
  var DEFAULT_COMMAND_STALE_TIMEOUT_MS = 12e4;
91612
91827
  var DEFAULT_AI_COMMAND_STALE_TIMEOUT_MS = 30 * 6e4;
@@ -92093,7 +92308,21 @@ async function sendRejectContentToTarget(content3, target, params) {
92093
92308
  }
92094
92309
  });
92095
92310
  logWithTimestamp(`[okx-agent-task] task reject xmtp envelope ${rawText}`);
92096
- await conversation.send(rawText);
92311
+ const sendStartMs = Date.now();
92312
+ const xmtpMessageId = await conversation.send(rawText);
92313
+ logXmtpMessageSent({
92314
+ xmtpMessageId,
92315
+ conversationId: target.groupId,
92316
+ jobId,
92317
+ chatType: "group",
92318
+ component: "node_command_processor",
92319
+ myXmtpAddress: target.address,
92320
+ toXmtpAddress,
92321
+ senderAgentId: senderAgent?.agentId,
92322
+ toAgentId: receiverAgent?.agentId ?? target.toAgentId,
92323
+ role: senderAgent?.role,
92324
+ sendDurationMs: Date.now() - sendStartMs
92325
+ });
92097
92326
  }
92098
92327
  async function denyTargets(targets, params) {
92099
92328
  return await Promise.all(
@@ -92407,6 +92636,7 @@ function trimForUser2(value) {
92407
92636
  // src/message-handler.ts
92408
92637
  init_log();
92409
92638
  var import_node_crypto10 = require("node:crypto");
92639
+ init_sentry_logger();
92410
92640
  init_paths();
92411
92641
  init_session_store();
92412
92642
  init_ai_provider();
@@ -93218,7 +93448,7 @@ async function processFileMessage(ctx, deps, options = {}) {
93218
93448
  if (!providerGate.allowed) {
93219
93449
  return true;
93220
93450
  }
93221
- logger.info(LogEvent.SYSTEM_NOTIFICATION_RECEIVED, {
93451
+ logger.info(LogEvent.SYSTEM_NOTIFICATION_RECEIVED, timing.extras({
93222
93452
  ...agentExtras({ walletAddress: deps.myXmtpAddress, onchainosAgentId: systemNotification.agentId }),
93223
93453
  taskId: systemNotification.jobId ?? "",
93224
93454
  agentId: systemNotification.agentId ?? "",
@@ -93227,10 +93457,11 @@ async function processFileMessage(ctx, deps, options = {}) {
93227
93457
  messageId: systemMessageId,
93228
93458
  systemEvent: systemNotification.event ?? "",
93229
93459
  stage: "inbound/system_notification_received",
93460
+ source: options.source ?? "live",
93230
93461
  isDirectCommunication: String(systemNotification.isDirectCommunication),
93231
93462
  providerBinding: providerGate.provider ?? "",
93232
93463
  providerBindingCreated: String(providerGate.created)
93233
- });
93464
+ }));
93234
93465
  const routeResolveStartedAt = Date.now();
93235
93466
  const targets = directTarget ? [{
93236
93467
  sessionKey: directTarget.sessionKey,
@@ -93246,7 +93477,7 @@ async function processFileMessage(ctx, deps, options = {}) {
93246
93477
  );
93247
93478
  }
93248
93479
  const primaryTarget = targets[0];
93249
- logger.info(LogEvent.SYSTEM_NOTIFICATION_ROUTED, {
93480
+ logger.info(LogEvent.SYSTEM_NOTIFICATION_ROUTED, timing.extras({
93250
93481
  ...agentExtras({ walletAddress: deps.myXmtpAddress, onchainosAgentId: systemNotification.agentId }),
93251
93482
  taskId: systemNotification.jobId ?? "",
93252
93483
  agentId: primaryTarget?.agentId ?? systemNotification.agentId ?? "",
@@ -93258,8 +93489,9 @@ async function processFileMessage(ctx, deps, options = {}) {
93258
93489
  targetCount: String(targets.length),
93259
93490
  systemEvent: systemNotification.event ?? "",
93260
93491
  stage: "inbound/system_notification_routed",
93492
+ source: options.source ?? "live",
93261
93493
  isDirectCommunication: String(systemNotification.isDirectCommunication)
93262
- });
93494
+ }));
93263
93495
  if (!options.skipNotify) {
93264
93496
  maybeNotifyInboundAgentMessage({
93265
93497
  deps,
@@ -93590,7 +93822,7 @@ function processOfflineFromCoreDeps(store, ctx, deps, options) {
93590
93822
  allowGroup: deps.allowGroup,
93591
93823
  onJobMessageStored: options.onJobMessageStored,
93592
93824
  onSessionMessage: options.onSessionMessage
93593
- }, options);
93825
+ }, { ...options, source: "replay" });
93594
93826
  }
93595
93827
  function buildSystemStoredMessage(params) {
93596
93828
  const now = Date.now();
@@ -93623,6 +93855,7 @@ var import_node_path21 = require("node:path");
93623
93855
 
93624
93856
  // ../core/src/xmtp-sdk/onchainos/signer.ts
93625
93857
  init_log();
93858
+ init_sentry_logger();
93626
93859
  async function onchainosSign(agentId, keyUuid, walletAddress, message) {
93627
93860
  logWithTimestamp(
93628
93861
  `[onchainos-signer] executing: onchainos agent xmtp-sign --key-uuid ${keyUuid} --message <${message.length} chars>`
@@ -93757,6 +93990,7 @@ init_paths();
93757
93990
 
93758
93991
  // src/user-attention-watchers.ts
93759
93992
  var import_node_crypto11 = require("node:crypto");
93993
+ init_sentry_logger();
93760
93994
  var USER_ATTENTION_WATCH_REPLACED_MESSAGE = "Another okx-a2a user watch with the same job scope was started, so this watcher has been closed. Do not run this watch command again automatically, because starting another watcher may interrupt a different session that is already monitoring task progress.";
93761
93995
  var USER_ATTENTION_WATCHER_SCAN_MS = 500;
93762
93996
  var USER_ATTENTION_WATCHER_TTL_MS = 15e3;
@@ -93881,16 +94115,8 @@ function userWatchEventDeliveredSentryExtra(event) {
93881
94115
  // src/listener.ts
93882
94116
  init_daemon_lock();
93883
94117
  init_ai_provider();
93884
-
93885
- // ../core/src/sentry-config.ts
93886
- var environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
93887
- var SENTRY_CONFIG = {
93888
- projectName: "okx/openclaw-okx-a2a-extension",
93889
- release: "0.1.6",
93890
- environment
93891
- };
93892
-
93893
- // src/listener.ts
94118
+ init_sentry_logger();
94119
+ init_sentry_config();
93894
94120
  var DEFAULT_OFFLINE_REPLAY_INTERVAL_SEC = 300;
93895
94121
  var DEFAULT_XMTP_CLIENT_RECYCLE_INTERVAL_SEC = 6 * 60 * 60;
93896
94122
  var XMTP_CLIENT_RECYCLE_INTERVAL_ENV = "OKX_A2A_XMTP_CLIENT_RECYCLE_INTERVAL_SEC";
@@ -94124,12 +94350,12 @@ async function runListenerWithLock(options, paths) {
94124
94350
  }));
94125
94351
  }
94126
94352
  });
94127
- service.setPluginVersion("0.1.6");
94353
+ service.setPluginVersion("0.1.7");
94128
94354
  await service.init();
94129
94355
  const pluginVersionStatus = service.pluginVersionStatus;
94130
94356
  if (pluginVersionStatus.unavailable) {
94131
94357
  throw new Error(
94132
- `@okxweb3/a2a-node v${"0.1.6"} is below the required minimum v${pluginVersionStatus.minVersion}`
94358
+ `@okxweb3/a2a-node v${"0.1.7"} is below the required minimum v${pluginVersionStatus.minVersion}`
94133
94359
  );
94134
94360
  }
94135
94361
  const systemConfig = service.getSystemConfig();
@@ -94147,7 +94373,7 @@ async function runListenerWithLock(options, paths) {
94147
94373
  onchainosAgentId: "*",
94148
94374
  reason: "system-config missing sentryDsn",
94149
94375
  pluginId: "@okxweb3/a2a-node",
94150
- pluginVersion: "0.1.6"
94376
+ pluginVersion: "0.1.7"
94151
94377
  });
94152
94378
  }
94153
94379
  logWithTimestamp(
@@ -94468,7 +94694,7 @@ async function runListenerWithLock(options, paths) {
94468
94694
  await markDaemonReady(paths.daemonLockPath);
94469
94695
  logWithTimestamp(`[okx-agent-task] daemon ready lock=${paths.daemonLockPath}`);
94470
94696
  await new Promise((resolve6) => {
94471
- const shutdown = (signal) => {
94697
+ const shutdown2 = (signal) => {
94472
94698
  if (stopping) {
94473
94699
  return;
94474
94700
  }
@@ -94507,8 +94733,8 @@ async function runListenerWithLock(options, paths) {
94507
94733
  resolve6();
94508
94734
  })();
94509
94735
  };
94510
- process.once("SIGTERM", shutdown);
94511
- process.once("SIGINT", shutdown);
94736
+ process.once("SIGTERM", shutdown2);
94737
+ process.once("SIGINT", shutdown2);
94512
94738
  });
94513
94739
  }
94514
94740
  async function timeSettled(fn) {
@@ -95578,6 +95804,20 @@ var gatewayPluginChecker = {
95578
95804
  const installed = await isGatewayPluginInstalled(ctx.target);
95579
95805
  const hermesPathSuffix = ctx.target === "hermes" ? ` (checked ${resolveHermesPluginYamlPath()})` : "";
95580
95806
  if (installed) {
95807
+ if (ctx.target === "hermes" && ctx.hermesGatewayRestartPending) {
95808
+ return {
95809
+ id: "gateway_plugin",
95810
+ title: "Gateway plugin installed",
95811
+ status: "fail",
95812
+ severity: "required",
95813
+ detail: "the Hermes okx-a2a plugin was just installed/updated in this run, but the running Hermes gateway has not loaded it yet",
95814
+ fix: {
95815
+ kind: "manual",
95816
+ description: "The Hermes okx-a2a plugin was just installed and takes effect after the Hermes gateway restarts \u2014 run /restart inside Hermes (or restart the Hermes app), then re-run okx-a2a doctor to confirm.",
95817
+ command: "/restart"
95818
+ }
95819
+ };
95820
+ }
95581
95821
  return {
95582
95822
  id: "gateway_plugin",
95583
95823
  title: "Gateway plugin installed",
@@ -95609,6 +95849,9 @@ var gatewayPluginChecker = {
95609
95849
  }
95610
95850
  const { installGatewayPluginForDoctor: installGatewayPluginForDoctor2 } = await Promise.resolve().then(() => (init_update_cli(), update_cli_exports));
95611
95851
  const { gatewayRestarted } = await installGatewayPluginForDoctor2(ctx.target);
95852
+ if (ctx.target === "hermes" && !gatewayRestarted) {
95853
+ ctx.hermesGatewayRestartPending = true;
95854
+ }
95612
95855
  return gatewayRestarted ? `installed the ${ctx.target} okx-a2a plugin and restarted the gateway` : `installed the ${ctx.target} okx-a2a plugin; gateway restart was deferred because doctor is running inside the ${ctx.target} gateway (restarting now would kill this session). Restart the gateway to load the plugin.`;
95613
95856
  }
95614
95857
  };
@@ -95884,10 +96127,11 @@ async function runDoctor(options = {}) {
95884
96127
  platform: options.platform ?? process.platform,
95885
96128
  env: options.env ?? process.env,
95886
96129
  target: options.target ?? resolveDoctorTarget(options.env ?? process.env),
95887
- cliVersion: options.cliVersion ?? (true ? "0.1.6" : "0.0.0"),
96130
+ cliVersion: options.cliVersion ?? (true ? "0.1.7" : "0.0.0"),
95888
96131
  fixMode: options.fix === true,
95889
96132
  nonInteractive: options.nonInteractive === true,
95890
- packageChanged: false
96133
+ packageChanged: false,
96134
+ hermesGatewayRestartPending: false
95891
96135
  };
95892
96136
  const checkers = options.checkers ?? CHECKERS;
95893
96137
  const fixesApplied = [];
@@ -96055,6 +96299,7 @@ async function handleDoctorCommand(args) {
96055
96299
  setRedirectCommandStdoutToStderr(false);
96056
96300
  }
96057
96301
  };
96302
+ const startedAtMs = Date.now();
96058
96303
  let report;
96059
96304
  try {
96060
96305
  report = await runDoctor({ fix, nonInteractive, ...rawTarget ? { target: rawTarget } : {} });
@@ -96066,10 +96311,14 @@ async function handleDoctorCommand(args) {
96066
96311
  if (!json) {
96067
96312
  console.error(`doctor crashed: ${message}`);
96068
96313
  }
96314
+ const { reportDoctorCrashToSentry: reportDoctorCrashToSentry2 } = await Promise.resolve().then(() => (init_doctor_sentry(), doctor_sentry_exports));
96315
+ await reportDoctorCrashToSentry2(error, { fix, nonInteractive, durationMs: Date.now() - startedAtMs });
96069
96316
  await writeStdoutAndExit(out2, 2);
96070
96317
  return;
96071
96318
  }
96072
96319
  restoreStdout();
96320
+ const { reportDoctorRunToSentry: reportDoctorRunToSentry2 } = await Promise.resolve().then(() => (init_doctor_sentry(), doctor_sentry_exports));
96321
+ await reportDoctorRunToSentry2(report, { fix, nonInteractive, durationMs: Date.now() - startedAtMs });
96073
96322
  const out = json ? `${JSON.stringify(report)}
96074
96323
  ` : `${formatDoctorReportForHumans(report)}
96075
96324
  `;
@@ -96089,6 +96338,7 @@ async function writeStdoutAndExit(output, code2) {
96089
96338
  }
96090
96339
 
96091
96340
  // src/index.ts
96341
+ init_doctor_sentry();
96092
96342
  init_win_native_launcher();
96093
96343
  // Annotate the CommonJS export names for ESM import in node:
96094
96344
  0 && (module.exports = {
@@ -96129,6 +96379,7 @@ init_win_native_launcher();
96129
96379
  buildAutostartVbs,
96130
96380
  buildBackupJobSessionKey,
96131
96381
  buildDispatchSessionKey,
96382
+ buildDoctorSentryExtra,
96132
96383
  buildExternalCommandInvocation,
96133
96384
  buildLauncherEntryJs,
96134
96385
  buildPendingConversationBackupDispatch,
@@ -96206,6 +96457,7 @@ init_win_native_launcher();
96206
96457
  refreshAgentsAndWait,
96207
96458
  registerUserAttentionWatcher,
96208
96459
  removeUserAttentionWatcher,
96460
+ reportDoctorRunToSentry,
96209
96461
  resolveAiPermissionPreset,
96210
96462
  resolveAiProviderCommand,
96211
96463
  resolveAiProviderForDispatch,