@okxweb3/a2a-node 0.0.13-beta-d0ec14bc63-260622192924 → 0.0.13
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.
- package/dist/cli.js +4427 -4155
- package/dist/index.js +1373 -1167
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1589,7 +1589,7 @@ var require_misc = __commonJS({
|
|
|
1589
1589
|
}
|
|
1590
1590
|
}
|
|
1591
1591
|
var SEMVER_REGEXP = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
|
|
1592
|
-
function
|
|
1592
|
+
function parseSemver3(input) {
|
|
1593
1593
|
const match = input.match(SEMVER_REGEXP) || [];
|
|
1594
1594
|
const major = parseInt(match[1], 10);
|
|
1595
1595
|
const minor = parseInt(match[2], 10);
|
|
@@ -1631,7 +1631,7 @@ var require_misc = __commonJS({
|
|
|
1631
1631
|
exports2.arrayify = arrayify;
|
|
1632
1632
|
exports2.checkOrSetAlreadyCaught = checkOrSetAlreadyCaught;
|
|
1633
1633
|
exports2.getEventDescription = getEventDescription;
|
|
1634
|
-
exports2.parseSemver =
|
|
1634
|
+
exports2.parseSemver = parseSemver3;
|
|
1635
1635
|
exports2.uuid4 = uuid4;
|
|
1636
1636
|
}
|
|
1637
1637
|
});
|
|
@@ -1913,7 +1913,7 @@ var require_path = __commonJS({
|
|
|
1913
1913
|
function isAbsolute2(path) {
|
|
1914
1914
|
return path.charAt(0) === "/";
|
|
1915
1915
|
}
|
|
1916
|
-
function
|
|
1916
|
+
function join18(...args) {
|
|
1917
1917
|
return normalizePath(args.join("/"));
|
|
1918
1918
|
}
|
|
1919
1919
|
function dirname6(path) {
|
|
@@ -1938,7 +1938,7 @@ var require_path = __commonJS({
|
|
|
1938
1938
|
exports2.basename = basename3;
|
|
1939
1939
|
exports2.dirname = dirname6;
|
|
1940
1940
|
exports2.isAbsolute = isAbsolute2;
|
|
1941
|
-
exports2.join =
|
|
1941
|
+
exports2.join = join18;
|
|
1942
1942
|
exports2.normalizePath = normalizePath;
|
|
1943
1943
|
exports2.relative = relative;
|
|
1944
1944
|
exports2.resolve = resolve4;
|
|
@@ -67932,7 +67932,6 @@ __export(index_exports, {
|
|
|
67932
67932
|
GatewayOutboundBehavior: () => GatewayOutboundBehavior,
|
|
67933
67933
|
InvalidXmtpMessageStore: () => InvalidXmtpMessageStore,
|
|
67934
67934
|
OFFLINE_REPLAY_SYNC_INTERVAL: () => OFFLINE_REPLAY_SYNC_INTERVAL,
|
|
67935
|
-
OPENCLAW_GATEWAY_ROUTE_GROUP_ID: () => OPENCLAW_GATEWAY_ROUTE_GROUP_ID,
|
|
67936
67935
|
SYSTEM_NOTIFICATION_SESSION_KEY: () => SYSTEM_NOTIFICATION_SESSION_KEY,
|
|
67937
67936
|
SessionStore: () => SessionStore,
|
|
67938
67937
|
SqliteOutboundBehavior: () => SqliteOutboundBehavior,
|
|
@@ -67946,7 +67945,6 @@ __export(index_exports, {
|
|
|
67946
67945
|
bindJobProviderToCurrentDefaultIfMissing: () => bindJobProviderToCurrentDefaultIfMissing,
|
|
67947
67946
|
bindJobProviderToCurrentRuntimeIfMissing: () => bindJobProviderToCurrentRuntimeIfMissing,
|
|
67948
67947
|
bindMessageJobProviderToCurrentDefault: () => bindMessageJobProviderToCurrentDefault,
|
|
67949
|
-
bindOpenClawGatewayRouteFromEnv: () => bindOpenClawGatewayRouteFromEnv,
|
|
67950
67948
|
buildAgentMessageNotice: () => buildAgentMessageNotice,
|
|
67951
67949
|
buildAiAdapterCommand: () => buildAiAdapterCommand,
|
|
67952
67950
|
buildAiProviderEnv: () => buildAiProviderEnv,
|
|
@@ -67967,18 +67965,19 @@ __export(index_exports, {
|
|
|
67967
67965
|
createFileMessageHandler: () => createFileMessageHandler,
|
|
67968
67966
|
createOutboundBehavior: () => createOutboundBehavior,
|
|
67969
67967
|
createUserAttentionWatchParentMonitor: () => createUserAttentionWatchParentMonitor,
|
|
67970
|
-
currentOpenClawGatewaySessionKey: () => currentOpenClawGatewaySessionKey,
|
|
67971
67968
|
detectAiProviders: () => detectAiProviders,
|
|
67972
67969
|
detectCurrentAiProvider: () => detectCurrentAiProvider,
|
|
67973
67970
|
detectGatewayInvocation: () => detectGatewayInvocation,
|
|
67974
67971
|
detectRuntime: () => detectRuntime,
|
|
67972
|
+
ensureCommunicationMinVersions: () => ensureCommunicationMinVersions,
|
|
67975
67973
|
ensureDefaultAiProvider: () => ensureDefaultAiProvider,
|
|
67976
67974
|
extractAiSessionId: () => extractAiSessionId,
|
|
67977
|
-
extractXmtpSentAtMs: () =>
|
|
67975
|
+
extractXmtpSentAtMs: () => extractXmtpSentAtMs2,
|
|
67978
67976
|
getDaemonStatus: () => getDaemonStatus,
|
|
67979
67977
|
handleXmtpSendCommand: () => handleXmtpSendCommand,
|
|
67980
67978
|
hasAiRuntimeMarker: () => hasAiRuntimeMarker,
|
|
67981
67979
|
heartbeatUserAttentionWatcher: () => heartbeatUserAttentionWatcher,
|
|
67980
|
+
isBelowRequiredVersion: () => isBelowRequiredVersion,
|
|
67982
67981
|
isOriginalParentProcessAlive: () => isOriginalParentProcessAlive,
|
|
67983
67982
|
isPrereleaseVersion: () => isPrereleaseVersion,
|
|
67984
67983
|
isRetryableOpenClawGatewayError: () => isRetryableOpenClawGatewayError,
|
|
@@ -68001,8 +68000,6 @@ __export(index_exports, {
|
|
|
68001
68000
|
resolveConfiguredAiProviderForJob: () => resolveConfiguredAiProviderForJob,
|
|
68002
68001
|
resolveDirectCommunicationSessionTarget: () => resolveDirectCommunicationSessionTarget,
|
|
68003
68002
|
resolveOpenClawGatewayConfig: () => resolveOpenClawGatewayConfig,
|
|
68004
|
-
resolveOpenClawGatewayRoute: () => resolveOpenClawGatewayRoute,
|
|
68005
|
-
resolveOpenClawGatewayRoutes: () => resolveOpenClawGatewayRoutes,
|
|
68006
68003
|
resolveSystemNotificationTargets: () => resolveSystemNotificationTargets,
|
|
68007
68004
|
resolveTaskConfigPath: () => resolveTaskConfigPath,
|
|
68008
68005
|
resolveTaskHome: () => resolveTaskHome,
|
|
@@ -68561,10 +68558,6 @@ var SessionStore = class {
|
|
|
68561
68558
|
VALUES (?, ?, ?, ?)
|
|
68562
68559
|
ON CONFLICT(job_id) DO UPDATE SET
|
|
68563
68560
|
provider = excluded.provider,
|
|
68564
|
-
gateway_routes_json = CASE
|
|
68565
|
-
WHEN job_provider_bindings.provider = excluded.provider THEN job_provider_bindings.gateway_routes_json
|
|
68566
|
-
ELSE NULL
|
|
68567
|
-
END,
|
|
68568
68561
|
updated_at = excluded.updated_at
|
|
68569
68562
|
`).run(params.jobId, params.provider, now, now);
|
|
68570
68563
|
const binding = this.getJobProviderBinding(params.jobId);
|
|
@@ -68573,52 +68566,43 @@ var SessionStore = class {
|
|
|
68573
68566
|
}
|
|
68574
68567
|
return binding;
|
|
68575
68568
|
}
|
|
68576
|
-
|
|
68569
|
+
upsertJobGatewayRoute(params) {
|
|
68577
68570
|
assertNonEmpty(params.jobId, "jobId");
|
|
68578
|
-
|
|
68579
|
-
|
|
68571
|
+
assertNonEmpty(params.route.platform, "route.platform");
|
|
68572
|
+
assertNonEmpty(params.route.chatId, "route.chatId");
|
|
68573
|
+
if (params.provider) {
|
|
68574
|
+
assertAiProvider(params.provider);
|
|
68575
|
+
}
|
|
68580
68576
|
const now = this.timestamp();
|
|
68581
68577
|
return this.transaction(() => {
|
|
68582
|
-
this.db.prepare(`
|
|
68583
|
-
INSERT OR IGNORE INTO job_provider_bindings(job_id, provider, created_at, updated_at)
|
|
68584
|
-
VALUES (?, ?, ?, ?)
|
|
68585
|
-
`).run(params.jobId, params.provider, now, now);
|
|
68586
68578
|
const existing = this.getJobProviderBinding(params.jobId);
|
|
68587
68579
|
if (!existing) {
|
|
68588
|
-
|
|
68589
|
-
|
|
68590
|
-
|
|
68591
|
-
|
|
68580
|
+
this.db.prepare(`
|
|
68581
|
+
INSERT INTO job_provider_bindings(job_id, provider, gateway_routes_json, created_at, updated_at)
|
|
68582
|
+
VALUES (?, ?, ?, ?, ?)
|
|
68583
|
+
`).run(
|
|
68584
|
+
params.jobId,
|
|
68585
|
+
params.provider ?? "hermes",
|
|
68586
|
+
JSON.stringify([normalizeGatewayRoute(params.route, now)]),
|
|
68587
|
+
now,
|
|
68588
|
+
now
|
|
68589
|
+
);
|
|
68590
|
+
} else {
|
|
68591
|
+
const route = normalizeGatewayRoute(params.route, now);
|
|
68592
|
+
const routes = upsertGatewayRoute(existing.gatewayRoutes, route);
|
|
68593
|
+
this.db.prepare(`
|
|
68594
|
+
UPDATE job_provider_bindings
|
|
68595
|
+
SET gateway_routes_json = ?, updated_at = ?
|
|
68596
|
+
WHERE job_id = ?
|
|
68597
|
+
`).run(JSON.stringify(routes), now, params.jobId);
|
|
68592
68598
|
}
|
|
68593
|
-
this.db.prepare(`
|
|
68594
|
-
UPDATE job_provider_bindings
|
|
68595
|
-
SET gateway_routes_json = ?, updated_at = ?
|
|
68596
|
-
WHERE job_id = ? AND provider = ?
|
|
68597
|
-
`).run(routesJson, now, params.jobId, params.provider);
|
|
68598
68599
|
const binding = this.getJobProviderBinding(params.jobId);
|
|
68599
68600
|
if (!binding) {
|
|
68600
|
-
throw new Error(`Failed to read job_provider_bindings ${params.jobId} after route
|
|
68601
|
+
throw new Error(`Failed to read job_provider_bindings ${params.jobId} after route upsert`);
|
|
68601
68602
|
}
|
|
68602
68603
|
return binding;
|
|
68603
68604
|
});
|
|
68604
68605
|
}
|
|
68605
|
-
clearJobProviderGatewayRoutes(params) {
|
|
68606
|
-
assertNonEmpty(params.jobId, "jobId");
|
|
68607
|
-
if (params.provider) {
|
|
68608
|
-
assertAiProvider(params.provider);
|
|
68609
|
-
}
|
|
68610
|
-
const now = this.timestamp();
|
|
68611
|
-
const result = params.provider ? this.db.prepare(`
|
|
68612
|
-
UPDATE job_provider_bindings
|
|
68613
|
-
SET gateway_routes_json = NULL, updated_at = ?
|
|
68614
|
-
WHERE job_id = ? AND provider = ?
|
|
68615
|
-
`).run(now, params.jobId, params.provider) : this.db.prepare(`
|
|
68616
|
-
UPDATE job_provider_bindings
|
|
68617
|
-
SET gateway_routes_json = NULL, updated_at = ?
|
|
68618
|
-
WHERE job_id = ?
|
|
68619
|
-
`).run(now, params.jobId);
|
|
68620
|
-
return Number(result.changes ?? 0) > 0;
|
|
68621
|
-
}
|
|
68622
68606
|
deleteJobProviderBinding(jobId) {
|
|
68623
68607
|
assertNonEmpty(jobId, "jobId");
|
|
68624
68608
|
const result = this.db.prepare("DELETE FROM job_provider_bindings WHERE job_id = ?").run(jobId);
|
|
@@ -69393,54 +69377,82 @@ function mapJobProviderBindingRow(row) {
|
|
|
69393
69377
|
return {
|
|
69394
69378
|
jobId: row.job_id,
|
|
69395
69379
|
provider: row.provider,
|
|
69396
|
-
|
|
69380
|
+
gatewayRoutes: parseGatewayRoutes(row.gateway_routes_json),
|
|
69397
69381
|
createdAt: row.created_at,
|
|
69398
69382
|
updatedAt: row.updated_at
|
|
69399
69383
|
};
|
|
69400
69384
|
}
|
|
69401
|
-
function
|
|
69385
|
+
function parseGatewayRoutes(value) {
|
|
69386
|
+
if (!value) {
|
|
69387
|
+
return [];
|
|
69388
|
+
}
|
|
69402
69389
|
try {
|
|
69403
69390
|
const parsed = JSON.parse(value);
|
|
69404
69391
|
if (!Array.isArray(parsed)) {
|
|
69405
69392
|
return [];
|
|
69406
69393
|
}
|
|
69407
|
-
return
|
|
69394
|
+
return parsed.flatMap((item) => {
|
|
69395
|
+
const route = normalizeGatewayRouteInput(item);
|
|
69396
|
+
return route ? [route] : [];
|
|
69397
|
+
});
|
|
69408
69398
|
} catch {
|
|
69409
69399
|
return [];
|
|
69410
69400
|
}
|
|
69411
69401
|
}
|
|
69412
|
-
function
|
|
69413
|
-
if (!Array.isArray(value)) {
|
|
69414
|
-
return
|
|
69402
|
+
function normalizeGatewayRouteInput(value) {
|
|
69403
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
69404
|
+
return null;
|
|
69415
69405
|
}
|
|
69416
|
-
const
|
|
69417
|
-
|
|
69418
|
-
|
|
69419
|
-
|
|
69420
|
-
|
|
69421
|
-
const record = item;
|
|
69422
|
-
const platform = normalizeOptionalString(record.platform);
|
|
69423
|
-
const sessionKey = normalizeOptionalString(record.sessionKey);
|
|
69424
|
-
if (!platform || !sessionKey) {
|
|
69425
|
-
continue;
|
|
69426
|
-
}
|
|
69427
|
-
const gatewaySessionKey = normalizeOptionalString(record.gatewaySessionKey);
|
|
69428
|
-
const chatId = normalizeOptionalString(record.chatId);
|
|
69429
|
-
const threadId = normalizeOptionalString(record.threadId);
|
|
69430
|
-
const updatedAt = normalizeOptionalString(record.updatedAt);
|
|
69431
|
-
routes.push({
|
|
69432
|
-
platform,
|
|
69433
|
-
sessionKey,
|
|
69434
|
-
...gatewaySessionKey ? { gatewaySessionKey } : {},
|
|
69435
|
-
...chatId ? { chatId } : {},
|
|
69436
|
-
...threadId ? { threadId } : {},
|
|
69437
|
-
...updatedAt ? { updatedAt } : {}
|
|
69438
|
-
});
|
|
69406
|
+
const item = value;
|
|
69407
|
+
const platform = readText(item.platform);
|
|
69408
|
+
const chatId = readText(item.chatId) ?? readText(item.chat_id);
|
|
69409
|
+
if (!platform || !chatId) {
|
|
69410
|
+
return null;
|
|
69439
69411
|
}
|
|
69440
|
-
return
|
|
69412
|
+
return {
|
|
69413
|
+
platform,
|
|
69414
|
+
chatId,
|
|
69415
|
+
chatName: readText(item.chatName) ?? readText(item.chat_name) ?? "",
|
|
69416
|
+
chatType: readText(item.chatType) ?? readText(item.chat_type) ?? (readText(item.threadId) || readText(item.thread_id) ? "thread" : "dm"),
|
|
69417
|
+
threadId: readText(item.threadId) ?? readText(item.thread_id) ?? "",
|
|
69418
|
+
userId: readText(item.userId) ?? readText(item.user_id) ?? "",
|
|
69419
|
+
userName: readText(item.userName) ?? readText(item.user_name) ?? "",
|
|
69420
|
+
sessionKey: readText(item.sessionKey) ?? readText(item.session_key) ?? "",
|
|
69421
|
+
gatewaySessionKey: readText(item.gatewaySessionKey) ?? readText(item.gateway_session_key) ?? "",
|
|
69422
|
+
updatedAt: readText(item.updatedAt) ?? readText(item.updated_at) ?? ""
|
|
69423
|
+
};
|
|
69424
|
+
}
|
|
69425
|
+
function normalizeGatewayRoute(route, updatedAt) {
|
|
69426
|
+
return {
|
|
69427
|
+
platform: route.platform,
|
|
69428
|
+
chatId: route.chatId,
|
|
69429
|
+
chatName: route.chatName ?? "",
|
|
69430
|
+
chatType: route.chatType || (route.threadId ? "thread" : "dm"),
|
|
69431
|
+
threadId: route.threadId ?? "",
|
|
69432
|
+
userId: route.userId ?? "",
|
|
69433
|
+
userName: route.userName ?? "",
|
|
69434
|
+
sessionKey: route.sessionKey ?? route.gatewaySessionKey ?? "",
|
|
69435
|
+
gatewaySessionKey: route.gatewaySessionKey ?? route.sessionKey ?? "",
|
|
69436
|
+
updatedAt
|
|
69437
|
+
};
|
|
69438
|
+
}
|
|
69439
|
+
function upsertGatewayRoute(routes, route) {
|
|
69440
|
+
const key = gatewayRouteKey(route);
|
|
69441
|
+
const next = routes.filter((item) => gatewayRouteKey(item) !== key);
|
|
69442
|
+
next.push(route);
|
|
69443
|
+
return next;
|
|
69444
|
+
}
|
|
69445
|
+
function gatewayRouteKey(route) {
|
|
69446
|
+
return `${route.platform}
|
|
69447
|
+
${route.chatId}
|
|
69448
|
+
${route.threadId ?? ""}`;
|
|
69441
69449
|
}
|
|
69442
|
-
function
|
|
69443
|
-
|
|
69450
|
+
function readText(value) {
|
|
69451
|
+
if (typeof value !== "string") {
|
|
69452
|
+
return null;
|
|
69453
|
+
}
|
|
69454
|
+
const trimmed = value.trim();
|
|
69455
|
+
return trimmed || null;
|
|
69444
69456
|
}
|
|
69445
69457
|
|
|
69446
69458
|
// src/daemon-lock.ts
|
|
@@ -69587,6 +69599,7 @@ async function ensureDaemonDirs(homeDir) {
|
|
|
69587
69599
|
}
|
|
69588
69600
|
async function ensureAiWorkspace(paths) {
|
|
69589
69601
|
const aiWorkingDir = paths.workspaceDir;
|
|
69602
|
+
await (0, import_promises2.rm)(aiWorkingDir, { recursive: true, force: true });
|
|
69590
69603
|
ensureTaskDir(aiWorkingDir);
|
|
69591
69604
|
return aiWorkingDir;
|
|
69592
69605
|
}
|
|
@@ -69779,6 +69792,32 @@ async function stopDaemon(homeDir) {
|
|
|
69779
69792
|
};
|
|
69780
69793
|
}
|
|
69781
69794
|
|
|
69795
|
+
// ../core/src/log.ts
|
|
69796
|
+
function formatLogTimestamp(date = /* @__PURE__ */ new Date()) {
|
|
69797
|
+
return date.toLocaleString(void 0, {
|
|
69798
|
+
year: "numeric",
|
|
69799
|
+
month: "2-digit",
|
|
69800
|
+
day: "2-digit",
|
|
69801
|
+
hour: "2-digit",
|
|
69802
|
+
minute: "2-digit",
|
|
69803
|
+
second: "2-digit",
|
|
69804
|
+
fractionalSecondDigits: 3,
|
|
69805
|
+
hour12: false
|
|
69806
|
+
});
|
|
69807
|
+
}
|
|
69808
|
+
function prefixArgs(args) {
|
|
69809
|
+
return [`[${formatLogTimestamp()}]`, ...args];
|
|
69810
|
+
}
|
|
69811
|
+
function logWithTimestamp(...args) {
|
|
69812
|
+
console.log(...prefixArgs(args));
|
|
69813
|
+
}
|
|
69814
|
+
function warnWithTimestamp(...args) {
|
|
69815
|
+
console.warn(...prefixArgs(args));
|
|
69816
|
+
}
|
|
69817
|
+
function errorWithTimestamp(...args) {
|
|
69818
|
+
console.error(...prefixArgs(args));
|
|
69819
|
+
}
|
|
69820
|
+
|
|
69782
69821
|
// src/ai-runner.ts
|
|
69783
69822
|
var import_node_crypto3 = require("node:crypto");
|
|
69784
69823
|
var import_node_fs7 = require("node:fs");
|
|
@@ -70282,7 +70321,7 @@ function detectGatewayInvocation(env = process.env) {
|
|
|
70282
70321
|
if (!isTruthyRuntimeMarker(env.OKX_A2A_IN_GATEWAY)) {
|
|
70283
70322
|
return null;
|
|
70284
70323
|
}
|
|
70285
|
-
const provider = env.OKX_A2A_GATEWAY_PROVIDER
|
|
70324
|
+
const provider = env.OKX_A2A_GATEWAY_PROVIDER;
|
|
70286
70325
|
if (!provider) {
|
|
70287
70326
|
return null;
|
|
70288
70327
|
}
|
|
@@ -70935,6 +70974,7 @@ var LogEvent = {
|
|
|
70935
70974
|
USER_DISPATCHED: "User dispatched",
|
|
70936
70975
|
SESSION_DISPATCHED: "Session dispatched",
|
|
70937
70976
|
SYNC_TICK_COMPLETED: "Sync tick completed",
|
|
70977
|
+
INBOUND_HANDLER_ENTERED: "Inbound handler entered",
|
|
70938
70978
|
MESSAGE_RECEIVED: "Message received",
|
|
70939
70979
|
MESSAGE_SENT: "Message sent",
|
|
70940
70980
|
INBOUND_BUYER_PENDING: "Inbound buyer: no session, group still Unknown (pending)",
|
|
@@ -70972,6 +71012,8 @@ var LogEvent = {
|
|
|
70972
71012
|
AGENTS_WAKEUP_NOTIFIED: "Agents wakeup notified",
|
|
70973
71013
|
CONFIG_SENSITIVE_WORDS_REFRESHED: "Sensitive words config refreshed",
|
|
70974
71014
|
CONFIG_SYSTEM_REFRESHED: "System config refreshed",
|
|
71015
|
+
FORCED_UPDATE_STARTED: "Forced update started",
|
|
71016
|
+
FORCED_UPDATE_SUCCEEDED: "Forced update succeeded",
|
|
70975
71017
|
GATEWAY_DISCONNECTED: "Gateway disconnected",
|
|
70976
71018
|
GATEWAY_REQUEST: "Gateway request",
|
|
70977
71019
|
GATEWAY_DELIVERY_BUFFERED: "Gateway delivery buffered",
|
|
@@ -70982,6 +71024,9 @@ var LogEvent = {
|
|
|
70982
71024
|
USER_WATCH_EVENT_DELIVERED: "User watch event delivered",
|
|
70983
71025
|
INBOUND_DM_RAW: "Inbound DM raw",
|
|
70984
71026
|
INBOUND_GROUP_RAW: "Inbound group raw",
|
|
71027
|
+
SYSTEM_NOTIFICATION_RECEIVED: "System notification received",
|
|
71028
|
+
SYSTEM_NOTIFICATION_ROUTED: "System notification routed",
|
|
71029
|
+
HERMES_SESSION_ROUTE_BINDING: "Hermes session route binding",
|
|
70985
71030
|
// ── error ─────────────────────────────────────────────────────
|
|
70986
71031
|
XMTP_CONNECTION_FAILED: "XMTP connection failed",
|
|
70987
71032
|
CONVERSATIONS_STREAM_FAILED: "conversations.stream failed",
|
|
@@ -71031,6 +71076,7 @@ var LogEvent = {
|
|
|
71031
71076
|
CACHE_LOAD_FAILED: "Cache load failed",
|
|
71032
71077
|
CACHE_WRITE_FAILED: "Cache write failed",
|
|
71033
71078
|
CONFIG_LOAD_FAILED: "Config load failed",
|
|
71079
|
+
FORCED_UPDATE_FAILED: "Forced update failed",
|
|
71034
71080
|
SENTRY_INIT_SKIPPED: "Sentry init skipped",
|
|
71035
71081
|
AGENT_DB_DIR_CREATE_FAILED: "Agent DB dir create failed"
|
|
71036
71082
|
};
|
|
@@ -71180,6 +71226,9 @@ var SENTRY_INFO_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
|
71180
71226
|
LogEvent.INBOUND_DELIVERED,
|
|
71181
71227
|
LogEvent.INBOUND_DM_RAW,
|
|
71182
71228
|
LogEvent.INBOUND_GROUP_RAW,
|
|
71229
|
+
LogEvent.SYSTEM_NOTIFICATION_RECEIVED,
|
|
71230
|
+
LogEvent.SYSTEM_NOTIFICATION_ROUTED,
|
|
71231
|
+
LogEvent.HERMES_SESSION_ROUTE_BINDING,
|
|
71183
71232
|
LogEvent.INBOUND_BLOCKED_ADDRESS_MISMATCH,
|
|
71184
71233
|
LogEvent.INBOUND_BLOCKED_INELIGIBLE,
|
|
71185
71234
|
LogEvent.INBOUND_BLOCKED_SENSITIVE,
|
|
@@ -71204,10 +71253,13 @@ var SENTRY_INFO_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
|
71204
71253
|
LogEvent.BOOTSTRAP_APPLIED,
|
|
71205
71254
|
LogEvent.CONFIG_SENSITIVE_WORDS_REFRESHED,
|
|
71206
71255
|
LogEvent.CONFIG_SYSTEM_REFRESHED,
|
|
71256
|
+
LogEvent.FORCED_UPDATE_STARTED,
|
|
71257
|
+
LogEvent.FORCED_UPDATE_SUCCEEDED,
|
|
71207
71258
|
LogEvent.CONVERSATION_HISTORY_QUERIED,
|
|
71208
71259
|
LogEvent.FILE_DOWNLOADED,
|
|
71209
71260
|
LogEvent.FILE_UPLOADED,
|
|
71210
71261
|
LogEvent.GROUP_CONSENT_CHANGED,
|
|
71262
|
+
LogEvent.INBOUND_HANDLER_ENTERED,
|
|
71211
71263
|
LogEvent.MESSAGE_RECEIVED,
|
|
71212
71264
|
LogEvent.OFFLINE_REPLAY_MESSAGE_REPLAYED,
|
|
71213
71265
|
LogEvent.AGENT_REFRESH_SESSION_EXPIRED,
|
|
@@ -71235,7 +71287,7 @@ var SentryLogger = class _SentryLogger {
|
|
|
71235
71287
|
}
|
|
71236
71288
|
init(config) {
|
|
71237
71289
|
if (this.initialized) {
|
|
71238
|
-
|
|
71290
|
+
warnWithTimestamp("[logger] Already initialized, skipping.");
|
|
71239
71291
|
return;
|
|
71240
71292
|
}
|
|
71241
71293
|
try {
|
|
@@ -71545,7 +71597,7 @@ async function runAiAdapter(options) {
|
|
|
71545
71597
|
const permissionPreset = options.permissionPreset ?? (options.provider === "codex" || options.provider === "claude" ? resolveAiPermissionPresetForRun(homeDir, options.env ?? process.env) : void 0);
|
|
71546
71598
|
const built = buildAiAdapterCommand({ ...options, homeDir, permissionPreset });
|
|
71547
71599
|
const startedAt = Date.now();
|
|
71548
|
-
|
|
71600
|
+
errorWithTimestamp(
|
|
71549
71601
|
`[okx-agent-task] AI adapter start provider=${options.provider} command=${built.command} mode=${options.sessionId ? "resume" : "new"} cwd=${options.cwd ?? process.cwd()}`
|
|
71550
71602
|
);
|
|
71551
71603
|
const child = (0, import_node_child_process3.spawn)(built.command, built.args, {
|
|
@@ -71623,7 +71675,7 @@ async function runAiAdapter(options) {
|
|
|
71623
71675
|
if (trailingStderr) {
|
|
71624
71676
|
sessionId = trailingStderr;
|
|
71625
71677
|
}
|
|
71626
|
-
|
|
71678
|
+
errorWithTimestamp(
|
|
71627
71679
|
`[okx-agent-task] AI adapter done provider=${options.provider} exitCode=${exitCode ?? "null"} sessionId=${sessionId ?? "(none)"} duration=${durationMs}ms timeout=${timedOut ? "yes" : "no"} stdout=${stdout.length}B stderr=${stderr.length}B`
|
|
71628
71680
|
);
|
|
71629
71681
|
if (timedOut || exitCode !== 0 || !sessionId) {
|
|
@@ -72071,18 +72123,20 @@ var AiRunner = class {
|
|
|
72071
72123
|
const normalized = this.normalizeRunRequest(request);
|
|
72072
72124
|
const queueKey = this.buildRunQueueKey(normalized);
|
|
72073
72125
|
const triggeredAt = normalized.triggeredAtMs ?? Date.now();
|
|
72074
|
-
|
|
72075
|
-
|
|
72076
|
-
|
|
72077
|
-
|
|
72078
|
-
|
|
72079
|
-
|
|
72080
|
-
|
|
72081
|
-
|
|
72082
|
-
|
|
72083
|
-
|
|
72084
|
-
|
|
72085
|
-
|
|
72126
|
+
if (isAiLifecycleLoggingEnabled()) {
|
|
72127
|
+
await this.appendLlmLog({
|
|
72128
|
+
type: "trigger",
|
|
72129
|
+
source: normalized.source,
|
|
72130
|
+
sessionKey: normalized.sessionKey,
|
|
72131
|
+
jobId: normalized.jobId,
|
|
72132
|
+
agentId: normalized.agentId,
|
|
72133
|
+
messageId: normalized.messageId,
|
|
72134
|
+
queueKey,
|
|
72135
|
+
triggeredAtMs: triggeredAt,
|
|
72136
|
+
commandPendingMs: normalized.commandPendingMs,
|
|
72137
|
+
content: normalized.prompt
|
|
72138
|
+
});
|
|
72139
|
+
}
|
|
72086
72140
|
const enqueuedAt = Date.now();
|
|
72087
72141
|
const previous = this.dispatchQueues.get(queueKey) ?? Promise.resolve();
|
|
72088
72142
|
const next = previous.catch(() => void 0).then(() => this.runUnlocked(normalized, enqueuedAt, triggeredAt));
|
|
@@ -72128,7 +72182,7 @@ var AiRunner = class {
|
|
|
72128
72182
|
}
|
|
72129
72183
|
async runUnlocked(request, enqueuedAt, triggeredAt) {
|
|
72130
72184
|
if (process.env.OKX_AGENT_TASK_DISABLE_AI === "1") {
|
|
72131
|
-
|
|
72185
|
+
errorWithTimestamp("[okx-agent-task] AI dispatch disabled by OKX_AGENT_TASK_DISABLE_AI=1");
|
|
72132
72186
|
return;
|
|
72133
72187
|
}
|
|
72134
72188
|
try {
|
|
@@ -72143,8 +72197,9 @@ var AiRunner = class {
|
|
|
72143
72197
|
const queueWaitMs = dispatchStartedAt - enqueuedAt;
|
|
72144
72198
|
const commandPendingMs = request.commandPendingMs ?? 0;
|
|
72145
72199
|
ensureTaskDir(this.logsDir);
|
|
72146
|
-
const
|
|
72147
|
-
const
|
|
72200
|
+
const lifecycleLogsEnabled = isAiLifecycleLoggingEnabled();
|
|
72201
|
+
const logPath = lifecycleLogsEnabled ? this.buildRunLogPath(request) : "";
|
|
72202
|
+
const log = lifecycleLogsEnabled ? (0, import_node_fs7.createWriteStream)(logPath, { flags: "a" }) : null;
|
|
72148
72203
|
let existing = null;
|
|
72149
72204
|
let storeReadStartedAt;
|
|
72150
72205
|
let storeReadEndedAt;
|
|
@@ -72183,7 +72238,7 @@ var AiRunner = class {
|
|
|
72183
72238
|
const toolFailures = createAiToolFailureTracker(provider);
|
|
72184
72239
|
const captureAiSessionId = (candidate) => {
|
|
72185
72240
|
if (existingAiSessionId && candidate !== existingAiSessionId) {
|
|
72186
|
-
|
|
72241
|
+
errorWithTimestamp(
|
|
72187
72242
|
`[okx-agent-task] ignoring mismatched ${provider} session id ${this.formatRunTarget(request)} expected=${existingAiSessionId} got=${candidate}`
|
|
72188
72243
|
);
|
|
72189
72244
|
return;
|
|
@@ -72259,7 +72314,7 @@ var AiRunner = class {
|
|
|
72259
72314
|
firstStdoutAt ??= Date.now();
|
|
72260
72315
|
stdoutFull += chunk.toString("utf8");
|
|
72261
72316
|
stdoutText = appendOutput(stdoutText, chunk);
|
|
72262
|
-
log
|
|
72317
|
+
log?.write(chunk);
|
|
72263
72318
|
parseStdoutChunk(chunk);
|
|
72264
72319
|
});
|
|
72265
72320
|
child.stderr?.on("data", (chunk) => {
|
|
@@ -72267,7 +72322,7 @@ var AiRunner = class {
|
|
|
72267
72322
|
const text = chunk.toString("utf8");
|
|
72268
72323
|
stderrFull += text;
|
|
72269
72324
|
stderrText += text;
|
|
72270
|
-
log
|
|
72325
|
+
log?.write(chunk);
|
|
72271
72326
|
parseStderrText(text);
|
|
72272
72327
|
});
|
|
72273
72328
|
const target = formatDispatchTarget({
|
|
@@ -72277,7 +72332,7 @@ var AiRunner = class {
|
|
|
72277
72332
|
messageId: request.messageId
|
|
72278
72333
|
});
|
|
72279
72334
|
const label = request.source === "job-dispatch" ? "AI dispatch" : "AI session";
|
|
72280
|
-
|
|
72335
|
+
errorWithTimestamp(
|
|
72281
72336
|
`[okx-agent-task] ${label} start ${target} provider=${provider} mode=${existingAiSessionId ? "resume" : "new"} pid=${child.pid ?? "unknown"} commandPending=${commandPendingMs ?? ""}ms queue=${queueWaitMs}ms prepare=${Date.now() - dispatchStartedAt}ms storeRead=${storeReadMs ?? ""}ms providerResolve=${resolveMs}ms cwd=${aiCwd} log=${logPath}`
|
|
72282
72337
|
);
|
|
72283
72338
|
const timeout = timeoutMs === null ? null : setTimeout(() => {
|
|
@@ -72286,7 +72341,7 @@ var AiRunner = class {
|
|
|
72286
72341
|
`;
|
|
72287
72342
|
stderrFull += message;
|
|
72288
72343
|
stderrText += message;
|
|
72289
|
-
log
|
|
72344
|
+
log?.write(message);
|
|
72290
72345
|
console.error(message.trim());
|
|
72291
72346
|
child.kill("SIGTERM");
|
|
72292
72347
|
setTimeout(() => {
|
|
@@ -72319,9 +72374,11 @@ var AiRunner = class {
|
|
|
72319
72374
|
const sessionWriteEndedAt = Date.now();
|
|
72320
72375
|
const sessionWriteMs = sessionWriteEndedAt - sessionWriteStartedAt;
|
|
72321
72376
|
const logFileCloseStartedAt = Date.now();
|
|
72322
|
-
|
|
72323
|
-
|
|
72324
|
-
|
|
72377
|
+
if (log) {
|
|
72378
|
+
await new Promise((resolve4) => {
|
|
72379
|
+
log.end(resolve4);
|
|
72380
|
+
});
|
|
72381
|
+
}
|
|
72325
72382
|
const logFileCloseEndedAt = Date.now();
|
|
72326
72383
|
const totalMs = logFileCloseEndedAt - triggeredAt;
|
|
72327
72384
|
const trailingStdoutLine = stdoutBuffer.trim();
|
|
@@ -72365,7 +72422,7 @@ var AiRunner = class {
|
|
|
72365
72422
|
aiSessionId,
|
|
72366
72423
|
timedOut
|
|
72367
72424
|
});
|
|
72368
|
-
|
|
72425
|
+
errorWithTimestamp(
|
|
72369
72426
|
`[okx-agent-task] ${label} done ${target} provider=${provider} exitCode=${exitCode ?? "null"} signal=${closeResult.signal ?? "none"} timeout=${timedOut ? "yes" : "no"} aiSession=${shortenValue(aiSessionId)} commandPending=${commandPendingMs ?? ""}ms queue=${queueWaitMs}ms cli=${cliMs}ms sessionWrite=${sessionWriteMs}ms total=${totalMs}ms result=${summarizeAiOutput(stdoutText, stderrText)}`
|
|
72370
72427
|
);
|
|
72371
72428
|
const aiFailureExtra = (reason) => aiRunSentryExtra({
|
|
@@ -72390,56 +72447,58 @@ var AiRunner = class {
|
|
|
72390
72447
|
timeToFirstStdoutMs: firstStdoutAt === null ? null : firstStdoutAt - spawnedAt,
|
|
72391
72448
|
timeToFirstStderrMs: firstStderrAt === null ? null : firstStderrAt - spawnedAt
|
|
72392
72449
|
});
|
|
72393
|
-
|
|
72394
|
-
|
|
72395
|
-
|
|
72396
|
-
|
|
72397
|
-
|
|
72398
|
-
|
|
72399
|
-
|
|
72400
|
-
|
|
72401
|
-
|
|
72402
|
-
|
|
72403
|
-
|
|
72404
|
-
|
|
72405
|
-
|
|
72406
|
-
|
|
72407
|
-
|
|
72408
|
-
|
|
72409
|
-
|
|
72410
|
-
|
|
72411
|
-
|
|
72412
|
-
|
|
72413
|
-
|
|
72414
|
-
|
|
72415
|
-
|
|
72416
|
-
|
|
72417
|
-
|
|
72418
|
-
|
|
72419
|
-
|
|
72420
|
-
|
|
72421
|
-
|
|
72422
|
-
|
|
72423
|
-
|
|
72424
|
-
|
|
72425
|
-
|
|
72426
|
-
|
|
72427
|
-
|
|
72428
|
-
|
|
72429
|
-
|
|
72430
|
-
|
|
72431
|
-
|
|
72432
|
-
|
|
72433
|
-
|
|
72434
|
-
|
|
72435
|
-
|
|
72436
|
-
|
|
72437
|
-
|
|
72438
|
-
|
|
72439
|
-
|
|
72440
|
-
|
|
72441
|
-
|
|
72442
|
-
|
|
72450
|
+
if (lifecycleLogsEnabled) {
|
|
72451
|
+
await this.appendLlmLog({
|
|
72452
|
+
type: "ai-output",
|
|
72453
|
+
source: request.source,
|
|
72454
|
+
sessionKey: request.sessionKey,
|
|
72455
|
+
jobId: request.jobId,
|
|
72456
|
+
agentId: request.agentId,
|
|
72457
|
+
messageId: request.messageId,
|
|
72458
|
+
provider,
|
|
72459
|
+
mode: existingAiSessionId ? "resume" : "new",
|
|
72460
|
+
pid: child.pid ?? null,
|
|
72461
|
+
cwd: aiCwd,
|
|
72462
|
+
logPath,
|
|
72463
|
+
exitCode,
|
|
72464
|
+
closeSignal: closeResult.signal,
|
|
72465
|
+
aiSessionId,
|
|
72466
|
+
timedOut,
|
|
72467
|
+
timeoutMs,
|
|
72468
|
+
triggeredAtMs: triggeredAt,
|
|
72469
|
+
enqueuedAtMs: enqueuedAt,
|
|
72470
|
+
runStartedAtMs: dispatchStartedAt,
|
|
72471
|
+
storeReadStartedAtMs: storeReadStartedAt,
|
|
72472
|
+
storeReadEndedAtMs: storeReadEndedAt,
|
|
72473
|
+
providerResolveStartedAtMs: resolveStartedAt,
|
|
72474
|
+
providerResolveEndedAtMs: resolveEndedAt,
|
|
72475
|
+
spawnStartedAtMs: spawnStartedAt,
|
|
72476
|
+
spawnedAtMs: spawnedAt,
|
|
72477
|
+
firstStdoutAtMs: firstStdoutAt,
|
|
72478
|
+
firstStderrAtMs: firstStderrAt,
|
|
72479
|
+
childClosedAtMs: childClosedAt,
|
|
72480
|
+
sessionWriteStartedAtMs: sessionWriteStartedAt,
|
|
72481
|
+
sessionWriteEndedAtMs: sessionWriteEndedAt,
|
|
72482
|
+
logFileCloseStartedAtMs: logFileCloseStartedAt,
|
|
72483
|
+
logFileCloseEndedAtMs: logFileCloseEndedAt,
|
|
72484
|
+
commandPendingMs,
|
|
72485
|
+
queueWaitMs,
|
|
72486
|
+
triggerToEnqueueMs: enqueuedAt - triggeredAt,
|
|
72487
|
+
runStartToSpawnMs: spawnedAt - dispatchStartedAt,
|
|
72488
|
+
storeReadMs,
|
|
72489
|
+
providerResolveMs: resolveMs,
|
|
72490
|
+
timeToFirstStdoutMs: firstStdoutAt === null ? null : firstStdoutAt - spawnedAt,
|
|
72491
|
+
timeToFirstStderrMs: firstStderrAt === null ? null : firstStderrAt - spawnedAt,
|
|
72492
|
+
spawnToCloseMs: childClosedAt - spawnedAt,
|
|
72493
|
+
runStartToCloseMs: childClosedAt - dispatchStartedAt,
|
|
72494
|
+
sessionWriteMs,
|
|
72495
|
+
logFileCloseMs: logFileCloseEndedAt - logFileCloseStartedAt,
|
|
72496
|
+
cliMs,
|
|
72497
|
+
totalMs,
|
|
72498
|
+
stdout: stdoutFull,
|
|
72499
|
+
stderr: stderrFull
|
|
72500
|
+
});
|
|
72501
|
+
}
|
|
72443
72502
|
if (isMissingResumeSessionFailure({
|
|
72444
72503
|
provider,
|
|
72445
72504
|
existingAiSessionId,
|
|
@@ -72451,7 +72510,7 @@ var AiRunner = class {
|
|
|
72451
72510
|
provider,
|
|
72452
72511
|
request
|
|
72453
72512
|
});
|
|
72454
|
-
|
|
72513
|
+
errorWithTimestamp(
|
|
72455
72514
|
`[okx-agent-task] ${provider} resume session is unavailable; retrying ${target} as a new session without prior context.`
|
|
72456
72515
|
);
|
|
72457
72516
|
return this.runAi(request, enqueuedAt, triggeredAt, true);
|
|
@@ -72624,30 +72683,6 @@ var AiRunner = class {
|
|
|
72624
72683
|
});
|
|
72625
72684
|
}
|
|
72626
72685
|
}
|
|
72627
|
-
buildArgs(provider, event, aiSessionId, cwd = this.resolveAiWorkingDir()) {
|
|
72628
|
-
const sessionKey = buildDispatchSessionKey(event.jobId, event.sessionAgentId);
|
|
72629
|
-
return this.buildRunArgs(provider, {
|
|
72630
|
-
source: "job-dispatch",
|
|
72631
|
-
sessionKey,
|
|
72632
|
-
prompt: this.buildPrompt(event),
|
|
72633
|
-
jobId: event.jobId,
|
|
72634
|
-
agentId: event.sessionAgentId,
|
|
72635
|
-
messageId: event.message.id,
|
|
72636
|
-
jobFilePath: event.jobFilePath,
|
|
72637
|
-
sessionAgentId: event.sessionAgentId
|
|
72638
|
-
}, aiSessionId, cwd);
|
|
72639
|
-
}
|
|
72640
|
-
buildSessionArgs(provider, event, aiSessionId, cwd = this.resolveAiWorkingDir()) {
|
|
72641
|
-
const messageId = event.messageId ?? `session-${Date.now()}`;
|
|
72642
|
-
return this.buildRunArgs(provider, {
|
|
72643
|
-
source: "session-message",
|
|
72644
|
-
sessionKey: event.sessionKey,
|
|
72645
|
-
prompt: this.buildSessionPrompt({ ...event, messageId }),
|
|
72646
|
-
jobId: event.jobId,
|
|
72647
|
-
agentId: event.agentId,
|
|
72648
|
-
messageId
|
|
72649
|
-
}, aiSessionId, cwd);
|
|
72650
|
-
}
|
|
72651
72686
|
buildRunArgs(provider, request, aiSessionId, cwd = this.resolveAiWorkingDir()) {
|
|
72652
72687
|
const permissionPreset = this.resolveAiPermissionPresetForRun();
|
|
72653
72688
|
const prompt = request.prompt;
|
|
@@ -72795,7 +72830,7 @@ var AiRunner = class {
|
|
|
72795
72830
|
logPath: runContext?.logPath
|
|
72796
72831
|
})
|
|
72797
72832
|
);
|
|
72798
|
-
|
|
72833
|
+
errorWithTimestamp("[okx-agent-task] failed to create user_attention for AI run failure:", attentionErr);
|
|
72799
72834
|
}
|
|
72800
72835
|
}
|
|
72801
72836
|
async reportAiToolFailures(failures, context) {
|
|
@@ -72847,7 +72882,7 @@ var AiRunner = class {
|
|
|
72847
72882
|
reason: "user_attention_create_failed"
|
|
72848
72883
|
}
|
|
72849
72884
|
);
|
|
72850
|
-
|
|
72885
|
+
errorWithTimestamp("[okx-agent-task] failed to create user_attention for AI tool failure:", attentionErr);
|
|
72851
72886
|
}
|
|
72852
72887
|
}
|
|
72853
72888
|
}
|
|
@@ -72862,7 +72897,7 @@ var AiRunner = class {
|
|
|
72862
72897
|
ensureTaskDir(this.logsDir);
|
|
72863
72898
|
await (0, import_promises5.appendFile)((0, import_node_path11.join)(this.logsDir, "llm.log"), formatLlmLogEntry(entry), "utf8");
|
|
72864
72899
|
} catch (err2) {
|
|
72865
|
-
|
|
72900
|
+
errorWithTimestamp("[okx-agent-task] failed to append llm.log:", err2);
|
|
72866
72901
|
}
|
|
72867
72902
|
}
|
|
72868
72903
|
};
|
|
@@ -72892,6 +72927,13 @@ function aiRunToolFailureSentryExtra(failure, context) {
|
|
|
72892
72927
|
return out;
|
|
72893
72928
|
}, {});
|
|
72894
72929
|
}
|
|
72930
|
+
function isAiLifecycleLoggingEnabled(env = process.env) {
|
|
72931
|
+
const raw = env.OKX_A2A_AI_LIFECYCLE_LOGS ?? env.OKX_AGENT_TASK_AI_LIFECYCLE_LOGS;
|
|
72932
|
+
if (!raw) {
|
|
72933
|
+
return true;
|
|
72934
|
+
}
|
|
72935
|
+
return !["0", "false", "no", "off"].includes(raw.trim().toLowerCase());
|
|
72936
|
+
}
|
|
72895
72937
|
function safeProcessCwd() {
|
|
72896
72938
|
try {
|
|
72897
72939
|
return process.cwd();
|
|
@@ -74175,7 +74217,6 @@ var CommandStore = class {
|
|
|
74175
74217
|
myAgentId: params.myAgentId,
|
|
74176
74218
|
toAgentId: params.toAgentId,
|
|
74177
74219
|
toXmtpAddress: params.toXmtpAddress,
|
|
74178
|
-
gatewaySessionKeys: params.gatewaySessionKeys,
|
|
74179
74220
|
createdAt: Date.now()
|
|
74180
74221
|
};
|
|
74181
74222
|
}
|
|
@@ -74339,7 +74380,7 @@ var CommandStore = class {
|
|
|
74339
74380
|
});
|
|
74340
74381
|
continue;
|
|
74341
74382
|
}
|
|
74342
|
-
|
|
74383
|
+
logWithTimestamp(`[okx-agent-task] invalid queued command row id=${row.id} type=${row.type}`);
|
|
74343
74384
|
}
|
|
74344
74385
|
return commands;
|
|
74345
74386
|
}
|
|
@@ -74411,7 +74452,7 @@ var CommandStore = class {
|
|
|
74411
74452
|
status === "processing" ? mtimeMs : null
|
|
74412
74453
|
);
|
|
74413
74454
|
} catch (err2) {
|
|
74414
|
-
|
|
74455
|
+
logWithTimestamp(`[okx-agent-task] failed to import legacy command ${path}:`, err2);
|
|
74415
74456
|
}
|
|
74416
74457
|
}
|
|
74417
74458
|
}
|
|
@@ -76771,6 +76812,53 @@ function selfFilterMiddleware() {
|
|
|
76771
76812
|
};
|
|
76772
76813
|
}
|
|
76773
76814
|
|
|
76815
|
+
// ../core/src/xmtp-sdk/inbound-timing.ts
|
|
76816
|
+
function createInboundTimingTracker(xmtpSentAtMs, xmtpReceivedAtMs = Date.now()) {
|
|
76817
|
+
const durations = {};
|
|
76818
|
+
return {
|
|
76819
|
+
xmtpSentAtMs,
|
|
76820
|
+
xmtpReceivedAtMs,
|
|
76821
|
+
xmtpDeliveryMs: safeDuration(xmtpReceivedAtMs, xmtpSentAtMs),
|
|
76822
|
+
mark(stage, startedAtMs) {
|
|
76823
|
+
const key = stage.endsWith("Ms") ? stage : `${stage}Ms`;
|
|
76824
|
+
const durationMs = safeDuration(Date.now(), startedAtMs);
|
|
76825
|
+
durations[key] = durationMs;
|
|
76826
|
+
return durationMs;
|
|
76827
|
+
},
|
|
76828
|
+
extras(extra = {}) {
|
|
76829
|
+
return {
|
|
76830
|
+
xmtpSentAtMs,
|
|
76831
|
+
xmtpReceivedAtMs,
|
|
76832
|
+
xmtpDeliveryMs: safeDuration(xmtpReceivedAtMs, xmtpSentAtMs),
|
|
76833
|
+
handlerTotalMs: safeDuration(Date.now(), xmtpReceivedAtMs),
|
|
76834
|
+
...durations,
|
|
76835
|
+
...extra
|
|
76836
|
+
};
|
|
76837
|
+
}
|
|
76838
|
+
};
|
|
76839
|
+
}
|
|
76840
|
+
function extractXmtpSentAtMs(msg) {
|
|
76841
|
+
if (typeof msg.sentAtNs === "bigint") {
|
|
76842
|
+
return Number(msg.sentAtNs / 1000000n);
|
|
76843
|
+
}
|
|
76844
|
+
if (typeof msg.sentAtNs === "number") {
|
|
76845
|
+
return Math.floor(msg.sentAtNs / 1e6);
|
|
76846
|
+
}
|
|
76847
|
+
if (msg.sentAt instanceof Date) {
|
|
76848
|
+
return msg.sentAt.getTime();
|
|
76849
|
+
}
|
|
76850
|
+
if (typeof msg.sentAt === "number") {
|
|
76851
|
+
return msg.sentAt;
|
|
76852
|
+
}
|
|
76853
|
+
return Date.now();
|
|
76854
|
+
}
|
|
76855
|
+
function safeDuration(endMs, startMs) {
|
|
76856
|
+
if (!Number.isFinite(endMs) || !Number.isFinite(startMs)) {
|
|
76857
|
+
return 0;
|
|
76858
|
+
}
|
|
76859
|
+
return Math.max(0, Math.round(endMs - startMs));
|
|
76860
|
+
}
|
|
76861
|
+
|
|
76774
76862
|
// ../core/src/xmtp-sdk/middleware/logging.ts
|
|
76775
76863
|
function loggingMiddleware(identity3) {
|
|
76776
76864
|
const tag = `[xmtp-sdk:${identity3.walletAddress ?? "?"}]`;
|
|
@@ -76778,46 +76866,38 @@ function loggingMiddleware(identity3) {
|
|
|
76778
76866
|
const msg = ctx.message;
|
|
76779
76867
|
const conv = ctx.conversation;
|
|
76780
76868
|
const conversationId = conv.id;
|
|
76869
|
+
const xmtpReceivedAtMs = Date.now();
|
|
76870
|
+
const xmtpSentAtMs = extractXmtpSentAtMs(msg);
|
|
76871
|
+
const ownInboxId = ctx.client?.inboxId ?? identity3.inboxId ?? "";
|
|
76781
76872
|
const content3 = JSON.stringify(msg);
|
|
76782
76873
|
const contentSummary = summarizeMessageContent(msg.content);
|
|
76783
76874
|
const baseExtras = {
|
|
76784
76875
|
...agentExtras(identity3),
|
|
76785
76876
|
...jobIdExtras(msg.content),
|
|
76786
76877
|
peerInboxId: msg.senderInboxId,
|
|
76878
|
+
senderInboxId: msg.senderInboxId,
|
|
76879
|
+
ownInboxId,
|
|
76787
76880
|
conversationId,
|
|
76788
76881
|
messageId: msg.id,
|
|
76789
|
-
|
|
76882
|
+
kind: msg.kind ?? "unknown",
|
|
76883
|
+
source: "live",
|
|
76884
|
+
xmtpSentAtMs: String(xmtpSentAtMs),
|
|
76885
|
+
xmtpReceivedAtMs: String(xmtpReceivedAtMs),
|
|
76886
|
+
xmtpDeliveryMs: String(safeDuration(xmtpReceivedAtMs, xmtpSentAtMs)),
|
|
76887
|
+
stage: "inbound/stream_observed"
|
|
76790
76888
|
};
|
|
76791
76889
|
if (conv instanceof Group) {
|
|
76792
76890
|
const groupName = conv.name ?? "unnamed";
|
|
76793
|
-
|
|
76794
|
-
|
|
76795
|
-
let membersFetchFailed = "0";
|
|
76796
|
-
try {
|
|
76797
|
-
const members = await conv.members();
|
|
76798
|
-
memberCount = String(members.length);
|
|
76799
|
-
const addresses = members.flatMap(
|
|
76800
|
-
(m) => m.accountIdentifiers.map((id) => id.identifier)
|
|
76801
|
-
);
|
|
76802
|
-
membersInfo = ` members=[${addresses.join(", ")}]`;
|
|
76803
|
-
} catch (err2) {
|
|
76804
|
-
console.log(`${tag} [group] members fetch failed:`, err2);
|
|
76805
|
-
memberCount = "fetch-failed";
|
|
76806
|
-
membersInfo = " members=[fetch failed]";
|
|
76807
|
-
membersFetchFailed = "1";
|
|
76808
|
-
}
|
|
76809
|
-
console.log(
|
|
76810
|
-
`${tag} [group] conv=${conversationId} name="${groupName}"${membersInfo} sender=${msg.senderInboxId} msg=${msg.id} bytes=${content3.length} ${contentSummary}`
|
|
76891
|
+
logWithTimestamp(
|
|
76892
|
+
`${tag} [group] conv=${conversationId} name="${groupName}" sender=${msg.senderInboxId} msg=${msg.id} bytes=${content3.length} ${contentSummary}`
|
|
76811
76893
|
);
|
|
76812
76894
|
logger.info(LogEvent.MESSAGE_RECEIVED, {
|
|
76813
76895
|
...baseExtras,
|
|
76814
76896
|
chatType: "group",
|
|
76815
|
-
groupName
|
|
76816
|
-
memberCount,
|
|
76817
|
-
membersFetchFailed
|
|
76897
|
+
groupName
|
|
76818
76898
|
});
|
|
76819
76899
|
} else {
|
|
76820
|
-
|
|
76900
|
+
logWithTimestamp(
|
|
76821
76901
|
`${tag} [dm] conv=${conversationId} sender=${msg.senderInboxId} msg=${msg.id} bytes=${content3.length} ${contentSummary}`
|
|
76822
76902
|
);
|
|
76823
76903
|
logger.info(LogEvent.MESSAGE_RECEIVED, {
|
|
@@ -83103,11 +83183,11 @@ async function createAgentWithInstallationPrune(signer, options, context) {
|
|
|
83103
83183
|
if (!oldest) {
|
|
83104
83184
|
throw err2;
|
|
83105
83185
|
}
|
|
83106
|
-
|
|
83186
|
+
logWithTimestamp(
|
|
83107
83187
|
`${prefix} installation cap reached for ${context.address} (agentId=${context.agentId}); revoking oldest installation ${oldest.id}`
|
|
83108
83188
|
);
|
|
83109
83189
|
await Client.revokeInstallations(signer, inboxId, [oldest.bytes], options.env, options.gatewayHost);
|
|
83110
|
-
|
|
83190
|
+
logWithTimestamp(
|
|
83111
83191
|
`${prefix} revoked oldest installation for ${context.address} (agentId=${context.agentId}); retrying client init`
|
|
83112
83192
|
);
|
|
83113
83193
|
return await Agent.create(signer, options);
|
|
@@ -83201,7 +83281,7 @@ function loadSensitiveWordsFromCache(dataDir) {
|
|
|
83201
83281
|
}
|
|
83202
83282
|
return null;
|
|
83203
83283
|
} catch (err2) {
|
|
83204
|
-
|
|
83284
|
+
logWithTimestamp("[xmtp-sdk] failed to read sensitive-words.json cache:", err2);
|
|
83205
83285
|
logger.error(LogEvent.CACHE_LOAD_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), { cacheName: "sensitive-words" });
|
|
83206
83286
|
return null;
|
|
83207
83287
|
}
|
|
@@ -83211,19 +83291,19 @@ function saveSensitiveWordsToCache(dataDir, words) {
|
|
|
83211
83291
|
ensureCacheDir(dataDir);
|
|
83212
83292
|
(0, import_node_fs10.writeFileSync)(cachePath(dataDir, "sensitive-words.json"), JSON.stringify(words));
|
|
83213
83293
|
} catch (err2) {
|
|
83214
|
-
|
|
83294
|
+
logWithTimestamp(`[xmtp-sdk] failed to write sensitive-words.json:`, err2);
|
|
83215
83295
|
logger.error(LogEvent.CACHE_WRITE_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), { cacheName: "sensitive-words" });
|
|
83216
83296
|
}
|
|
83217
83297
|
}
|
|
83218
83298
|
async function loadSensitiveWordsWith(dataDir, fetcher) {
|
|
83219
83299
|
if (!fetcher) {
|
|
83220
|
-
|
|
83300
|
+
logWithTimestamp("[xmtp-sdk] sensitive-words fetcher not provided by host");
|
|
83221
83301
|
return loadSensitiveWordsFromCache(dataDir);
|
|
83222
83302
|
}
|
|
83223
83303
|
const cached = loadSensitiveWordsFromCache(dataDir);
|
|
83224
83304
|
try {
|
|
83225
83305
|
const words = await fetcher();
|
|
83226
|
-
|
|
83306
|
+
logWithTimestamp(`[xmtp-sdk] fetched ${words.length} sensitive words from API`);
|
|
83227
83307
|
saveSensitiveWordsToCache(dataDir, words);
|
|
83228
83308
|
logger.info(LogEvent.CONFIG_SENSITIVE_WORDS_REFRESHED, {
|
|
83229
83309
|
count: String(words.length),
|
|
@@ -83231,17 +83311,17 @@ async function loadSensitiveWordsWith(dataDir, fetcher) {
|
|
|
83231
83311
|
});
|
|
83232
83312
|
return words;
|
|
83233
83313
|
} catch (err2) {
|
|
83234
|
-
|
|
83314
|
+
logWithTimestamp(`[xmtp-sdk] API fetch for sensitive words failed:`, err2);
|
|
83235
83315
|
}
|
|
83236
83316
|
if (cached) {
|
|
83237
|
-
|
|
83317
|
+
logWithTimestamp(`[xmtp-sdk] using ${cached.length} cached sensitive words from disk`);
|
|
83238
83318
|
logger.info(LogEvent.CONFIG_SENSITIVE_WORDS_REFRESHED, {
|
|
83239
83319
|
count: String(cached.length),
|
|
83240
83320
|
source: "cache"
|
|
83241
83321
|
});
|
|
83242
83322
|
return cached;
|
|
83243
83323
|
}
|
|
83244
|
-
|
|
83324
|
+
logWithTimestamp(`[xmtp-sdk] sensitive-words load failed: neither API nor local cache available`);
|
|
83245
83325
|
logger.error(LogEvent.CONFIG_LOAD_FAILED, void 0, {
|
|
83246
83326
|
config: "sensitive-words",
|
|
83247
83327
|
reason: "no-api-no-cache"
|
|
@@ -83260,7 +83340,7 @@ function loadSystemConfigFromCache(dataDir) {
|
|
|
83260
83340
|
}
|
|
83261
83341
|
return null;
|
|
83262
83342
|
} catch (err2) {
|
|
83263
|
-
|
|
83343
|
+
logWithTimestamp("[xmtp-sdk] failed to read system-config.json cache:", err2);
|
|
83264
83344
|
logger.error(LogEvent.CACHE_LOAD_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), { cacheName: "system-config" });
|
|
83265
83345
|
return null;
|
|
83266
83346
|
}
|
|
@@ -83270,18 +83350,18 @@ function saveSystemConfigToCache(dataDir, config) {
|
|
|
83270
83350
|
ensureCacheDir(dataDir);
|
|
83271
83351
|
(0, import_node_fs10.writeFileSync)(cachePath(dataDir, "system-config.json"), JSON.stringify(config));
|
|
83272
83352
|
} catch (err2) {
|
|
83273
|
-
|
|
83353
|
+
logWithTimestamp(`[xmtp-sdk] failed to write system-config.json:`, err2);
|
|
83274
83354
|
logger.error(LogEvent.CACHE_WRITE_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), { cacheName: "system-config" });
|
|
83275
83355
|
}
|
|
83276
83356
|
}
|
|
83277
83357
|
async function loadSystemConfigWith(dataDir, fetcher) {
|
|
83278
83358
|
if (!fetcher) {
|
|
83279
|
-
|
|
83359
|
+
logWithTimestamp("[xmtp-sdk] system-config fetcher not provided by host");
|
|
83280
83360
|
return loadSystemConfigFromCache(dataDir);
|
|
83281
83361
|
}
|
|
83282
83362
|
try {
|
|
83283
83363
|
const config = await fetcher();
|
|
83284
|
-
|
|
83364
|
+
logWithTimestamp(
|
|
83285
83365
|
`[xmtp-sdk] fetched system-config from API: ${Object.keys(config).length} keys`
|
|
83286
83366
|
);
|
|
83287
83367
|
saveSystemConfigToCache(dataDir, config);
|
|
@@ -83291,11 +83371,11 @@ async function loadSystemConfigWith(dataDir, fetcher) {
|
|
|
83291
83371
|
});
|
|
83292
83372
|
return config;
|
|
83293
83373
|
} catch (err2) {
|
|
83294
|
-
|
|
83374
|
+
logWithTimestamp(`[xmtp-sdk] API fetch for system-config failed:`, err2);
|
|
83295
83375
|
}
|
|
83296
83376
|
const cached = loadSystemConfigFromCache(dataDir);
|
|
83297
83377
|
if (cached) {
|
|
83298
|
-
|
|
83378
|
+
logWithTimestamp(
|
|
83299
83379
|
`[xmtp-sdk] using cached system-config from disk: ${Object.keys(cached).length} keys`
|
|
83300
83380
|
);
|
|
83301
83381
|
logger.info(LogEvent.CONFIG_SYSTEM_REFRESHED, {
|
|
@@ -83304,7 +83384,7 @@ async function loadSystemConfigWith(dataDir, fetcher) {
|
|
|
83304
83384
|
});
|
|
83305
83385
|
return cached;
|
|
83306
83386
|
}
|
|
83307
|
-
|
|
83387
|
+
logWithTimestamp(`[xmtp-sdk] system-config load failed: neither API nor local cache available`);
|
|
83308
83388
|
logger.error(LogEvent.CONFIG_LOAD_FAILED, void 0, {
|
|
83309
83389
|
config: "system-config",
|
|
83310
83390
|
reason: "no-api-no-cache"
|
|
@@ -83328,7 +83408,7 @@ function loadSyncByAddress(dataDir) {
|
|
|
83328
83408
|
}
|
|
83329
83409
|
}
|
|
83330
83410
|
} catch (err2) {
|
|
83331
|
-
|
|
83411
|
+
logWithTimestamp("[xmtp-sdk] failed to read last-sync.json cache:", err2);
|
|
83332
83412
|
logger.error(LogEvent.CACHE_LOAD_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), { cacheName: "last-sync" });
|
|
83333
83413
|
}
|
|
83334
83414
|
return map;
|
|
@@ -83352,7 +83432,7 @@ function saveSyncForAddress(dataDir, address, timestampMs) {
|
|
|
83352
83432
|
data.syncByAddress[address] = timestampMs;
|
|
83353
83433
|
(0, import_node_fs10.writeFileSync)(path, JSON.stringify(data, null, 2));
|
|
83354
83434
|
} catch (err2) {
|
|
83355
|
-
|
|
83435
|
+
logWithTimestamp(
|
|
83356
83436
|
`[xmtp-sdk] failed to write last-sync.json (address=${address}):`,
|
|
83357
83437
|
err2
|
|
83358
83438
|
);
|
|
@@ -83461,6 +83541,18 @@ function parseTips(raw) {
|
|
|
83461
83541
|
function parseStringArray(raw) {
|
|
83462
83542
|
return Array.isArray(raw) ? raw.filter((value) => typeof value === "string" && value.length > 0) : [];
|
|
83463
83543
|
}
|
|
83544
|
+
function readOptionalString(record, key) {
|
|
83545
|
+
const value = record[key];
|
|
83546
|
+
return typeof value === "string" ? value : "";
|
|
83547
|
+
}
|
|
83548
|
+
function readMinVersion(raw) {
|
|
83549
|
+
const container = raw.minVersion && typeof raw.minVersion === "object" && !Array.isArray(raw.minVersion) ? raw.minVersion : raw.minVersions && typeof raw.minVersions === "object" && !Array.isArray(raw.minVersions) ? raw.minVersions : {};
|
|
83550
|
+
return {
|
|
83551
|
+
cli: readOptionalString(container, "cli") || readOptionalString(raw, "cliMinVersion"),
|
|
83552
|
+
openclaw: readOptionalString(container, "openclaw") || readOptionalString(raw, "openclawMinVersion"),
|
|
83553
|
+
hermes: readOptionalString(container, "hermes") || readOptionalString(raw, "hermesMinVersion")
|
|
83554
|
+
};
|
|
83555
|
+
}
|
|
83464
83556
|
function parseExtConfig(raw) {
|
|
83465
83557
|
const obj = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
83466
83558
|
return {
|
|
@@ -83482,13 +83574,14 @@ function parseSystemConfig(raw) {
|
|
|
83482
83574
|
acc.push({ address, inboxId, type });
|
|
83483
83575
|
return acc;
|
|
83484
83576
|
}, []) : [];
|
|
83577
|
+
const minVersion = readMinVersion(raw);
|
|
83485
83578
|
return {
|
|
83486
83579
|
heartbeatInterval: typeof raw.heartbeatInterval === "number" ? raw.heartbeatInterval : SYSTEM_CONFIG_DEFAULTS.heartbeatInterval,
|
|
83487
83580
|
maxFileSizeBytes: typeof raw.maxFileSizeBytes === "number" && Number.isFinite(raw.maxFileSizeBytes) && raw.maxFileSizeBytes > 0 ? raw.maxFileSizeBytes : SYSTEM_CONFIG_DEFAULTS.maxFileSizeBytes,
|
|
83488
83581
|
sensitiveUploadReg: parseStringArray(raw.SENSITIVE_UPLOAD_REG),
|
|
83489
83582
|
accounts,
|
|
83490
83583
|
sentryDsn: typeof raw.sentryDsn === "string" ? raw.sentryDsn : "",
|
|
83491
|
-
|
|
83584
|
+
minVersion,
|
|
83492
83585
|
extConfig: parseExtConfig(raw.extConfig)
|
|
83493
83586
|
};
|
|
83494
83587
|
}
|
|
@@ -83537,11 +83630,7 @@ var XmtpService = class _XmtpService {
|
|
|
83537
83630
|
_initFailures = [];
|
|
83538
83631
|
_backupReady = Promise.resolve();
|
|
83539
83632
|
_onAfterInitError = null;
|
|
83540
|
-
|
|
83541
|
-
_pluginVersionStatus = {
|
|
83542
|
-
unavailable: false,
|
|
83543
|
-
minVersion: ""
|
|
83544
|
-
};
|
|
83633
|
+
_cliVersion = "";
|
|
83545
83634
|
dataDir = DEFAULT_DATA_DIR;
|
|
83546
83635
|
syncByAddress = /* @__PURE__ */ new Map();
|
|
83547
83636
|
agentListFingerprint;
|
|
@@ -83572,12 +83661,12 @@ var XmtpService = class _XmtpService {
|
|
|
83572
83661
|
return this.dataDir;
|
|
83573
83662
|
}
|
|
83574
83663
|
async init() {
|
|
83575
|
-
|
|
83664
|
+
logWithTimestamp("[xmtp-sdk] init: loading system-config first to gate on plugin version...");
|
|
83576
83665
|
this._initFailures = [];
|
|
83577
83666
|
try {
|
|
83578
83667
|
ensureA2aTaskDir(this.dataDir);
|
|
83579
83668
|
} catch (err2) {
|
|
83580
|
-
|
|
83669
|
+
logWithTimestamp(`[xmtp-sdk] failed to create data directory: ${this.dataDir}`, err2);
|
|
83581
83670
|
logger.error(
|
|
83582
83671
|
LogEvent.AGENT_DB_DIR_CREATE_FAILED,
|
|
83583
83672
|
err2 instanceof Error ? err2 : new Error(String(err2)),
|
|
@@ -83589,11 +83678,11 @@ var XmtpService = class _XmtpService {
|
|
|
83589
83678
|
]);
|
|
83590
83679
|
if (systemConfigResult.status === "fulfilled" && systemConfigResult.value) {
|
|
83591
83680
|
this.systemConfig = parseSystemConfig(systemConfigResult.value);
|
|
83592
|
-
this.
|
|
83593
|
-
if (this.
|
|
83681
|
+
const cliMinVersion = this.systemConfig.minVersion.cli;
|
|
83682
|
+
if (this.isCliBelowMinVersion(cliMinVersion)) {
|
|
83594
83683
|
this._initialized = false;
|
|
83595
|
-
|
|
83596
|
-
`[xmtp-sdk] init
|
|
83684
|
+
logWithTimestamp(
|
|
83685
|
+
`[xmtp-sdk] init paused: cli v${this._cliVersion} is below the required minimum v${cliMinVersion}; daemon updater will attempt a forced update.`
|
|
83597
83686
|
);
|
|
83598
83687
|
return;
|
|
83599
83688
|
}
|
|
@@ -83602,7 +83691,7 @@ var XmtpService = class _XmtpService {
|
|
|
83602
83691
|
"loadSystemConfig returned null (neither API nor local cache is available)"
|
|
83603
83692
|
);
|
|
83604
83693
|
this._initFailures.push({ action: "loadSystemConfig", error: err2 });
|
|
83605
|
-
|
|
83694
|
+
logWithTimestamp("[xmtp-sdk] init: loadSystemConfig failed:", err2.message);
|
|
83606
83695
|
}
|
|
83607
83696
|
const [sensitiveWordsResult, clientsResult] = await Promise.allSettled([
|
|
83608
83697
|
loadSensitiveWordsWith(this.dataDir, this.tools.fetchSensitiveWords),
|
|
@@ -83612,7 +83701,7 @@ var XmtpService = class _XmtpService {
|
|
|
83612
83701
|
this._onAfterInitError = null;
|
|
83613
83702
|
this._backupReady = afterInit ? afterInit().catch((err2) => {
|
|
83614
83703
|
this._onAfterInitError = err2 instanceof Error ? err2 : new Error(String(err2));
|
|
83615
|
-
|
|
83704
|
+
logWithTimestamp(
|
|
83616
83705
|
"[xmtp-sdk] tools.onAfterInit failed (will retry on first use):",
|
|
83617
83706
|
err2
|
|
83618
83707
|
);
|
|
@@ -83622,39 +83711,36 @@ var XmtpService = class _XmtpService {
|
|
|
83622
83711
|
} else {
|
|
83623
83712
|
this.sensitiveWords = null;
|
|
83624
83713
|
const reason = sensitiveWordsResult.status === "rejected" ? sensitiveWordsResult.reason : "loadSensitiveWords returned null (neither API nor local cache is available)";
|
|
83625
|
-
|
|
83714
|
+
logWithTimestamp(
|
|
83626
83715
|
"[xmtp-sdk] init: loadSensitiveWords failed; will lazy-retry during message handling:",
|
|
83627
83716
|
reason
|
|
83628
83717
|
);
|
|
83629
83718
|
}
|
|
83630
83719
|
if (clientsResult.status === "fulfilled") {
|
|
83631
|
-
|
|
83720
|
+
logWithTimestamp(
|
|
83632
83721
|
`[xmtp-sdk] init: XMTP clients initialized, ${clientsResult.value.size} clients`
|
|
83633
83722
|
);
|
|
83634
83723
|
} else {
|
|
83635
83724
|
const err2 = clientsResult.reason instanceof Error ? clientsResult.reason : new Error(String(clientsResult.reason));
|
|
83636
83725
|
this._initFailures.push({ action: "initXmtpInstall", error: err2 });
|
|
83637
|
-
|
|
83726
|
+
logWithTimestamp("[xmtp-sdk] init: initXmtpInstall failed:", err2.message);
|
|
83638
83727
|
}
|
|
83639
83728
|
this._initialized = this._initFailures.length === 0;
|
|
83640
|
-
if (this._initialized) {
|
|
83641
|
-
this.evaluatePluginVersion();
|
|
83642
|
-
}
|
|
83643
83729
|
const clientCount = clientsResult.status === "fulfilled" ? clientsResult.value.size : 0;
|
|
83644
|
-
|
|
83730
|
+
logWithTimestamp(
|
|
83645
83731
|
`[xmtp-sdk] init done: initialized=${this._initialized}, clients=${clientCount}, failures=${this._initFailures.length}`
|
|
83646
83732
|
);
|
|
83647
83733
|
}
|
|
83648
83734
|
async retryFailedInit() {
|
|
83649
83735
|
const remaining = [];
|
|
83650
83736
|
for (const failure of this._initFailures) {
|
|
83651
|
-
|
|
83737
|
+
logWithTimestamp(`[xmtp-sdk] retryFailedInit: retrying ${failure.action}...`);
|
|
83652
83738
|
try {
|
|
83653
83739
|
if (failure.action === "loadSystemConfig") {
|
|
83654
83740
|
const config = await loadSystemConfigWith(this.dataDir, this.tools.fetchSystemConfig);
|
|
83655
83741
|
if (config) {
|
|
83656
83742
|
this.systemConfig = parseSystemConfig(config);
|
|
83657
|
-
|
|
83743
|
+
logWithTimestamp(
|
|
83658
83744
|
`[xmtp-sdk] retryFailedInit: loadSystemConfig retry succeeded`
|
|
83659
83745
|
);
|
|
83660
83746
|
} else {
|
|
@@ -83667,12 +83753,12 @@ var XmtpService = class _XmtpService {
|
|
|
83667
83753
|
}
|
|
83668
83754
|
} else if (failure.action === "initXmtpInstall") {
|
|
83669
83755
|
await this.initXmtpInstall();
|
|
83670
|
-
|
|
83756
|
+
logWithTimestamp(`[xmtp-sdk] retryFailedInit: initXmtpInstall retry succeeded`);
|
|
83671
83757
|
}
|
|
83672
83758
|
} catch (err2) {
|
|
83673
83759
|
const error = err2 instanceof Error ? err2 : new Error(String(err2));
|
|
83674
83760
|
remaining.push({ action: failure.action, error });
|
|
83675
|
-
|
|
83761
|
+
logWithTimestamp(
|
|
83676
83762
|
`[xmtp-sdk] retryFailedInit: ${failure.action} retry failed:`,
|
|
83677
83763
|
error.message
|
|
83678
83764
|
);
|
|
@@ -83681,18 +83767,17 @@ var XmtpService = class _XmtpService {
|
|
|
83681
83767
|
this._initFailures = remaining;
|
|
83682
83768
|
if (remaining.length === 0) {
|
|
83683
83769
|
this._initialized = true;
|
|
83684
|
-
this.evaluatePluginVersion();
|
|
83685
83770
|
}
|
|
83686
83771
|
return { ok: remaining.length === 0, failures: remaining };
|
|
83687
83772
|
}
|
|
83688
83773
|
async initXmtpInstall() {
|
|
83689
|
-
|
|
83774
|
+
logWithTimestamp(`==============XMTP_ENV: ${this.env}==============`);
|
|
83690
83775
|
const initStart = Date.now();
|
|
83691
83776
|
const dbDir = this.dataDir;
|
|
83692
83777
|
try {
|
|
83693
83778
|
ensureA2aTaskDir(dbDir);
|
|
83694
83779
|
} catch (err2) {
|
|
83695
|
-
|
|
83780
|
+
logWithTimestamp(`[xmtp-sdk] failed to create data directory: ${dbDir}`, err2);
|
|
83696
83781
|
logger.error(
|
|
83697
83782
|
LogEvent.AGENT_DB_DIR_CREATE_FAILED,
|
|
83698
83783
|
err2 instanceof Error ? err2 : new Error(String(err2)),
|
|
@@ -83701,7 +83786,7 @@ var XmtpService = class _XmtpService {
|
|
|
83701
83786
|
return this.clients;
|
|
83702
83787
|
}
|
|
83703
83788
|
this.syncByAddress = loadSyncByAddress(this.dataDir);
|
|
83704
|
-
|
|
83789
|
+
logWithTimestamp(
|
|
83705
83790
|
`[xmtp-sdk] sync timestamps: ${this.syncByAddress.size} addresses on record`
|
|
83706
83791
|
);
|
|
83707
83792
|
if (!this.tools.listAllAgentsWithMetadata) {
|
|
@@ -83714,7 +83799,7 @@ var XmtpService = class _XmtpService {
|
|
|
83714
83799
|
this.agentListFingerprint = agentList.fingerprint;
|
|
83715
83800
|
this.setAgentStatusIndex(agentList.allAgents ?? agentList.agents);
|
|
83716
83801
|
const agents = agentList.agents;
|
|
83717
|
-
|
|
83802
|
+
logWithTimestamp(
|
|
83718
83803
|
`[xmtp-sdk] fetched ${agents.length} agents from onchainos changed=${agentList.changed} duration=${agentList.durationMs}ms`
|
|
83719
83804
|
);
|
|
83720
83805
|
this.allAgents = agents;
|
|
@@ -83725,7 +83810,7 @@ var XmtpService = class _XmtpService {
|
|
|
83725
83810
|
onchainosAgentIds: agents.map((a) => a.agentId).join(",")
|
|
83726
83811
|
});
|
|
83727
83812
|
}).catch((err2) => {
|
|
83728
|
-
|
|
83813
|
+
logWithTimestamp("[xmtp-sdk] notifyAgentsWakeup unexpected error:", err2);
|
|
83729
83814
|
logger.error(
|
|
83730
83815
|
LogEvent.NOTIFY_AGENTS_WAKEUP_FAILED,
|
|
83731
83816
|
err2 instanceof Error ? err2 : new Error(String(err2)),
|
|
@@ -83755,7 +83840,7 @@ var XmtpService = class _XmtpService {
|
|
|
83755
83840
|
const { address, agent, agentInfo } = r.value;
|
|
83756
83841
|
this.stoppedAddresses.delete(address.toLowerCase());
|
|
83757
83842
|
this.clients.set(address, agent);
|
|
83758
|
-
|
|
83843
|
+
logWithTimestamp(
|
|
83759
83844
|
`[xmtp-sdk] identity initialized: ${address} (agentId=${agentInfo.agentId})`
|
|
83760
83845
|
);
|
|
83761
83846
|
logger.info(LogEvent.AGENT_CLIENT_CREATED, {
|
|
@@ -83768,7 +83853,7 @@ var XmtpService = class _XmtpService {
|
|
|
83768
83853
|
});
|
|
83769
83854
|
} else {
|
|
83770
83855
|
failedAgents.push(agents[i]);
|
|
83771
|
-
|
|
83856
|
+
logWithTimestamp(
|
|
83772
83857
|
`[xmtp-sdk] identity init failed: ${agents[i].communicationAddress} (agentId=${agents[i].agentId})`,
|
|
83773
83858
|
r.reason
|
|
83774
83859
|
);
|
|
@@ -83784,7 +83869,7 @@ var XmtpService = class _XmtpService {
|
|
|
83784
83869
|
}
|
|
83785
83870
|
}
|
|
83786
83871
|
if (failedAgents.length > 0) {
|
|
83787
|
-
|
|
83872
|
+
logWithTimestamp(
|
|
83788
83873
|
`[xmtp-sdk] ${failedAgents.length} client(s) failed to initialize, retrying in 1s...`
|
|
83789
83874
|
);
|
|
83790
83875
|
await new Promise((r) => setTimeout(r, 1e3));
|
|
@@ -83795,7 +83880,7 @@ var XmtpService = class _XmtpService {
|
|
|
83795
83880
|
const { address, agent, agentInfo } = r.value;
|
|
83796
83881
|
this.stoppedAddresses.delete(address.toLowerCase());
|
|
83797
83882
|
this.clients.set(address, agent);
|
|
83798
|
-
|
|
83883
|
+
logWithTimestamp(
|
|
83799
83884
|
`[xmtp-sdk] retry succeeded: ${address} (agentId=${agentInfo.agentId})`
|
|
83800
83885
|
);
|
|
83801
83886
|
logger.info(LogEvent.AGENT_CLIENT_CREATED, {
|
|
@@ -83808,7 +83893,7 @@ var XmtpService = class _XmtpService {
|
|
|
83808
83893
|
});
|
|
83809
83894
|
} else {
|
|
83810
83895
|
const info = failedAgents[i];
|
|
83811
|
-
|
|
83896
|
+
logWithTimestamp(
|
|
83812
83897
|
`[xmtp-sdk] retry still failed: ${info.communicationAddress} (agentId=${info.agentId})`,
|
|
83813
83898
|
r.reason
|
|
83814
83899
|
);
|
|
@@ -83824,7 +83909,7 @@ var XmtpService = class _XmtpService {
|
|
|
83824
83909
|
}
|
|
83825
83910
|
}
|
|
83826
83911
|
}
|
|
83827
|
-
|
|
83912
|
+
logWithTimestamp(
|
|
83828
83913
|
`[xmtp-sdk] initialized ${this.clients.size}/${agents.length} clients in total`
|
|
83829
83914
|
);
|
|
83830
83915
|
await this.startListening();
|
|
@@ -83842,7 +83927,7 @@ var XmtpService = class _XmtpService {
|
|
|
83842
83927
|
}
|
|
83843
83928
|
async refreshAgents() {
|
|
83844
83929
|
if (this.refreshAgentsInFlight) {
|
|
83845
|
-
|
|
83930
|
+
logWithTimestamp(`[xmtp-sdk] refresh: a refresh is already in flight, reusing the same promise`);
|
|
83846
83931
|
return this.refreshAgentsInFlight;
|
|
83847
83932
|
}
|
|
83848
83933
|
this.refreshAgentsInFlight = this.runRefreshAgents().finally(() => {
|
|
@@ -83867,7 +83952,7 @@ var XmtpService = class _XmtpService {
|
|
|
83867
83952
|
changed = agentList.changed;
|
|
83868
83953
|
} catch (err2) {
|
|
83869
83954
|
if (isSessionExpiredError(err2)) {
|
|
83870
|
-
|
|
83955
|
+
logWithTimestamp(
|
|
83871
83956
|
"[xmtp-sdk] refresh: onchainos session expired, taking all local clients offline"
|
|
83872
83957
|
);
|
|
83873
83958
|
logger.info(LogEvent.AGENT_REFRESH_SESSION_EXPIRED, {
|
|
@@ -83901,11 +83986,11 @@ var XmtpService = class _XmtpService {
|
|
|
83901
83986
|
try {
|
|
83902
83987
|
this.stoppedAddresses.add(address.toLowerCase());
|
|
83903
83988
|
client.stop();
|
|
83904
|
-
|
|
83989
|
+
logWithTimestamp(
|
|
83905
83990
|
`[xmtp-sdk] refresh: stopped client: ${address} (agentId=${agentInfo.agentId})`
|
|
83906
83991
|
);
|
|
83907
83992
|
} catch (err2) {
|
|
83908
|
-
|
|
83993
|
+
logWithTimestamp(`[xmtp-sdk] refresh: failed to stop client: ${address}`, err2);
|
|
83909
83994
|
logger.error(LogEvent.AGENT_REFRESH_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), {
|
|
83910
83995
|
walletAddress: address,
|
|
83911
83996
|
onchainosAgentId: agentInfo.agentId,
|
|
@@ -83927,7 +84012,7 @@ var XmtpService = class _XmtpService {
|
|
|
83927
84012
|
try {
|
|
83928
84013
|
ensureA2aTaskDir(dbDir);
|
|
83929
84014
|
} catch (err2) {
|
|
83930
|
-
|
|
84015
|
+
logWithTimestamp(`[xmtp-sdk] refresh: failed to create data directory: ${dbDir}`, err2);
|
|
83931
84016
|
logger.error(LogEvent.AGENT_REFRESH_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), {
|
|
83932
84017
|
onchainosAgentId: "*",
|
|
83933
84018
|
phase: "mkdir",
|
|
@@ -83964,7 +84049,7 @@ var XmtpService = class _XmtpService {
|
|
|
83964
84049
|
const { address, agentInfo } = r.value;
|
|
83965
84050
|
this.stoppedAddresses.delete(address.toLowerCase());
|
|
83966
84051
|
this.clients.set(address, r.value.agent);
|
|
83967
|
-
|
|
84052
|
+
logWithTimestamp(
|
|
83968
84053
|
`[xmtp-sdk] refresh: identity initialized: ${address} (agentId=${agentInfo.agentId})`
|
|
83969
84054
|
);
|
|
83970
84055
|
logger.info(LogEvent.AGENT_CLIENT_CREATED, {
|
|
@@ -83978,7 +84063,7 @@ var XmtpService = class _XmtpService {
|
|
|
83978
84063
|
});
|
|
83979
84064
|
} else {
|
|
83980
84065
|
failedAgents.push(added[i]);
|
|
83981
|
-
|
|
84066
|
+
logWithTimestamp(
|
|
83982
84067
|
`[xmtp-sdk] refresh: identity init failed: ${added[i].communicationAddress} (agentId=${added[i].agentId})`,
|
|
83983
84068
|
r.reason
|
|
83984
84069
|
);
|
|
@@ -83995,7 +84080,7 @@ var XmtpService = class _XmtpService {
|
|
|
83995
84080
|
}
|
|
83996
84081
|
}
|
|
83997
84082
|
if (failedAgents.length > 0) {
|
|
83998
|
-
|
|
84083
|
+
logWithTimestamp(
|
|
83999
84084
|
`[xmtp-sdk] refresh: ${failedAgents.length} client(s) failed to initialize, retrying in 1s...`
|
|
84000
84085
|
);
|
|
84001
84086
|
await new Promise((r) => setTimeout(r, 1e3));
|
|
@@ -84006,7 +84091,7 @@ var XmtpService = class _XmtpService {
|
|
|
84006
84091
|
const { address, agentInfo } = r.value;
|
|
84007
84092
|
this.stoppedAddresses.delete(address.toLowerCase());
|
|
84008
84093
|
this.clients.set(address, r.value.agent);
|
|
84009
|
-
|
|
84094
|
+
logWithTimestamp(
|
|
84010
84095
|
`[xmtp-sdk] refresh: retry succeeded: ${address} (agentId=${agentInfo.agentId})`
|
|
84011
84096
|
);
|
|
84012
84097
|
logger.info(LogEvent.AGENT_CLIENT_CREATED, {
|
|
@@ -84020,7 +84105,7 @@ var XmtpService = class _XmtpService {
|
|
|
84020
84105
|
});
|
|
84021
84106
|
} else {
|
|
84022
84107
|
const info = failedAgents[i];
|
|
84023
|
-
|
|
84108
|
+
logWithTimestamp(
|
|
84024
84109
|
`[xmtp-sdk] refresh: retry still failed: ${info.communicationAddress} (agentId=${info.agentId})`,
|
|
84025
84110
|
r.reason
|
|
84026
84111
|
);
|
|
@@ -84043,11 +84128,11 @@ var XmtpService = class _XmtpService {
|
|
|
84043
84128
|
for (const agentInfo of added) {
|
|
84044
84129
|
const address = agentInfo.communicationAddress;
|
|
84045
84130
|
if (this.syncByAddress.has(address) && this.clients.has(address)) {
|
|
84046
|
-
|
|
84131
|
+
logWithTimestamp(
|
|
84047
84132
|
`[xmtp-sdk] refresh: ${address} has a prior sync timestamp, triggering offline replay`
|
|
84048
84133
|
);
|
|
84049
84134
|
this.replayOfflineMessagesForAddress(address).catch((err2) => {
|
|
84050
|
-
|
|
84135
|
+
logWithTimestamp(`[xmtp-sdk] refresh: ${address} offline replay failed:`, err2);
|
|
84051
84136
|
logger.error(
|
|
84052
84137
|
LogEvent.OFFLINE_REPLAY_FAILED,
|
|
84053
84138
|
err2 instanceof Error ? err2 : new Error(String(err2)),
|
|
@@ -84155,13 +84240,13 @@ var XmtpService = class _XmtpService {
|
|
|
84155
84240
|
);
|
|
84156
84241
|
if (result !== null) {
|
|
84157
84242
|
this.sensitiveWords = result;
|
|
84158
|
-
|
|
84243
|
+
logWithTimestamp(
|
|
84159
84244
|
`[xmtp-sdk] lazy-retry sensitive-words succeeded: ${result.length} entries`
|
|
84160
84245
|
);
|
|
84161
84246
|
return result;
|
|
84162
84247
|
}
|
|
84163
84248
|
this.sensitiveWordsLastFailedAtMs = Date.now();
|
|
84164
|
-
|
|
84249
|
+
logWithTimestamp(
|
|
84165
84250
|
"[xmtp-sdk] lazy-retry sensitive-words failed, entering cooldown"
|
|
84166
84251
|
);
|
|
84167
84252
|
return null;
|
|
@@ -84174,27 +84259,14 @@ var XmtpService = class _XmtpService {
|
|
|
84174
84259
|
getSystemConfig() {
|
|
84175
84260
|
return this.systemConfig;
|
|
84176
84261
|
}
|
|
84177
|
-
// The
|
|
84178
|
-
//
|
|
84179
|
-
//
|
|
84180
|
-
|
|
84181
|
-
|
|
84182
|
-
|
|
84183
|
-
|
|
84184
|
-
|
|
84185
|
-
get pluginVersionStatus() {
|
|
84186
|
-
return this._pluginVersionStatus;
|
|
84187
|
-
}
|
|
84188
|
-
evaluatePluginVersion() {
|
|
84189
|
-
const min = this.systemConfig.minAvailablePluginVersion;
|
|
84190
|
-
if (!min || !isValidSemver(min) || !isValidSemver(this._pluginVersion)) {
|
|
84191
|
-
this._pluginVersionStatus = { unavailable: false, minVersion: min ?? "" };
|
|
84192
|
-
return;
|
|
84193
|
-
}
|
|
84194
|
-
this._pluginVersionStatus = {
|
|
84195
|
-
unavailable: semverLt(this._pluginVersion, min),
|
|
84196
|
-
minVersion: min
|
|
84197
|
-
};
|
|
84262
|
+
// The daemon reports its own build version before init(); startup can pause
|
|
84263
|
+
// before XMTP clients are created while the node listener performs the actual
|
|
84264
|
+
// forced update.
|
|
84265
|
+
setCliVersion(version2) {
|
|
84266
|
+
this._cliVersion = version2 ?? "";
|
|
84267
|
+
}
|
|
84268
|
+
isCliBelowMinVersion(minVersion) {
|
|
84269
|
+
return Boolean(minVersion) && isValidSemver(minVersion) && isValidSemver(this._cliVersion) && semverLt(this._cliVersion, minVersion);
|
|
84198
84270
|
}
|
|
84199
84271
|
// Force-refresh systemConfig from onchainos API (falls back to disk
|
|
84200
84272
|
// cache). Single in-flight promise is shared by concurrent callers so
|
|
@@ -84209,7 +84281,6 @@ var XmtpService = class _XmtpService {
|
|
|
84209
84281
|
const raw = await loadSystemConfigWith(this.dataDir, this.tools.fetchSystemConfig);
|
|
84210
84282
|
if (raw) {
|
|
84211
84283
|
this.systemConfig = parseSystemConfig(raw);
|
|
84212
|
-
this.evaluatePluginVersion();
|
|
84213
84284
|
}
|
|
84214
84285
|
} finally {
|
|
84215
84286
|
this.systemConfigRefreshInflight = null;
|
|
@@ -84260,7 +84331,7 @@ var XmtpService = class _XmtpService {
|
|
|
84260
84331
|
async allowGroup(myXmtpAddress, groupId) {
|
|
84261
84332
|
const agent = this.getClientByAddress(myXmtpAddress);
|
|
84262
84333
|
if (!agent) {
|
|
84263
|
-
|
|
84334
|
+
logWithTimestamp(
|
|
84264
84335
|
`[xmtp-sdk] allowGroup: no client found for address=${myXmtpAddress}`
|
|
84265
84336
|
);
|
|
84266
84337
|
logger.error(LogEvent.GROUP_CONSENT_UPDATE_FAILED, void 0, {
|
|
@@ -84281,7 +84352,7 @@ var XmtpService = class _XmtpService {
|
|
|
84281
84352
|
(c) => c instanceof Group && c.id === groupId
|
|
84282
84353
|
);
|
|
84283
84354
|
if (!group) {
|
|
84284
|
-
|
|
84355
|
+
logWithTimestamp(`[xmtp-sdk] allowGroup: groupId=${groupId} not found`);
|
|
84285
84356
|
logger.error(LogEvent.GROUP_CONSENT_UPDATE_FAILED, void 0, {
|
|
84286
84357
|
...agentExtras({
|
|
84287
84358
|
walletAddress: myXmtpAddress,
|
|
@@ -84295,13 +84366,13 @@ var XmtpService = class _XmtpService {
|
|
|
84295
84366
|
return false;
|
|
84296
84367
|
}
|
|
84297
84368
|
if (group.consentState === import_node_bindings2.ConsentState.Allowed) {
|
|
84298
|
-
|
|
84369
|
+
logWithTimestamp(
|
|
84299
84370
|
`[xmtp-sdk] allowGroup: groupId=${groupId} already Allowed, skipping`
|
|
84300
84371
|
);
|
|
84301
84372
|
return true;
|
|
84302
84373
|
}
|
|
84303
84374
|
group.updateConsentState(import_node_bindings2.ConsentState.Allowed);
|
|
84304
|
-
|
|
84375
|
+
logWithTimestamp(`[xmtp-sdk] allowGroup: groupId=${groupId} marked as Allowed`);
|
|
84305
84376
|
logger.info(LogEvent.GROUP_CONSENT_CHANGED, {
|
|
84306
84377
|
...agentExtras({
|
|
84307
84378
|
walletAddress: myXmtpAddress,
|
|
@@ -84313,7 +84384,7 @@ var XmtpService = class _XmtpService {
|
|
|
84313
84384
|
});
|
|
84314
84385
|
return true;
|
|
84315
84386
|
} catch (err2) {
|
|
84316
|
-
|
|
84387
|
+
logWithTimestamp(`[xmtp-sdk] allowGroup failed: groupId=${groupId}`, err2);
|
|
84317
84388
|
logger.error(LogEvent.GROUP_CONSENT_UPDATE_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), {
|
|
84318
84389
|
...agentExtras({
|
|
84319
84390
|
walletAddress: myXmtpAddress,
|
|
@@ -84330,14 +84401,14 @@ var XmtpService = class _XmtpService {
|
|
|
84330
84401
|
const tag = `[xmtp-sdk:listUnknownGroups:${clientAddress}]`;
|
|
84331
84402
|
const agent = this.getClientByAddress(clientAddress);
|
|
84332
84403
|
if (!agent) {
|
|
84333
|
-
|
|
84404
|
+
logWithTimestamp(`${tag} no client found, returning empty`);
|
|
84334
84405
|
return [];
|
|
84335
84406
|
}
|
|
84336
84407
|
await agent.client.conversations.syncAll([import_node_bindings2.ConsentState.Unknown]);
|
|
84337
84408
|
const groups = await agent.client.conversations.list({
|
|
84338
84409
|
consentStates: [import_node_bindings2.ConsentState.Unknown]
|
|
84339
84410
|
});
|
|
84340
|
-
|
|
84411
|
+
logWithTimestamp(`${tag} Unknown groups: ${groups.length}`);
|
|
84341
84412
|
const myInboxId = agent.client.inboxId;
|
|
84342
84413
|
const myAgentId = this.getAgentByAddress(clientAddress)?.agentId ?? null;
|
|
84343
84414
|
const result = [];
|
|
@@ -84381,7 +84452,7 @@ var XmtpService = class _XmtpService {
|
|
|
84381
84452
|
messages: chatMsgs
|
|
84382
84453
|
});
|
|
84383
84454
|
} catch (err2) {
|
|
84384
|
-
|
|
84455
|
+
logWithTimestamp(`${tag} failed to read group ${conv.id}:`, err2);
|
|
84385
84456
|
logger.error(
|
|
84386
84457
|
LogEvent.INBOUND_ROUTING_FAILED,
|
|
84387
84458
|
err2 instanceof Error ? err2 : new Error(String(err2)),
|
|
@@ -84402,7 +84473,7 @@ var XmtpService = class _XmtpService {
|
|
|
84402
84473
|
async denyGroup(myXmtpAddress, groupId) {
|
|
84403
84474
|
const agent = this.getClientByAddress(myXmtpAddress);
|
|
84404
84475
|
if (!agent) {
|
|
84405
|
-
|
|
84476
|
+
logWithTimestamp(
|
|
84406
84477
|
`[xmtp-sdk] denyGroup: no client found for address=${myXmtpAddress}`
|
|
84407
84478
|
);
|
|
84408
84479
|
logger.error(LogEvent.GROUP_CONSENT_UPDATE_FAILED, void 0, {
|
|
@@ -84423,7 +84494,7 @@ var XmtpService = class _XmtpService {
|
|
|
84423
84494
|
(c) => c instanceof Group && c.id === groupId
|
|
84424
84495
|
);
|
|
84425
84496
|
if (!group) {
|
|
84426
|
-
|
|
84497
|
+
logWithTimestamp(`[xmtp-sdk] denyGroup: groupId=${groupId} not found`);
|
|
84427
84498
|
logger.error(LogEvent.GROUP_CONSENT_UPDATE_FAILED, void 0, {
|
|
84428
84499
|
...agentExtras({
|
|
84429
84500
|
walletAddress: myXmtpAddress,
|
|
@@ -84437,7 +84508,7 @@ var XmtpService = class _XmtpService {
|
|
|
84437
84508
|
return false;
|
|
84438
84509
|
}
|
|
84439
84510
|
group.updateConsentState(import_node_bindings2.ConsentState.Denied);
|
|
84440
|
-
|
|
84511
|
+
logWithTimestamp(`[xmtp-sdk] denyGroup: groupId=${groupId} marked as Denied`);
|
|
84441
84512
|
logger.info(LogEvent.GROUP_CONSENT_CHANGED, {
|
|
84442
84513
|
...agentExtras({
|
|
84443
84514
|
walletAddress: myXmtpAddress,
|
|
@@ -84449,7 +84520,7 @@ var XmtpService = class _XmtpService {
|
|
|
84449
84520
|
});
|
|
84450
84521
|
return true;
|
|
84451
84522
|
} catch (err2) {
|
|
84452
|
-
|
|
84523
|
+
logWithTimestamp(`[xmtp-sdk] denyGroup failed: groupId=${groupId}`, err2);
|
|
84453
84524
|
logger.error(LogEvent.GROUP_CONSENT_UPDATE_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), {
|
|
84454
84525
|
...agentExtras({
|
|
84455
84526
|
walletAddress: myXmtpAddress,
|
|
@@ -84481,9 +84552,9 @@ var XmtpService = class _XmtpService {
|
|
|
84481
84552
|
import_node_bindings2.ConsentState.Allowed,
|
|
84482
84553
|
import_node_bindings2.ConsentState.Unknown
|
|
84483
84554
|
]);
|
|
84484
|
-
|
|
84555
|
+
logWithTimestamp(`${tag} conversations synced (non-Denied)`);
|
|
84485
84556
|
} catch (err2) {
|
|
84486
|
-
|
|
84557
|
+
logWithTimestamp(`${tag} conversation sync failed, skipping this client:`, err2);
|
|
84487
84558
|
logger.error(
|
|
84488
84559
|
LogEvent.CONVERSATIONS_STREAM_FAILED,
|
|
84489
84560
|
err2 instanceof Error ? err2 : void 0,
|
|
@@ -84491,8 +84562,8 @@ var XmtpService = class _XmtpService {
|
|
|
84491
84562
|
);
|
|
84492
84563
|
return;
|
|
84493
84564
|
}
|
|
84494
|
-
agent.use(selfFilterMiddleware());
|
|
84495
84565
|
agent.use(loggingMiddleware(identity3));
|
|
84566
|
+
agent.use(selfFilterMiddleware());
|
|
84496
84567
|
const inboundFactory = this.tools.createInboundMiddleware;
|
|
84497
84568
|
if (inboundFactory) {
|
|
84498
84569
|
agent.use(
|
|
@@ -84511,7 +84582,7 @@ var XmtpService = class _XmtpService {
|
|
|
84511
84582
|
})
|
|
84512
84583
|
);
|
|
84513
84584
|
} else {
|
|
84514
|
-
|
|
84585
|
+
logWithTimestamp(
|
|
84515
84586
|
`${tag} tools.createInboundMiddleware not injected \u2014 inbound routing disabled`
|
|
84516
84587
|
);
|
|
84517
84588
|
}
|
|
@@ -84519,7 +84590,7 @@ var XmtpService = class _XmtpService {
|
|
|
84519
84590
|
const initialSyncMs = Date.now();
|
|
84520
84591
|
this.syncByAddress.set(address, initialSyncMs);
|
|
84521
84592
|
saveSyncForAddress(this.dataDir, address, initialSyncMs);
|
|
84522
|
-
|
|
84593
|
+
logWithTimestamp(
|
|
84523
84594
|
`${tag} initialized sync timestamp at ${new Date(initialSyncMs).toISOString()}`
|
|
84524
84595
|
);
|
|
84525
84596
|
}
|
|
@@ -84527,13 +84598,13 @@ var XmtpService = class _XmtpService {
|
|
|
84527
84598
|
const BASE_DELAY_MS = 1e3;
|
|
84528
84599
|
const startWithRetry = async (attempt = 0) => {
|
|
84529
84600
|
if (this.stoppedAddresses.has(address.toLowerCase()) || !this.clients.has(address)) {
|
|
84530
|
-
|
|
84601
|
+
logWithTimestamp(`${tag} start skipped: client stopped or removed`);
|
|
84531
84602
|
return;
|
|
84532
84603
|
}
|
|
84533
84604
|
try {
|
|
84534
84605
|
await agent.start();
|
|
84535
84606
|
} catch (err2) {
|
|
84536
|
-
|
|
84607
|
+
logWithTimestamp(`${tag} agent.start error (attempt=${attempt}):`, err2);
|
|
84537
84608
|
logger.error(
|
|
84538
84609
|
LogEvent.AGENT_START_FAILED,
|
|
84539
84610
|
err2 instanceof Error ? err2 : void 0,
|
|
@@ -84547,24 +84618,24 @@ var XmtpService = class _XmtpService {
|
|
|
84547
84618
|
};
|
|
84548
84619
|
const scheduleRetry = (attempt) => {
|
|
84549
84620
|
if (this.stoppedAddresses.has(address.toLowerCase()) || !this.clients.has(address)) {
|
|
84550
|
-
|
|
84621
|
+
logWithTimestamp(`${tag} reconnect skipped: client stopped or removed`);
|
|
84551
84622
|
return;
|
|
84552
84623
|
}
|
|
84553
84624
|
if (attempt >= MAX_RETRIES) {
|
|
84554
|
-
|
|
84625
|
+
logWithTimestamp(`${tag} reached max retries (${MAX_RETRIES}), giving up reconnect`);
|
|
84555
84626
|
return;
|
|
84556
84627
|
}
|
|
84557
84628
|
const delay = BASE_DELAY_MS * 2 ** attempt;
|
|
84558
|
-
|
|
84629
|
+
logWithTimestamp(`${tag} reconnecting in ${delay}ms (attempt=${attempt + 1})`);
|
|
84559
84630
|
setTimeout(() => void startWithRetry(attempt + 1), delay);
|
|
84560
84631
|
};
|
|
84561
84632
|
agent.on("error", (err2) => {
|
|
84562
|
-
|
|
84633
|
+
logWithTimestamp(`${tag} agent stream error:`, err2);
|
|
84563
84634
|
logger.error(LogEvent.AGENT_STREAM_ERROR, err2, agentExtras(identity3));
|
|
84564
84635
|
scheduleRetry(0);
|
|
84565
84636
|
});
|
|
84566
84637
|
void startWithRetry();
|
|
84567
|
-
|
|
84638
|
+
logWithTimestamp(`${tag} message listener started`);
|
|
84568
84639
|
});
|
|
84569
84640
|
}
|
|
84570
84641
|
async replayOfflineMessagesForAddress(address) {
|
|
@@ -84590,7 +84661,7 @@ var XmtpService = class _XmtpService {
|
|
|
84590
84661
|
};
|
|
84591
84662
|
const processOffline = this.tools.processOfflineMessage;
|
|
84592
84663
|
if (!processOffline) {
|
|
84593
|
-
|
|
84664
|
+
logWithTimestamp(
|
|
84594
84665
|
`${tag} tools.processOfflineMessage not injected \u2014 offline replay skipped`
|
|
84595
84666
|
);
|
|
84596
84667
|
summary.durationMs = Date.now() - addressReplayStartedAt;
|
|
@@ -84611,7 +84682,7 @@ var XmtpService = class _XmtpService {
|
|
|
84611
84682
|
summary.listMs = Date.now() - listStartedAt;
|
|
84612
84683
|
summary.conversations = conversations.length;
|
|
84613
84684
|
} catch (err2) {
|
|
84614
|
-
|
|
84685
|
+
logWithTimestamp(`${tag} conversation sync/list failed, skipping:`, err2);
|
|
84615
84686
|
logger.error(
|
|
84616
84687
|
LogEvent.OFFLINE_REPLAY_FAILED,
|
|
84617
84688
|
err2 instanceof Error ? err2 : void 0,
|
|
@@ -84697,7 +84768,7 @@ var XmtpService = class _XmtpService {
|
|
|
84697
84768
|
const handleMs = Date.now() - handleStartedAt;
|
|
84698
84769
|
summary.handleMs += handleMs;
|
|
84699
84770
|
if (handled) {
|
|
84700
|
-
|
|
84771
|
+
logWithTimestamp(
|
|
84701
84772
|
`${tag} replayed content=${preview}`
|
|
84702
84773
|
);
|
|
84703
84774
|
summary.replayed++;
|
|
@@ -84716,7 +84787,7 @@ var XmtpService = class _XmtpService {
|
|
|
84716
84787
|
summary.skipped++;
|
|
84717
84788
|
}
|
|
84718
84789
|
} catch (err2) {
|
|
84719
|
-
|
|
84790
|
+
logWithTimestamp(`${tag} replay handling failed: msgId=${msg.id}`, err2);
|
|
84720
84791
|
logger.error(
|
|
84721
84792
|
LogEvent.OFFLINE_REPLAY_MESSAGE_FAILED,
|
|
84722
84793
|
err2 instanceof Error ? err2 : void 0,
|
|
@@ -84739,7 +84810,7 @@ var XmtpService = class _XmtpService {
|
|
|
84739
84810
|
}
|
|
84740
84811
|
}
|
|
84741
84812
|
} catch (err2) {
|
|
84742
|
-
|
|
84813
|
+
logWithTimestamp(`${tag} failed to read messages from conversation ${conv.id}:`, err2);
|
|
84743
84814
|
logger.error(
|
|
84744
84815
|
LogEvent.OFFLINE_REPLAY_FAILED,
|
|
84745
84816
|
err2 instanceof Error ? err2 : void 0,
|
|
@@ -84879,7 +84950,7 @@ async function resolve2() {
|
|
|
84879
84950
|
}
|
|
84880
84951
|
const envBin = process.env.ONCHAINOS_BIN;
|
|
84881
84952
|
if (envBin) {
|
|
84882
|
-
|
|
84953
|
+
logWithTimestamp(`[onchainos] using ONCHAINOS_BIN=${envBin}`);
|
|
84883
84954
|
resolvedBin = envBin;
|
|
84884
84955
|
return resolvedBin;
|
|
84885
84956
|
}
|
|
@@ -84888,17 +84959,17 @@ async function resolve2() {
|
|
|
84888
84959
|
const { stdout } = await execFileAsync(shell, ["-lc", "command -v onchainos"]);
|
|
84889
84960
|
const bin = extractExecutablePath(stdout);
|
|
84890
84961
|
if (bin) {
|
|
84891
|
-
|
|
84962
|
+
logWithTimestamp(`[onchainos] resolved binary via shell: ${bin}`);
|
|
84892
84963
|
resolvedBin = bin;
|
|
84893
84964
|
return resolvedBin;
|
|
84894
84965
|
}
|
|
84895
84966
|
} catch (err2) {
|
|
84896
|
-
|
|
84967
|
+
logWithTimestamp(
|
|
84897
84968
|
"[onchainos] shell resolve failed, will fallback to bare 'onchainos':",
|
|
84898
84969
|
err2
|
|
84899
84970
|
);
|
|
84900
84971
|
}
|
|
84901
|
-
|
|
84972
|
+
logWithTimestamp(
|
|
84902
84973
|
"[onchainos] could not resolve binary path, falling back to bare 'onchainos'"
|
|
84903
84974
|
);
|
|
84904
84975
|
resolvedBin = "onchainos";
|
|
@@ -84948,16 +85019,16 @@ function commandForLog(bin, args) {
|
|
|
84948
85019
|
async function exec(args) {
|
|
84949
85020
|
const bin = await resolve2();
|
|
84950
85021
|
const cmd = commandForLog(bin, args);
|
|
84951
|
-
|
|
85022
|
+
logWithTimestamp(`[onchainos] exec: ${cmd}`);
|
|
84952
85023
|
const t0 = Date.now();
|
|
84953
85024
|
try {
|
|
84954
85025
|
const result = await execFileAsync(bin, args);
|
|
84955
|
-
|
|
85026
|
+
logWithTimestamp(
|
|
84956
85027
|
`[onchainos] exec done: ${cmd} (${Date.now() - t0}ms, stdout=${result.stdout.length}B, stderr=${result.stderr.length}B)`
|
|
84957
85028
|
);
|
|
84958
85029
|
return result;
|
|
84959
85030
|
} catch (err2) {
|
|
84960
|
-
|
|
85031
|
+
logWithTimestamp(
|
|
84961
85032
|
`[onchainos] exec error: ${cmd} (${Date.now() - t0}ms) code=${err2.code} signal=${err2.signal} killed=${err2.killed} message=${err2.message}`
|
|
84962
85033
|
);
|
|
84963
85034
|
logger.error(
|
|
@@ -84985,21 +85056,7 @@ async function exec(args) {
|
|
|
84985
85056
|
}
|
|
84986
85057
|
}
|
|
84987
85058
|
|
|
84988
|
-
// ../core/src/xmtp-sdk/onchainos/
|
|
84989
|
-
function isAccountAgentGroup(item) {
|
|
84990
|
-
return typeof item === "object" && item !== null && Array.isArray(item.agentList);
|
|
84991
|
-
}
|
|
84992
|
-
function normalizeAgentPage(raw) {
|
|
84993
|
-
const list = [];
|
|
84994
|
-
for (const item of raw.list) {
|
|
84995
|
-
if (isAccountAgentGroup(item)) {
|
|
84996
|
-
list.push(...item.agentList);
|
|
84997
|
-
} else {
|
|
84998
|
-
list.push(item);
|
|
84999
|
-
}
|
|
85000
|
-
}
|
|
85001
|
-
return { list, page: raw.page, pageSize: raw.pageSize, total: raw.total };
|
|
85002
|
-
}
|
|
85059
|
+
// ../core/src/xmtp-sdk/onchainos/cli-response.ts
|
|
85003
85060
|
var CliErrorReason = {
|
|
85004
85061
|
OK_FALSE: "ok_false",
|
|
85005
85062
|
JSON_PARSE_FAILED: "json_parse_failed"
|
|
@@ -85047,6 +85104,8 @@ function parseCliJson(stdout, command, extras = {}) {
|
|
|
85047
85104
|
throw parseErr;
|
|
85048
85105
|
}
|
|
85049
85106
|
}
|
|
85107
|
+
|
|
85108
|
+
// ../core/src/xmtp-sdk/onchainos/session-expired.ts
|
|
85050
85109
|
var SESSION_EXPIRED_RE2 = /session expired/i;
|
|
85051
85110
|
function isSessionExpired(stdout) {
|
|
85052
85111
|
try {
|
|
@@ -85056,14 +85115,7 @@ function isSessionExpired(stdout) {
|
|
|
85056
85115
|
return SESSION_EXPIRED_RE2.test(stdout);
|
|
85057
85116
|
}
|
|
85058
85117
|
}
|
|
85059
|
-
|
|
85060
|
-
var EXPIRED_NOTIFY_COOLDOWN_MS = 5 * 60 * 1e3;
|
|
85061
|
-
function notifySessionExpired(command) {
|
|
85062
|
-
const now = Date.now();
|
|
85063
|
-
if (now - lastExpiredNotifyAt < EXPIRED_NOTIFY_COOLDOWN_MS) {
|
|
85064
|
-
return;
|
|
85065
|
-
}
|
|
85066
|
-
lastExpiredNotifyAt = now;
|
|
85118
|
+
function reportSessionExpired(command) {
|
|
85067
85119
|
logger.error(
|
|
85068
85120
|
LogEvent.ONCHAINOS_SESSION_EXPIRED,
|
|
85069
85121
|
new Error("onchainos session expired"),
|
|
@@ -85077,9 +85129,87 @@ function notifySessionExpired(command) {
|
|
|
85077
85129
|
reason: "session_expired"
|
|
85078
85130
|
}
|
|
85079
85131
|
);
|
|
85132
|
+
}
|
|
85133
|
+
|
|
85134
|
+
// ../core/src/xmtp-sdk/onchainos/system-config.ts
|
|
85135
|
+
function notifyExpired(command, options) {
|
|
85136
|
+
if (options?.notifySessionExpired) {
|
|
85137
|
+
options.notifySessionExpired(command);
|
|
85138
|
+
return;
|
|
85139
|
+
}
|
|
85140
|
+
reportSessionExpired(command);
|
|
85141
|
+
}
|
|
85142
|
+
function guardSessionExpired(stdout, command, options) {
|
|
85143
|
+
if (isSessionExpired(stdout)) {
|
|
85144
|
+
notifyExpired(command, options);
|
|
85145
|
+
}
|
|
85146
|
+
}
|
|
85147
|
+
function guardCatchSessionExpired(err2, command, options) {
|
|
85148
|
+
const stdout = String(err2?.stdout ?? "");
|
|
85149
|
+
if (stdout && isSessionExpired(stdout)) {
|
|
85150
|
+
notifyExpired(command, options);
|
|
85151
|
+
}
|
|
85152
|
+
}
|
|
85153
|
+
async function fetchSystemConfig(options) {
|
|
85154
|
+
logWithTimestamp(`[onchainos] fetching system-config`);
|
|
85155
|
+
let stdout;
|
|
85156
|
+
let stderr;
|
|
85157
|
+
try {
|
|
85158
|
+
({ stdout, stderr } = await exec(["agent", "system-config"]));
|
|
85159
|
+
} catch (err2) {
|
|
85160
|
+
guardCatchSessionExpired(err2, "system-config", options);
|
|
85161
|
+
throw err2;
|
|
85162
|
+
}
|
|
85163
|
+
if (stderr) {
|
|
85164
|
+
logWithTimestamp(`[onchainos] stderr (system-config): ${stderr}`);
|
|
85165
|
+
}
|
|
85166
|
+
const res = parseCliJson(
|
|
85167
|
+
stdout,
|
|
85168
|
+
"system-config"
|
|
85169
|
+
);
|
|
85170
|
+
if (!res.ok) {
|
|
85171
|
+
guardSessionExpired(stdout, "system-config", options);
|
|
85172
|
+
const parseErr = new Error(`onchainos agent system-config failed`);
|
|
85173
|
+
logger.error(
|
|
85174
|
+
LogEvent.ONCHAINOS_CLI_ERROR,
|
|
85175
|
+
parseErr,
|
|
85176
|
+
cliOkFalseExtras(stdout, "system-config")
|
|
85177
|
+
);
|
|
85178
|
+
throw parseErr;
|
|
85179
|
+
}
|
|
85180
|
+
logWithTimestamp(
|
|
85181
|
+
`[onchainos] fetched system-config: ${Object.keys(res.data).length} keys`
|
|
85182
|
+
);
|
|
85183
|
+
return res.data;
|
|
85184
|
+
}
|
|
85185
|
+
|
|
85186
|
+
// ../core/src/xmtp-sdk/onchainos/index.ts
|
|
85187
|
+
function isAccountAgentGroup(item) {
|
|
85188
|
+
return typeof item === "object" && item !== null && Array.isArray(item.agentList);
|
|
85189
|
+
}
|
|
85190
|
+
function normalizeAgentPage(raw) {
|
|
85191
|
+
const list = [];
|
|
85192
|
+
for (const item of raw.list) {
|
|
85193
|
+
if (isAccountAgentGroup(item)) {
|
|
85194
|
+
list.push(...item.agentList);
|
|
85195
|
+
} else {
|
|
85196
|
+
list.push(item);
|
|
85197
|
+
}
|
|
85198
|
+
}
|
|
85199
|
+
return { list, page: raw.page, pageSize: raw.pageSize, total: raw.total };
|
|
85200
|
+
}
|
|
85201
|
+
var lastExpiredNotifyAt = 0;
|
|
85202
|
+
var EXPIRED_NOTIFY_COOLDOWN_MS = 5 * 60 * 1e3;
|
|
85203
|
+
function notifySessionExpired(command) {
|
|
85204
|
+
const now = Date.now();
|
|
85205
|
+
if (now - lastExpiredNotifyAt < EXPIRED_NOTIFY_COOLDOWN_MS) {
|
|
85206
|
+
return;
|
|
85207
|
+
}
|
|
85208
|
+
lastExpiredNotifyAt = now;
|
|
85209
|
+
reportSessionExpired(command);
|
|
85080
85210
|
const hook = XmtpService.getInstance().tools.notifySessionExpired;
|
|
85081
85211
|
if (!hook) {
|
|
85082
|
-
|
|
85212
|
+
logWithTimestamp(
|
|
85083
85213
|
"[onchainos] tools.notifySessionExpired not injected \u2014 skipping user notice"
|
|
85084
85214
|
);
|
|
85085
85215
|
return;
|
|
@@ -85087,15 +85217,15 @@ function notifySessionExpired(command) {
|
|
|
85087
85217
|
try {
|
|
85088
85218
|
hook(command);
|
|
85089
85219
|
} catch (err2) {
|
|
85090
|
-
|
|
85220
|
+
logWithTimestamp("[onchainos] tools.notifySessionExpired threw:", err2);
|
|
85091
85221
|
}
|
|
85092
85222
|
}
|
|
85093
|
-
function
|
|
85223
|
+
function guardSessionExpired2(stdout, command) {
|
|
85094
85224
|
if (isSessionExpired(stdout)) {
|
|
85095
85225
|
notifySessionExpired(command);
|
|
85096
85226
|
}
|
|
85097
85227
|
}
|
|
85098
|
-
function
|
|
85228
|
+
function guardCatchSessionExpired2(err2, command) {
|
|
85099
85229
|
const stdout = String(err2?.stdout ?? "");
|
|
85100
85230
|
if (stdout && isSessionExpired(stdout)) {
|
|
85101
85231
|
notifySessionExpired(command);
|
|
@@ -85152,7 +85282,7 @@ async function fetchAgentPage(page) {
|
|
|
85152
85282
|
commandStatus: "rejected"
|
|
85153
85283
|
});
|
|
85154
85284
|
}
|
|
85155
|
-
|
|
85285
|
+
guardCatchSessionExpired2(err2, "list-agents");
|
|
85156
85286
|
throw err2;
|
|
85157
85287
|
}
|
|
85158
85288
|
logAgentListResponse({
|
|
@@ -85168,7 +85298,7 @@ async function fetchAgentPage(page) {
|
|
|
85168
85298
|
{ page: String(page), pageSize: String(PAGE_SIZE) }
|
|
85169
85299
|
);
|
|
85170
85300
|
if (!res.ok) {
|
|
85171
|
-
|
|
85301
|
+
guardSessionExpired2(stdout, "list-agents");
|
|
85172
85302
|
const parseErr = new Error("onchainos agent get failed");
|
|
85173
85303
|
logger.error(
|
|
85174
85304
|
LogEvent.ONCHAINOS_CLI_ERROR,
|
|
@@ -85187,7 +85317,7 @@ var ONCHAINOS_CHAIN_INDEX = "196";
|
|
|
85187
85317
|
async function fetchAgentsByIds(agentIds) {
|
|
85188
85318
|
const requested = [...new Set(agentIds.filter(Boolean))];
|
|
85189
85319
|
if (requested.length > 0) {
|
|
85190
|
-
|
|
85320
|
+
logWithTimestamp(
|
|
85191
85321
|
`[onchainos] executing: onchainos agent get --agent-ids ${requested.join(",")}`
|
|
85192
85322
|
);
|
|
85193
85323
|
let stdout;
|
|
@@ -85200,11 +85330,11 @@ async function fetchAgentsByIds(agentIds) {
|
|
|
85200
85330
|
requested.join(",")
|
|
85201
85331
|
]));
|
|
85202
85332
|
} catch (err2) {
|
|
85203
|
-
|
|
85333
|
+
guardCatchSessionExpired2(err2, "get-agents-by-ids");
|
|
85204
85334
|
throw err2;
|
|
85205
85335
|
}
|
|
85206
85336
|
if (stderr) {
|
|
85207
|
-
|
|
85337
|
+
logWithTimestamp(`[onchainos] stderr (get-agents-by-ids): ${stderr}`);
|
|
85208
85338
|
}
|
|
85209
85339
|
const res = parseCliJson(
|
|
85210
85340
|
stdout,
|
|
@@ -85212,7 +85342,7 @@ async function fetchAgentsByIds(agentIds) {
|
|
|
85212
85342
|
{ agentIds: requested.join(",") }
|
|
85213
85343
|
);
|
|
85214
85344
|
if (!res.ok) {
|
|
85215
|
-
|
|
85345
|
+
guardSessionExpired2(stdout, "get-agents-by-ids");
|
|
85216
85346
|
const parseErr = new Error("onchainos agent get --agent-ids failed");
|
|
85217
85347
|
logger.error(
|
|
85218
85348
|
LogEvent.ONCHAINOS_CLI_ERROR,
|
|
@@ -85237,7 +85367,7 @@ async function fetchAgentsByIds(agentIds) {
|
|
|
85237
85367
|
return result;
|
|
85238
85368
|
}
|
|
85239
85369
|
async function fetchAgentByAddress(communicationAddress) {
|
|
85240
|
-
|
|
85370
|
+
logWithTimestamp(
|
|
85241
85371
|
`[onchainos] executing: onchainos agent get-by-address --communication-address ${communicationAddress} --chain-index ${ONCHAINOS_CHAIN_INDEX}`
|
|
85242
85372
|
);
|
|
85243
85373
|
let stdout;
|
|
@@ -85252,11 +85382,11 @@ async function fetchAgentByAddress(communicationAddress) {
|
|
|
85252
85382
|
ONCHAINOS_CHAIN_INDEX
|
|
85253
85383
|
]));
|
|
85254
85384
|
} catch (err2) {
|
|
85255
|
-
|
|
85385
|
+
guardCatchSessionExpired2(err2, "get-agent-by-address");
|
|
85256
85386
|
throw err2;
|
|
85257
85387
|
}
|
|
85258
85388
|
if (stderr) {
|
|
85259
|
-
|
|
85389
|
+
logWithTimestamp(`[onchainos] stderr (get-agent-by-address): ${stderr}`);
|
|
85260
85390
|
}
|
|
85261
85391
|
const res = parseCliJson(
|
|
85262
85392
|
stdout,
|
|
@@ -85264,7 +85394,7 @@ async function fetchAgentByAddress(communicationAddress) {
|
|
|
85264
85394
|
{ communicationAddress, chainIndex: ONCHAINOS_CHAIN_INDEX }
|
|
85265
85395
|
);
|
|
85266
85396
|
if (!res.ok) {
|
|
85267
|
-
|
|
85397
|
+
guardSessionExpired2(stdout, "get-agent-by-address");
|
|
85268
85398
|
const parseErr = new Error("onchainos agent get-by-address failed");
|
|
85269
85399
|
logger.error(
|
|
85270
85400
|
LogEvent.ONCHAINOS_CLI_ERROR,
|
|
@@ -85303,7 +85433,7 @@ async function listAllAgentsWithMetadata(previousFingerprint) {
|
|
|
85303
85433
|
const changed = previousFingerprint === void 0 || previousFingerprint !== fingerprint;
|
|
85304
85434
|
const stderrLines = stderrs.map(filterNoisyAgentIdentityLog).filter((line) => line.length > 0);
|
|
85305
85435
|
for (const line of stderrLines) {
|
|
85306
|
-
|
|
85436
|
+
logWithTimestamp(`[onchainos] stderr (${line})`);
|
|
85307
85437
|
}
|
|
85308
85438
|
return {
|
|
85309
85439
|
allAgents: agents,
|
|
@@ -85331,11 +85461,11 @@ function filterNoisyAgentIdentityLog(stderr) {
|
|
|
85331
85461
|
}
|
|
85332
85462
|
async function notifyAgentsWakeup(agentIds) {
|
|
85333
85463
|
if (agentIds.length === 0) {
|
|
85334
|
-
|
|
85464
|
+
logWithTimestamp("[onchainos] wakeup-notify: agentIds empty, skipping");
|
|
85335
85465
|
return;
|
|
85336
85466
|
}
|
|
85337
85467
|
const ids = agentIds.join(",");
|
|
85338
|
-
|
|
85468
|
+
logWithTimestamp(`[onchainos] sending wakeup-notify (agent-ids=${ids})`);
|
|
85339
85469
|
try {
|
|
85340
85470
|
const { stderr } = await exec([
|
|
85341
85471
|
"agent",
|
|
@@ -85344,19 +85474,19 @@ async function notifyAgentsWakeup(agentIds) {
|
|
|
85344
85474
|
ids
|
|
85345
85475
|
]);
|
|
85346
85476
|
if (stderr) {
|
|
85347
|
-
|
|
85477
|
+
logWithTimestamp(`[onchainos] stderr (wakeup-notify): ${stderr}`);
|
|
85348
85478
|
}
|
|
85349
|
-
|
|
85479
|
+
logWithTimestamp(`[onchainos] wakeup-notify succeeded (agent-ids=${ids})`);
|
|
85350
85480
|
} catch (err2) {
|
|
85351
|
-
|
|
85352
|
-
|
|
85481
|
+
guardCatchSessionExpired2(err2, "wakeup-notify");
|
|
85482
|
+
logWithTimestamp(
|
|
85353
85483
|
`[onchainos] wakeup-notify failed (agent-ids=${ids}):`,
|
|
85354
85484
|
err2?.message ?? err2
|
|
85355
85485
|
);
|
|
85356
85486
|
}
|
|
85357
85487
|
}
|
|
85358
85488
|
async function sendHeartbeat(chainIndex) {
|
|
85359
|
-
|
|
85489
|
+
logWithTimestamp(`[onchainos] sending heartbeat (chain-index=${chainIndex})`);
|
|
85360
85490
|
try {
|
|
85361
85491
|
const { stderr } = await exec([
|
|
85362
85492
|
"agent",
|
|
@@ -85365,16 +85495,16 @@ async function sendHeartbeat(chainIndex) {
|
|
|
85365
85495
|
chainIndex
|
|
85366
85496
|
]);
|
|
85367
85497
|
if (stderr) {
|
|
85368
|
-
|
|
85498
|
+
logWithTimestamp(`[onchainos] stderr (heartbeat): ${stderr}`);
|
|
85369
85499
|
}
|
|
85370
|
-
|
|
85500
|
+
logWithTimestamp(`[onchainos] heartbeat sent`);
|
|
85371
85501
|
} catch (err2) {
|
|
85372
|
-
|
|
85502
|
+
guardCatchSessionExpired2(err2, "heartbeat");
|
|
85373
85503
|
throw err2;
|
|
85374
85504
|
}
|
|
85375
85505
|
}
|
|
85376
85506
|
async function checkMessageEligible(params) {
|
|
85377
|
-
|
|
85507
|
+
logWithTimestamp(
|
|
85378
85508
|
`[onchainos] checking message-eligible: job=${params.jobId} direction=${params.direction} providerSecurityRate=${params.providerSecurityRate}`
|
|
85379
85509
|
);
|
|
85380
85510
|
let stdout;
|
|
@@ -85403,11 +85533,11 @@ async function checkMessageEligible(params) {
|
|
|
85403
85533
|
String(params.providerSecurityRate)
|
|
85404
85534
|
]));
|
|
85405
85535
|
} catch (err2) {
|
|
85406
|
-
|
|
85536
|
+
guardCatchSessionExpired2(err2, "message-eligible");
|
|
85407
85537
|
throw new Error("message-eligible-cli-error", { cause: err2 });
|
|
85408
85538
|
}
|
|
85409
85539
|
if (stderr) {
|
|
85410
|
-
|
|
85540
|
+
logWithTimestamp(`[onchainos] stderr (message-eligible): ${stderr}`);
|
|
85411
85541
|
}
|
|
85412
85542
|
let res;
|
|
85413
85543
|
try {
|
|
@@ -85426,8 +85556,8 @@ async function checkMessageEligible(params) {
|
|
|
85426
85556
|
throw new Error("message-eligible-json-parse-failed", { cause: err2 });
|
|
85427
85557
|
}
|
|
85428
85558
|
if (!res.ok) {
|
|
85429
|
-
|
|
85430
|
-
|
|
85559
|
+
guardSessionExpired2(stdout, "message-eligible");
|
|
85560
|
+
warnWithTimestamp(
|
|
85431
85561
|
`[onchainos] message-eligible ok=false: ${stdout.slice(0, 200)}`
|
|
85432
85562
|
);
|
|
85433
85563
|
logger.error(
|
|
@@ -85449,62 +85579,30 @@ async function checkMessageEligible(params) {
|
|
|
85449
85579
|
);
|
|
85450
85580
|
throw new Error("message-eligible-ok-false");
|
|
85451
85581
|
}
|
|
85452
|
-
|
|
85582
|
+
logWithTimestamp(
|
|
85453
85583
|
`[onchainos] message-eligible result: eligible=${res.data.eligible}`
|
|
85454
85584
|
);
|
|
85455
85585
|
return res.data;
|
|
85456
85586
|
}
|
|
85457
|
-
async function fetchSystemConfig() {
|
|
85458
|
-
console.log(`[onchainos] fetching system-config`);
|
|
85459
|
-
let stdout;
|
|
85460
|
-
let stderr;
|
|
85461
|
-
try {
|
|
85462
|
-
({ stdout, stderr } = await exec(["agent", "system-config"]));
|
|
85463
|
-
} catch (err2) {
|
|
85464
|
-
guardCatchSessionExpired(err2, "system-config");
|
|
85465
|
-
throw err2;
|
|
85466
|
-
}
|
|
85467
|
-
if (stderr) {
|
|
85468
|
-
console.log(`[onchainos] stderr (system-config): ${stderr}`);
|
|
85469
|
-
}
|
|
85470
|
-
const res = parseCliJson(
|
|
85471
|
-
stdout,
|
|
85472
|
-
"system-config"
|
|
85473
|
-
);
|
|
85474
|
-
if (!res.ok) {
|
|
85475
|
-
guardSessionExpired(stdout, "system-config");
|
|
85476
|
-
const parseErr = new Error(`onchainos agent system-config failed`);
|
|
85477
|
-
logger.error(
|
|
85478
|
-
LogEvent.ONCHAINOS_CLI_ERROR,
|
|
85479
|
-
parseErr,
|
|
85480
|
-
cliOkFalseExtras(stdout, "system-config")
|
|
85481
|
-
);
|
|
85482
|
-
throw parseErr;
|
|
85483
|
-
}
|
|
85484
|
-
console.log(
|
|
85485
|
-
`[onchainos] fetched system-config: ${Object.keys(res.data).length} keys`
|
|
85486
|
-
);
|
|
85487
|
-
return res.data;
|
|
85488
|
-
}
|
|
85489
85587
|
async function fetchSensitiveWords() {
|
|
85490
|
-
|
|
85588
|
+
logWithTimestamp(`[onchainos] fetching sensitive words`);
|
|
85491
85589
|
let stdout;
|
|
85492
85590
|
let stderr;
|
|
85493
85591
|
try {
|
|
85494
85592
|
({ stdout, stderr } = await exec(["agent", "sensitive-words"]));
|
|
85495
85593
|
} catch (err2) {
|
|
85496
|
-
|
|
85594
|
+
guardCatchSessionExpired2(err2, "sensitive-words");
|
|
85497
85595
|
throw err2;
|
|
85498
85596
|
}
|
|
85499
85597
|
if (stderr) {
|
|
85500
|
-
|
|
85598
|
+
logWithTimestamp(`[onchainos] stderr (sensitive-words): ${stderr}`);
|
|
85501
85599
|
}
|
|
85502
85600
|
const res = parseCliJson(
|
|
85503
85601
|
stdout,
|
|
85504
85602
|
"sensitive-words"
|
|
85505
85603
|
);
|
|
85506
85604
|
if (!res.ok) {
|
|
85507
|
-
|
|
85605
|
+
guardSessionExpired2(stdout, "sensitive-words");
|
|
85508
85606
|
const parseErr = new Error(`onchainos agent sensitive-words failed`);
|
|
85509
85607
|
logger.error(
|
|
85510
85608
|
LogEvent.ONCHAINOS_CLI_ERROR,
|
|
@@ -85522,7 +85620,7 @@ async function fetchSensitiveWords() {
|
|
|
85522
85620
|
}
|
|
85523
85621
|
}
|
|
85524
85622
|
const result = [...words];
|
|
85525
|
-
|
|
85623
|
+
logWithTimestamp(
|
|
85526
85624
|
`[onchainos] fetched ${res.data.length} sensitive word entries \u2192 ${result.length} unique words`
|
|
85527
85625
|
);
|
|
85528
85626
|
return result;
|
|
@@ -85640,7 +85738,7 @@ function setOpenClawWebSocketFactoryForTests(factory) {
|
|
|
85640
85738
|
}
|
|
85641
85739
|
function clearClient() {
|
|
85642
85740
|
if (sharedClient) {
|
|
85643
|
-
|
|
85741
|
+
errorWithTimestamp(`${LOG_PREFIX} clear client`);
|
|
85644
85742
|
sharedClient.close();
|
|
85645
85743
|
}
|
|
85646
85744
|
sharedClient = null;
|
|
@@ -85668,7 +85766,7 @@ async function ensureClient(timeoutMs) {
|
|
|
85668
85766
|
const elapsedMs = Date.now() - startedAt;
|
|
85669
85767
|
const remainingMs = Math.max(1, timeoutMs - elapsedMs);
|
|
85670
85768
|
const fallbackProtocol = firstProtocol === PREFERRED_PROTOCOL_VERSION ? LEGACY_PROTOCOL_VERSION : PREFERRED_PROTOCOL_VERSION;
|
|
85671
|
-
|
|
85769
|
+
errorWithTimestamp(
|
|
85672
85770
|
`${LOG_PREFIX} protocol fallback from=${firstProtocol} to=${fallbackProtocol} remainingMs=${remainingMs}: ${formatErrorMessage(err2)}`
|
|
85673
85771
|
);
|
|
85674
85772
|
const fallbackClient = new MinimalGatewayClient(config, fallbackProtocol);
|
|
@@ -85680,7 +85778,7 @@ async function ensureClient(timeoutMs) {
|
|
|
85680
85778
|
}
|
|
85681
85779
|
function stopOpenClawGateway() {
|
|
85682
85780
|
if (!sharedClient) {
|
|
85683
|
-
|
|
85781
|
+
errorWithTimestamp(`${LOG_PREFIX} stop requested with no active client`);
|
|
85684
85782
|
return;
|
|
85685
85783
|
}
|
|
85686
85784
|
clearClient();
|
|
@@ -85688,12 +85786,12 @@ function stopOpenClawGateway() {
|
|
|
85688
85786
|
async function callOpenClawGateway(opts) {
|
|
85689
85787
|
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
85690
85788
|
const startedAt = Date.now();
|
|
85691
|
-
|
|
85789
|
+
errorWithTimestamp(`${LOG_PREFIX} rpc start method=${opts.method} timeoutMs=${timeoutMs}`);
|
|
85692
85790
|
for (let attempt = 0; ; attempt += 1) {
|
|
85693
85791
|
try {
|
|
85694
85792
|
const client = await ensureClient(timeoutMs);
|
|
85695
85793
|
const result = await client.request(opts.method, opts.params, { timeoutMs });
|
|
85696
|
-
|
|
85794
|
+
errorWithTimestamp(`${LOG_PREFIX} rpc ok method=${opts.method} durationMs=${Date.now() - startedAt} attempts=${attempt + 1}`);
|
|
85697
85795
|
return result;
|
|
85698
85796
|
} catch (err2) {
|
|
85699
85797
|
const message = err2 instanceof Error ? err2.message : String(err2);
|
|
@@ -85702,13 +85800,13 @@ async function callOpenClawGateway(opts) {
|
|
|
85702
85800
|
clearClient();
|
|
85703
85801
|
}
|
|
85704
85802
|
if (isGatewayStartingError(err2) && delayMs !== void 0 && Date.now() + delayMs - startedAt < timeoutMs) {
|
|
85705
|
-
|
|
85803
|
+
errorWithTimestamp(
|
|
85706
85804
|
`${LOG_PREFIX} rpc retry method=${opts.method} attempt=${attempt + 1} delayMs=${delayMs}: ${message}`
|
|
85707
85805
|
);
|
|
85708
85806
|
await sleep(delayMs);
|
|
85709
85807
|
continue;
|
|
85710
85808
|
}
|
|
85711
|
-
|
|
85809
|
+
errorWithTimestamp(
|
|
85712
85810
|
`${LOG_PREFIX} rpc failed method=${opts.method} durationMs=${Date.now() - startedAt} attempts=${attempt + 1}: ${message}`
|
|
85713
85811
|
);
|
|
85714
85812
|
if (isGatewayStartingError(err2)) {
|
|
@@ -85804,7 +85902,7 @@ var MinimalGatewayClient = class {
|
|
|
85804
85902
|
return this.ready && !this.closed && this.ws?.readyState === 1;
|
|
85805
85903
|
}
|
|
85806
85904
|
async connect(timeoutMs) {
|
|
85807
|
-
|
|
85905
|
+
errorWithTimestamp(
|
|
85808
85906
|
`${LOG_PREFIX} connect url=${this.config.url} source=${this.config.source} instanceId=${this.instanceId} protocol=${this.protocolVersion} passwordConfigured=${!!this.config.password} tokenConfigured=${!!this.config.token} scopes=${DEFAULT_SCOPES.join(",")}`
|
|
85809
85907
|
);
|
|
85810
85908
|
const ws = wsFactory(this.config.url);
|
|
@@ -85861,7 +85959,7 @@ var MinimalGatewayClient = class {
|
|
|
85861
85959
|
}
|
|
85862
85960
|
});
|
|
85863
85961
|
});
|
|
85864
|
-
|
|
85962
|
+
errorWithTimestamp(`${LOG_PREFIX} hello ok instanceId=${this.instanceId} protocol=${this.protocolVersion}`);
|
|
85865
85963
|
}
|
|
85866
85964
|
request(method, params, options = {}) {
|
|
85867
85965
|
if (method === "connect") {
|
|
@@ -85937,7 +86035,7 @@ var MinimalGatewayClient = class {
|
|
|
85937
86035
|
try {
|
|
85938
86036
|
frame = JSON.parse(String(raw));
|
|
85939
86037
|
} catch (err2) {
|
|
85940
|
-
|
|
86038
|
+
errorWithTimestamp(`${LOG_PREFIX} invalid frame: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
85941
86039
|
return;
|
|
85942
86040
|
}
|
|
85943
86041
|
if (frame.type !== "res") {
|
|
@@ -85959,7 +86057,7 @@ var MinimalGatewayClient = class {
|
|
|
85959
86057
|
pending.reject(toGatewayError(frame.error));
|
|
85960
86058
|
}
|
|
85961
86059
|
handleClose(code2, reason) {
|
|
85962
|
-
|
|
86060
|
+
errorWithTimestamp(`${LOG_PREFIX} closed instanceId=${this.instanceId} code=${code2 ?? 0} reason=${reason || "no reason"}`);
|
|
85963
86061
|
this.ready = false;
|
|
85964
86062
|
for (const [id, pending] of this.pending) {
|
|
85965
86063
|
clearTimeout(pending.timer);
|
|
@@ -85983,7 +86081,7 @@ function readSyncedGatewayConfig(env) {
|
|
|
85983
86081
|
token: synced.token
|
|
85984
86082
|
};
|
|
85985
86083
|
} catch (err2) {
|
|
85986
|
-
|
|
86084
|
+
errorWithTimestamp(`${LOG_PREFIX} failed to read synced gateway config: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
85987
86085
|
return null;
|
|
85988
86086
|
}
|
|
85989
86087
|
}
|
|
@@ -85994,7 +86092,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
|
|
|
85994
86092
|
client: {
|
|
85995
86093
|
id: "gateway-client",
|
|
85996
86094
|
displayName: "okx-a2a-node",
|
|
85997
|
-
version: "0.0.13
|
|
86095
|
+
version: "0.0.13",
|
|
85998
86096
|
platform: "node",
|
|
85999
86097
|
mode: "backend",
|
|
86000
86098
|
instanceId
|
|
@@ -86005,7 +86103,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
|
|
|
86005
86103
|
commands: [],
|
|
86006
86104
|
permissions: {},
|
|
86007
86105
|
locale: Intl.DateTimeFormat().resolvedOptions().locale || "en-US",
|
|
86008
|
-
userAgent: `okx-a2a-node/${"0.0.13
|
|
86106
|
+
userAgent: `okx-a2a-node/${"0.0.13"}`,
|
|
86009
86107
|
auth: {
|
|
86010
86108
|
...config.token ? { token: config.token } : {},
|
|
86011
86109
|
...config.password ? { password: config.password } : {}
|
|
@@ -86130,313 +86228,6 @@ function safeDecode(value) {
|
|
|
86130
86228
|
}
|
|
86131
86229
|
}
|
|
86132
86230
|
|
|
86133
|
-
// src/openclaw-route.ts
|
|
86134
|
-
var import_node_fs13 = require("node:fs");
|
|
86135
|
-
var import_node_os5 = require("node:os");
|
|
86136
|
-
var import_node_path17 = require("node:path");
|
|
86137
|
-
var OPENCLAW_GATEWAY_ROUTE_GROUP_ID = "__openclaw_gateway_route__";
|
|
86138
|
-
var CURRENT_GATEWAY_SESSION_KEYS_ENV = "OKX_A2A_CURRENT_GATEWAY_SESSION_KEYS";
|
|
86139
|
-
var NON_DELIVERY_CHANNELS = /* @__PURE__ */ new Set(["heartbeat", "cron", "webhook", "voice"]);
|
|
86140
|
-
var ACTIVE_ORIGIN_TTL_MS = 30 * 6e4;
|
|
86141
|
-
function currentOpenClawGatewaySessionKey(env = process.env) {
|
|
86142
|
-
for (const candidate of currentOpenClawGatewaySessionCandidates(env)) {
|
|
86143
|
-
if (candidate.ok) {
|
|
86144
|
-
return candidate.sessionKey;
|
|
86145
|
-
}
|
|
86146
|
-
}
|
|
86147
|
-
return null;
|
|
86148
|
-
}
|
|
86149
|
-
function bindOpenClawGatewayRouteFromEnv(store, input, env = process.env) {
|
|
86150
|
-
const jobId = normalizeText(input.jobId);
|
|
86151
|
-
if (!jobId) {
|
|
86152
|
-
return null;
|
|
86153
|
-
}
|
|
86154
|
-
let routes = readOpenClawRouteEntries(store, jobId);
|
|
86155
|
-
let firstBound = null;
|
|
86156
|
-
for (const candidate of currentOpenClawGatewaySessionCandidates(env, input.gatewaySessionKeys)) {
|
|
86157
|
-
if (!candidate.ok) {
|
|
86158
|
-
logOpenClawRouteSkip(candidate.reason, {
|
|
86159
|
-
jobId,
|
|
86160
|
-
sessionKey: candidate.sessionKey,
|
|
86161
|
-
existingRoute: resolveOpenClawGatewayRoute(store, { jobId })
|
|
86162
|
-
});
|
|
86163
|
-
continue;
|
|
86164
|
-
}
|
|
86165
|
-
const channel = channelFromOpenClawGatewaySessionKey(candidate.sessionKey);
|
|
86166
|
-
if (!channel) {
|
|
86167
|
-
logOpenClawRouteSkip("invalid_gateway_session_key", {
|
|
86168
|
-
jobId,
|
|
86169
|
-
sessionKey: candidate.sessionKey,
|
|
86170
|
-
existingRoute: resolveOpenClawGatewayRoute(store, { jobId })
|
|
86171
|
-
});
|
|
86172
|
-
continue;
|
|
86173
|
-
}
|
|
86174
|
-
const existingRoute = routes.find((route2) => route2.platform === channel) ?? null;
|
|
86175
|
-
const route = existingRoute ?? buildOpenClawRouteEntry(candidate.sessionKey, channel);
|
|
86176
|
-
routes = persistOpenClawRouteBinding(routes, route);
|
|
86177
|
-
firstBound ??= route.sessionKey;
|
|
86178
|
-
}
|
|
86179
|
-
if (firstBound) {
|
|
86180
|
-
const binding = store.setJobProviderGatewayRoutes({ jobId, provider: "openclaw", routes });
|
|
86181
|
-
if (binding.provider !== "openclaw") {
|
|
86182
|
-
return null;
|
|
86183
|
-
}
|
|
86184
|
-
return firstBound;
|
|
86185
|
-
}
|
|
86186
|
-
return resolveOpenClawGatewayRoute(store, { jobId })?.sessionKey ?? null;
|
|
86187
|
-
}
|
|
86188
|
-
function currentOpenClawGatewaySessionCandidates(env = process.env, explicitSessionKeys) {
|
|
86189
|
-
const platform = normalizeText(env.OKX_A2A_CURRENT_GATEWAY_PLATFORM);
|
|
86190
|
-
const chatId = normalizeText(env.OKX_A2A_CURRENT_GATEWAY_CHAT_ID);
|
|
86191
|
-
const threadId = normalizeText(env.OKX_A2A_CURRENT_GATEWAY_THREAD_ID);
|
|
86192
|
-
const rawKeys = [
|
|
86193
|
-
...Array.isArray(explicitSessionKeys) ? explicitSessionKeys : [],
|
|
86194
|
-
...readGatewaySessionKeysEnv(env),
|
|
86195
|
-
normalizeText(env.OKX_A2A_CURRENT_GATEWAY_SESSION_KEY),
|
|
86196
|
-
platform && chatId ? deriveOpenClawGatewaySessionKey({ platform, chatId, threadId }) : null,
|
|
86197
|
-
normalizeText(env.OKX_A2A_CURRENT_SESSION_KEY),
|
|
86198
|
-
...readSingleActiveOriginSessionKey(env)
|
|
86199
|
-
];
|
|
86200
|
-
const seen = /* @__PURE__ */ new Set();
|
|
86201
|
-
const candidates = [];
|
|
86202
|
-
for (const key of rawKeys) {
|
|
86203
|
-
const normalized = normalizeText(key);
|
|
86204
|
-
if (!normalized || seen.has(normalized)) {
|
|
86205
|
-
continue;
|
|
86206
|
-
}
|
|
86207
|
-
seen.add(normalized);
|
|
86208
|
-
candidates.push(validateOpenClawGatewaySessionKey(normalized));
|
|
86209
|
-
}
|
|
86210
|
-
if (candidates.length > 0) {
|
|
86211
|
-
return candidates;
|
|
86212
|
-
}
|
|
86213
|
-
return [{ ok: false, reason: "missing_gateway_session_key" }];
|
|
86214
|
-
}
|
|
86215
|
-
function resolveOpenClawGatewayRoute(store, input) {
|
|
86216
|
-
return resolveOpenClawGatewayRoutes(store, input)[0] ?? null;
|
|
86217
|
-
}
|
|
86218
|
-
function resolveOpenClawGatewayRoutes(store, input) {
|
|
86219
|
-
const jobId = normalizeText(input.jobId) ?? inferJobIdFromSessionKey2(normalizeText(input.sessionKey));
|
|
86220
|
-
if (jobId) {
|
|
86221
|
-
return readOpenClawRouteEntries(store, jobId).map((route) => toOpenClawGatewayRoute(route, jobId));
|
|
86222
|
-
}
|
|
86223
|
-
return [];
|
|
86224
|
-
}
|
|
86225
|
-
function isValidOpenClawGatewaySessionKey(sessionKey) {
|
|
86226
|
-
return validateOpenClawGatewaySessionKey(sessionKey).ok;
|
|
86227
|
-
}
|
|
86228
|
-
function buildOpenClawRouteEntry(sessionKey, channel) {
|
|
86229
|
-
const parsed = parseOpenClawGatewaySessionKey(sessionKey);
|
|
86230
|
-
return {
|
|
86231
|
-
platform: channel,
|
|
86232
|
-
sessionKey,
|
|
86233
|
-
gatewaySessionKey: sessionKey,
|
|
86234
|
-
...parsed.chatId ? { chatId: parsed.chatId } : {},
|
|
86235
|
-
...parsed.threadId ? { threadId: parsed.threadId } : {},
|
|
86236
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
86237
|
-
};
|
|
86238
|
-
}
|
|
86239
|
-
function persistOpenClawRouteBinding(routes, route) {
|
|
86240
|
-
const nextRoute = {
|
|
86241
|
-
...route,
|
|
86242
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
86243
|
-
};
|
|
86244
|
-
if (routes.some((existing) => existing.platform === nextRoute.platform)) {
|
|
86245
|
-
return routes;
|
|
86246
|
-
}
|
|
86247
|
-
return [...routes, nextRoute];
|
|
86248
|
-
}
|
|
86249
|
-
function toOpenClawGatewayRoute(route, jobId) {
|
|
86250
|
-
const sessionKey = route.gatewaySessionKey || route.sessionKey;
|
|
86251
|
-
return {
|
|
86252
|
-
sessionKey,
|
|
86253
|
-
jobId,
|
|
86254
|
-
routeSessionKey: route.sessionKey,
|
|
86255
|
-
updatedAt: route.updatedAt ?? "",
|
|
86256
|
-
channel: route.platform
|
|
86257
|
-
};
|
|
86258
|
-
}
|
|
86259
|
-
function readOpenClawRouteEntries(store, jobId) {
|
|
86260
|
-
const binding = store?.getJobProviderBinding(jobId);
|
|
86261
|
-
if (binding?.provider !== "openclaw") {
|
|
86262
|
-
return [];
|
|
86263
|
-
}
|
|
86264
|
-
const routes = binding.gatewayRoutes ?? [];
|
|
86265
|
-
const seenChannels = /* @__PURE__ */ new Set();
|
|
86266
|
-
const validRoutes = [];
|
|
86267
|
-
for (const route of routes) {
|
|
86268
|
-
const sessionKey = normalizeText(route.gatewaySessionKey) ?? normalizeText(route.sessionKey);
|
|
86269
|
-
const channel = channelFromOpenClawGatewaySessionKey(sessionKey);
|
|
86270
|
-
if (!sessionKey || !channel || seenChannels.has(channel)) {
|
|
86271
|
-
continue;
|
|
86272
|
-
}
|
|
86273
|
-
seenChannels.add(channel);
|
|
86274
|
-
validRoutes.push({
|
|
86275
|
-
platform: channel,
|
|
86276
|
-
sessionKey: route.sessionKey,
|
|
86277
|
-
gatewaySessionKey: sessionKey,
|
|
86278
|
-
...route.chatId ? { chatId: route.chatId } : {},
|
|
86279
|
-
...route.threadId ? { threadId: route.threadId } : {},
|
|
86280
|
-
...route.updatedAt ? { updatedAt: route.updatedAt } : {}
|
|
86281
|
-
});
|
|
86282
|
-
}
|
|
86283
|
-
return validRoutes;
|
|
86284
|
-
}
|
|
86285
|
-
function parseOpenClawGatewaySessionKey(sessionKey) {
|
|
86286
|
-
const parts = sessionKey.split(":");
|
|
86287
|
-
if (parts.length < 4 || parts[0] !== "agent") {
|
|
86288
|
-
return {};
|
|
86289
|
-
}
|
|
86290
|
-
const platform = parts[2];
|
|
86291
|
-
const targetKind = parts[3];
|
|
86292
|
-
if (platform === "discord" && targetKind === "thread") {
|
|
86293
|
-
return {
|
|
86294
|
-
...parts[4] ? { chatId: parts[4] } : {},
|
|
86295
|
-
...parts[5] ? { threadId: parts[5] } : {}
|
|
86296
|
-
};
|
|
86297
|
-
}
|
|
86298
|
-
if (platform === "discord" && targetKind === "channel") {
|
|
86299
|
-
return parts[4] ? { chatId: parts[4] } : {};
|
|
86300
|
-
}
|
|
86301
|
-
if (platform === "discord" && targetKind === "dm") {
|
|
86302
|
-
return parts[4] ? { chatId: parts[4] } : {};
|
|
86303
|
-
}
|
|
86304
|
-
if (platform === "telegram" && targetKind === "direct") {
|
|
86305
|
-
return parts[4] ? { chatId: parts[4] } : {};
|
|
86306
|
-
}
|
|
86307
|
-
if (platform === "telegram" && targetKind === "group") {
|
|
86308
|
-
return {
|
|
86309
|
-
...parts[4] ? { chatId: parts[4] } : {},
|
|
86310
|
-
...parts[6] ? { threadId: parts[6] } : {}
|
|
86311
|
-
};
|
|
86312
|
-
}
|
|
86313
|
-
return {};
|
|
86314
|
-
}
|
|
86315
|
-
function validateOpenClawGatewaySessionKey(sessionKey) {
|
|
86316
|
-
const key = normalizeText(sessionKey);
|
|
86317
|
-
if (!key) {
|
|
86318
|
-
return { ok: false, reason: "missing_gateway_session_key" };
|
|
86319
|
-
}
|
|
86320
|
-
if (key.startsWith("backup:")) {
|
|
86321
|
-
return { ok: false, reason: "internal_gateway_session_key", sessionKey: key };
|
|
86322
|
-
}
|
|
86323
|
-
if (key === "agent:main") {
|
|
86324
|
-
return { ok: true, sessionKey: key };
|
|
86325
|
-
}
|
|
86326
|
-
const parts = key.split(":");
|
|
86327
|
-
if (parts.length < 4 || parts[0] !== "agent" || !parts[1]) {
|
|
86328
|
-
return { ok: false, reason: "invalid_gateway_session_key", sessionKey: key };
|
|
86329
|
-
}
|
|
86330
|
-
const platform = parts[2];
|
|
86331
|
-
if (!platform || platform === "okx-a2a" || NON_DELIVERY_CHANNELS.has(platform)) {
|
|
86332
|
-
return { ok: false, reason: "internal_gateway_session_key", sessionKey: key };
|
|
86333
|
-
}
|
|
86334
|
-
return { ok: true, sessionKey: key };
|
|
86335
|
-
}
|
|
86336
|
-
function channelFromOpenClawGatewaySessionKey(sessionKey) {
|
|
86337
|
-
const key = normalizeText(sessionKey);
|
|
86338
|
-
if (!key) {
|
|
86339
|
-
return null;
|
|
86340
|
-
}
|
|
86341
|
-
if (key === "agent:main") {
|
|
86342
|
-
return "main";
|
|
86343
|
-
}
|
|
86344
|
-
const validation = validateOpenClawGatewaySessionKey(key);
|
|
86345
|
-
if (!validation.ok) {
|
|
86346
|
-
return null;
|
|
86347
|
-
}
|
|
86348
|
-
return key.split(":")[2] ?? null;
|
|
86349
|
-
}
|
|
86350
|
-
function deriveOpenClawGatewaySessionKey(input) {
|
|
86351
|
-
const chatId = encodeURIComponent(input.chatId);
|
|
86352
|
-
const threadId = input.threadId ? encodeURIComponent(input.threadId) : "";
|
|
86353
|
-
if (input.platform === "telegram") {
|
|
86354
|
-
return threadId ? `agent:main:telegram:group:${chatId}:topic:${threadId}` : `agent:main:telegram:direct:${chatId}`;
|
|
86355
|
-
}
|
|
86356
|
-
return threadId ? `agent:main:${input.platform}:thread:${chatId}:${threadId}` : `agent:main:${input.platform}:dm:${chatId}`;
|
|
86357
|
-
}
|
|
86358
|
-
function readGatewaySessionKeysEnv(env) {
|
|
86359
|
-
const raw = normalizeText(env[CURRENT_GATEWAY_SESSION_KEYS_ENV]);
|
|
86360
|
-
if (!raw) {
|
|
86361
|
-
return [];
|
|
86362
|
-
}
|
|
86363
|
-
try {
|
|
86364
|
-
const parsed = JSON.parse(raw);
|
|
86365
|
-
if (Array.isArray(parsed)) {
|
|
86366
|
-
return parsed.filter((item) => typeof item === "string" && item.trim().length > 0);
|
|
86367
|
-
}
|
|
86368
|
-
} catch {
|
|
86369
|
-
}
|
|
86370
|
-
return raw.split(",").map((item) => item.trim()).filter(Boolean);
|
|
86371
|
-
}
|
|
86372
|
-
function readSingleActiveOriginSessionKey(env) {
|
|
86373
|
-
const path = (0, import_node_path17.join)(resolveTaskHome2(env), "run", "gateway-route-origins.json");
|
|
86374
|
-
if (!(0, import_node_fs13.existsSync)(path)) {
|
|
86375
|
-
return [];
|
|
86376
|
-
}
|
|
86377
|
-
try {
|
|
86378
|
-
const parsed = JSON.parse((0, import_node_fs13.readFileSync)(path, "utf8"));
|
|
86379
|
-
if (!isRecord2(parsed) || !Array.isArray(parsed.origins)) {
|
|
86380
|
-
return [];
|
|
86381
|
-
}
|
|
86382
|
-
const now = Date.now();
|
|
86383
|
-
const valid = parsed.origins.filter((item) => isRecord2(item)).map((item) => ({
|
|
86384
|
-
sessionKey: normalizeText(typeof item.sessionKey === "string" ? item.sessionKey : null),
|
|
86385
|
-
count: typeof item.count === "number" && Number.isFinite(item.count) ? item.count : 0,
|
|
86386
|
-
updatedAt: typeof item.updatedAt === "number" && Number.isFinite(item.updatedAt) ? item.updatedAt : 0
|
|
86387
|
-
})).filter((item) => item.sessionKey && item.count > 0 && now - item.updatedAt <= ACTIVE_ORIGIN_TTL_MS && validateOpenClawGatewaySessionKey(item.sessionKey).ok);
|
|
86388
|
-
const sessionKeys = [...new Set(valid.map((item) => item.sessionKey).filter(Boolean))];
|
|
86389
|
-
return sessionKeys.length === 1 ? sessionKeys : [];
|
|
86390
|
-
} catch (err2) {
|
|
86391
|
-
console.error(
|
|
86392
|
-
`[openclaw-route] failed to read active gateway route origin state: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
86393
|
-
);
|
|
86394
|
-
return [];
|
|
86395
|
-
}
|
|
86396
|
-
}
|
|
86397
|
-
function resolveTaskHome2(env) {
|
|
86398
|
-
return env.OKX_AGENT_TASK_HOME?.trim() || (0, import_node_path17.join)((0, import_node_os5.homedir)(), ".okx-agent-task");
|
|
86399
|
-
}
|
|
86400
|
-
function logOpenClawRouteSkip(reason, input) {
|
|
86401
|
-
if (reason === "missing_gateway_session_key") {
|
|
86402
|
-
return;
|
|
86403
|
-
}
|
|
86404
|
-
console.error(
|
|
86405
|
-
`[openclaw-route] skipped gateway route bind reason=${reason} jobId=${input.jobId} sessionKey=${input.sessionKey ?? "(none)"} existingRoute=${input.existingRoute?.sessionKey ?? "(none)"}`
|
|
86406
|
-
);
|
|
86407
|
-
}
|
|
86408
|
-
function inferJobIdFromSessionKey2(sessionKey) {
|
|
86409
|
-
if (!sessionKey) {
|
|
86410
|
-
return null;
|
|
86411
|
-
}
|
|
86412
|
-
const parts = sessionKey.split(":");
|
|
86413
|
-
if (parts.length >= 2 && parts[0] === "job") {
|
|
86414
|
-
return safeDecode2(parts[1]);
|
|
86415
|
-
}
|
|
86416
|
-
if (sessionKey.startsWith("backup:")) {
|
|
86417
|
-
return safeDecode2(sessionKey.slice("backup:".length));
|
|
86418
|
-
}
|
|
86419
|
-
const gatewayJob = /(?:^|[?&:])job=([^:&]+)/.exec(sessionKey);
|
|
86420
|
-
if (gatewayJob?.[1]) {
|
|
86421
|
-
return safeDecode2(gatewayJob[1]);
|
|
86422
|
-
}
|
|
86423
|
-
return null;
|
|
86424
|
-
}
|
|
86425
|
-
function normalizeText(value) {
|
|
86426
|
-
const text = value?.trim();
|
|
86427
|
-
return text ? text : null;
|
|
86428
|
-
}
|
|
86429
|
-
function isRecord2(value) {
|
|
86430
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
86431
|
-
}
|
|
86432
|
-
function safeDecode2(value) {
|
|
86433
|
-
try {
|
|
86434
|
-
return decodeURIComponent(value);
|
|
86435
|
-
} catch {
|
|
86436
|
-
return value;
|
|
86437
|
-
}
|
|
86438
|
-
}
|
|
86439
|
-
|
|
86440
86231
|
// src/outbound-behavior.ts
|
|
86441
86232
|
var SqliteOutboundBehavior = class {
|
|
86442
86233
|
provider;
|
|
@@ -86524,7 +86315,7 @@ function assertLatestUserFanoutDelivered(operation, payload) {
|
|
|
86524
86315
|
const result = payload;
|
|
86525
86316
|
const dispatched = Array.isArray(result.dispatched) ? result.dispatched.length : null;
|
|
86526
86317
|
const failed = Array.isArray(result.failed) ? result.failed.length : null;
|
|
86527
|
-
if (
|
|
86318
|
+
if (result.ok === false || dispatched === 0) {
|
|
86528
86319
|
throw Object.assign(
|
|
86529
86320
|
new Error(
|
|
86530
86321
|
`${operation} did not deliver to any OpenClaw user session (dispatched=${dispatched ?? "unknown"} failed=${failed ?? "unknown"})`
|
|
@@ -86545,10 +86336,10 @@ var GatewayOutboundBehavior = class {
|
|
|
86545
86336
|
}
|
|
86546
86337
|
async createSession(input) {
|
|
86547
86338
|
const gatewaySessionKey = this.resolveGatewaySessionKey(input);
|
|
86548
|
-
|
|
86339
|
+
errorWithTimestamp(`${GATEWAY_OUTBOUND_LOG_PREFIX} createSession sessionKey=${input.sessionKey} gatewaySessionKey=${gatewaySessionKey}`);
|
|
86549
86340
|
try {
|
|
86550
86341
|
await this.gateway.callSessionsCreate({ key: gatewaySessionKey });
|
|
86551
|
-
|
|
86342
|
+
errorWithTimestamp(`${GATEWAY_OUTBOUND_LOG_PREFIX} createSession ok sessionKey=${input.sessionKey} gatewaySessionKey=${gatewaySessionKey}`);
|
|
86552
86343
|
logger.info(LogEvent.SESSION_CREATED, gatewayOutboundExtra("sessions.create", {
|
|
86553
86344
|
sessionKey: input.sessionKey,
|
|
86554
86345
|
gatewaySessionKey,
|
|
@@ -86566,7 +86357,7 @@ var GatewayOutboundBehavior = class {
|
|
|
86566
86357
|
async deleteSession(input) {
|
|
86567
86358
|
const stored = this.sessionMetaStore?.getSession(input.sessionKey);
|
|
86568
86359
|
const gatewaySessionKey = this.resolveGatewaySessionKey(input);
|
|
86569
|
-
|
|
86360
|
+
errorWithTimestamp(`${GATEWAY_OUTBOUND_LOG_PREFIX} deleteSession sessionKey=${input.sessionKey} gatewaySessionKey=${gatewaySessionKey}`);
|
|
86570
86361
|
try {
|
|
86571
86362
|
const result = await this.gateway.callDeleteSessions({
|
|
86572
86363
|
sessionKey: input.sessionKey,
|
|
@@ -86574,7 +86365,7 @@ var GatewayOutboundBehavior = class {
|
|
|
86574
86365
|
...stored?.myAgentId ? { myAgentId: stored.myAgentId } : {},
|
|
86575
86366
|
...stored?.toAgentId ? { toAgentId: stored.toAgentId } : {}
|
|
86576
86367
|
});
|
|
86577
|
-
|
|
86368
|
+
errorWithTimestamp(`${GATEWAY_OUTBOUND_LOG_PREFIX} deleteSession ok sessionKey=${input.sessionKey} gatewaySessionKey=${gatewaySessionKey} deleted=${result.deleted ?? "(unknown)"}`);
|
|
86578
86369
|
logger.info(LogEvent.SESSION_DELETED, gatewayOutboundExtra("okx-a2a.delete_sessions", {
|
|
86579
86370
|
sessionKey: input.sessionKey,
|
|
86580
86371
|
gatewaySessionKey,
|
|
@@ -86590,7 +86381,7 @@ var GatewayOutboundBehavior = class {
|
|
|
86590
86381
|
}
|
|
86591
86382
|
async dispatchSessionMessage(input) {
|
|
86592
86383
|
const gatewaySessionKey = this.resolveGatewaySessionKey(input);
|
|
86593
|
-
|
|
86384
|
+
errorWithTimestamp(
|
|
86594
86385
|
`${GATEWAY_OUTBOUND_LOG_PREFIX} dispatchSessionMessage sessionKey=${input.sessionKey} gatewaySessionKey=${gatewaySessionKey} jobId=${input.jobId ?? "(none)"} agentId=${input.agentId ?? "(none)"} messageId=${input.messageId ?? "(none)"}`
|
|
86595
86386
|
);
|
|
86596
86387
|
try {
|
|
@@ -86599,7 +86390,7 @@ var GatewayOutboundBehavior = class {
|
|
|
86599
86390
|
message: input.content,
|
|
86600
86391
|
...input.messageId ? { idempotencyKey: input.messageId } : {}
|
|
86601
86392
|
});
|
|
86602
|
-
|
|
86393
|
+
errorWithTimestamp(
|
|
86603
86394
|
`${GATEWAY_OUTBOUND_LOG_PREFIX} dispatchSessionMessage ok sessionKey=${input.sessionKey} gatewaySessionKey=${gatewaySessionKey} messageId=${input.messageId ?? "(none)"}`
|
|
86604
86395
|
);
|
|
86605
86396
|
logger.info(LogEvent.SESSION_DISPATCHED, gatewayOutboundExtra("sessions.send", {
|
|
@@ -86628,7 +86419,7 @@ var GatewayOutboundBehavior = class {
|
|
|
86628
86419
|
jobId: input.jobId ?? null,
|
|
86629
86420
|
messageId: input.messageId ?? null
|
|
86630
86421
|
});
|
|
86631
|
-
|
|
86422
|
+
errorWithTimestamp(
|
|
86632
86423
|
`${GATEWAY_OUTBOUND_LOG_PREFIX} dispatchSessionMessage buffered sessionKey=${input.sessionKey} gatewaySessionKey=${gatewaySessionKey} messageId=${input.messageId ?? "(none)"}: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
86633
86424
|
);
|
|
86634
86425
|
logger.error(LogEvent.GATEWAY_REQUEST_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), gatewayOutboundExtra("sessions.send", {
|
|
@@ -86658,22 +86449,13 @@ var GatewayOutboundBehavior = class {
|
|
|
86658
86449
|
});
|
|
86659
86450
|
}
|
|
86660
86451
|
async dispatchUser(input) {
|
|
86661
|
-
|
|
86662
|
-
if (routed) {
|
|
86663
|
-
await this.dispatchUserToGatewaySession(input, routed);
|
|
86664
|
-
return null;
|
|
86665
|
-
}
|
|
86666
|
-
console.error(
|
|
86452
|
+
errorWithTimestamp(
|
|
86667
86453
|
`${GATEWAY_OUTBOUND_LOG_PREFIX} dispatchUser latestUserSessions jobId=${input.jobId ?? "(none)"} idempotencyKey=${input.idempotencyKey ?? "(none)"}`
|
|
86668
86454
|
);
|
|
86669
86455
|
try {
|
|
86670
|
-
const result = await this.gateway.callDispatchUserToLatestSessions({
|
|
86671
|
-
content: input.userContent,
|
|
86672
|
-
...input.jobId ? { jobId: input.jobId } : {},
|
|
86673
|
-
...input.sessionKey ? { currentSessionKey: input.sessionKey } : {}
|
|
86674
|
-
});
|
|
86456
|
+
const result = await this.gateway.callDispatchUserToLatestSessions({ content: input.userContent });
|
|
86675
86457
|
assertLatestUserFanoutDelivered("okx-a2a.dispatch_user", result);
|
|
86676
|
-
|
|
86458
|
+
errorWithTimestamp(`${GATEWAY_OUTBOUND_LOG_PREFIX} dispatchUser latestUserSessions ok`);
|
|
86677
86459
|
logger.info(LogEvent.USER_DISPATCHED, gatewayOutboundExtra("okx-a2a.dispatch_user", {
|
|
86678
86460
|
jobId: input.jobId ?? "",
|
|
86679
86461
|
status: "delivered"
|
|
@@ -86694,7 +86476,7 @@ var GatewayOutboundBehavior = class {
|
|
|
86694
86476
|
jobId: input.jobId ?? null,
|
|
86695
86477
|
messageId: input.idempotencyKey ?? null
|
|
86696
86478
|
});
|
|
86697
|
-
|
|
86479
|
+
errorWithTimestamp(
|
|
86698
86480
|
`${GATEWAY_OUTBOUND_LOG_PREFIX} dispatchUser latestUserSessions buffered idempotencyKey=${input.idempotencyKey ?? "(none)"}: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
86699
86481
|
);
|
|
86700
86482
|
logger.error(LogEvent.USER_DISPATCH_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), gatewayOutboundExtra("okx-a2a.dispatch_user", {
|
|
@@ -86709,93 +86491,17 @@ var GatewayOutboundBehavior = class {
|
|
|
86709
86491
|
}
|
|
86710
86492
|
return null;
|
|
86711
86493
|
}
|
|
86712
|
-
resolveUserGatewaySessionKey(input) {
|
|
86713
|
-
const routes = resolveOpenClawGatewayRoutes(this.sessionMetaStore, input);
|
|
86714
|
-
if (routes.length > 0) {
|
|
86715
|
-
return { sessionKeys: routes.map((route) => route.sessionKey), source: "stored_openclaw_routes" };
|
|
86716
|
-
}
|
|
86717
|
-
if (input.sessionKey?.startsWith("agent:")) {
|
|
86718
|
-
return isValidOpenClawGatewaySessionKey(input.sessionKey) ? { sessionKeys: [input.sessionKey], source: "explicit_gateway_session" } : null;
|
|
86719
|
-
}
|
|
86720
|
-
return null;
|
|
86721
|
-
}
|
|
86722
|
-
async dispatchUserToGatewaySession(input, routed) {
|
|
86723
|
-
const gatewaySessionKey = routed.sessionKeys.join(",");
|
|
86724
|
-
console.error(
|
|
86725
|
-
`${GATEWAY_OUTBOUND_LOG_PREFIX} dispatchUser routed sessionKey=${input.sessionKey ?? "(none)"} gatewaySessionKey=${gatewaySessionKey} source=${routed.source} jobId=${input.jobId ?? "(none)"} idempotencyKey=${input.idempotencyKey ?? "(none)"}`
|
|
86726
|
-
);
|
|
86727
|
-
try {
|
|
86728
|
-
const result = await this.gateway.callDispatchUserToLatestSessions({
|
|
86729
|
-
content: input.userContent,
|
|
86730
|
-
label: "okx-a2a",
|
|
86731
|
-
...routed.source === "stored_openclaw_routes" ? { sessionKeys: routed.sessionKeys } : { sessionKey: routed.sessionKeys[0] }
|
|
86732
|
-
});
|
|
86733
|
-
assertLatestUserFanoutDelivered("okx-a2a.dispatch_user", result);
|
|
86734
|
-
console.error(`${GATEWAY_OUTBOUND_LOG_PREFIX} dispatchUser routed ok gatewaySessionKey=${gatewaySessionKey} source=${routed.source}`);
|
|
86735
|
-
logger.info(LogEvent.USER_DISPATCHED, gatewayOutboundExtra("okx-a2a.dispatch_user", {
|
|
86736
|
-
sessionKey: input.sessionKey ?? "",
|
|
86737
|
-
gatewaySessionKey,
|
|
86738
|
-
jobId: input.jobId ?? "",
|
|
86739
|
-
source: routed.source,
|
|
86740
|
-
status: "delivered"
|
|
86741
|
-
}));
|
|
86742
|
-
} catch (err2) {
|
|
86743
|
-
if (!this.store || !isRetryableOpenClawGatewayError(err2)) {
|
|
86744
|
-
logger.error(LogEvent.USER_DISPATCH_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), gatewayOutboundExtra("okx-a2a.dispatch_user", {
|
|
86745
|
-
sessionKey: input.sessionKey ?? "",
|
|
86746
|
-
gatewaySessionKey,
|
|
86747
|
-
jobId: input.jobId ?? "",
|
|
86748
|
-
source: routed.source,
|
|
86749
|
-
status: "failed"
|
|
86750
|
-
}));
|
|
86751
|
-
throw err2;
|
|
86752
|
-
}
|
|
86753
|
-
this.store.enqueuePendingGatewayDelivery({
|
|
86754
|
-
kind: "chat_inject",
|
|
86755
|
-
provider: this.provider,
|
|
86756
|
-
sessionKey: routed.sessionKeys[0] ?? "openclaw:routed-user-sessions",
|
|
86757
|
-
content: input.userContent,
|
|
86758
|
-
jobId: input.jobId ?? null,
|
|
86759
|
-
messageId: input.idempotencyKey ?? null
|
|
86760
|
-
});
|
|
86761
|
-
console.error(
|
|
86762
|
-
`${GATEWAY_OUTBOUND_LOG_PREFIX} dispatchUser routed buffered gatewaySessionKey=${gatewaySessionKey} source=${routed.source} idempotencyKey=${input.idempotencyKey ?? "(none)"}: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
86763
|
-
);
|
|
86764
|
-
logger.error(LogEvent.USER_DISPATCH_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), gatewayOutboundExtra("okx-a2a.dispatch_user", {
|
|
86765
|
-
sessionKey: input.sessionKey ?? "",
|
|
86766
|
-
gatewaySessionKey,
|
|
86767
|
-
jobId: input.jobId ?? "",
|
|
86768
|
-
source: routed.source,
|
|
86769
|
-
status: "buffered"
|
|
86770
|
-
}));
|
|
86771
|
-
logger.info(LogEvent.GATEWAY_DELIVERY_BUFFERED, gatewayOutboundExtra("okx-a2a.dispatch_user", {
|
|
86772
|
-
sessionKey: input.sessionKey ?? "",
|
|
86773
|
-
gatewaySessionKey,
|
|
86774
|
-
jobId: input.jobId ?? "",
|
|
86775
|
-
messageId: input.idempotencyKey ?? "",
|
|
86776
|
-
source: routed.source,
|
|
86777
|
-
status: "buffered"
|
|
86778
|
-
}));
|
|
86779
|
-
}
|
|
86780
|
-
}
|
|
86781
86494
|
async promptUser(input) {
|
|
86782
|
-
|
|
86783
|
-
if (routed) {
|
|
86784
|
-
await this.promptUserToGatewaySession(input, routed);
|
|
86785
|
-
return null;
|
|
86786
|
-
}
|
|
86787
|
-
console.error(
|
|
86495
|
+
errorWithTimestamp(
|
|
86788
86496
|
`${GATEWAY_OUTBOUND_LOG_PREFIX} promptUser latestUserSessions jobId=${input.jobId ?? "(none)"} idempotencyKey=${input.idempotencyKey ?? "(none)"}`
|
|
86789
86497
|
);
|
|
86790
86498
|
try {
|
|
86791
86499
|
const result = await this.gateway.callPromptUserToLatestSessions({
|
|
86792
86500
|
userContent: input.userContent,
|
|
86793
|
-
llmContent: input.llmContent
|
|
86794
|
-
...input.jobId ? { jobId: input.jobId } : {},
|
|
86795
|
-
...input.sessionKey ? { currentSessionKey: input.sessionKey } : {}
|
|
86501
|
+
llmContent: input.llmContent
|
|
86796
86502
|
});
|
|
86797
86503
|
assertLatestUserFanoutDelivered("okx-a2a.prompt_user", result);
|
|
86798
|
-
|
|
86504
|
+
errorWithTimestamp(`${GATEWAY_OUTBOUND_LOG_PREFIX} promptUser latestUserSessions ok`);
|
|
86799
86505
|
logger.info(LogEvent.PROMPT_USER_CHECKPOINT, gatewayOutboundExtra("okx-a2a.prompt_user", {
|
|
86800
86506
|
jobId: input.jobId ?? "",
|
|
86801
86507
|
status: "delivered"
|
|
@@ -86817,7 +86523,7 @@ var GatewayOutboundBehavior = class {
|
|
|
86817
86523
|
jobId: input.jobId ?? null,
|
|
86818
86524
|
messageId: input.idempotencyKey ?? null
|
|
86819
86525
|
});
|
|
86820
|
-
|
|
86526
|
+
errorWithTimestamp(
|
|
86821
86527
|
`${GATEWAY_OUTBOUND_LOG_PREFIX} promptUser latestUserSessions buffered idempotencyKey=${input.idempotencyKey ?? "(none)"}: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
86822
86528
|
);
|
|
86823
86529
|
logger.error(LogEvent.PROMPT_USER_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), gatewayOutboundExtra("okx-a2a.prompt_user", {
|
|
@@ -86832,66 +86538,6 @@ var GatewayOutboundBehavior = class {
|
|
|
86832
86538
|
}
|
|
86833
86539
|
return null;
|
|
86834
86540
|
}
|
|
86835
|
-
async promptUserToGatewaySession(input, routed) {
|
|
86836
|
-
const gatewaySessionKey = routed.sessionKeys.join(",");
|
|
86837
|
-
console.error(
|
|
86838
|
-
`${GATEWAY_OUTBOUND_LOG_PREFIX} promptUser routed sessionKey=${input.sessionKey ?? "(none)"} gatewaySessionKey=${gatewaySessionKey} source=${routed.source} jobId=${input.jobId ?? "(none)"} idempotencyKey=${input.idempotencyKey ?? "(none)"}`
|
|
86839
|
-
);
|
|
86840
|
-
try {
|
|
86841
|
-
const result = await this.gateway.callPromptUserToLatestSessions({
|
|
86842
|
-
userContent: input.userContent,
|
|
86843
|
-
llmContent: input.llmContent,
|
|
86844
|
-
...routed.source === "stored_openclaw_routes" ? { sessionKeys: routed.sessionKeys } : { sessionKey: routed.sessionKeys[0] }
|
|
86845
|
-
});
|
|
86846
|
-
assertLatestUserFanoutDelivered("okx-a2a.prompt_user", result);
|
|
86847
|
-
console.error(`${GATEWAY_OUTBOUND_LOG_PREFIX} promptUser routed ok gatewaySessionKey=${gatewaySessionKey} source=${routed.source}`);
|
|
86848
|
-
logger.info(LogEvent.PROMPT_USER_CHECKPOINT, gatewayOutboundExtra("routed_prompt_user", {
|
|
86849
|
-
sessionKey: input.sessionKey ?? "",
|
|
86850
|
-
gatewaySessionKey,
|
|
86851
|
-
jobId: input.jobId ?? "",
|
|
86852
|
-
source: routed.source,
|
|
86853
|
-
status: "delivered"
|
|
86854
|
-
}));
|
|
86855
|
-
} catch (err2) {
|
|
86856
|
-
if (!this.store || !isRetryableOpenClawGatewayError(err2)) {
|
|
86857
|
-
logger.error(LogEvent.PROMPT_USER_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), gatewayOutboundExtra("routed_prompt_user", {
|
|
86858
|
-
sessionKey: input.sessionKey ?? "",
|
|
86859
|
-
gatewaySessionKey,
|
|
86860
|
-
jobId: input.jobId ?? "",
|
|
86861
|
-
source: routed.source,
|
|
86862
|
-
status: "failed"
|
|
86863
|
-
}));
|
|
86864
|
-
throw err2;
|
|
86865
|
-
}
|
|
86866
|
-
this.store.enqueuePendingGatewayDelivery({
|
|
86867
|
-
kind: "chat_inject",
|
|
86868
|
-
provider: this.provider,
|
|
86869
|
-
sessionKey: routed.sessionKeys[0] ?? "openclaw:routed-user-sessions",
|
|
86870
|
-
content: input.userContent,
|
|
86871
|
-
llmContent: input.llmContent,
|
|
86872
|
-
jobId: input.jobId ?? null,
|
|
86873
|
-
messageId: input.idempotencyKey ?? null
|
|
86874
|
-
});
|
|
86875
|
-
console.error(
|
|
86876
|
-
`${GATEWAY_OUTBOUND_LOG_PREFIX} promptUser routed buffered gatewaySessionKey=${gatewaySessionKey} source=${routed.source} idempotencyKey=${input.idempotencyKey ?? "(none)"}: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
86877
|
-
);
|
|
86878
|
-
logger.error(LogEvent.PROMPT_USER_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), gatewayOutboundExtra("routed_prompt_user", {
|
|
86879
|
-
sessionKey: input.sessionKey ?? "",
|
|
86880
|
-
gatewaySessionKey,
|
|
86881
|
-
jobId: input.jobId ?? "",
|
|
86882
|
-
source: routed.source,
|
|
86883
|
-
status: "buffered"
|
|
86884
|
-
}));
|
|
86885
|
-
logger.info(LogEvent.GATEWAY_DELIVERY_BUFFERED, gatewayOutboundExtra("routed_prompt_user", {
|
|
86886
|
-
sessionKey: input.sessionKey ?? "",
|
|
86887
|
-
gatewaySessionKey,
|
|
86888
|
-
jobId: input.jobId ?? "",
|
|
86889
|
-
messageId: input.idempotencyKey ?? "",
|
|
86890
|
-
source: routed.source,
|
|
86891
|
-
status: "buffered"
|
|
86892
|
-
}));
|
|
86893
|
-
}
|
|
86894
|
-
}
|
|
86895
86541
|
};
|
|
86896
86542
|
function createOutboundBehavior(provider, deps) {
|
|
86897
86543
|
if (provider === "openclaw") {
|
|
@@ -86980,27 +86626,15 @@ function resolveOutboundProvider(store, input) {
|
|
|
86980
86626
|
if (input.override) {
|
|
86981
86627
|
return input.override;
|
|
86982
86628
|
}
|
|
86983
|
-
if (input.jobId && resolveOpenClawGatewayRoute(store, { jobId: input.jobId })) {
|
|
86984
|
-
return "openclaw";
|
|
86985
|
-
}
|
|
86986
86629
|
try {
|
|
86987
|
-
|
|
86630
|
+
return resolveConfiguredAiProviderForJob({
|
|
86988
86631
|
store,
|
|
86989
86632
|
jobId: input.jobId,
|
|
86990
86633
|
env: process.env
|
|
86991
|
-
});
|
|
86992
|
-
if (configured) {
|
|
86993
|
-
return configured;
|
|
86994
|
-
}
|
|
86634
|
+
}) ?? "codex";
|
|
86995
86635
|
} catch {
|
|
86636
|
+
return "codex";
|
|
86996
86637
|
}
|
|
86997
|
-
if (readSyncedOpenClawGatewayConfig(store.homeDir)) {
|
|
86998
|
-
if (input.jobId?.trim()) {
|
|
86999
|
-
return store.bindJobProviderIfMissing({ jobId: input.jobId.trim(), provider: "openclaw" }).binding.provider;
|
|
87000
|
-
}
|
|
87001
|
-
return "openclaw";
|
|
87002
|
-
}
|
|
87003
|
-
return "codex";
|
|
87004
86638
|
}
|
|
87005
86639
|
async function notifyAgentMessageToUserAttention(input) {
|
|
87006
86640
|
const ownedStore = input.store ? null : new SessionStore();
|
|
@@ -87019,12 +86653,12 @@ async function notifyAgentMessageToUserAttention(input) {
|
|
|
87019
86653
|
sessionKey: input.sessionKey ?? null,
|
|
87020
86654
|
idempotencyKey
|
|
87021
86655
|
});
|
|
87022
|
-
|
|
86656
|
+
logWithTimestamp(
|
|
87023
86657
|
`[notifyAgentMessageToUserAttention] provider=${provider} direction=${input.direction} job=${input.jobId} item=${item?.id ?? "(gateway)"}`
|
|
87024
86658
|
);
|
|
87025
86659
|
return item;
|
|
87026
86660
|
} catch (err2) {
|
|
87027
|
-
|
|
86661
|
+
logWithTimestamp(
|
|
87028
86662
|
`[notifyAgentMessageToUserAttention] failed direction=${input.direction} job=${input.jobId}:`,
|
|
87029
86663
|
err2
|
|
87030
86664
|
);
|
|
@@ -87050,12 +86684,12 @@ async function notifySystemMessageToUser(input) {
|
|
|
87050
86684
|
sessionKey: input.sessionKey ?? null,
|
|
87051
86685
|
idempotencyKey
|
|
87052
86686
|
});
|
|
87053
|
-
|
|
86687
|
+
logWithTimestamp(
|
|
87054
86688
|
`[notifySystemMessageToUser] provider=${provider} title=${input.title} item=${item?.id ?? "(gateway)"}`
|
|
87055
86689
|
);
|
|
87056
86690
|
return item;
|
|
87057
86691
|
} catch (err2) {
|
|
87058
|
-
|
|
86692
|
+
logWithTimestamp(
|
|
87059
86693
|
`[notifySystemMessageToUser] failed title=${input.title}:`,
|
|
87060
86694
|
err2
|
|
87061
86695
|
);
|
|
@@ -87114,7 +86748,7 @@ function assertRecipientAvailable(agent) {
|
|
|
87114
86748
|
}
|
|
87115
86749
|
}
|
|
87116
86750
|
function logRecipientStatusLookupFailed(context, err2) {
|
|
87117
|
-
|
|
86751
|
+
logWithTimestamp(`[okx-agent-task] recipient status lookup failed, continuing (${context}):`, err2);
|
|
87118
86752
|
}
|
|
87119
86753
|
function bindOutboundJobProviderToCurrentDefault(sessionStore, jobId) {
|
|
87120
86754
|
if (!jobId || jobId === BACKUP_JOB_ID) {
|
|
@@ -87126,15 +86760,12 @@ function bindOutboundJobProviderToCurrentDefault(sessionStore, jobId) {
|
|
|
87126
86760
|
jobId
|
|
87127
86761
|
});
|
|
87128
86762
|
if (result?.created) {
|
|
87129
|
-
|
|
86763
|
+
logWithTimestamp(`[okx-agent-task] job provider bound from outbound-xmtp: job=${jobId} provider=${result.provider}`);
|
|
87130
86764
|
}
|
|
87131
86765
|
} catch (err2) {
|
|
87132
|
-
|
|
86766
|
+
logWithTimestamp(`[okx-agent-task] job provider bind failed from outbound-xmtp: job=${jobId}`, err2);
|
|
87133
86767
|
}
|
|
87134
86768
|
}
|
|
87135
|
-
function bindOutboundOpenClawRouteIfCurrent(sessionStore, jobId, gatewaySessionKeys) {
|
|
87136
|
-
bindOpenClawGatewayRouteFromEnv(sessionStore, { jobId, gatewaySessionKeys });
|
|
87137
|
-
}
|
|
87138
86769
|
function buildTaskPayload(replyToMessageId) {
|
|
87139
86770
|
return {
|
|
87140
86771
|
taskMinVersion: TASK_MIN_VERSION,
|
|
@@ -87280,13 +86911,13 @@ async function assertOutboundEligible(params) {
|
|
|
87280
86911
|
providerSecurityRate
|
|
87281
86912
|
});
|
|
87282
86913
|
} catch (err2) {
|
|
87283
|
-
|
|
86914
|
+
logWithTimestamp(
|
|
87284
86915
|
`[okx-agent-task] outbound message-eligible call failed, letting send continue: senderAgentId=${senderAgent.agentId} receiverAgentId=${receiverAgent.agentId} job=${jobId} group=${groupId}`,
|
|
87285
86916
|
err2
|
|
87286
86917
|
);
|
|
87287
86918
|
return;
|
|
87288
86919
|
}
|
|
87289
|
-
|
|
86920
|
+
logWithTimestamp(
|
|
87290
86921
|
`[okx-agent-task] outbound message-eligible: senderAgentId=${senderAgent.agentId} receiverAgentId=${receiverAgent.agentId} job=${jobId} group=${groupId} result=${JSON.stringify(result)}`
|
|
87291
86922
|
);
|
|
87292
86923
|
if (!result.eligible) {
|
|
@@ -87362,7 +86993,7 @@ async function refreshCachedBlockedAgentById(agentId, cached) {
|
|
|
87362
86993
|
const [remote] = await fetchAgentsByIds([agentId]);
|
|
87363
86994
|
if (remote?.agentId) {
|
|
87364
86995
|
cacheResolvedAgent(remote);
|
|
87365
|
-
|
|
86996
|
+
logWithTimestamp(
|
|
87366
86997
|
`[okx-agent-task] refreshed blocked recipient cache by agentId=${agentId}: oldStatus=${cached.status} newStatus=${remote.status}`
|
|
87367
86998
|
);
|
|
87368
86999
|
return remote;
|
|
@@ -87380,7 +87011,7 @@ async function refreshCachedBlockedAgentByAddress(communicationAddress, cached)
|
|
|
87380
87011
|
const remote = await fetchAgentByAddress(communicationAddress);
|
|
87381
87012
|
if (remote?.agentId) {
|
|
87382
87013
|
cacheResolvedAgent(remote);
|
|
87383
|
-
|
|
87014
|
+
logWithTimestamp(
|
|
87384
87015
|
`[okx-agent-task] refreshed blocked recipient cache by address=${communicationAddress}: oldStatus=${cached.status} newStatus=${remote.status}`
|
|
87385
87016
|
);
|
|
87386
87017
|
return remote;
|
|
@@ -87434,7 +87065,7 @@ async function resolveRemoteByAgentId(params) {
|
|
|
87434
87065
|
const fallbackAgent = await resolveAgentByAddressFromCacheOrNetwork(service, fallbackAddress);
|
|
87435
87066
|
remoteAgent = fallbackAgent ?? remoteAgent;
|
|
87436
87067
|
} catch (err2) {
|
|
87437
|
-
|
|
87068
|
+
logWithTimestamp(
|
|
87438
87069
|
`[okx-agent-task] remote agent lookup failed for ${fallbackAddress}, continuing without receiverAgentId:`,
|
|
87439
87070
|
err2
|
|
87440
87071
|
);
|
|
@@ -87466,7 +87097,7 @@ async function resolveRemote(params) {
|
|
|
87466
87097
|
try {
|
|
87467
87098
|
remoteAgent = await resolveAgentByAddressFromCacheOrNetwork(service, toXmtpAddress);
|
|
87468
87099
|
} catch (err2) {
|
|
87469
|
-
|
|
87100
|
+
logWithTimestamp(
|
|
87470
87101
|
`[okx-agent-task] remote agent lookup failed for ${toXmtpAddress}, continuing without receiverAgentId:`,
|
|
87471
87102
|
err2
|
|
87472
87103
|
);
|
|
@@ -87497,7 +87128,7 @@ async function resolveRemoteWithoutFile(params) {
|
|
|
87497
87128
|
try {
|
|
87498
87129
|
remoteAgent = await resolveAgentByAddressFromCacheOrNetwork(service, command.toXmtpAddress);
|
|
87499
87130
|
} catch (err2) {
|
|
87500
|
-
|
|
87131
|
+
logWithTimestamp(
|
|
87501
87132
|
`[okx-agent-task] remote agent lookup failed for ${command.toXmtpAddress}, continuing without receiverAgentId:`,
|
|
87502
87133
|
err2
|
|
87503
87134
|
);
|
|
@@ -87571,7 +87202,6 @@ async function handleSqliteGroupSendCommand(params) {
|
|
|
87571
87202
|
myAgentXmtpAddress: myXmtpAddress,
|
|
87572
87203
|
toAgentXmtpAddress: remote.toXmtpAddress
|
|
87573
87204
|
});
|
|
87574
|
-
bindOutboundOpenClawRouteIfCurrent(sessionStore, command.jobId, command.gatewaySessionKeys);
|
|
87575
87205
|
return { conversation: conversation2, created: created2 };
|
|
87576
87206
|
}
|
|
87577
87207
|
);
|
|
@@ -87594,7 +87224,7 @@ async function handleSqliteGroupSendCommand(params) {
|
|
|
87594
87224
|
receiverAgentId: remote.remoteAgent?.agentId ?? remote.toAgentId ?? null,
|
|
87595
87225
|
payload: buildTaskPayload(command.replyToMessageId)
|
|
87596
87226
|
});
|
|
87597
|
-
|
|
87227
|
+
logWithTimestamp(`[okx-agent-task] xmtp envelope ${rawText}`);
|
|
87598
87228
|
await conversation.send(rawText);
|
|
87599
87229
|
const messageId = `outbound-${(0, import_node_crypto8.randomUUID)()}`;
|
|
87600
87230
|
await notifyAgentMessageToUserAttention({
|
|
@@ -87615,7 +87245,7 @@ async function handleSqliteGroupSendCommand(params) {
|
|
|
87615
87245
|
content: command.message,
|
|
87616
87246
|
store: sessionStore
|
|
87617
87247
|
});
|
|
87618
|
-
|
|
87248
|
+
logWithTimestamp(
|
|
87619
87249
|
`[okx-agent-task] sent xmtp message via sqlite session=${sessionKey} group=${conversation.id} created=${created}`
|
|
87620
87250
|
);
|
|
87621
87251
|
return { messageId };
|
|
@@ -87731,7 +87361,7 @@ async function handleGroupSendCommand(params) {
|
|
|
87731
87361
|
receiverAgentId: remoteAgent?.agentId ?? session.toAgentId ?? null,
|
|
87732
87362
|
payload: buildTaskPayload(command.replyToMessageId)
|
|
87733
87363
|
});
|
|
87734
|
-
|
|
87364
|
+
logWithTimestamp(`[okx-agent-task] xmtp envelope ${rawText}`);
|
|
87735
87365
|
await conversation.send(rawText);
|
|
87736
87366
|
const now = Date.now();
|
|
87737
87367
|
const messageId = `outbound-${(0, import_node_crypto8.randomUUID)()}`;
|
|
@@ -87898,7 +87528,7 @@ async function handleXmtpSendCommand(params) {
|
|
|
87898
87528
|
const sessionStore2 = params.sessionStore ?? ownedStore2;
|
|
87899
87529
|
try {
|
|
87900
87530
|
bindOutboundJobProviderToCurrentDefault(sessionStore2, command.jobId);
|
|
87901
|
-
|
|
87531
|
+
resolveConfiguredAiProviderForJob({ store: sessionStore2, jobId: command.jobId });
|
|
87902
87532
|
return await handleSqliteGroupSendCommand({
|
|
87903
87533
|
command,
|
|
87904
87534
|
service,
|
|
@@ -87912,7 +87542,7 @@ async function handleXmtpSendCommand(params) {
|
|
|
87912
87542
|
const sessionStore = params.sessionStore ?? ownedStore;
|
|
87913
87543
|
try {
|
|
87914
87544
|
bindOutboundJobProviderToCurrentDefault(sessionStore, command.jobId);
|
|
87915
|
-
|
|
87545
|
+
resolveConfiguredAiProviderForJob({ store: sessionStore, jobId: command.jobId });
|
|
87916
87546
|
const { file, sessionAgentId } = await readFileForSend({
|
|
87917
87547
|
command,
|
|
87918
87548
|
store,
|
|
@@ -88069,7 +87699,7 @@ function startCommandProcessor(params) {
|
|
|
88069
87699
|
timeoutMs: staleTimeoutMs,
|
|
88070
87700
|
reason: "pending_expired"
|
|
88071
87701
|
}));
|
|
88072
|
-
|
|
87702
|
+
logWithTimestamp(
|
|
88073
87703
|
`[okx-agent-task] ${command.type} command expired id=${command.id}: ${message}`
|
|
88074
87704
|
);
|
|
88075
87705
|
continue;
|
|
@@ -88085,7 +87715,7 @@ function startCommandProcessor(params) {
|
|
|
88085
87715
|
`${command.type} command timed out after ${formatDuration2(executionTimeoutMs)}`
|
|
88086
87716
|
);
|
|
88087
87717
|
await commands.complete(command, result);
|
|
88088
|
-
|
|
87718
|
+
logWithTimestamp(formatCommandCompleted(command, result));
|
|
88089
87719
|
} catch (err2) {
|
|
88090
87720
|
const message = err2 instanceof Error ? err2.message : String(err2);
|
|
88091
87721
|
await commands.complete(command, {
|
|
@@ -88105,7 +87735,7 @@ function startCommandProcessor(params) {
|
|
|
88105
87735
|
if (command.type === "xmtp-send") {
|
|
88106
87736
|
await notifyCommandFailure(params, command, message);
|
|
88107
87737
|
}
|
|
88108
|
-
|
|
87738
|
+
logWithTimestamp(
|
|
88109
87739
|
`[okx-agent-task] ${command.type} command failed id=${command.id}: ${message}`
|
|
88110
87740
|
);
|
|
88111
87741
|
}
|
|
@@ -88120,7 +87750,7 @@ function startCommandProcessor(params) {
|
|
|
88120
87750
|
reason: "tick_exception"
|
|
88121
87751
|
}
|
|
88122
87752
|
);
|
|
88123
|
-
|
|
87753
|
+
logWithTimestamp("[okx-agent-task] command processor tick failed:", err2);
|
|
88124
87754
|
} finally {
|
|
88125
87755
|
inFlight = false;
|
|
88126
87756
|
}
|
|
@@ -88158,7 +87788,7 @@ function startCommandProcessor(params) {
|
|
|
88158
87788
|
timeoutMs: aiStaleTimeoutMs,
|
|
88159
87789
|
reason: "pending_expired"
|
|
88160
87790
|
}));
|
|
88161
|
-
|
|
87791
|
+
logWithTimestamp(
|
|
88162
87792
|
`[okx-agent-task] ${command.type}/${command.kind} command expired id=${command.id}: ${message}`
|
|
88163
87793
|
);
|
|
88164
87794
|
continue;
|
|
@@ -88182,7 +87812,7 @@ function startCommandProcessor(params) {
|
|
|
88182
87812
|
reason: "tick_exception"
|
|
88183
87813
|
}
|
|
88184
87814
|
);
|
|
88185
|
-
|
|
87815
|
+
logWithTimestamp("[okx-agent-task] AI command processor tick failed:", err2);
|
|
88186
87816
|
} finally {
|
|
88187
87817
|
aiScanInFlight = false;
|
|
88188
87818
|
}
|
|
@@ -88191,7 +87821,7 @@ function startCommandProcessor(params) {
|
|
|
88191
87821
|
try {
|
|
88192
87822
|
const result = await handleDaemonCommand(command, { ...params, aiRunner, commandPendingMs });
|
|
88193
87823
|
await commands.complete(command, result);
|
|
88194
|
-
|
|
87824
|
+
logWithTimestamp(formatCommandCompleted(command, result));
|
|
88195
87825
|
} catch (err2) {
|
|
88196
87826
|
const message = err2 instanceof Error ? err2.message : String(err2);
|
|
88197
87827
|
await commands.complete(command, {
|
|
@@ -88207,7 +87837,7 @@ function startCommandProcessor(params) {
|
|
|
88207
87837
|
reason: isTimeout ? "ai_timeout" : "ai_error"
|
|
88208
87838
|
})
|
|
88209
87839
|
);
|
|
88210
|
-
|
|
87840
|
+
logWithTimestamp(
|
|
88211
87841
|
`[okx-agent-task] ${command.type}/${command.kind} command failed id=${command.id}: ${message}`
|
|
88212
87842
|
);
|
|
88213
87843
|
} finally {
|
|
@@ -88488,7 +88118,7 @@ async function failStaleProcessing(commands, params, staleTimeoutMs, aiStaleTime
|
|
|
88488
88118
|
if (entry.command.type === "xmtp-send") {
|
|
88489
88119
|
await notifyCommandFailure(params, entry.command, message);
|
|
88490
88120
|
}
|
|
88491
|
-
|
|
88121
|
+
logWithTimestamp(
|
|
88492
88122
|
`[okx-agent-task] recovered stale ${entry.command.type} command id=${entry.command.id}: ${message}`
|
|
88493
88123
|
);
|
|
88494
88124
|
}
|
|
@@ -88552,9 +88182,9 @@ async function notifyCommandFailure(params, command, message) {
|
|
|
88552
88182
|
].join("\n")
|
|
88553
88183
|
});
|
|
88554
88184
|
await notifyUserAttentionChanged(params.homeDir ?? params.sessionStore.homeDir);
|
|
88555
|
-
|
|
88185
|
+
logWithTimestamp(`[okx-agent-task] queued xmtp-send failure notification todo=${item.id} command=${command.id}`);
|
|
88556
88186
|
} catch (err2) {
|
|
88557
|
-
|
|
88187
|
+
logWithTimestamp(`[okx-agent-task] failed to notify xmtp-send failure command=${command.id}:`, err2);
|
|
88558
88188
|
}
|
|
88559
88189
|
}
|
|
88560
88190
|
function readPositiveEnv(name2, fallback) {
|
|
@@ -88635,7 +88265,7 @@ function extractRawText(content3) {
|
|
|
88635
88265
|
}
|
|
88636
88266
|
return safeStringify(content3);
|
|
88637
88267
|
}
|
|
88638
|
-
function
|
|
88268
|
+
function extractXmtpSentAtMs2(msg) {
|
|
88639
88269
|
if (typeof msg.sentAtNs === "bigint") {
|
|
88640
88270
|
return Number(msg.sentAtNs / 1000000n);
|
|
88641
88271
|
}
|
|
@@ -88773,12 +88403,12 @@ function bindMessageJobProviderToCurrentDefault(deps, jobId, stage = "inbound-xm
|
|
|
88773
88403
|
return { allowed: true, created: false, provider: null, currentProvider };
|
|
88774
88404
|
}
|
|
88775
88405
|
if (result?.created) {
|
|
88776
|
-
|
|
88406
|
+
logWithTimestamp(
|
|
88777
88407
|
`[okx-agent-task:${deps.myXmtpAddress}] job provider bound from ${stage}: job=${shortenLogValue(jobId)} provider=${result.provider}`
|
|
88778
88408
|
);
|
|
88779
88409
|
}
|
|
88780
88410
|
if (currentProvider && result.provider !== currentProvider) {
|
|
88781
|
-
|
|
88411
|
+
logWithTimestamp(
|
|
88782
88412
|
`[okx-agent-task:${deps.myXmtpAddress}] job provider owner differs from default at ${stage}: job=${shortenLogValue(jobId)} owner=${result.provider} default=${currentProvider}; dispatch will use owner binding`
|
|
88783
88413
|
);
|
|
88784
88414
|
}
|
|
@@ -88789,7 +88419,7 @@ function bindMessageJobProviderToCurrentDefault(deps, jobId, stage = "inbound-xm
|
|
|
88789
88419
|
currentProvider
|
|
88790
88420
|
};
|
|
88791
88421
|
} catch (err2) {
|
|
88792
|
-
|
|
88422
|
+
logWithTimestamp(
|
|
88793
88423
|
`[okx-agent-task:${deps.myXmtpAddress}] job provider bind failed from ${stage}: job=${shortenLogValue(jobId)}`,
|
|
88794
88424
|
err2
|
|
88795
88425
|
);
|
|
@@ -88863,7 +88493,7 @@ async function maybeAllowProviderGroup(deps, chatType, conversationId) {
|
|
|
88863
88493
|
try {
|
|
88864
88494
|
await deps.allowGroup(deps.myXmtpAddress, conversationId);
|
|
88865
88495
|
} catch (err2) {
|
|
88866
|
-
|
|
88496
|
+
logWithTimestamp(
|
|
88867
88497
|
`[okx-agent-task:${deps.myXmtpAddress}] allowGroup failed for ${conversationId}:`,
|
|
88868
88498
|
err2
|
|
88869
88499
|
);
|
|
@@ -88887,7 +88517,7 @@ function notifyPendingConversationToBackup(params) {
|
|
|
88887
88517
|
messageId: params.messageId
|
|
88888
88518
|
});
|
|
88889
88519
|
void Promise.resolve(params.deps.onSessionMessage?.(event)).catch((err2) => {
|
|
88890
|
-
|
|
88520
|
+
logWithTimestamp(`[okx-agent-task:${params.deps.myXmtpAddress}] pending conversation backup dispatch failed:`, err2);
|
|
88891
88521
|
});
|
|
88892
88522
|
}
|
|
88893
88523
|
function maybeNotifyInboundAgentMessage(params) {
|
|
@@ -88903,7 +88533,7 @@ function maybeNotifyInboundAgentMessage(params) {
|
|
|
88903
88533
|
messageId: params.messageId,
|
|
88904
88534
|
store: params.deps.sessionStore
|
|
88905
88535
|
}).catch((err2) => {
|
|
88906
|
-
|
|
88536
|
+
logWithTimestamp(`[okx-agent-task:${params.deps.myXmtpAddress}] system user notification failed:`, err2);
|
|
88907
88537
|
});
|
|
88908
88538
|
return;
|
|
88909
88539
|
}
|
|
@@ -88932,7 +88562,7 @@ function maybeNotifyInboundAgentMessage(params) {
|
|
|
88932
88562
|
content: content3,
|
|
88933
88563
|
store: params.deps.sessionStore
|
|
88934
88564
|
}).catch((err2) => {
|
|
88935
|
-
|
|
88565
|
+
logWithTimestamp(`[okx-agent-task:${params.deps.myXmtpAddress}] inbound user notification failed:`, err2);
|
|
88936
88566
|
});
|
|
88937
88567
|
}
|
|
88938
88568
|
function stringifySystemPayload(payload) {
|
|
@@ -89007,7 +88637,7 @@ async function isTrustedDmSender(params) {
|
|
|
89007
88637
|
}
|
|
89008
88638
|
if (!matches(trustedInboxIds)) {
|
|
89009
88639
|
logger.info(LogEvent.INBOUND_DROP_DM_NON_SYSTEM, { ...dmExtras(), reason: "sender_not_in_system_whitelist" });
|
|
89010
|
-
|
|
88640
|
+
logWithTimestamp(
|
|
89011
88641
|
`[okx-agent-task:${myXmtpAddress}] DM sender not in system whitelist, dropping: senderInboxId=${senderInboxId || "(empty)"}`
|
|
89012
88642
|
);
|
|
89013
88643
|
return false;
|
|
@@ -89040,7 +88670,7 @@ async function claimedAddressMatchesSender(params) {
|
|
|
89040
88670
|
});
|
|
89041
88671
|
return !!claimedInboxId && !!senderInboxId && claimedInboxId.toLowerCase() === senderInboxId.toLowerCase();
|
|
89042
88672
|
} catch (err2) {
|
|
89043
|
-
|
|
88673
|
+
logWithTimestamp(
|
|
89044
88674
|
`[okx-agent-task:${myXmtpAddress}] getInboxIdByIdentifier failed, blocking address check:`,
|
|
89045
88675
|
err2
|
|
89046
88676
|
);
|
|
@@ -89073,7 +88703,7 @@ function recordInvalidXmtpMessageBestEffort(input) {
|
|
|
89073
88703
|
store.close();
|
|
89074
88704
|
}
|
|
89075
88705
|
} catch (err2) {
|
|
89076
|
-
|
|
88706
|
+
logWithTimestamp(`${input.logTag} failed to record invalid xmtp message ${input.messageId}:`, err2);
|
|
89077
88707
|
}
|
|
89078
88708
|
}
|
|
89079
88709
|
async function verifyInboundA2AGroupMessage(params) {
|
|
@@ -89086,13 +88716,14 @@ async function verifyInboundA2AGroupMessage(params) {
|
|
|
89086
88716
|
groupId,
|
|
89087
88717
|
messageId,
|
|
89088
88718
|
consentState,
|
|
89089
|
-
trustedSystemSender = false
|
|
88719
|
+
trustedSystemSender = false,
|
|
88720
|
+
timing
|
|
89090
88721
|
} = params;
|
|
89091
88722
|
if (!isA2AEnvelope(payload)) {
|
|
89092
88723
|
return true;
|
|
89093
88724
|
}
|
|
89094
88725
|
if (trustedSystemSender) {
|
|
89095
|
-
|
|
88726
|
+
logWithTimestamp(
|
|
89096
88727
|
`[okx-agent-task:${myXmtpAddress}] trusted system/security group sender, skipping inbound policy checks: sender=${senderAddress} job=${jobId} group=${groupId}`
|
|
89097
88728
|
);
|
|
89098
88729
|
return true;
|
|
@@ -89100,14 +88731,20 @@ async function verifyInboundA2AGroupMessage(params) {
|
|
|
89100
88731
|
const service = XmtpService.getInstance();
|
|
89101
88732
|
const myAgent = service.getAgentByAddress(myXmtpAddress);
|
|
89102
88733
|
const claimedAddress = readString3(payload.fromXmtpAddress);
|
|
89103
|
-
|
|
89104
|
-
|
|
89105
|
-
|
|
89106
|
-
|
|
89107
|
-
|
|
89108
|
-
|
|
89109
|
-
|
|
89110
|
-
|
|
88734
|
+
let claimedAddressMatches = true;
|
|
88735
|
+
if (claimedAddress) {
|
|
88736
|
+
const addressCheckStartedAt = Date.now();
|
|
88737
|
+
claimedAddressMatches = await claimedAddressMatchesSender({
|
|
88738
|
+
myXmtpAddress,
|
|
88739
|
+
claimedAddress,
|
|
88740
|
+
senderAddress,
|
|
88741
|
+
senderInboxId,
|
|
88742
|
+
messageId,
|
|
88743
|
+
conversationId: groupId
|
|
88744
|
+
});
|
|
88745
|
+
timing?.mark("addressCheck", addressCheckStartedAt);
|
|
88746
|
+
}
|
|
88747
|
+
if (claimedAddress && !claimedAddressMatches) {
|
|
89111
88748
|
const shouldAutoDeny = consentState === import_node_bindings2.ConsentState.Unknown && (myAgent?.role === 1 /* CLIENT */ || myAgent?.role == null);
|
|
89112
88749
|
let autoDenyAttempted = false;
|
|
89113
88750
|
let autoDenySucceeded = false;
|
|
@@ -89115,7 +88752,9 @@ async function verifyInboundA2AGroupMessage(params) {
|
|
|
89115
88752
|
if (shouldAutoDeny) {
|
|
89116
88753
|
autoDenyAttempted = true;
|
|
89117
88754
|
try {
|
|
88755
|
+
const denyStartedAt = Date.now();
|
|
89118
88756
|
autoDenySucceeded = await service.denyGroup(myXmtpAddress, groupId);
|
|
88757
|
+
timing?.mark("autoDeny", denyStartedAt);
|
|
89119
88758
|
} catch (err2) {
|
|
89120
88759
|
autoDenyError = err2 instanceof Error ? err2.message : String(err2);
|
|
89121
88760
|
logger.error(LogEvent.GROUP_CONSENT_UPDATE_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), {
|
|
@@ -89131,7 +88770,7 @@ async function verifyInboundA2AGroupMessage(params) {
|
|
|
89131
88770
|
});
|
|
89132
88771
|
}
|
|
89133
88772
|
}
|
|
89134
|
-
|
|
88773
|
+
logWithTimestamp(
|
|
89135
88774
|
`[okx-agent-task:${myXmtpAddress}] address spoofing detected, dropping: claimed=${claimedAddress} actual=${senderAddress} autoDeny=${autoDenyAttempted ? String(autoDenySucceeded) : "skipped"}`
|
|
89136
88775
|
);
|
|
89137
88776
|
recordInvalidXmtpMessageBestEffort({
|
|
@@ -89159,7 +88798,8 @@ async function verifyInboundA2AGroupMessage(params) {
|
|
|
89159
88798
|
action: autoDenyAttempted ? "auto-deny" : "drop",
|
|
89160
88799
|
autoDenyAttempted: String(autoDenyAttempted),
|
|
89161
88800
|
autoDenySucceeded: String(autoDenySucceeded),
|
|
89162
|
-
autoDenyError
|
|
88801
|
+
autoDenyError,
|
|
88802
|
+
...timing?.extras()
|
|
89163
88803
|
});
|
|
89164
88804
|
return false;
|
|
89165
88805
|
}
|
|
@@ -89170,6 +88810,7 @@ async function verifyInboundA2AGroupMessage(params) {
|
|
|
89170
88810
|
const isSenderClient = senderRole === 1 /* CLIENT */;
|
|
89171
88811
|
const providerSecurityRate = (isSenderClient ? myAgent.securityRate : XmtpService.getInstance().getAgentStatusByAgentId(senderAgentId)?.securityRate) ?? 0;
|
|
89172
88812
|
try {
|
|
88813
|
+
const eligibilityStartedAt = Date.now();
|
|
89173
88814
|
const result = await checkMessageEligible({
|
|
89174
88815
|
agentId: myAgent.agentId,
|
|
89175
88816
|
clientAgentId: isSenderClient ? senderAgentId : myAgent.agentId,
|
|
@@ -89181,11 +88822,12 @@ async function verifyInboundA2AGroupMessage(params) {
|
|
|
89181
88822
|
direction: isSenderClient ? "client_to_provider" : "provider_to_client",
|
|
89182
88823
|
providerSecurityRate
|
|
89183
88824
|
});
|
|
89184
|
-
|
|
88825
|
+
timing?.mark("eligibilityCheck", eligibilityStartedAt);
|
|
88826
|
+
logWithTimestamp(
|
|
89185
88827
|
`[okx-agent-task:${myXmtpAddress}] inbound message-eligible: senderAgentId=${senderAgentId} job=${jobId} group=${groupId} result=${JSON.stringify(result)}`
|
|
89186
88828
|
);
|
|
89187
88829
|
if (!result.eligible) {
|
|
89188
|
-
|
|
88830
|
+
logWithTimestamp(
|
|
89189
88831
|
`[okx-agent-task:${myXmtpAddress}] message-eligible check failed, dropping: sender=${senderAddress} job=${jobId} reason=${result.reason ?? ""}`
|
|
89190
88832
|
);
|
|
89191
88833
|
logger.info(LogEvent.INBOUND_BLOCKED_INELIGIBLE, {
|
|
@@ -89199,7 +88841,8 @@ async function verifyInboundA2AGroupMessage(params) {
|
|
|
89199
88841
|
direction: isSenderClient ? "client_to_provider" : "provider_to_client",
|
|
89200
88842
|
providerSecurityRate: String(providerSecurityRate),
|
|
89201
88843
|
stage: "inbound/eligibility_check",
|
|
89202
|
-
reason: result.reason ?? ""
|
|
88844
|
+
reason: result.reason ?? "",
|
|
88845
|
+
...timing?.extras()
|
|
89203
88846
|
});
|
|
89204
88847
|
recordInvalidXmtpMessageBestEffort({
|
|
89205
88848
|
messageId,
|
|
@@ -89216,7 +88859,7 @@ async function verifyInboundA2AGroupMessage(params) {
|
|
|
89216
88859
|
return false;
|
|
89217
88860
|
}
|
|
89218
88861
|
} catch (err2) {
|
|
89219
|
-
|
|
88862
|
+
logWithTimestamp(
|
|
89220
88863
|
`[okx-agent-task:${myXmtpAddress}] message-eligible call failed, letting message through:`,
|
|
89221
88864
|
err2
|
|
89222
88865
|
);
|
|
@@ -89231,7 +88874,8 @@ async function verifyInboundA2AGroupMessage(params) {
|
|
|
89231
88874
|
direction: isSenderClient ? "client_to_provider" : "provider_to_client",
|
|
89232
88875
|
providerSecurityRate: String(providerSecurityRate),
|
|
89233
88876
|
stage: "inbound/eligibility_check",
|
|
89234
|
-
reason: "exception"
|
|
88877
|
+
reason: "exception",
|
|
88878
|
+
...timing?.extras()
|
|
89235
88879
|
});
|
|
89236
88880
|
}
|
|
89237
88881
|
}
|
|
@@ -89240,11 +88884,13 @@ async function verifyInboundA2AGroupMessage(params) {
|
|
|
89240
88884
|
return true;
|
|
89241
88885
|
}
|
|
89242
88886
|
try {
|
|
88887
|
+
const sensitiveStartedAt = Date.now();
|
|
89243
88888
|
const hitWord = await service.checkSensitiveWord(content3);
|
|
88889
|
+
timing?.mark("sensitiveCheck", sensitiveStartedAt);
|
|
89244
88890
|
if (!hitWord) {
|
|
89245
88891
|
return true;
|
|
89246
88892
|
}
|
|
89247
|
-
|
|
88893
|
+
logWithTimestamp(
|
|
89248
88894
|
`[okx-agent-task:${myXmtpAddress}] sensitive word matched, dropping: job=${jobId} group=${groupId}`
|
|
89249
88895
|
);
|
|
89250
88896
|
logger.info(LogEvent.INBOUND_BLOCKED_SENSITIVE, {
|
|
@@ -89257,7 +88903,8 @@ async function verifyInboundA2AGroupMessage(params) {
|
|
|
89257
88903
|
messageId,
|
|
89258
88904
|
stage: "inbound/sensitive_check",
|
|
89259
88905
|
reason: "sensitive_word",
|
|
89260
|
-
hitWord
|
|
88906
|
+
hitWord,
|
|
88907
|
+
...timing?.extras()
|
|
89261
88908
|
});
|
|
89262
88909
|
recordInvalidXmtpMessageBestEffort({
|
|
89263
88910
|
messageId,
|
|
@@ -89273,7 +88920,7 @@ async function verifyInboundA2AGroupMessage(params) {
|
|
|
89273
88920
|
});
|
|
89274
88921
|
return false;
|
|
89275
88922
|
} catch (err2) {
|
|
89276
|
-
|
|
88923
|
+
logWithTimestamp(
|
|
89277
88924
|
`[okx-agent-task:${myXmtpAddress}] checkSensitiveWord errored, letting message through:`,
|
|
89278
88925
|
err2
|
|
89279
88926
|
);
|
|
@@ -89286,31 +88933,44 @@ async function verifyInboundA2AGroupMessage(params) {
|
|
|
89286
88933
|
conversationId: groupId,
|
|
89287
88934
|
messageId,
|
|
89288
88935
|
stage: "inbound/sensitive_check",
|
|
89289
|
-
reason: "exception"
|
|
88936
|
+
reason: "exception",
|
|
88937
|
+
...timing?.extras()
|
|
89290
88938
|
});
|
|
89291
88939
|
}
|
|
89292
88940
|
return true;
|
|
89293
88941
|
}
|
|
89294
88942
|
async function processFileMessage(ctx, deps, options = {}) {
|
|
89295
88943
|
const messageId = ctx.message.id ?? "";
|
|
88944
|
+
const timing = createInboundTimingTracker(extractXmtpSentAtMs2(ctx.message));
|
|
89296
88945
|
if (messageId && !tryMarkProcessed(messageId)) {
|
|
89297
|
-
|
|
88946
|
+
logWithTimestamp(`[okx-agent-task:${deps.myXmtpAddress}] duplicate message ignored: ${messageId}`);
|
|
89298
88947
|
return false;
|
|
89299
88948
|
}
|
|
89300
88949
|
const { chatType, conversationId } = getConversationInfo(ctx.conversation);
|
|
88950
|
+
const commonDeliveryExtras = (extra = {}) => timing.extras({
|
|
88951
|
+
...agentExtras({ walletAddress: deps.myXmtpAddress }),
|
|
88952
|
+
conversationId,
|
|
88953
|
+
messageId,
|
|
88954
|
+
chatType,
|
|
88955
|
+
...extra
|
|
88956
|
+
});
|
|
89301
88957
|
if (chatType === "dm") {
|
|
88958
|
+
const dmTrustStartedAt = Date.now();
|
|
89302
88959
|
const trusted = await isTrustedDmSender({
|
|
89303
88960
|
myXmtpAddress: deps.myXmtpAddress,
|
|
89304
88961
|
senderInboxId: ctx.message.senderInboxId ?? "",
|
|
89305
88962
|
messageId,
|
|
89306
88963
|
conversationId
|
|
89307
88964
|
});
|
|
88965
|
+
timing.mark("dmTrustCheck", dmTrustStartedAt);
|
|
89308
88966
|
if (!trusted) {
|
|
89309
88967
|
return true;
|
|
89310
88968
|
}
|
|
89311
88969
|
}
|
|
88970
|
+
const parseStartedAt = Date.now();
|
|
89312
88971
|
const rawText = extractRawText(ctx.message.content);
|
|
89313
88972
|
const parsed = parsePayload(rawText);
|
|
88973
|
+
timing.mark("payloadParse", parseStartedAt);
|
|
89314
88974
|
const systemNotification = chatType === "dm" && parsed.parsed ? extractSystemNotification(parsed.payload) : null;
|
|
89315
88975
|
if (systemNotification) {
|
|
89316
88976
|
const systemMessageId = messageId || `system-${(0, import_node_crypto9.randomUUID)()}`;
|
|
@@ -89326,7 +88986,7 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
89326
88986
|
reason: "system_dm_missing_agent_id"
|
|
89327
88987
|
}
|
|
89328
88988
|
);
|
|
89329
|
-
|
|
88989
|
+
logWithTimestamp(
|
|
89330
88990
|
`[okx-agent-task:${deps.myXmtpAddress}] system DM missing agentId, dropping message=${shortenLogValue(systemMessageId)}`
|
|
89331
88991
|
);
|
|
89332
88992
|
return true;
|
|
@@ -89344,28 +89004,59 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
89344
89004
|
reason: "invalid_direct_communication_payload"
|
|
89345
89005
|
}
|
|
89346
89006
|
);
|
|
89347
|
-
|
|
89007
|
+
logWithTimestamp(
|
|
89348
89008
|
`[okx-agent-task:${deps.myXmtpAddress}] invalid direct communication system DM, dropping message=${shortenLogValue(systemMessageId)}`
|
|
89349
89009
|
);
|
|
89350
89010
|
return true;
|
|
89351
89011
|
}
|
|
89012
|
+
const providerBindStartedAt = Date.now();
|
|
89352
89013
|
const providerGate = bindMessageJobProviderToCurrentDefault(deps, systemNotification.jobId, "system-notification");
|
|
89014
|
+
timing.mark("providerBind", providerBindStartedAt);
|
|
89353
89015
|
if (!providerGate.allowed) {
|
|
89354
89016
|
return true;
|
|
89355
89017
|
}
|
|
89018
|
+
logger.info(LogEvent.SYSTEM_NOTIFICATION_RECEIVED, {
|
|
89019
|
+
...agentExtras({ walletAddress: deps.myXmtpAddress, onchainosAgentId: systemNotification.agentId }),
|
|
89020
|
+
taskId: systemNotification.jobId ?? "",
|
|
89021
|
+
agentId: systemNotification.agentId ?? "",
|
|
89022
|
+
providerAgentId: systemNotification.providerAgentId ?? "",
|
|
89023
|
+
clientAgentId: systemNotification.clientAgentId ?? "",
|
|
89024
|
+
messageId: systemMessageId,
|
|
89025
|
+
systemEvent: systemNotification.event ?? "",
|
|
89026
|
+
stage: "inbound/system_notification_received",
|
|
89027
|
+
isDirectCommunication: String(systemNotification.isDirectCommunication),
|
|
89028
|
+
providerBinding: providerGate.provider ?? "",
|
|
89029
|
+
providerBindingCreated: String(providerGate.created)
|
|
89030
|
+
});
|
|
89031
|
+
const routeResolveStartedAt = Date.now();
|
|
89356
89032
|
const targets = directTarget ? [{
|
|
89357
89033
|
sessionKey: directTarget.sessionKey,
|
|
89358
89034
|
route: "job",
|
|
89359
89035
|
jobId: directTarget.jobId,
|
|
89360
89036
|
agentId: directTarget.myAgentId
|
|
89361
89037
|
}] : resolveSystemNotificationTargets(deps, systemNotification);
|
|
89038
|
+
timing.mark("routeResolve", routeResolveStartedAt);
|
|
89362
89039
|
if (directTarget) {
|
|
89363
89040
|
upsertDirectCommunicationSession(deps, directTarget);
|
|
89364
|
-
|
|
89041
|
+
logWithTimestamp(
|
|
89365
89042
|
`[okx-agent-task:${deps.myXmtpAddress}] direct communication session prepared session=${directTarget.sessionKey} job=${shortenLogValue(directTarget.jobId)} myAgent=${directTarget.myAgentId} toAgent=${directTarget.toAgentId}`
|
|
89366
89043
|
);
|
|
89367
89044
|
}
|
|
89368
89045
|
const primaryTarget = targets[0];
|
|
89046
|
+
logger.info(LogEvent.SYSTEM_NOTIFICATION_ROUTED, {
|
|
89047
|
+
...agentExtras({ walletAddress: deps.myXmtpAddress, onchainosAgentId: systemNotification.agentId }),
|
|
89048
|
+
taskId: systemNotification.jobId ?? "",
|
|
89049
|
+
agentId: primaryTarget?.agentId ?? systemNotification.agentId ?? "",
|
|
89050
|
+
providerAgentId: systemNotification.providerAgentId ?? "",
|
|
89051
|
+
clientAgentId: systemNotification.clientAgentId ?? "",
|
|
89052
|
+
messageId: systemMessageId,
|
|
89053
|
+
sessionKey: primaryTarget?.sessionKey ?? SYSTEM_NOTIFICATION_SESSION_KEY,
|
|
89054
|
+
route: primaryTarget ? `system/${primaryTarget.route}` : "system/none",
|
|
89055
|
+
targetCount: String(targets.length),
|
|
89056
|
+
systemEvent: systemNotification.event ?? "",
|
|
89057
|
+
stage: "inbound/system_notification_routed",
|
|
89058
|
+
isDirectCommunication: String(systemNotification.isDirectCommunication)
|
|
89059
|
+
});
|
|
89369
89060
|
if (!options.skipNotify) {
|
|
89370
89061
|
maybeNotifyInboundAgentMessage({
|
|
89371
89062
|
deps,
|
|
@@ -89377,24 +89068,40 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
89377
89068
|
});
|
|
89378
89069
|
}
|
|
89379
89070
|
for (const target of targets) {
|
|
89071
|
+
const dispatchStartedAt = Date.now();
|
|
89380
89072
|
void Promise.resolve(deps.onSessionMessage?.({
|
|
89381
89073
|
sessionKey: target.sessionKey,
|
|
89382
89074
|
content: rawText,
|
|
89383
89075
|
messageId: systemMessageId,
|
|
89384
89076
|
jobId: target.jobId ?? null,
|
|
89385
89077
|
agentId: target.agentId ?? null
|
|
89386
|
-
})).
|
|
89387
|
-
|
|
89078
|
+
})).then(() => {
|
|
89079
|
+
timing.mark("sessionDispatch", dispatchStartedAt);
|
|
89080
|
+
logger.info(LogEvent.INBOUND_DELIVERED, commonDeliveryExtras({
|
|
89081
|
+
taskId: target.jobId ?? "",
|
|
89082
|
+
agentId: target.agentId ?? "",
|
|
89083
|
+
sessionKey: target.sessionKey,
|
|
89084
|
+
messageId: systemMessageId,
|
|
89085
|
+
route: `system/${target.route}`,
|
|
89086
|
+
stage: "inbound/system_session_dispatch",
|
|
89087
|
+
dispatchTarget: deps.onSessionMessage ? "session" : "none"
|
|
89088
|
+
}));
|
|
89089
|
+
}).catch((err2) => {
|
|
89090
|
+
logWithTimestamp(`[okx-agent-task:${deps.myXmtpAddress}] onSessionMessage failed:`, err2);
|
|
89388
89091
|
});
|
|
89389
|
-
|
|
89092
|
+
logWithTimestamp(
|
|
89390
89093
|
`[okx-agent-task:${deps.myXmtpAddress}] session dispatch queued route=system/${target.route} session=${target.sessionKey} message=${shortenLogValue(systemMessageId)} ${summarizePayloadForLog(parsed.payload)}`
|
|
89391
89094
|
);
|
|
89392
89095
|
}
|
|
89393
89096
|
return true;
|
|
89394
89097
|
}
|
|
89098
|
+
const routeStartedAt = Date.now();
|
|
89395
89099
|
const route = routeMessage(chatType, parsed.parsed, parsed.payload);
|
|
89100
|
+
timing.mark("routeResolve", routeStartedAt);
|
|
89396
89101
|
if (route.route === "job") {
|
|
89102
|
+
const providerBindStartedAt = Date.now();
|
|
89397
89103
|
const providerGate = bindMessageJobProviderToCurrentDefault(deps, route.jobId, "inbound-xmtp");
|
|
89104
|
+
timing.mark("providerBind", providerBindStartedAt);
|
|
89398
89105
|
if (!providerGate.allowed) {
|
|
89399
89106
|
return true;
|
|
89400
89107
|
}
|
|
@@ -89404,12 +89111,14 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
89404
89111
|
payload: parsed.parsed ? parsed.payload : null,
|
|
89405
89112
|
myXmtpAddress: deps.myXmtpAddress
|
|
89406
89113
|
}) : null;
|
|
89407
|
-
const xmtpSentAtMs =
|
|
89114
|
+
const xmtpSentAtMs = extractXmtpSentAtMs2(ctx.message);
|
|
89408
89115
|
let senderAddress = "";
|
|
89409
89116
|
try {
|
|
89117
|
+
const senderStartedAt = Date.now();
|
|
89410
89118
|
senderAddress = await ctx.getSenderAddress();
|
|
89119
|
+
timing.mark("senderResolve", senderStartedAt);
|
|
89411
89120
|
} catch (err2) {
|
|
89412
|
-
|
|
89121
|
+
logWithTimestamp(
|
|
89413
89122
|
`[okx-agent-task:${deps.myXmtpAddress}] getSenderAddress failed for ${messageId || "(no-id)"}:`,
|
|
89414
89123
|
err2
|
|
89415
89124
|
);
|
|
@@ -89422,7 +89131,7 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
89422
89131
|
senderInboxId: ctx.message.senderInboxId ?? ""
|
|
89423
89132
|
});
|
|
89424
89133
|
if (payloadObject?.msgType !== A2A_MESSAGE_TYPE && !trustedSystemSender) {
|
|
89425
|
-
|
|
89134
|
+
logWithTimestamp(
|
|
89426
89135
|
`[okx-agent-task:${deps.myXmtpAddress}] group message unsupported msgType, dropping: msgType=${String(payloadObject?.msgType ?? "(missing)")} job=${shortenLogValue(route.jobId)} group=${conversationId}`
|
|
89427
89136
|
);
|
|
89428
89137
|
logger.info(LogEvent.INBOUND_DROP_UNSUPPORTED_MSGTYPE, {
|
|
@@ -89436,7 +89145,8 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
89436
89145
|
msgType: readString3(payloadObject?.msgType) ?? "",
|
|
89437
89146
|
msgTypeType: typeof payloadObject?.msgType,
|
|
89438
89147
|
stage: "inbound/payload_parse",
|
|
89439
|
-
reason: "unsupported_msg_type"
|
|
89148
|
+
reason: "unsupported_msg_type",
|
|
89149
|
+
...timing.extras()
|
|
89440
89150
|
});
|
|
89441
89151
|
return true;
|
|
89442
89152
|
}
|
|
@@ -89453,7 +89163,8 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
89453
89163
|
groupId: conversationId,
|
|
89454
89164
|
messageId,
|
|
89455
89165
|
consentState: ctx.conversation instanceof Group ? ctx.conversation.consentState : void 0,
|
|
89456
|
-
trustedSystemSender
|
|
89166
|
+
trustedSystemSender,
|
|
89167
|
+
timing
|
|
89457
89168
|
});
|
|
89458
89169
|
if (!accepted) {
|
|
89459
89170
|
return true;
|
|
@@ -89471,7 +89182,7 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
89471
89182
|
localAgentRole: localAgent?.role ?? null,
|
|
89472
89183
|
hasExistingSession: !!existingSession
|
|
89473
89184
|
})) {
|
|
89474
|
-
|
|
89185
|
+
logWithTimestamp(
|
|
89475
89186
|
`[okx-agent-task:${deps.myXmtpAddress}] buyer inbound group kept pending: session=${sessionKey} job=${shortenLogValue(route.jobId)} group=${conversationId} consent=${String(consentState)} message=${shortenLogValue(routedMessageId)}`
|
|
89476
89187
|
);
|
|
89477
89188
|
logger.info(LogEvent.INBOUND_BUYER_PENDING, {
|
|
@@ -89484,7 +89195,8 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
89484
89195
|
messageId: routedMessageId,
|
|
89485
89196
|
consentState: String(consentState),
|
|
89486
89197
|
stage: "inbound/buyer_pending",
|
|
89487
|
-
reason: "unknown_group_without_session"
|
|
89198
|
+
reason: "unknown_group_without_session",
|
|
89199
|
+
...timing.extras()
|
|
89488
89200
|
});
|
|
89489
89201
|
if (!options.skipNotify) {
|
|
89490
89202
|
notifyPendingConversationToBackup({
|
|
@@ -89500,7 +89212,7 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
89500
89212
|
idempotencyKey: `pending-conversation:${conversationId}`,
|
|
89501
89213
|
store: deps.sessionStore
|
|
89502
89214
|
}).catch((err2) => {
|
|
89503
|
-
|
|
89215
|
+
logWithTimestamp(`[okx-agent-task:${deps.myXmtpAddress}] pending conversation user notification failed:`, err2);
|
|
89504
89216
|
});
|
|
89505
89217
|
}
|
|
89506
89218
|
return true;
|
|
@@ -89514,14 +89226,29 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
89514
89226
|
myAgentXmtpAddress: deps.myXmtpAddress,
|
|
89515
89227
|
toAgentXmtpAddress: senderAddress || null
|
|
89516
89228
|
});
|
|
89229
|
+
const dispatchStartedAt = Date.now();
|
|
89517
89230
|
void Promise.resolve(deps.onSessionMessage?.({
|
|
89518
89231
|
sessionKey,
|
|
89519
89232
|
content: rawText,
|
|
89520
89233
|
messageId: routedMessageId,
|
|
89521
89234
|
jobId: route.jobId,
|
|
89522
89235
|
agentId: myAgentId
|
|
89523
|
-
})).
|
|
89524
|
-
|
|
89236
|
+
})).then(() => {
|
|
89237
|
+
timing.mark("sessionDispatch", dispatchStartedAt);
|
|
89238
|
+
logger.info(LogEvent.INBOUND_DELIVERED, commonDeliveryExtras({
|
|
89239
|
+
taskId: route.jobId,
|
|
89240
|
+
agentId: myAgentId ?? "",
|
|
89241
|
+
peerWalletAddress: senderAddress,
|
|
89242
|
+
peerInboxId: ctx.message.senderInboxId ?? "",
|
|
89243
|
+
peerAgentId: toAgentId ?? "",
|
|
89244
|
+
sessionKey,
|
|
89245
|
+
messageId: routedMessageId,
|
|
89246
|
+
route: "group",
|
|
89247
|
+
stage: "inbound/group_session_dispatch",
|
|
89248
|
+
dispatchTarget: deps.onSessionMessage ? "session" : "none"
|
|
89249
|
+
}));
|
|
89250
|
+
}).catch((err2) => {
|
|
89251
|
+
logWithTimestamp(`[okx-agent-task:${deps.myXmtpAddress}] onSessionMessage failed:`, err2);
|
|
89525
89252
|
});
|
|
89526
89253
|
if (!options.skipNotify) {
|
|
89527
89254
|
maybeNotifyInboundAgentMessage({
|
|
@@ -89535,7 +89262,7 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
89535
89262
|
});
|
|
89536
89263
|
}
|
|
89537
89264
|
void maybeAllowProviderGroup(deps, chatType, conversationId);
|
|
89538
|
-
|
|
89265
|
+
logWithTimestamp(
|
|
89539
89266
|
`[okx-agent-task:${deps.myXmtpAddress}] session dispatch queued route=group session=${sessionKey} message=${shortenLogValue(routedMessageId)} ${summarizePayloadForLog(parsed.payload)}`
|
|
89540
89267
|
);
|
|
89541
89268
|
return true;
|
|
@@ -89555,7 +89282,9 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
89555
89282
|
rawText,
|
|
89556
89283
|
payload: parsed.parsed ? parsed.payload : null
|
|
89557
89284
|
};
|
|
89285
|
+
const storeAppendStartedAt = Date.now();
|
|
89558
89286
|
await deps.store.append(route.jobId, stored, sessionAgentId);
|
|
89287
|
+
timing.mark("storeAppend", storeAppendStartedAt);
|
|
89559
89288
|
if ((route.route === "job" || parsed.parsed && !isA2AEnvelope(stored.payload)) && !options.skipNotify) {
|
|
89560
89289
|
const payloadObject = isPlainObject3(stored.payload) ? stored.payload : null;
|
|
89561
89290
|
const sender = isPlainObject3(payloadObject?.sender) ? payloadObject.sender : null;
|
|
@@ -89588,17 +89317,31 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
89588
89317
|
}
|
|
89589
89318
|
if (route.route === "job" && !options.skipAi) {
|
|
89590
89319
|
const jobFilePath = deps.store.jobFilePath(route.jobId, sessionAgentId);
|
|
89320
|
+
const dispatchStartedAt = Date.now();
|
|
89591
89321
|
void Promise.resolve(deps.onJobMessageStored?.({
|
|
89592
89322
|
jobId: route.jobId,
|
|
89593
89323
|
jobFilePath,
|
|
89594
89324
|
sessionAgentId,
|
|
89595
89325
|
message: stored
|
|
89596
|
-
})).
|
|
89597
|
-
|
|
89326
|
+
})).then(() => {
|
|
89327
|
+
timing.mark("jobDispatch", dispatchStartedAt);
|
|
89328
|
+
logger.info(LogEvent.INBOUND_DELIVERED, commonDeliveryExtras({
|
|
89329
|
+
taskId: route.jobId,
|
|
89330
|
+
peerWalletAddress: senderAddress,
|
|
89331
|
+
peerInboxId: ctx.message.senderInboxId ?? "",
|
|
89332
|
+
sessionAgentId: sessionAgentId ?? "",
|
|
89333
|
+
messageId: stored.id,
|
|
89334
|
+
route: route.route,
|
|
89335
|
+
routeReason: route.routeReason,
|
|
89336
|
+
stage: "inbound/job_store_dispatch",
|
|
89337
|
+
dispatchTarget: deps.onJobMessageStored ? "job" : "none"
|
|
89338
|
+
}));
|
|
89339
|
+
}).catch((err2) => {
|
|
89340
|
+
logWithTimestamp(`[okx-agent-task:${deps.myXmtpAddress}] onJobMessageStored failed:`, err2);
|
|
89598
89341
|
});
|
|
89599
89342
|
}
|
|
89600
89343
|
void maybeAllowProviderGroup(deps, chatType, conversationId);
|
|
89601
|
-
|
|
89344
|
+
logWithTimestamp(
|
|
89602
89345
|
`[okx-agent-task:${deps.myXmtpAddress}] stored ${chatType} message route=${route.route} job=${shortenLogValue(route.jobId)} reason=${route.routeReason} message=${shortenLogValue(stored.id)} ${summarizePayloadForLog(stored.payload)}`
|
|
89603
89346
|
);
|
|
89604
89347
|
return true;
|
|
@@ -89606,16 +89349,34 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
89606
89349
|
function createFileMessageHandler(deps) {
|
|
89607
89350
|
return async (ctx, _next) => {
|
|
89608
89351
|
const msg = ctx.message;
|
|
89352
|
+
const inboundCtx = ctx;
|
|
89353
|
+
const xmtpReceivedAtMs = Date.now();
|
|
89354
|
+
const xmtpSentAtMs = extractXmtpSentAtMs2(inboundCtx.message);
|
|
89355
|
+
const { chatType, conversationId } = getConversationInfo(ctx.conversation);
|
|
89356
|
+
logger.info(LogEvent.INBOUND_HANDLER_ENTERED, {
|
|
89357
|
+
...agentExtras({ walletAddress: deps.myXmtpAddress }),
|
|
89358
|
+
...jobIdExtras(inboundCtx.message.content),
|
|
89359
|
+
source: "live",
|
|
89360
|
+
stage: "inbound/handler_entered",
|
|
89361
|
+
chatType,
|
|
89362
|
+
conversationId,
|
|
89363
|
+
messageId: inboundCtx.message.id ?? "",
|
|
89364
|
+
kind: msg.kind ?? "unknown",
|
|
89365
|
+
senderInboxId: inboundCtx.message.senderInboxId ?? "",
|
|
89366
|
+
xmtpSentAtMs: String(xmtpSentAtMs),
|
|
89367
|
+
xmtpReceivedAtMs: String(xmtpReceivedAtMs),
|
|
89368
|
+
xmtpDeliveryMs: String(safeDuration(xmtpReceivedAtMs, xmtpSentAtMs))
|
|
89369
|
+
});
|
|
89609
89370
|
if (msg.kind && msg.kind !== "application") {
|
|
89610
89371
|
return;
|
|
89611
89372
|
}
|
|
89612
89373
|
try {
|
|
89613
89374
|
const handled = await processFileMessage(ctx, deps);
|
|
89614
89375
|
if (handled) {
|
|
89615
|
-
deps.onMessageProcessed?.(
|
|
89376
|
+
deps.onMessageProcessed?.(extractXmtpSentAtMs2(ctx.message));
|
|
89616
89377
|
}
|
|
89617
89378
|
} catch (err2) {
|
|
89618
|
-
|
|
89379
|
+
logWithTimestamp(`[okx-agent-task:${deps.myXmtpAddress}] process message failed:`, err2);
|
|
89619
89380
|
}
|
|
89620
89381
|
};
|
|
89621
89382
|
}
|
|
@@ -89664,7 +89425,7 @@ function isA2AEnvelope(payload) {
|
|
|
89664
89425
|
|
|
89665
89426
|
// ../core/src/xmtp-sdk/onchainos/signer.ts
|
|
89666
89427
|
async function onchainosSign(agentId, keyUuid, walletAddress, message) {
|
|
89667
|
-
|
|
89428
|
+
logWithTimestamp(
|
|
89668
89429
|
`[onchainos-signer] executing: onchainos agent xmtp-sign --key-uuid ${keyUuid} --message <${message.length} chars>`
|
|
89669
89430
|
);
|
|
89670
89431
|
let stdout;
|
|
@@ -89686,7 +89447,7 @@ async function onchainosSign(agentId, keyUuid, walletAddress, message) {
|
|
|
89686
89447
|
throw err2;
|
|
89687
89448
|
}
|
|
89688
89449
|
if (stderr) {
|
|
89689
|
-
|
|
89450
|
+
logWithTimestamp(`[onchainos-signer] stderr: ${stderr}`);
|
|
89690
89451
|
}
|
|
89691
89452
|
const res = parseCliJson(stdout, "xmtp-sign", {
|
|
89692
89453
|
onchainosAgentId: agentId,
|
|
@@ -89711,7 +89472,7 @@ async function onchainosSign(agentId, keyUuid, walletAddress, message) {
|
|
|
89711
89472
|
);
|
|
89712
89473
|
throw signErr;
|
|
89713
89474
|
}
|
|
89714
|
-
|
|
89475
|
+
logWithTimestamp(
|
|
89715
89476
|
`[onchainos-signer] sign success, signature=${res.data.signature.slice(0, 20)}...`
|
|
89716
89477
|
);
|
|
89717
89478
|
return toBytes(res.data.signature);
|
|
@@ -89720,7 +89481,7 @@ function createOnchainosSigner(agent) {
|
|
|
89720
89481
|
const address = agent.communicationAddress.toLowerCase();
|
|
89721
89482
|
const keyUuid = agent.keyUuid;
|
|
89722
89483
|
const agentId = agent.agentId;
|
|
89723
|
-
|
|
89484
|
+
logWithTimestamp(
|
|
89724
89485
|
`[onchainos-signer] creating signer for ${address} (keyUuid=${keyUuid})`
|
|
89725
89486
|
);
|
|
89726
89487
|
return {
|
|
@@ -89730,7 +89491,7 @@ function createOnchainosSigner(agent) {
|
|
|
89730
89491
|
identifierKind: 0
|
|
89731
89492
|
}),
|
|
89732
89493
|
signMessage: async (message) => {
|
|
89733
|
-
|
|
89494
|
+
logWithTimestamp(`[onchainos-signer] signing message for ${address}`);
|
|
89734
89495
|
return await onchainosSign(agentId, keyUuid, address, message);
|
|
89735
89496
|
}
|
|
89736
89497
|
};
|
|
@@ -89888,10 +89649,545 @@ function userWatchEventDeliveredSentryExtra(event) {
|
|
|
89888
89649
|
var environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
|
|
89889
89650
|
var SENTRY_CONFIG = {
|
|
89890
89651
|
projectName: "okx/openclaw-okx-a2a-extension",
|
|
89891
|
-
release: "0.0.13
|
|
89652
|
+
release: "0.0.13",
|
|
89892
89653
|
environment
|
|
89893
89654
|
};
|
|
89894
89655
|
|
|
89656
|
+
// src/forced-update.ts
|
|
89657
|
+
var import_node_child_process7 = require("node:child_process");
|
|
89658
|
+
|
|
89659
|
+
// src/update-cli.ts
|
|
89660
|
+
var import_node_child_process6 = require("node:child_process");
|
|
89661
|
+
var import_promises6 = require("node:fs/promises");
|
|
89662
|
+
var import_node_os5 = require("node:os");
|
|
89663
|
+
var import_node_path17 = require("node:path");
|
|
89664
|
+
var UPDATE_PACKAGES = {
|
|
89665
|
+
node: "@okxweb3/a2a-node",
|
|
89666
|
+
openclaw: "@okxweb3/a2a-openclaw",
|
|
89667
|
+
hermes: "@okxweb3/a2a-hermes"
|
|
89668
|
+
};
|
|
89669
|
+
function isPrereleaseVersion(version2) {
|
|
89670
|
+
return /\d+\.\d+\.\d+-[0-9A-Za-z.-]+/.test(version2);
|
|
89671
|
+
}
|
|
89672
|
+
async function normalizeHermesOkxA2aPluginConfig(configFile = resolveHermesConfigPath()) {
|
|
89673
|
+
let content3;
|
|
89674
|
+
try {
|
|
89675
|
+
content3 = await (0, import_promises6.readFile)(configFile, "utf8");
|
|
89676
|
+
} catch (error) {
|
|
89677
|
+
if (isNodeError(error) && error.code === "ENOENT") {
|
|
89678
|
+
return false;
|
|
89679
|
+
}
|
|
89680
|
+
throw error;
|
|
89681
|
+
}
|
|
89682
|
+
const normalized = normalizeHermesPluginConfigContent(content3);
|
|
89683
|
+
if (!normalized.changed) {
|
|
89684
|
+
return false;
|
|
89685
|
+
}
|
|
89686
|
+
await (0, import_promises6.writeFile)(configFile, normalized.content);
|
|
89687
|
+
console.log(`[update] normalized Hermes plugins.enabled okx-a2a entry in ${configFile}`);
|
|
89688
|
+
return true;
|
|
89689
|
+
}
|
|
89690
|
+
function normalizeHermesPluginConfigContent(content3) {
|
|
89691
|
+
const trailingNewline = content3.endsWith("\n");
|
|
89692
|
+
const duplicateRepair = removeDuplicateInlineEnabledHeaders(content3.replace(/\n$/, "").split(/\n/));
|
|
89693
|
+
const lines = duplicateRepair.lines;
|
|
89694
|
+
let changed = duplicateRepair.changed;
|
|
89695
|
+
let hasOkxA2a = false;
|
|
89696
|
+
let inPlugins = false;
|
|
89697
|
+
let pluginsIndent = -1;
|
|
89698
|
+
let inEnabled = false;
|
|
89699
|
+
let enabledIndent = -1;
|
|
89700
|
+
let emittedOkxA2a = false;
|
|
89701
|
+
const output = [];
|
|
89702
|
+
for (const line of lines) {
|
|
89703
|
+
const currentIndent = lineIndent(line);
|
|
89704
|
+
const significant = line.trim() !== "" && !line.trimStart().startsWith("#");
|
|
89705
|
+
const parsedListValue = parseYamlListValue(line);
|
|
89706
|
+
if (inEnabled && significant && (currentIndent < enabledIndent || currentIndent === enabledIndent && !parsedListValue)) {
|
|
89707
|
+
inEnabled = false;
|
|
89708
|
+
emittedOkxA2a = false;
|
|
89709
|
+
}
|
|
89710
|
+
if (inPlugins && significant && currentIndent <= pluginsIndent && !isPluginsHeader(line)) {
|
|
89711
|
+
inPlugins = false;
|
|
89712
|
+
inEnabled = false;
|
|
89713
|
+
emittedOkxA2a = false;
|
|
89714
|
+
}
|
|
89715
|
+
if (isPluginsHeader(line)) {
|
|
89716
|
+
inPlugins = true;
|
|
89717
|
+
pluginsIndent = currentIndent;
|
|
89718
|
+
output.push(line);
|
|
89719
|
+
continue;
|
|
89720
|
+
}
|
|
89721
|
+
if (inPlugins && isEnabledHeader(line) && currentIndent > pluginsIndent) {
|
|
89722
|
+
inEnabled = true;
|
|
89723
|
+
enabledIndent = currentIndent;
|
|
89724
|
+
emittedOkxA2a = false;
|
|
89725
|
+
output.push(line);
|
|
89726
|
+
continue;
|
|
89727
|
+
}
|
|
89728
|
+
const inlineEnabled = inPlugins ? parseInlineEnabledList(line) : null;
|
|
89729
|
+
if (inlineEnabled && currentIndent > pluginsIndent) {
|
|
89730
|
+
const normalized = normalizeInlineEnabledList(inlineEnabled);
|
|
89731
|
+
output.push(...normalized.lines);
|
|
89732
|
+
changed ||= normalized.changed;
|
|
89733
|
+
hasOkxA2a ||= normalized.hasOkxA2a;
|
|
89734
|
+
continue;
|
|
89735
|
+
}
|
|
89736
|
+
if (inEnabled) {
|
|
89737
|
+
const parsed = parsedListValue;
|
|
89738
|
+
if (parsed && (parsed.value === "okx-a2a" || parsed.value === "platforms/okx-a2a")) {
|
|
89739
|
+
hasOkxA2a = true;
|
|
89740
|
+
if (!emittedOkxA2a) {
|
|
89741
|
+
const normalized = `${parsed.indent}- okx-a2a`;
|
|
89742
|
+
output.push(normalized);
|
|
89743
|
+
changed ||= normalized !== line;
|
|
89744
|
+
emittedOkxA2a = true;
|
|
89745
|
+
} else {
|
|
89746
|
+
changed = true;
|
|
89747
|
+
}
|
|
89748
|
+
continue;
|
|
89749
|
+
}
|
|
89750
|
+
}
|
|
89751
|
+
output.push(line);
|
|
89752
|
+
}
|
|
89753
|
+
return { content: `${output.join("\n")}${trailingNewline ? "\n" : ""}`, changed, hasOkxA2a };
|
|
89754
|
+
}
|
|
89755
|
+
function removeDuplicateInlineEnabledHeaders(lines) {
|
|
89756
|
+
let changed = false;
|
|
89757
|
+
let inPlugins = false;
|
|
89758
|
+
let pluginsIndent = -1;
|
|
89759
|
+
const output = [];
|
|
89760
|
+
for (let i = 0; i < lines.length; i++) {
|
|
89761
|
+
const line = lines[i];
|
|
89762
|
+
const currentIndent = lineIndent(line);
|
|
89763
|
+
const significant = line.trim() !== "" && !line.trimStart().startsWith("#");
|
|
89764
|
+
if (inPlugins && significant && currentIndent <= pluginsIndent && !isPluginsHeader(line)) {
|
|
89765
|
+
inPlugins = false;
|
|
89766
|
+
}
|
|
89767
|
+
if (isPluginsHeader(line)) {
|
|
89768
|
+
inPlugins = true;
|
|
89769
|
+
pluginsIndent = currentIndent;
|
|
89770
|
+
output.push(line);
|
|
89771
|
+
continue;
|
|
89772
|
+
}
|
|
89773
|
+
if (inPlugins && isEmptyInlineEnabledList(line) && hasLaterEnabledHeaderInPlugins(lines, i + 1, pluginsIndent)) {
|
|
89774
|
+
changed = true;
|
|
89775
|
+
continue;
|
|
89776
|
+
}
|
|
89777
|
+
output.push(line);
|
|
89778
|
+
}
|
|
89779
|
+
return { lines: output, changed };
|
|
89780
|
+
}
|
|
89781
|
+
function hasLaterEnabledHeaderInPlugins(lines, startIndex, pluginsIndent) {
|
|
89782
|
+
for (let i = startIndex; i < lines.length; i++) {
|
|
89783
|
+
const line = lines[i];
|
|
89784
|
+
const significant = line.trim() !== "" && !line.trimStart().startsWith("#");
|
|
89785
|
+
if (significant && lineIndent(line) <= pluginsIndent) {
|
|
89786
|
+
return false;
|
|
89787
|
+
}
|
|
89788
|
+
if (isEnabledHeader(line) || parseInlineEnabledList(line)) {
|
|
89789
|
+
return true;
|
|
89790
|
+
}
|
|
89791
|
+
}
|
|
89792
|
+
return false;
|
|
89793
|
+
}
|
|
89794
|
+
function isEmptyInlineEnabledList(line) {
|
|
89795
|
+
const inline = parseInlineEnabledList(line);
|
|
89796
|
+
return !!inline && inline.values.length === 0;
|
|
89797
|
+
}
|
|
89798
|
+
function resolveHermesConfigPath() {
|
|
89799
|
+
return (0, import_node_path17.join)(process.env.HERMES_HOME ?? (0, import_node_path17.join)((0, import_node_os5.homedir)(), ".hermes"), "config.yaml");
|
|
89800
|
+
}
|
|
89801
|
+
function lineIndent(line) {
|
|
89802
|
+
const match = line.match(/^\s*/);
|
|
89803
|
+
return match?.[0].length ?? 0;
|
|
89804
|
+
}
|
|
89805
|
+
function isPluginsHeader(line) {
|
|
89806
|
+
return /^[\s]*plugins:[\s]*(?:#.*)?$/.test(line);
|
|
89807
|
+
}
|
|
89808
|
+
function isEnabledHeader(line) {
|
|
89809
|
+
return /^[\s]*enabled:[\s]*(?:#.*)?$/.test(line);
|
|
89810
|
+
}
|
|
89811
|
+
function parseInlineEnabledList(line) {
|
|
89812
|
+
const match = line.match(/^(\s*)enabled:\s*\[(.*)\]\s*(?:#.*)?$/);
|
|
89813
|
+
if (!match) {
|
|
89814
|
+
return null;
|
|
89815
|
+
}
|
|
89816
|
+
const values = (match[2] ?? "").split(",").map((value) => value.trim().replace(/^["']|["']$/g, "")).filter(Boolean);
|
|
89817
|
+
return { indent: match[1] ?? "", values };
|
|
89818
|
+
}
|
|
89819
|
+
function normalizeInlineEnabledList(input) {
|
|
89820
|
+
let hasOkxA2a = false;
|
|
89821
|
+
const values = [];
|
|
89822
|
+
for (const value of input.values) {
|
|
89823
|
+
if (value === "okx-a2a" || value === "platforms/okx-a2a") {
|
|
89824
|
+
hasOkxA2a = true;
|
|
89825
|
+
if (!values.includes("okx-a2a")) {
|
|
89826
|
+
values.push("okx-a2a");
|
|
89827
|
+
}
|
|
89828
|
+
continue;
|
|
89829
|
+
}
|
|
89830
|
+
values.push(value);
|
|
89831
|
+
}
|
|
89832
|
+
return {
|
|
89833
|
+
lines: values.length > 0 ? [`${input.indent}enabled:`, ...values.map((value) => `${input.indent} - ${value}`)] : [`${input.indent}enabled: []`],
|
|
89834
|
+
changed: hasOkxA2a,
|
|
89835
|
+
hasOkxA2a
|
|
89836
|
+
};
|
|
89837
|
+
}
|
|
89838
|
+
function parseYamlListValue(line) {
|
|
89839
|
+
const match = line.match(/^(\s*)-\s*(?:"([^"]*)"|'([^']*)'|([^#\s]+))(?:\s*(?:#.*)?)?$/);
|
|
89840
|
+
if (!match) {
|
|
89841
|
+
return null;
|
|
89842
|
+
}
|
|
89843
|
+
return {
|
|
89844
|
+
indent: match[1] ?? "",
|
|
89845
|
+
value: match[2] ?? match[3] ?? match[4] ?? ""
|
|
89846
|
+
};
|
|
89847
|
+
}
|
|
89848
|
+
function isNodeError(error) {
|
|
89849
|
+
return error instanceof Error && "code" in error;
|
|
89850
|
+
}
|
|
89851
|
+
async function getInstalledGatewayPluginVersion(target) {
|
|
89852
|
+
if (target === "hermes") {
|
|
89853
|
+
return await getInstalledHermesPluginVersion() ?? await getGlobalNpmPackageVersion(UPDATE_PACKAGES.hermes);
|
|
89854
|
+
}
|
|
89855
|
+
return (await getInstalledOpenClawPluginInfo()).version;
|
|
89856
|
+
}
|
|
89857
|
+
async function getInstalledOpenClawPluginInfo() {
|
|
89858
|
+
let result = await runCommandCaptureOptional("openclaw", ["plugins", "list", "--json"]);
|
|
89859
|
+
if (!result.ok) {
|
|
89860
|
+
result = await runCommandCaptureOptional("openclaw", ["plugins", "list"]);
|
|
89861
|
+
}
|
|
89862
|
+
if (!result.ok) {
|
|
89863
|
+
return { installed: false, version: null };
|
|
89864
|
+
}
|
|
89865
|
+
return parseOpenClawPluginList(result.stdout);
|
|
89866
|
+
}
|
|
89867
|
+
function parseOpenClawPluginList(output) {
|
|
89868
|
+
if (!output.trim()) {
|
|
89869
|
+
return { installed: false, version: null };
|
|
89870
|
+
}
|
|
89871
|
+
try {
|
|
89872
|
+
return findOpenClawPluginInJson(JSON.parse(output));
|
|
89873
|
+
} catch {
|
|
89874
|
+
return {
|
|
89875
|
+
installed: output.includes(UPDATE_PACKAGES.openclaw) || /(^|[\s@/])okx-a2a($|[\s@])/.test(output),
|
|
89876
|
+
version: parsePackageVersionFromText(output)
|
|
89877
|
+
};
|
|
89878
|
+
}
|
|
89879
|
+
}
|
|
89880
|
+
function findOpenClawPluginInJson(value) {
|
|
89881
|
+
if (Array.isArray(value)) {
|
|
89882
|
+
for (const item of value) {
|
|
89883
|
+
const found = findOpenClawPluginInJson(item);
|
|
89884
|
+
if (found.installed) {
|
|
89885
|
+
return found;
|
|
89886
|
+
}
|
|
89887
|
+
}
|
|
89888
|
+
return { installed: false, version: null };
|
|
89889
|
+
}
|
|
89890
|
+
if (!value || typeof value !== "object") {
|
|
89891
|
+
return { installed: false, version: null };
|
|
89892
|
+
}
|
|
89893
|
+
const record = value;
|
|
89894
|
+
if (isOpenClawPluginRecord(record)) {
|
|
89895
|
+
return { installed: true, version: readVersionField(record) };
|
|
89896
|
+
}
|
|
89897
|
+
const dependencies = record.dependencies;
|
|
89898
|
+
if (dependencies && typeof dependencies === "object") {
|
|
89899
|
+
const dependency = dependencies[UPDATE_PACKAGES.openclaw] ?? dependencies["okx-a2a"];
|
|
89900
|
+
if (dependency && typeof dependency === "object") {
|
|
89901
|
+
return { installed: true, version: readVersionField(dependency) };
|
|
89902
|
+
}
|
|
89903
|
+
}
|
|
89904
|
+
for (const key of ["plugins", "items", "data", "installed"]) {
|
|
89905
|
+
const child = record[key];
|
|
89906
|
+
if (child !== void 0) {
|
|
89907
|
+
const found = findOpenClawPluginInJson(child);
|
|
89908
|
+
if (found.installed) {
|
|
89909
|
+
return found;
|
|
89910
|
+
}
|
|
89911
|
+
}
|
|
89912
|
+
}
|
|
89913
|
+
return { installed: false, version: null };
|
|
89914
|
+
}
|
|
89915
|
+
function isOpenClawPluginRecord(record) {
|
|
89916
|
+
return Object.values(record).some((value) => {
|
|
89917
|
+
if (typeof value !== "string") {
|
|
89918
|
+
return false;
|
|
89919
|
+
}
|
|
89920
|
+
return value === "okx-a2a" || value === UPDATE_PACKAGES.openclaw || value.endsWith("/okx-a2a");
|
|
89921
|
+
});
|
|
89922
|
+
}
|
|
89923
|
+
function readVersionField(record) {
|
|
89924
|
+
for (const key of ["version", "installedVersion", "packageVersion"]) {
|
|
89925
|
+
const value = record[key];
|
|
89926
|
+
if (typeof value === "string" && value.trim()) {
|
|
89927
|
+
return value.trim();
|
|
89928
|
+
}
|
|
89929
|
+
}
|
|
89930
|
+
return null;
|
|
89931
|
+
}
|
|
89932
|
+
function parsePackageVersionFromText(output) {
|
|
89933
|
+
return output.match(/@okxweb3\/a2a-openclaw@([0-9A-Za-z.+-]+)/)?.[1] ?? null;
|
|
89934
|
+
}
|
|
89935
|
+
async function getInstalledHermesPluginVersion() {
|
|
89936
|
+
const pluginYaml = (0, import_node_path17.join)(process.env.HERMES_HOME ?? (0, import_node_path17.join)((0, import_node_os5.homedir)(), ".hermes"), "plugins", "platforms", "okx-a2a", "plugin.yaml");
|
|
89937
|
+
try {
|
|
89938
|
+
const content3 = await (0, import_promises6.readFile)(pluginYaml, "utf8");
|
|
89939
|
+
return parsePluginYamlVersion(content3);
|
|
89940
|
+
} catch (error) {
|
|
89941
|
+
if (isNodeError(error) && error.code === "ENOENT") {
|
|
89942
|
+
return null;
|
|
89943
|
+
}
|
|
89944
|
+
throw error;
|
|
89945
|
+
}
|
|
89946
|
+
}
|
|
89947
|
+
function parsePluginYamlVersion(content3) {
|
|
89948
|
+
for (const line of content3.split(/\r?\n/)) {
|
|
89949
|
+
const match = line.match(/^\s*version:\s*(?:"([^"]+)"|'([^']+)'|([^#\s]+))/);
|
|
89950
|
+
if (match) {
|
|
89951
|
+
return match[1] ?? match[2] ?? match[3] ?? null;
|
|
89952
|
+
}
|
|
89953
|
+
}
|
|
89954
|
+
return null;
|
|
89955
|
+
}
|
|
89956
|
+
async function getGlobalNpmPackageVersion(packageName) {
|
|
89957
|
+
const result = await runCommandCaptureOptional("npm", ["list", "-g", packageName, "--depth=0", "--json"]);
|
|
89958
|
+
if (!result.ok) {
|
|
89959
|
+
return null;
|
|
89960
|
+
}
|
|
89961
|
+
try {
|
|
89962
|
+
const parsed = JSON.parse(result.stdout);
|
|
89963
|
+
return parsed.dependencies?.[packageName]?.version ?? null;
|
|
89964
|
+
} catch {
|
|
89965
|
+
return null;
|
|
89966
|
+
}
|
|
89967
|
+
}
|
|
89968
|
+
async function runCommandCaptureOptional(command, args) {
|
|
89969
|
+
return await new Promise((resolvePromise) => {
|
|
89970
|
+
const child = (0, import_node_child_process6.spawn)(command, args, { stdio: ["ignore", "pipe", "ignore"] });
|
|
89971
|
+
let stdout = "";
|
|
89972
|
+
child.stdout.setEncoding("utf8");
|
|
89973
|
+
child.stdout.on("data", (chunk) => {
|
|
89974
|
+
stdout += chunk;
|
|
89975
|
+
});
|
|
89976
|
+
child.on("error", () => {
|
|
89977
|
+
resolvePromise({ ok: false, stdout });
|
|
89978
|
+
});
|
|
89979
|
+
child.on("close", (code2) => {
|
|
89980
|
+
resolvePromise({ ok: code2 === 0, stdout });
|
|
89981
|
+
});
|
|
89982
|
+
});
|
|
89983
|
+
}
|
|
89984
|
+
|
|
89985
|
+
// src/forced-update.ts
|
|
89986
|
+
var SEMVER_RE2 = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*)?$/;
|
|
89987
|
+
function normalizeSemverInput2(value) {
|
|
89988
|
+
return value.trim().replace(/^v/, "");
|
|
89989
|
+
}
|
|
89990
|
+
function parseSemver2(value) {
|
|
89991
|
+
const match = SEMVER_RE2.exec(normalizeSemverInput2(value));
|
|
89992
|
+
if (!match) {
|
|
89993
|
+
return null;
|
|
89994
|
+
}
|
|
89995
|
+
return {
|
|
89996
|
+
major: Number(match[1]),
|
|
89997
|
+
minor: Number(match[2]),
|
|
89998
|
+
patch: Number(match[3]),
|
|
89999
|
+
prerelease: match[4] ? match[4].split(".") : []
|
|
90000
|
+
};
|
|
90001
|
+
}
|
|
90002
|
+
function comparePrereleaseId2(a, b) {
|
|
90003
|
+
const aIsNumber = /^\d+$/.test(a);
|
|
90004
|
+
const bIsNumber = /^\d+$/.test(b);
|
|
90005
|
+
if (aIsNumber && bIsNumber) {
|
|
90006
|
+
const an = Number(a);
|
|
90007
|
+
const bn = Number(b);
|
|
90008
|
+
return an < bn ? -1 : an > bn ? 1 : 0;
|
|
90009
|
+
}
|
|
90010
|
+
if (aIsNumber) {
|
|
90011
|
+
return -1;
|
|
90012
|
+
}
|
|
90013
|
+
if (bIsNumber) {
|
|
90014
|
+
return 1;
|
|
90015
|
+
}
|
|
90016
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
90017
|
+
}
|
|
90018
|
+
function compareSemver2(a, b) {
|
|
90019
|
+
if (a.major !== b.major) {
|
|
90020
|
+
return a.major < b.major ? -1 : 1;
|
|
90021
|
+
}
|
|
90022
|
+
if (a.minor !== b.minor) {
|
|
90023
|
+
return a.minor < b.minor ? -1 : 1;
|
|
90024
|
+
}
|
|
90025
|
+
if (a.patch !== b.patch) {
|
|
90026
|
+
return a.patch < b.patch ? -1 : 1;
|
|
90027
|
+
}
|
|
90028
|
+
if (a.prerelease.length === 0 && b.prerelease.length === 0) {
|
|
90029
|
+
return 0;
|
|
90030
|
+
}
|
|
90031
|
+
if (a.prerelease.length === 0) {
|
|
90032
|
+
return 1;
|
|
90033
|
+
}
|
|
90034
|
+
if (b.prerelease.length === 0) {
|
|
90035
|
+
return -1;
|
|
90036
|
+
}
|
|
90037
|
+
const len = Math.min(a.prerelease.length, b.prerelease.length);
|
|
90038
|
+
for (let i = 0; i < len; i++) {
|
|
90039
|
+
const diff = comparePrereleaseId2(a.prerelease[i], b.prerelease[i]);
|
|
90040
|
+
if (diff !== 0) {
|
|
90041
|
+
return diff;
|
|
90042
|
+
}
|
|
90043
|
+
}
|
|
90044
|
+
if (a.prerelease.length !== b.prerelease.length) {
|
|
90045
|
+
return a.prerelease.length < b.prerelease.length ? -1 : 1;
|
|
90046
|
+
}
|
|
90047
|
+
return 0;
|
|
90048
|
+
}
|
|
90049
|
+
function isBelowRequiredVersion(currentVersion, minVersion) {
|
|
90050
|
+
const min = minVersion?.trim();
|
|
90051
|
+
if (!min) {
|
|
90052
|
+
return false;
|
|
90053
|
+
}
|
|
90054
|
+
const parsedMin = parseSemver2(min);
|
|
90055
|
+
if (!parsedMin) {
|
|
90056
|
+
logWithTimestamp(`[okx-agent-task] ignoring invalid forced minVersion=${min}`);
|
|
90057
|
+
return false;
|
|
90058
|
+
}
|
|
90059
|
+
const current = currentVersion?.trim();
|
|
90060
|
+
if (!current) {
|
|
90061
|
+
return true;
|
|
90062
|
+
}
|
|
90063
|
+
const parsedCurrent = parseSemver2(current);
|
|
90064
|
+
if (!parsedCurrent) {
|
|
90065
|
+
logWithTimestamp(`[okx-agent-task] current version is invalid, forcing update current=${current} min=${min}`);
|
|
90066
|
+
return true;
|
|
90067
|
+
}
|
|
90068
|
+
return compareSemver2(parsedCurrent, parsedMin) < 0;
|
|
90069
|
+
}
|
|
90070
|
+
async function ensureCommunicationMinVersions(input) {
|
|
90071
|
+
const runUpdate = input.runUpdate ?? runOkxA2aForcedUpdate;
|
|
90072
|
+
const cliMinVersion = input.systemConfig.minVersion.cli;
|
|
90073
|
+
const currentCliVersion = input.currentCliVersion ?? "0.0.13";
|
|
90074
|
+
if (isBelowRequiredVersion(currentCliVersion, cliMinVersion)) {
|
|
90075
|
+
await forceUpdate({
|
|
90076
|
+
target: "cli",
|
|
90077
|
+
currentVersion: currentCliVersion,
|
|
90078
|
+
minVersion: cliMinVersion,
|
|
90079
|
+
stage: input.stage,
|
|
90080
|
+
runUpdate
|
|
90081
|
+
});
|
|
90082
|
+
return { updated: true, target: "cli", currentVersion: currentCliVersion, minVersion: cliMinVersion };
|
|
90083
|
+
}
|
|
90084
|
+
const provider = resolveConfiguredAiProvider({ store: input.sessionStore, env: input.env });
|
|
90085
|
+
const gatewayTarget = providerToGatewayTarget(provider);
|
|
90086
|
+
if (!gatewayTarget) {
|
|
90087
|
+
logWithTimestamp(`[okx-agent-task] forced minVersion gateway check skipped provider=${provider ?? "(not set)"}`);
|
|
90088
|
+
return { updated: false };
|
|
90089
|
+
}
|
|
90090
|
+
const minVersion = input.systemConfig.minVersion[gatewayTarget];
|
|
90091
|
+
if (!minVersion) {
|
|
90092
|
+
return { updated: false, target: gatewayTarget };
|
|
90093
|
+
}
|
|
90094
|
+
const getGatewayVersion = input.getGatewayVersion ?? getInstalledGatewayPluginVersion;
|
|
90095
|
+
const currentVersion = await getGatewayVersion(gatewayTarget);
|
|
90096
|
+
if (!isBelowRequiredVersion(currentVersion, minVersion)) {
|
|
90097
|
+
return { updated: false, target: gatewayTarget, currentVersion, minVersion };
|
|
90098
|
+
}
|
|
90099
|
+
await forceUpdate({
|
|
90100
|
+
target: gatewayTarget,
|
|
90101
|
+
currentVersion,
|
|
90102
|
+
minVersion,
|
|
90103
|
+
stage: input.stage,
|
|
90104
|
+
runUpdate
|
|
90105
|
+
});
|
|
90106
|
+
return { updated: true, target: gatewayTarget, currentVersion, minVersion };
|
|
90107
|
+
}
|
|
90108
|
+
function providerToGatewayTarget(provider) {
|
|
90109
|
+
return provider === "openclaw" || provider === "hermes" ? provider : null;
|
|
90110
|
+
}
|
|
90111
|
+
async function forceUpdate(input) {
|
|
90112
|
+
const startedAt = Date.now();
|
|
90113
|
+
logWithTimestamp(
|
|
90114
|
+
`[okx-agent-task] forced update required target=${input.target} current=${input.currentVersion ?? "(unknown)"} min=${input.minVersion} stage=${input.stage}`
|
|
90115
|
+
);
|
|
90116
|
+
logger.info(LogEvent.FORCED_UPDATE_STARTED, forcedUpdateSentryExtra(input, startedAt, {
|
|
90117
|
+
status: "started",
|
|
90118
|
+
reason: "forced_update_required"
|
|
90119
|
+
}));
|
|
90120
|
+
try {
|
|
90121
|
+
await input.runUpdate(input.target);
|
|
90122
|
+
logger.info(LogEvent.FORCED_UPDATE_SUCCEEDED, forcedUpdateSentryExtra(input, startedAt, {
|
|
90123
|
+
status: "succeeded",
|
|
90124
|
+
reason: "update_completed"
|
|
90125
|
+
}));
|
|
90126
|
+
} catch (err2) {
|
|
90127
|
+
const error = err2 instanceof Error ? err2 : new Error(String(err2));
|
|
90128
|
+
logger.error(LogEvent.FORCED_UPDATE_FAILED, error, forcedUpdateSentryExtra(input, startedAt, {
|
|
90129
|
+
status: "failed",
|
|
90130
|
+
reason: "update_failed",
|
|
90131
|
+
errorName: error.name,
|
|
90132
|
+
errorMessage: error.message,
|
|
90133
|
+
errorStack: error.stack ?? "",
|
|
90134
|
+
...forcedUpdateErrorDetails(err2)
|
|
90135
|
+
}));
|
|
90136
|
+
throw err2;
|
|
90137
|
+
}
|
|
90138
|
+
}
|
|
90139
|
+
function forcedUpdateSentryExtra(input, startedAt, extra) {
|
|
90140
|
+
return {
|
|
90141
|
+
component: "node_listener",
|
|
90142
|
+
stage: input.stage,
|
|
90143
|
+
updateTarget: input.target,
|
|
90144
|
+
currentVersion: input.currentVersion ?? "",
|
|
90145
|
+
minVersion: input.minVersion,
|
|
90146
|
+
durationMs: String(Date.now() - startedAt),
|
|
90147
|
+
...extra
|
|
90148
|
+
};
|
|
90149
|
+
}
|
|
90150
|
+
function forcedUpdateErrorDetails(err2) {
|
|
90151
|
+
if (!err2 || typeof err2 !== "object") {
|
|
90152
|
+
return {};
|
|
90153
|
+
}
|
|
90154
|
+
const record = err2;
|
|
90155
|
+
return {
|
|
90156
|
+
exitCode: record.exitCode ?? record.code ?? "",
|
|
90157
|
+
signal: record.signal ?? ""
|
|
90158
|
+
};
|
|
90159
|
+
}
|
|
90160
|
+
function runOkxA2aForcedUpdate(target) {
|
|
90161
|
+
const args = [
|
|
90162
|
+
"update",
|
|
90163
|
+
...target === "cli" ? [] : [target],
|
|
90164
|
+
"--release",
|
|
90165
|
+
"latest",
|
|
90166
|
+
"--restart",
|
|
90167
|
+
"--yes"
|
|
90168
|
+
];
|
|
90169
|
+
return new Promise((resolvePromise, reject) => {
|
|
90170
|
+
const child = (0, import_node_child_process7.spawn)("okx-a2a", args, {
|
|
90171
|
+
stdio: "inherit",
|
|
90172
|
+
env: {
|
|
90173
|
+
...process.env,
|
|
90174
|
+
OKX_A2A_FORCED_UPDATE_TARGET: target
|
|
90175
|
+
}
|
|
90176
|
+
});
|
|
90177
|
+
child.on("error", reject);
|
|
90178
|
+
child.on("close", (code2, signal) => {
|
|
90179
|
+
if (code2 === 0) {
|
|
90180
|
+
resolvePromise();
|
|
90181
|
+
return;
|
|
90182
|
+
}
|
|
90183
|
+
reject(Object.assign(
|
|
90184
|
+
new Error(`okx-a2a ${args.join(" ")} failed with ${signal ? `signal=${signal}` : `code=${code2}`}`),
|
|
90185
|
+
{ exitCode: code2, signal }
|
|
90186
|
+
));
|
|
90187
|
+
});
|
|
90188
|
+
});
|
|
90189
|
+
}
|
|
90190
|
+
|
|
89895
90191
|
// src/listener.ts
|
|
89896
90192
|
var OFFLINE_REPLAY_SYNC_INTERVAL = 5;
|
|
89897
90193
|
function shouldRunOfflineReplay(syncCount, interval = OFFLINE_REPLAY_SYNC_INTERVAL) {
|
|
@@ -89908,9 +90204,9 @@ function stopClients(service) {
|
|
|
89908
90204
|
for (const [address, client] of service.getClients()) {
|
|
89909
90205
|
try {
|
|
89910
90206
|
client.stop();
|
|
89911
|
-
|
|
90207
|
+
logWithTimestamp(`[okx-agent-task] stopped XMTP client ${address}`);
|
|
89912
90208
|
} catch (err2) {
|
|
89913
|
-
|
|
90209
|
+
logWithTimestamp(`[okx-agent-task] failed to stop XMTP client ${address}:`, err2);
|
|
89914
90210
|
}
|
|
89915
90211
|
}
|
|
89916
90212
|
}
|
|
@@ -89918,12 +90214,12 @@ async function runListener(options = {}) {
|
|
|
89918
90214
|
const paths = resolveTaskPaths(options.homeDir);
|
|
89919
90215
|
const daemonLock = await acquireDaemonLock(paths, process.argv[1] ?? "okx-a2a");
|
|
89920
90216
|
if (!daemonLock) {
|
|
89921
|
-
|
|
90217
|
+
logWithTimestamp(
|
|
89922
90218
|
`[okx-agent-task] another daemon is already running for home=${paths.homeDir}; exiting before starting listeners`
|
|
89923
90219
|
);
|
|
89924
90220
|
return;
|
|
89925
90221
|
}
|
|
89926
|
-
|
|
90222
|
+
logWithTimestamp(
|
|
89927
90223
|
`[okx-agent-task] daemon lock acquired pid=${daemonLock.metadata.pid} lock=${paths.daemonLockPath}`
|
|
89928
90224
|
);
|
|
89929
90225
|
try {
|
|
@@ -89947,17 +90243,17 @@ async function runListenerWithLock(options, paths) {
|
|
|
89947
90243
|
stage: "user_attention_ipc_wake",
|
|
89948
90244
|
reason: "server_error"
|
|
89949
90245
|
});
|
|
89950
|
-
|
|
90246
|
+
logWithTimestamp("[okx-agent-task] user_attention IPC wake error:", err2);
|
|
89951
90247
|
}
|
|
89952
90248
|
});
|
|
89953
|
-
|
|
90249
|
+
logWithTimestamp(`[okx-agent-task] user_attention IPC wake listening at ${userAttentionEvents.path}`);
|
|
89954
90250
|
} catch (err2) {
|
|
89955
90251
|
logger.error(LogEvent.IPC_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), {
|
|
89956
90252
|
component: "node_listener",
|
|
89957
90253
|
stage: "user_attention_ipc_start",
|
|
89958
90254
|
reason: "start_failed"
|
|
89959
90255
|
});
|
|
89960
|
-
|
|
90256
|
+
logWithTimestamp("[okx-agent-task] failed to start user_attention IPC wake; watchers will use polling fallback:", err2);
|
|
89961
90257
|
}
|
|
89962
90258
|
const watcherCoordinator = startUserAttentionWatcherCoordinator({
|
|
89963
90259
|
store: sessionStore,
|
|
@@ -89967,16 +90263,18 @@ async function runListenerWithLock(options, paths) {
|
|
|
89967
90263
|
stage: "user_attention_watcher",
|
|
89968
90264
|
reason: "watcher_error"
|
|
89969
90265
|
});
|
|
89970
|
-
|
|
90266
|
+
logWithTimestamp("[okx-agent-task] user_attention watcher coordinator error:", err2);
|
|
89971
90267
|
}
|
|
89972
90268
|
});
|
|
89973
|
-
|
|
90269
|
+
logWithTimestamp("[okx-agent-task] user_attention watcher coordinator scanning SQLite watcher state");
|
|
89974
90270
|
const service = XmtpService.getInstance();
|
|
89975
90271
|
service.setDataDir(paths.xmtpDir);
|
|
89976
90272
|
service.setTools({
|
|
89977
90273
|
listAllAgentsWithMetadata: async (previousFingerprint) => listAllAgentsWithMetadata(previousFingerprint),
|
|
89978
90274
|
fetchSensitiveWords: async () => fetchSensitiveWords(),
|
|
89979
|
-
fetchSystemConfig: async () => fetchSystemConfig(
|
|
90275
|
+
fetchSystemConfig: async () => fetchSystemConfig({
|
|
90276
|
+
notifySessionExpired: (command) => service.tools.notifySessionExpired?.(command)
|
|
90277
|
+
}),
|
|
89980
90278
|
notifyAgentsWakeup: async (agentIds) => notifyAgentsWakeup(agentIds),
|
|
89981
90279
|
createSigner: (agent) => createOnchainosSigner(agent),
|
|
89982
90280
|
createInboundMiddleware: (deps) => createMiddlewareFromCoreDeps(store, deps, {
|
|
@@ -90007,13 +90305,23 @@ async function runListenerWithLock(options, paths) {
|
|
|
90007
90305
|
}));
|
|
90008
90306
|
}
|
|
90009
90307
|
});
|
|
90010
|
-
service.
|
|
90308
|
+
service.setCliVersion("0.0.13");
|
|
90011
90309
|
await service.init();
|
|
90012
|
-
const
|
|
90013
|
-
|
|
90014
|
-
|
|
90015
|
-
|
|
90310
|
+
const startupVersionCheck = await ensureCommunicationMinVersions({
|
|
90311
|
+
systemConfig: service.getSystemConfig(),
|
|
90312
|
+
sessionStore,
|
|
90313
|
+
stage: "startup"
|
|
90314
|
+
});
|
|
90315
|
+
if (startupVersionCheck.updated) {
|
|
90316
|
+
logWithTimestamp(
|
|
90317
|
+
`[okx-agent-task] forced update executed during startup target=${startupVersionCheck.target}; exiting current listener so restarted daemon can take over`
|
|
90016
90318
|
);
|
|
90319
|
+
await watcherCoordinator.stop();
|
|
90320
|
+
await userAttentionEvents?.close();
|
|
90321
|
+
stopClients(service);
|
|
90322
|
+
sessionStore.close();
|
|
90323
|
+
commands.close();
|
|
90324
|
+
return;
|
|
90017
90325
|
}
|
|
90018
90326
|
const systemConfig = service.getSystemConfig();
|
|
90019
90327
|
if (systemConfig.sentryDsn) {
|
|
@@ -90023,17 +90331,17 @@ async function runListenerWithLock(options, paths) {
|
|
|
90023
90331
|
agentPlatform: "node"
|
|
90024
90332
|
});
|
|
90025
90333
|
} else {
|
|
90026
|
-
|
|
90334
|
+
errorWithTimestamp(
|
|
90027
90335
|
"[okx-agent-task] system-config did not return sentryDsn; Sentry not initialized"
|
|
90028
90336
|
);
|
|
90029
90337
|
logger.error(LogEvent.SENTRY_INIT_SKIPPED, void 0, {
|
|
90030
90338
|
onchainosAgentId: "*",
|
|
90031
90339
|
reason: "system-config missing sentryDsn",
|
|
90032
90340
|
pluginId: "@okxweb3/a2a-node",
|
|
90033
|
-
pluginVersion: "0.0.13
|
|
90341
|
+
pluginVersion: "0.0.13"
|
|
90034
90342
|
});
|
|
90035
90343
|
}
|
|
90036
|
-
|
|
90344
|
+
logWithTimestamp(
|
|
90037
90345
|
`[okx-agent-task] listener initialized, clients=${service.getClients().size}, home=${store.homeDir}`
|
|
90038
90346
|
);
|
|
90039
90347
|
let syncInFlight = false;
|
|
@@ -90050,7 +90358,7 @@ async function runListenerWithLock(options, paths) {
|
|
|
90050
90358
|
const shouldReplay = shouldRunOfflineReplay(offlineReplaySyncCount);
|
|
90051
90359
|
offlineReplaySyncCount = nextOfflineReplaySyncCount(offlineReplaySyncCount);
|
|
90052
90360
|
if (!shouldHeartbeat) {
|
|
90053
|
-
|
|
90361
|
+
logWithTimestamp("[okx-agent-task] no active agents, skipping heartbeat");
|
|
90054
90362
|
}
|
|
90055
90363
|
const skippedTiming = { durationMs: 0 };
|
|
90056
90364
|
const [heartbeatResult, replayResult] = await Promise.all([
|
|
@@ -90068,7 +90376,7 @@ async function runListenerWithLock(options, paths) {
|
|
|
90068
90376
|
chainIndex: ONCHAINOS_CHAIN_INDEX,
|
|
90069
90377
|
communicationClass: "onchainos_or_network"
|
|
90070
90378
|
});
|
|
90071
|
-
|
|
90379
|
+
logWithTimestamp(`[okx-agent-task] heartbeat failed duration=${heartbeatMs}ms:`, heartbeatResult.error);
|
|
90072
90380
|
}
|
|
90073
90381
|
if (shouldReplay && replayResult.error) {
|
|
90074
90382
|
logger.error(LogEvent.OFFLINE_REPLAY_FAILED, replayResult.error instanceof Error ? replayResult.error : new Error(String(replayResult.error)), {
|
|
@@ -90078,10 +90386,10 @@ async function runListenerWithLock(options, paths) {
|
|
|
90078
90386
|
durationMs: String(replayMs),
|
|
90079
90387
|
communicationClass: "xmtp_replay_or_storage"
|
|
90080
90388
|
});
|
|
90081
|
-
|
|
90389
|
+
logWithTimestamp(`[okx-agent-task] offline replay failed duration=${replayMs}ms:`, replayResult.error);
|
|
90082
90390
|
}
|
|
90083
90391
|
const replaySummary = shouldReplay ? replayResult.value : void 0;
|
|
90084
|
-
|
|
90392
|
+
logWithTimestamp(
|
|
90085
90393
|
`[okx-agent-task] sync tick agents=${refresh.agentCount} changed=${refresh.changed ? "yes" : "no"} added=${refresh.added.length} removed=${refresh.removed.length} replayed=${replaySummary?.replayed ?? 0}`
|
|
90086
90394
|
);
|
|
90087
90395
|
} catch (err2) {
|
|
@@ -90091,7 +90399,7 @@ async function runListenerWithLock(options, paths) {
|
|
|
90091
90399
|
durationMs: String(Date.now() - tickStartedAt),
|
|
90092
90400
|
reason: "sync_tick_exception"
|
|
90093
90401
|
});
|
|
90094
|
-
|
|
90402
|
+
logWithTimestamp(`[okx-agent-task] sync tick failed total=${Date.now() - tickStartedAt}ms:`, err2);
|
|
90095
90403
|
} finally {
|
|
90096
90404
|
syncInFlight = false;
|
|
90097
90405
|
}
|
|
@@ -90107,7 +90415,7 @@ async function runListenerWithLock(options, paths) {
|
|
|
90107
90415
|
clearInterval(timer);
|
|
90108
90416
|
}
|
|
90109
90417
|
intervalSec = Math.max(10, nextIntervalSec);
|
|
90110
|
-
|
|
90418
|
+
logWithTimestamp(`[okx-agent-task] scheduled sync interval ${intervalSec}s`);
|
|
90111
90419
|
timer = setInterval(() => {
|
|
90112
90420
|
void syncTick();
|
|
90113
90421
|
}, intervalSec * 1e3);
|
|
@@ -90122,9 +90430,21 @@ async function runListenerWithLock(options, paths) {
|
|
|
90122
90430
|
if (stopping) {
|
|
90123
90431
|
return;
|
|
90124
90432
|
}
|
|
90433
|
+
const versionCheck = await ensureCommunicationMinVersions({
|
|
90434
|
+
systemConfig: service.getSystemConfig(),
|
|
90435
|
+
sessionStore,
|
|
90436
|
+
stage: "system_config_refresh"
|
|
90437
|
+
});
|
|
90438
|
+
if (versionCheck.updated) {
|
|
90439
|
+
logWithTimestamp(
|
|
90440
|
+
`[okx-agent-task] forced update executed after system-config refresh target=${versionCheck.target}; stopping current listener`
|
|
90441
|
+
);
|
|
90442
|
+
process.kill(process.pid, "SIGTERM");
|
|
90443
|
+
return;
|
|
90444
|
+
}
|
|
90125
90445
|
const nextIntervalSec = Math.max(10, service.getSystemConfig().heartbeatInterval);
|
|
90126
90446
|
if (nextIntervalSec !== previousIntervalSec) {
|
|
90127
|
-
|
|
90447
|
+
logWithTimestamp(
|
|
90128
90448
|
`[okx-agent-task] heartbeat interval changed from ${previousIntervalSec}s to ${nextIntervalSec}s; rescheduling sync timer`
|
|
90129
90449
|
);
|
|
90130
90450
|
scheduleSyncTimer(nextIntervalSec);
|
|
@@ -90135,7 +90455,7 @@ async function runListenerWithLock(options, paths) {
|
|
|
90135
90455
|
stage: "system_config_refresh",
|
|
90136
90456
|
reason: "refresh_failed"
|
|
90137
90457
|
});
|
|
90138
|
-
|
|
90458
|
+
logWithTimestamp("[okx-agent-task] system-config refresh failed:", err2);
|
|
90139
90459
|
}
|
|
90140
90460
|
};
|
|
90141
90461
|
scheduleSyncTimer(intervalSec);
|
|
@@ -90155,9 +90475,9 @@ async function runListenerWithLock(options, paths) {
|
|
|
90155
90475
|
return;
|
|
90156
90476
|
}
|
|
90157
90477
|
stopping = true;
|
|
90158
|
-
|
|
90478
|
+
logWithTimestamp(`[okx-agent-task] received ${signal}, stopping listener`);
|
|
90159
90479
|
const forceResolve = setTimeout(() => {
|
|
90160
|
-
|
|
90480
|
+
logWithTimestamp("[okx-agent-task] listener shutdown timed out; forcing process exit");
|
|
90161
90481
|
resolve4();
|
|
90162
90482
|
}, SHUTDOWN_FORCE_RESOLVE_MS);
|
|
90163
90483
|
void (async () => {
|
|
@@ -90175,7 +90495,7 @@ async function runListenerWithLock(options, paths) {
|
|
|
90175
90495
|
stage: "user_attention_ipc_close",
|
|
90176
90496
|
reason: "close_failed"
|
|
90177
90497
|
});
|
|
90178
|
-
|
|
90498
|
+
logWithTimestamp("[okx-agent-task] failed to close user_attention IPC wake:", err2);
|
|
90179
90499
|
}
|
|
90180
90500
|
stopClients(service);
|
|
90181
90501
|
sessionStore.close();
|
|
@@ -90196,117 +90516,6 @@ async function timeSettled(fn) {
|
|
|
90196
90516
|
return { durationMs: Date.now() - startedAt, error };
|
|
90197
90517
|
}
|
|
90198
90518
|
}
|
|
90199
|
-
|
|
90200
|
-
// src/update-cli.ts
|
|
90201
|
-
var import_promises6 = require("node:fs/promises");
|
|
90202
|
-
var import_node_os6 = require("node:os");
|
|
90203
|
-
var import_node_path18 = require("node:path");
|
|
90204
|
-
function isPrereleaseVersion(version2) {
|
|
90205
|
-
return /\d+\.\d+\.\d+-[0-9A-Za-z.-]+/.test(version2);
|
|
90206
|
-
}
|
|
90207
|
-
async function normalizeHermesOkxA2aPluginConfig(configFile = resolveHermesConfigPath()) {
|
|
90208
|
-
let content3;
|
|
90209
|
-
try {
|
|
90210
|
-
content3 = await (0, import_promises6.readFile)(configFile, "utf8");
|
|
90211
|
-
} catch (error) {
|
|
90212
|
-
if (isNodeError(error) && error.code === "ENOENT") {
|
|
90213
|
-
return false;
|
|
90214
|
-
}
|
|
90215
|
-
throw error;
|
|
90216
|
-
}
|
|
90217
|
-
const trailingNewline = content3.endsWith("\n");
|
|
90218
|
-
const lines = content3.replace(/\n$/, "").split(/\n/);
|
|
90219
|
-
let changed = false;
|
|
90220
|
-
let inPlugins = false;
|
|
90221
|
-
let pluginsIndent = -1;
|
|
90222
|
-
let inEnabled = false;
|
|
90223
|
-
let enabledIndent = -1;
|
|
90224
|
-
let emittedOkxA2a = false;
|
|
90225
|
-
const output = [];
|
|
90226
|
-
for (const line of lines) {
|
|
90227
|
-
const currentIndent = lineIndent(line);
|
|
90228
|
-
const significant = line.trim() !== "" && !line.trimStart().startsWith("#");
|
|
90229
|
-
const parsedListValue = parseYamlListValue(line);
|
|
90230
|
-
if (inEnabled && significant && (currentIndent < enabledIndent || currentIndent === enabledIndent && !parsedListValue)) {
|
|
90231
|
-
inEnabled = false;
|
|
90232
|
-
emittedOkxA2a = false;
|
|
90233
|
-
}
|
|
90234
|
-
if (inPlugins && significant && currentIndent <= pluginsIndent && !isPluginsHeader(line)) {
|
|
90235
|
-
inPlugins = false;
|
|
90236
|
-
inEnabled = false;
|
|
90237
|
-
emittedOkxA2a = false;
|
|
90238
|
-
}
|
|
90239
|
-
if (isPluginsHeader(line)) {
|
|
90240
|
-
inPlugins = true;
|
|
90241
|
-
pluginsIndent = currentIndent;
|
|
90242
|
-
output.push(line);
|
|
90243
|
-
continue;
|
|
90244
|
-
}
|
|
90245
|
-
if (inPlugins && isEnabledHeader(line) && currentIndent > pluginsIndent) {
|
|
90246
|
-
inEnabled = true;
|
|
90247
|
-
enabledIndent = currentIndent;
|
|
90248
|
-
emittedOkxA2a = false;
|
|
90249
|
-
output.push(line);
|
|
90250
|
-
continue;
|
|
90251
|
-
}
|
|
90252
|
-
if (inEnabled) {
|
|
90253
|
-
const parsed = parsedListValue;
|
|
90254
|
-
if (parsed && (parsed.value === "okx-a2a" || parsed.value === "platforms/okx-a2a")) {
|
|
90255
|
-
if (!emittedOkxA2a) {
|
|
90256
|
-
const normalized = `${parsed.indent}- okx-a2a`;
|
|
90257
|
-
output.push(normalized);
|
|
90258
|
-
changed ||= normalized !== line;
|
|
90259
|
-
emittedOkxA2a = true;
|
|
90260
|
-
} else {
|
|
90261
|
-
changed = true;
|
|
90262
|
-
}
|
|
90263
|
-
continue;
|
|
90264
|
-
}
|
|
90265
|
-
}
|
|
90266
|
-
output.push(line);
|
|
90267
|
-
}
|
|
90268
|
-
if (!changed) {
|
|
90269
|
-
return false;
|
|
90270
|
-
}
|
|
90271
|
-
await (0, import_promises6.writeFile)(configFile, `${output.join("\n")}${trailingNewline ? "\n" : ""}`);
|
|
90272
|
-
console.log(`[update] normalized Hermes plugins.enabled okx-a2a entry in ${configFile}`);
|
|
90273
|
-
return true;
|
|
90274
|
-
}
|
|
90275
|
-
function resolveHermesConfigPath() {
|
|
90276
|
-
return (0, import_node_path18.join)(process.env.HERMES_HOME ?? (0, import_node_path18.join)((0, import_node_os6.homedir)(), ".hermes"), "config.yaml");
|
|
90277
|
-
}
|
|
90278
|
-
function lineIndent(line) {
|
|
90279
|
-
const match = line.match(/^\s*/);
|
|
90280
|
-
return match?.[0].length ?? 0;
|
|
90281
|
-
}
|
|
90282
|
-
function isPluginsHeader(line) {
|
|
90283
|
-
return /^[\s]*plugins:[\s]*(?:#.*)?$/.test(line);
|
|
90284
|
-
}
|
|
90285
|
-
function isEnabledHeader(line) {
|
|
90286
|
-
return /^[\s]*enabled:[\s]*(?:#.*)?$/.test(line);
|
|
90287
|
-
}
|
|
90288
|
-
function parseYamlListValue(line) {
|
|
90289
|
-
const match = line.match(/^(\s*)-\s*(?:"([^"]*)"|'([^']*)'|([^#\s]+))(?:\s*(?:#.*)?)?$/);
|
|
90290
|
-
if (!match) {
|
|
90291
|
-
return null;
|
|
90292
|
-
}
|
|
90293
|
-
return {
|
|
90294
|
-
indent: match[1] ?? "",
|
|
90295
|
-
value: match[2] ?? match[3] ?? match[4] ?? ""
|
|
90296
|
-
};
|
|
90297
|
-
}
|
|
90298
|
-
function isNodeError(error) {
|
|
90299
|
-
return error instanceof Error && "code" in error;
|
|
90300
|
-
}
|
|
90301
|
-
function parsePluginYamlVersion(content3) {
|
|
90302
|
-
for (const line of content3.split(/\r?\n/)) {
|
|
90303
|
-
const match = line.match(/^\s*version:\s*(?:"([^"]+)"|'([^']+)'|([^#\s]+))/);
|
|
90304
|
-
if (match) {
|
|
90305
|
-
return match[1] ?? match[2] ?? match[3] ?? null;
|
|
90306
|
-
}
|
|
90307
|
-
}
|
|
90308
|
-
return null;
|
|
90309
|
-
}
|
|
90310
90519
|
// Annotate the CommonJS export names for ESM import in node:
|
|
90311
90520
|
0 && (module.exports = {
|
|
90312
90521
|
AI_PROVIDERS,
|
|
@@ -90318,7 +90527,6 @@ function parsePluginYamlVersion(content3) {
|
|
|
90318
90527
|
GatewayOutboundBehavior,
|
|
90319
90528
|
InvalidXmtpMessageStore,
|
|
90320
90529
|
OFFLINE_REPLAY_SYNC_INTERVAL,
|
|
90321
|
-
OPENCLAW_GATEWAY_ROUTE_GROUP_ID,
|
|
90322
90530
|
SYSTEM_NOTIFICATION_SESSION_KEY,
|
|
90323
90531
|
SessionStore,
|
|
90324
90532
|
SqliteOutboundBehavior,
|
|
@@ -90332,7 +90540,6 @@ function parsePluginYamlVersion(content3) {
|
|
|
90332
90540
|
bindJobProviderToCurrentDefaultIfMissing,
|
|
90333
90541
|
bindJobProviderToCurrentRuntimeIfMissing,
|
|
90334
90542
|
bindMessageJobProviderToCurrentDefault,
|
|
90335
|
-
bindOpenClawGatewayRouteFromEnv,
|
|
90336
90543
|
buildAgentMessageNotice,
|
|
90337
90544
|
buildAiAdapterCommand,
|
|
90338
90545
|
buildAiProviderEnv,
|
|
@@ -90353,11 +90560,11 @@ function parsePluginYamlVersion(content3) {
|
|
|
90353
90560
|
createFileMessageHandler,
|
|
90354
90561
|
createOutboundBehavior,
|
|
90355
90562
|
createUserAttentionWatchParentMonitor,
|
|
90356
|
-
currentOpenClawGatewaySessionKey,
|
|
90357
90563
|
detectAiProviders,
|
|
90358
90564
|
detectCurrentAiProvider,
|
|
90359
90565
|
detectGatewayInvocation,
|
|
90360
90566
|
detectRuntime,
|
|
90567
|
+
ensureCommunicationMinVersions,
|
|
90361
90568
|
ensureDefaultAiProvider,
|
|
90362
90569
|
extractAiSessionId,
|
|
90363
90570
|
extractXmtpSentAtMs,
|
|
@@ -90365,6 +90572,7 @@ function parsePluginYamlVersion(content3) {
|
|
|
90365
90572
|
handleXmtpSendCommand,
|
|
90366
90573
|
hasAiRuntimeMarker,
|
|
90367
90574
|
heartbeatUserAttentionWatcher,
|
|
90575
|
+
isBelowRequiredVersion,
|
|
90368
90576
|
isOriginalParentProcessAlive,
|
|
90369
90577
|
isPrereleaseVersion,
|
|
90370
90578
|
isRetryableOpenClawGatewayError,
|
|
@@ -90387,8 +90595,6 @@ function parsePluginYamlVersion(content3) {
|
|
|
90387
90595
|
resolveConfiguredAiProviderForJob,
|
|
90388
90596
|
resolveDirectCommunicationSessionTarget,
|
|
90389
90597
|
resolveOpenClawGatewayConfig,
|
|
90390
|
-
resolveOpenClawGatewayRoute,
|
|
90391
|
-
resolveOpenClawGatewayRoutes,
|
|
90392
90598
|
resolveSystemNotificationTargets,
|
|
90393
90599
|
resolveTaskConfigPath,
|
|
90394
90600
|
resolveTaskHome,
|