@okxweb3/a2a-node 0.0.14 → 0.0.15-beta-1d2e01866f-260623014705
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 +3164 -3511
- package/dist/index.js +243 -613
- 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 parseSemver2(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 = parseSemver2;
|
|
1635
1635
|
exports2.uuid4 = uuid4;
|
|
1636
1636
|
}
|
|
1637
1637
|
});
|
|
@@ -67969,7 +67969,6 @@ __export(index_exports, {
|
|
|
67969
67969
|
detectCurrentAiProvider: () => detectCurrentAiProvider,
|
|
67970
67970
|
detectGatewayInvocation: () => detectGatewayInvocation,
|
|
67971
67971
|
detectRuntime: () => detectRuntime,
|
|
67972
|
-
ensureCommunicationMinVersions: () => ensureCommunicationMinVersions,
|
|
67973
67972
|
ensureDefaultAiProvider: () => ensureDefaultAiProvider,
|
|
67974
67973
|
extractAiSessionId: () => extractAiSessionId,
|
|
67975
67974
|
extractXmtpSentAtMs: () => extractXmtpSentAtMs2,
|
|
@@ -67977,7 +67976,6 @@ __export(index_exports, {
|
|
|
67977
67976
|
handleXmtpSendCommand: () => handleXmtpSendCommand,
|
|
67978
67977
|
hasAiRuntimeMarker: () => hasAiRuntimeMarker,
|
|
67979
67978
|
heartbeatUserAttentionWatcher: () => heartbeatUserAttentionWatcher,
|
|
67980
|
-
isBelowRequiredVersion: () => isBelowRequiredVersion,
|
|
67981
67979
|
isOriginalParentProcessAlive: () => isOriginalParentProcessAlive,
|
|
67982
67980
|
isPrereleaseVersion: () => isPrereleaseVersion,
|
|
67983
67981
|
isRetryableOpenClawGatewayError: () => isRetryableOpenClawGatewayError,
|
|
@@ -70321,7 +70319,7 @@ function detectGatewayInvocation(env = process.env) {
|
|
|
70321
70319
|
if (!isTruthyRuntimeMarker(env.OKX_A2A_IN_GATEWAY)) {
|
|
70322
70320
|
return null;
|
|
70323
70321
|
}
|
|
70324
|
-
const provider = env.OKX_A2A_GATEWAY_PROVIDER;
|
|
70322
|
+
const provider = env.OKX_A2A_GATEWAY_PROVIDER ?? env.OKX_A2A_AI_PROVIDER ?? env.OKX_AGENT_TASK_AI_CLI;
|
|
70325
70323
|
if (!provider) {
|
|
70326
70324
|
return null;
|
|
70327
70325
|
}
|
|
@@ -71012,8 +71010,6 @@ var LogEvent = {
|
|
|
71012
71010
|
AGENTS_WAKEUP_NOTIFIED: "Agents wakeup notified",
|
|
71013
71011
|
CONFIG_SENSITIVE_WORDS_REFRESHED: "Sensitive words config refreshed",
|
|
71014
71012
|
CONFIG_SYSTEM_REFRESHED: "System config refreshed",
|
|
71015
|
-
FORCED_UPDATE_STARTED: "Forced update started",
|
|
71016
|
-
FORCED_UPDATE_SUCCEEDED: "Forced update succeeded",
|
|
71017
71013
|
GATEWAY_DISCONNECTED: "Gateway disconnected",
|
|
71018
71014
|
GATEWAY_REQUEST: "Gateway request",
|
|
71019
71015
|
GATEWAY_DELIVERY_BUFFERED: "Gateway delivery buffered",
|
|
@@ -71076,7 +71072,6 @@ var LogEvent = {
|
|
|
71076
71072
|
CACHE_LOAD_FAILED: "Cache load failed",
|
|
71077
71073
|
CACHE_WRITE_FAILED: "Cache write failed",
|
|
71078
71074
|
CONFIG_LOAD_FAILED: "Config load failed",
|
|
71079
|
-
FORCED_UPDATE_FAILED: "Forced update failed",
|
|
71080
71075
|
SENTRY_INIT_SKIPPED: "Sentry init skipped",
|
|
71081
71076
|
AGENT_DB_DIR_CREATE_FAILED: "Agent DB dir create failed"
|
|
71082
71077
|
};
|
|
@@ -71253,8 +71248,6 @@ var SENTRY_INFO_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
|
71253
71248
|
LogEvent.BOOTSTRAP_APPLIED,
|
|
71254
71249
|
LogEvent.CONFIG_SENSITIVE_WORDS_REFRESHED,
|
|
71255
71250
|
LogEvent.CONFIG_SYSTEM_REFRESHED,
|
|
71256
|
-
LogEvent.FORCED_UPDATE_STARTED,
|
|
71257
|
-
LogEvent.FORCED_UPDATE_SUCCEEDED,
|
|
71258
71251
|
LogEvent.CONVERSATION_HISTORY_QUERIED,
|
|
71259
71252
|
LogEvent.FILE_DOWNLOADED,
|
|
71260
71253
|
LogEvent.FILE_UPLOADED,
|
|
@@ -83541,18 +83534,6 @@ function parseTips(raw) {
|
|
|
83541
83534
|
function parseStringArray(raw) {
|
|
83542
83535
|
return Array.isArray(raw) ? raw.filter((value) => typeof value === "string" && value.length > 0) : [];
|
|
83543
83536
|
}
|
|
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
|
-
}
|
|
83556
83537
|
function parseExtConfig(raw) {
|
|
83557
83538
|
const obj = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
83558
83539
|
return {
|
|
@@ -83574,14 +83555,13 @@ function parseSystemConfig(raw) {
|
|
|
83574
83555
|
acc.push({ address, inboxId, type });
|
|
83575
83556
|
return acc;
|
|
83576
83557
|
}, []) : [];
|
|
83577
|
-
const minVersion = readMinVersion(raw);
|
|
83578
83558
|
return {
|
|
83579
83559
|
heartbeatInterval: typeof raw.heartbeatInterval === "number" ? raw.heartbeatInterval : SYSTEM_CONFIG_DEFAULTS.heartbeatInterval,
|
|
83580
83560
|
maxFileSizeBytes: typeof raw.maxFileSizeBytes === "number" && Number.isFinite(raw.maxFileSizeBytes) && raw.maxFileSizeBytes > 0 ? raw.maxFileSizeBytes : SYSTEM_CONFIG_DEFAULTS.maxFileSizeBytes,
|
|
83581
83561
|
sensitiveUploadReg: parseStringArray(raw.SENSITIVE_UPLOAD_REG),
|
|
83582
83562
|
accounts,
|
|
83583
83563
|
sentryDsn: typeof raw.sentryDsn === "string" ? raw.sentryDsn : "",
|
|
83584
|
-
|
|
83564
|
+
minAvailablePluginVersion: typeof raw.minAvailablePluginVersion === "string" ? raw.minAvailablePluginVersion : "",
|
|
83585
83565
|
extConfig: parseExtConfig(raw.extConfig)
|
|
83586
83566
|
};
|
|
83587
83567
|
}
|
|
@@ -83630,7 +83610,11 @@ var XmtpService = class _XmtpService {
|
|
|
83630
83610
|
_initFailures = [];
|
|
83631
83611
|
_backupReady = Promise.resolve();
|
|
83632
83612
|
_onAfterInitError = null;
|
|
83633
|
-
|
|
83613
|
+
_pluginVersion = "";
|
|
83614
|
+
_pluginVersionStatus = {
|
|
83615
|
+
unavailable: false,
|
|
83616
|
+
minVersion: ""
|
|
83617
|
+
};
|
|
83634
83618
|
dataDir = DEFAULT_DATA_DIR;
|
|
83635
83619
|
syncByAddress = /* @__PURE__ */ new Map();
|
|
83636
83620
|
agentListFingerprint;
|
|
@@ -83678,11 +83662,11 @@ var XmtpService = class _XmtpService {
|
|
|
83678
83662
|
]);
|
|
83679
83663
|
if (systemConfigResult.status === "fulfilled" && systemConfigResult.value) {
|
|
83680
83664
|
this.systemConfig = parseSystemConfig(systemConfigResult.value);
|
|
83681
|
-
|
|
83682
|
-
if (this.
|
|
83665
|
+
this.evaluatePluginVersion();
|
|
83666
|
+
if (this._pluginVersionStatus.unavailable) {
|
|
83683
83667
|
this._initialized = false;
|
|
83684
83668
|
logWithTimestamp(
|
|
83685
|
-
`[xmtp-sdk] init
|
|
83669
|
+
`[xmtp-sdk] init aborted: plugin v${this._pluginVersion} is below the required minimum v${this._pluginVersionStatus.minVersion}. Run \`openclaw plugins update okx-a2a\` to upgrade.`
|
|
83686
83670
|
);
|
|
83687
83671
|
return;
|
|
83688
83672
|
}
|
|
@@ -83726,6 +83710,9 @@ var XmtpService = class _XmtpService {
|
|
|
83726
83710
|
logWithTimestamp("[xmtp-sdk] init: initXmtpInstall failed:", err2.message);
|
|
83727
83711
|
}
|
|
83728
83712
|
this._initialized = this._initFailures.length === 0;
|
|
83713
|
+
if (this._initialized) {
|
|
83714
|
+
this.evaluatePluginVersion();
|
|
83715
|
+
}
|
|
83729
83716
|
const clientCount = clientsResult.status === "fulfilled" ? clientsResult.value.size : 0;
|
|
83730
83717
|
logWithTimestamp(
|
|
83731
83718
|
`[xmtp-sdk] init done: initialized=${this._initialized}, clients=${clientCount}, failures=${this._initFailures.length}`
|
|
@@ -83767,6 +83754,7 @@ var XmtpService = class _XmtpService {
|
|
|
83767
83754
|
this._initFailures = remaining;
|
|
83768
83755
|
if (remaining.length === 0) {
|
|
83769
83756
|
this._initialized = true;
|
|
83757
|
+
this.evaluatePluginVersion();
|
|
83770
83758
|
}
|
|
83771
83759
|
return { ok: remaining.length === 0, failures: remaining };
|
|
83772
83760
|
}
|
|
@@ -84259,14 +84247,27 @@ var XmtpService = class _XmtpService {
|
|
|
84259
84247
|
getSystemConfig() {
|
|
84260
84248
|
return this.systemConfig;
|
|
84261
84249
|
}
|
|
84262
|
-
// The
|
|
84263
|
-
// before
|
|
84264
|
-
//
|
|
84265
|
-
|
|
84266
|
-
|
|
84267
|
-
|
|
84268
|
-
|
|
84269
|
-
|
|
84250
|
+
// The plugin reports its own build version (injected via esbuild
|
|
84251
|
+
// define) before calling init(); we compare it once against
|
|
84252
|
+
// systemConfig.minAvailablePluginVersion when init completes, then
|
|
84253
|
+
// freeze the result. Tool guards read the cached status, so per-call
|
|
84254
|
+
// semver work is avoided entirely.
|
|
84255
|
+
setPluginVersion(version2) {
|
|
84256
|
+
this._pluginVersion = version2 ?? "";
|
|
84257
|
+
}
|
|
84258
|
+
get pluginVersionStatus() {
|
|
84259
|
+
return this._pluginVersionStatus;
|
|
84260
|
+
}
|
|
84261
|
+
evaluatePluginVersion() {
|
|
84262
|
+
const min = this.systemConfig.minAvailablePluginVersion;
|
|
84263
|
+
if (!min || !isValidSemver(min) || !isValidSemver(this._pluginVersion)) {
|
|
84264
|
+
this._pluginVersionStatus = { unavailable: false, minVersion: min ?? "" };
|
|
84265
|
+
return;
|
|
84266
|
+
}
|
|
84267
|
+
this._pluginVersionStatus = {
|
|
84268
|
+
unavailable: semverLt(this._pluginVersion, min),
|
|
84269
|
+
minVersion: min
|
|
84270
|
+
};
|
|
84270
84271
|
}
|
|
84271
84272
|
// Force-refresh systemConfig from onchainos API (falls back to disk
|
|
84272
84273
|
// cache). Single in-flight promise is shared by concurrent callers so
|
|
@@ -84281,6 +84282,7 @@ var XmtpService = class _XmtpService {
|
|
|
84281
84282
|
const raw = await loadSystemConfigWith(this.dataDir, this.tools.fetchSystemConfig);
|
|
84282
84283
|
if (raw) {
|
|
84283
84284
|
this.systemConfig = parseSystemConfig(raw);
|
|
84285
|
+
this.evaluatePluginVersion();
|
|
84284
84286
|
}
|
|
84285
84287
|
} finally {
|
|
84286
84288
|
this.systemConfigRefreshInflight = null;
|
|
@@ -85719,12 +85721,6 @@ var sharedClient = null;
|
|
|
85719
85721
|
function resolveOpenClawGatewayConfig(env = process.env) {
|
|
85720
85722
|
const synced = readSyncedGatewayConfig(env);
|
|
85721
85723
|
const explicitUrl = env.OKX_A2A_OPENCLAW_GATEWAY_URL?.trim() || void 0;
|
|
85722
|
-
if (!explicitUrl && !synced && requiresSyncedOpenClawGatewayConfig(env)) {
|
|
85723
|
-
const expectedPath = resolveOpenClawGatewayConfigPath(env.OKX_AGENT_TASK_HOME);
|
|
85724
|
-
throw new Error(
|
|
85725
|
-
`OpenClaw gateway URL was not synced. Expected ${expectedPath}. Restart the OpenClaw gateway so okx-a2a can read the gateway URL from openclaw-gateway.json.`
|
|
85726
|
-
);
|
|
85727
|
-
}
|
|
85728
85724
|
const defaultUrl = `ws://127.0.0.1:${DEFAULT_GATEWAY_PORT}`;
|
|
85729
85725
|
const url = explicitUrl ?? synced?.url ?? defaultUrl;
|
|
85730
85726
|
const password = env.OKX_A2A_OPENCLAW_GATEWAY_PASSWORD?.trim() || synced?.password || void 0;
|
|
@@ -86090,9 +86086,6 @@ function readSyncedGatewayConfig(env) {
|
|
|
86090
86086
|
return null;
|
|
86091
86087
|
}
|
|
86092
86088
|
}
|
|
86093
|
-
function requiresSyncedOpenClawGatewayConfig(env) {
|
|
86094
|
-
return env.OKX_A2A_GATEWAY_PROVIDER === "openclaw" || env.OKX_A2A_RUNTIME_CONTEXT === "openclaw-gateway" || env.OKX_A2A_IN_GATEWAY === "1";
|
|
86095
|
-
}
|
|
86096
86089
|
function buildConnectParams(config, instanceId, protocolVersion) {
|
|
86097
86090
|
return {
|
|
86098
86091
|
minProtocol: protocolVersion,
|
|
@@ -86100,7 +86093,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
|
|
|
86100
86093
|
client: {
|
|
86101
86094
|
id: "gateway-client",
|
|
86102
86095
|
displayName: "okx-a2a-node",
|
|
86103
|
-
version: "0.0.
|
|
86096
|
+
version: "0.0.15-beta-1d2e01866f-260623014705",
|
|
86104
86097
|
platform: "node",
|
|
86105
86098
|
mode: "backend",
|
|
86106
86099
|
instanceId
|
|
@@ -86111,7 +86104,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
|
|
|
86111
86104
|
commands: [],
|
|
86112
86105
|
permissions: {},
|
|
86113
86106
|
locale: Intl.DateTimeFormat().resolvedOptions().locale || "en-US",
|
|
86114
|
-
userAgent: `okx-a2a-node/${"0.0.
|
|
86107
|
+
userAgent: `okx-a2a-node/${"0.0.15-beta-1d2e01866f-260623014705"}`,
|
|
86115
86108
|
auth: {
|
|
86116
86109
|
...config.token ? { token: config.token } : {},
|
|
86117
86110
|
...config.password ? { password: config.password } : {}
|
|
@@ -89657,545 +89650,10 @@ function userWatchEventDeliveredSentryExtra(event) {
|
|
|
89657
89650
|
var environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
|
|
89658
89651
|
var SENTRY_CONFIG = {
|
|
89659
89652
|
projectName: "okx/openclaw-okx-a2a-extension",
|
|
89660
|
-
release: "0.0.
|
|
89653
|
+
release: "0.0.15-beta-1d2e01866f-260623014705",
|
|
89661
89654
|
environment
|
|
89662
89655
|
};
|
|
89663
89656
|
|
|
89664
|
-
// src/forced-update.ts
|
|
89665
|
-
var import_node_child_process7 = require("node:child_process");
|
|
89666
|
-
|
|
89667
|
-
// src/update-cli.ts
|
|
89668
|
-
var import_node_child_process6 = require("node:child_process");
|
|
89669
|
-
var import_promises6 = require("node:fs/promises");
|
|
89670
|
-
var import_node_os5 = require("node:os");
|
|
89671
|
-
var import_node_path17 = require("node:path");
|
|
89672
|
-
var UPDATE_PACKAGES = {
|
|
89673
|
-
node: "@okxweb3/a2a-node",
|
|
89674
|
-
openclaw: "@okxweb3/a2a-openclaw",
|
|
89675
|
-
hermes: "@okxweb3/a2a-hermes"
|
|
89676
|
-
};
|
|
89677
|
-
function isPrereleaseVersion(version2) {
|
|
89678
|
-
return /\d+\.\d+\.\d+-[0-9A-Za-z.-]+/.test(version2);
|
|
89679
|
-
}
|
|
89680
|
-
async function normalizeHermesOkxA2aPluginConfig(configFile = resolveHermesConfigPath()) {
|
|
89681
|
-
let content3;
|
|
89682
|
-
try {
|
|
89683
|
-
content3 = await (0, import_promises6.readFile)(configFile, "utf8");
|
|
89684
|
-
} catch (error) {
|
|
89685
|
-
if (isNodeError(error) && error.code === "ENOENT") {
|
|
89686
|
-
return false;
|
|
89687
|
-
}
|
|
89688
|
-
throw error;
|
|
89689
|
-
}
|
|
89690
|
-
const normalized = normalizeHermesPluginConfigContent(content3);
|
|
89691
|
-
if (!normalized.changed) {
|
|
89692
|
-
return false;
|
|
89693
|
-
}
|
|
89694
|
-
await (0, import_promises6.writeFile)(configFile, normalized.content);
|
|
89695
|
-
console.log(`[update] normalized Hermes plugins.enabled okx-a2a entry in ${configFile}`);
|
|
89696
|
-
return true;
|
|
89697
|
-
}
|
|
89698
|
-
function normalizeHermesPluginConfigContent(content3) {
|
|
89699
|
-
const trailingNewline = content3.endsWith("\n");
|
|
89700
|
-
const duplicateRepair = removeDuplicateInlineEnabledHeaders(content3.replace(/\n$/, "").split(/\n/));
|
|
89701
|
-
const lines = duplicateRepair.lines;
|
|
89702
|
-
let changed = duplicateRepair.changed;
|
|
89703
|
-
let hasOkxA2a = false;
|
|
89704
|
-
let inPlugins = false;
|
|
89705
|
-
let pluginsIndent = -1;
|
|
89706
|
-
let inEnabled = false;
|
|
89707
|
-
let enabledIndent = -1;
|
|
89708
|
-
let emittedOkxA2a = false;
|
|
89709
|
-
const output = [];
|
|
89710
|
-
for (const line of lines) {
|
|
89711
|
-
const currentIndent = lineIndent(line);
|
|
89712
|
-
const significant = line.trim() !== "" && !line.trimStart().startsWith("#");
|
|
89713
|
-
const parsedListValue = parseYamlListValue(line);
|
|
89714
|
-
if (inEnabled && significant && (currentIndent < enabledIndent || currentIndent === enabledIndent && !parsedListValue)) {
|
|
89715
|
-
inEnabled = false;
|
|
89716
|
-
emittedOkxA2a = false;
|
|
89717
|
-
}
|
|
89718
|
-
if (inPlugins && significant && currentIndent <= pluginsIndent && !isPluginsHeader(line)) {
|
|
89719
|
-
inPlugins = false;
|
|
89720
|
-
inEnabled = false;
|
|
89721
|
-
emittedOkxA2a = false;
|
|
89722
|
-
}
|
|
89723
|
-
if (isPluginsHeader(line)) {
|
|
89724
|
-
inPlugins = true;
|
|
89725
|
-
pluginsIndent = currentIndent;
|
|
89726
|
-
output.push(line);
|
|
89727
|
-
continue;
|
|
89728
|
-
}
|
|
89729
|
-
if (inPlugins && isEnabledHeader(line) && currentIndent > pluginsIndent) {
|
|
89730
|
-
inEnabled = true;
|
|
89731
|
-
enabledIndent = currentIndent;
|
|
89732
|
-
emittedOkxA2a = false;
|
|
89733
|
-
output.push(line);
|
|
89734
|
-
continue;
|
|
89735
|
-
}
|
|
89736
|
-
const inlineEnabled = inPlugins ? parseInlineEnabledList(line) : null;
|
|
89737
|
-
if (inlineEnabled && currentIndent > pluginsIndent) {
|
|
89738
|
-
const normalized = normalizeInlineEnabledList(inlineEnabled);
|
|
89739
|
-
output.push(...normalized.lines);
|
|
89740
|
-
changed ||= normalized.changed;
|
|
89741
|
-
hasOkxA2a ||= normalized.hasOkxA2a;
|
|
89742
|
-
continue;
|
|
89743
|
-
}
|
|
89744
|
-
if (inEnabled) {
|
|
89745
|
-
const parsed = parsedListValue;
|
|
89746
|
-
if (parsed && (parsed.value === "okx-a2a" || parsed.value === "platforms/okx-a2a")) {
|
|
89747
|
-
hasOkxA2a = true;
|
|
89748
|
-
if (!emittedOkxA2a) {
|
|
89749
|
-
const normalized = `${parsed.indent}- okx-a2a`;
|
|
89750
|
-
output.push(normalized);
|
|
89751
|
-
changed ||= normalized !== line;
|
|
89752
|
-
emittedOkxA2a = true;
|
|
89753
|
-
} else {
|
|
89754
|
-
changed = true;
|
|
89755
|
-
}
|
|
89756
|
-
continue;
|
|
89757
|
-
}
|
|
89758
|
-
}
|
|
89759
|
-
output.push(line);
|
|
89760
|
-
}
|
|
89761
|
-
return { content: `${output.join("\n")}${trailingNewline ? "\n" : ""}`, changed, hasOkxA2a };
|
|
89762
|
-
}
|
|
89763
|
-
function removeDuplicateInlineEnabledHeaders(lines) {
|
|
89764
|
-
let changed = false;
|
|
89765
|
-
let inPlugins = false;
|
|
89766
|
-
let pluginsIndent = -1;
|
|
89767
|
-
const output = [];
|
|
89768
|
-
for (let i = 0; i < lines.length; i++) {
|
|
89769
|
-
const line = lines[i];
|
|
89770
|
-
const currentIndent = lineIndent(line);
|
|
89771
|
-
const significant = line.trim() !== "" && !line.trimStart().startsWith("#");
|
|
89772
|
-
if (inPlugins && significant && currentIndent <= pluginsIndent && !isPluginsHeader(line)) {
|
|
89773
|
-
inPlugins = false;
|
|
89774
|
-
}
|
|
89775
|
-
if (isPluginsHeader(line)) {
|
|
89776
|
-
inPlugins = true;
|
|
89777
|
-
pluginsIndent = currentIndent;
|
|
89778
|
-
output.push(line);
|
|
89779
|
-
continue;
|
|
89780
|
-
}
|
|
89781
|
-
if (inPlugins && isEmptyInlineEnabledList(line) && hasLaterEnabledHeaderInPlugins(lines, i + 1, pluginsIndent)) {
|
|
89782
|
-
changed = true;
|
|
89783
|
-
continue;
|
|
89784
|
-
}
|
|
89785
|
-
output.push(line);
|
|
89786
|
-
}
|
|
89787
|
-
return { lines: output, changed };
|
|
89788
|
-
}
|
|
89789
|
-
function hasLaterEnabledHeaderInPlugins(lines, startIndex, pluginsIndent) {
|
|
89790
|
-
for (let i = startIndex; i < lines.length; i++) {
|
|
89791
|
-
const line = lines[i];
|
|
89792
|
-
const significant = line.trim() !== "" && !line.trimStart().startsWith("#");
|
|
89793
|
-
if (significant && lineIndent(line) <= pluginsIndent) {
|
|
89794
|
-
return false;
|
|
89795
|
-
}
|
|
89796
|
-
if (isEnabledHeader(line) || parseInlineEnabledList(line)) {
|
|
89797
|
-
return true;
|
|
89798
|
-
}
|
|
89799
|
-
}
|
|
89800
|
-
return false;
|
|
89801
|
-
}
|
|
89802
|
-
function isEmptyInlineEnabledList(line) {
|
|
89803
|
-
const inline = parseInlineEnabledList(line);
|
|
89804
|
-
return !!inline && inline.values.length === 0;
|
|
89805
|
-
}
|
|
89806
|
-
function resolveHermesConfigPath() {
|
|
89807
|
-
return (0, import_node_path17.join)(process.env.HERMES_HOME ?? (0, import_node_path17.join)((0, import_node_os5.homedir)(), ".hermes"), "config.yaml");
|
|
89808
|
-
}
|
|
89809
|
-
function lineIndent(line) {
|
|
89810
|
-
const match = line.match(/^\s*/);
|
|
89811
|
-
return match?.[0].length ?? 0;
|
|
89812
|
-
}
|
|
89813
|
-
function isPluginsHeader(line) {
|
|
89814
|
-
return /^[\s]*plugins:[\s]*(?:#.*)?$/.test(line);
|
|
89815
|
-
}
|
|
89816
|
-
function isEnabledHeader(line) {
|
|
89817
|
-
return /^[\s]*enabled:[\s]*(?:#.*)?$/.test(line);
|
|
89818
|
-
}
|
|
89819
|
-
function parseInlineEnabledList(line) {
|
|
89820
|
-
const match = line.match(/^(\s*)enabled:\s*\[(.*)\]\s*(?:#.*)?$/);
|
|
89821
|
-
if (!match) {
|
|
89822
|
-
return null;
|
|
89823
|
-
}
|
|
89824
|
-
const values = (match[2] ?? "").split(",").map((value) => value.trim().replace(/^["']|["']$/g, "")).filter(Boolean);
|
|
89825
|
-
return { indent: match[1] ?? "", values };
|
|
89826
|
-
}
|
|
89827
|
-
function normalizeInlineEnabledList(input) {
|
|
89828
|
-
let hasOkxA2a = false;
|
|
89829
|
-
const values = [];
|
|
89830
|
-
for (const value of input.values) {
|
|
89831
|
-
if (value === "okx-a2a" || value === "platforms/okx-a2a") {
|
|
89832
|
-
hasOkxA2a = true;
|
|
89833
|
-
if (!values.includes("okx-a2a")) {
|
|
89834
|
-
values.push("okx-a2a");
|
|
89835
|
-
}
|
|
89836
|
-
continue;
|
|
89837
|
-
}
|
|
89838
|
-
values.push(value);
|
|
89839
|
-
}
|
|
89840
|
-
return {
|
|
89841
|
-
lines: values.length > 0 ? [`${input.indent}enabled:`, ...values.map((value) => `${input.indent} - ${value}`)] : [`${input.indent}enabled: []`],
|
|
89842
|
-
changed: hasOkxA2a,
|
|
89843
|
-
hasOkxA2a
|
|
89844
|
-
};
|
|
89845
|
-
}
|
|
89846
|
-
function parseYamlListValue(line) {
|
|
89847
|
-
const match = line.match(/^(\s*)-\s*(?:"([^"]*)"|'([^']*)'|([^#\s]+))(?:\s*(?:#.*)?)?$/);
|
|
89848
|
-
if (!match) {
|
|
89849
|
-
return null;
|
|
89850
|
-
}
|
|
89851
|
-
return {
|
|
89852
|
-
indent: match[1] ?? "",
|
|
89853
|
-
value: match[2] ?? match[3] ?? match[4] ?? ""
|
|
89854
|
-
};
|
|
89855
|
-
}
|
|
89856
|
-
function isNodeError(error) {
|
|
89857
|
-
return error instanceof Error && "code" in error;
|
|
89858
|
-
}
|
|
89859
|
-
async function getInstalledGatewayPluginVersion(target) {
|
|
89860
|
-
if (target === "hermes") {
|
|
89861
|
-
return await getInstalledHermesPluginVersion() ?? await getGlobalNpmPackageVersion(UPDATE_PACKAGES.hermes);
|
|
89862
|
-
}
|
|
89863
|
-
return (await getInstalledOpenClawPluginInfo()).version;
|
|
89864
|
-
}
|
|
89865
|
-
async function getInstalledOpenClawPluginInfo() {
|
|
89866
|
-
let result = await runCommandCaptureOptional("openclaw", ["plugins", "list", "--json"]);
|
|
89867
|
-
if (!result.ok) {
|
|
89868
|
-
result = await runCommandCaptureOptional("openclaw", ["plugins", "list"]);
|
|
89869
|
-
}
|
|
89870
|
-
if (!result.ok) {
|
|
89871
|
-
return { installed: false, version: null };
|
|
89872
|
-
}
|
|
89873
|
-
return parseOpenClawPluginList(result.stdout);
|
|
89874
|
-
}
|
|
89875
|
-
function parseOpenClawPluginList(output) {
|
|
89876
|
-
if (!output.trim()) {
|
|
89877
|
-
return { installed: false, version: null };
|
|
89878
|
-
}
|
|
89879
|
-
try {
|
|
89880
|
-
return findOpenClawPluginInJson(JSON.parse(output));
|
|
89881
|
-
} catch {
|
|
89882
|
-
return {
|
|
89883
|
-
installed: output.includes(UPDATE_PACKAGES.openclaw) || /(^|[\s@/])okx-a2a($|[\s@])/.test(output),
|
|
89884
|
-
version: parsePackageVersionFromText(output)
|
|
89885
|
-
};
|
|
89886
|
-
}
|
|
89887
|
-
}
|
|
89888
|
-
function findOpenClawPluginInJson(value) {
|
|
89889
|
-
if (Array.isArray(value)) {
|
|
89890
|
-
for (const item of value) {
|
|
89891
|
-
const found = findOpenClawPluginInJson(item);
|
|
89892
|
-
if (found.installed) {
|
|
89893
|
-
return found;
|
|
89894
|
-
}
|
|
89895
|
-
}
|
|
89896
|
-
return { installed: false, version: null };
|
|
89897
|
-
}
|
|
89898
|
-
if (!value || typeof value !== "object") {
|
|
89899
|
-
return { installed: false, version: null };
|
|
89900
|
-
}
|
|
89901
|
-
const record = value;
|
|
89902
|
-
if (isOpenClawPluginRecord(record)) {
|
|
89903
|
-
return { installed: true, version: readVersionField(record) };
|
|
89904
|
-
}
|
|
89905
|
-
const dependencies = record.dependencies;
|
|
89906
|
-
if (dependencies && typeof dependencies === "object") {
|
|
89907
|
-
const dependency = dependencies[UPDATE_PACKAGES.openclaw] ?? dependencies["okx-a2a"];
|
|
89908
|
-
if (dependency && typeof dependency === "object") {
|
|
89909
|
-
return { installed: true, version: readVersionField(dependency) };
|
|
89910
|
-
}
|
|
89911
|
-
}
|
|
89912
|
-
for (const key of ["plugins", "items", "data", "installed"]) {
|
|
89913
|
-
const child = record[key];
|
|
89914
|
-
if (child !== void 0) {
|
|
89915
|
-
const found = findOpenClawPluginInJson(child);
|
|
89916
|
-
if (found.installed) {
|
|
89917
|
-
return found;
|
|
89918
|
-
}
|
|
89919
|
-
}
|
|
89920
|
-
}
|
|
89921
|
-
return { installed: false, version: null };
|
|
89922
|
-
}
|
|
89923
|
-
function isOpenClawPluginRecord(record) {
|
|
89924
|
-
return Object.values(record).some((value) => {
|
|
89925
|
-
if (typeof value !== "string") {
|
|
89926
|
-
return false;
|
|
89927
|
-
}
|
|
89928
|
-
return value === "okx-a2a" || value === UPDATE_PACKAGES.openclaw || value.endsWith("/okx-a2a");
|
|
89929
|
-
});
|
|
89930
|
-
}
|
|
89931
|
-
function readVersionField(record) {
|
|
89932
|
-
for (const key of ["version", "installedVersion", "packageVersion"]) {
|
|
89933
|
-
const value = record[key];
|
|
89934
|
-
if (typeof value === "string" && value.trim()) {
|
|
89935
|
-
return value.trim();
|
|
89936
|
-
}
|
|
89937
|
-
}
|
|
89938
|
-
return null;
|
|
89939
|
-
}
|
|
89940
|
-
function parsePackageVersionFromText(output) {
|
|
89941
|
-
return output.match(/@okxweb3\/a2a-openclaw@([0-9A-Za-z.+-]+)/)?.[1] ?? null;
|
|
89942
|
-
}
|
|
89943
|
-
async function getInstalledHermesPluginVersion() {
|
|
89944
|
-
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");
|
|
89945
|
-
try {
|
|
89946
|
-
const content3 = await (0, import_promises6.readFile)(pluginYaml, "utf8");
|
|
89947
|
-
return parsePluginYamlVersion(content3);
|
|
89948
|
-
} catch (error) {
|
|
89949
|
-
if (isNodeError(error) && error.code === "ENOENT") {
|
|
89950
|
-
return null;
|
|
89951
|
-
}
|
|
89952
|
-
throw error;
|
|
89953
|
-
}
|
|
89954
|
-
}
|
|
89955
|
-
function parsePluginYamlVersion(content3) {
|
|
89956
|
-
for (const line of content3.split(/\r?\n/)) {
|
|
89957
|
-
const match = line.match(/^\s*version:\s*(?:"([^"]+)"|'([^']+)'|([^#\s]+))/);
|
|
89958
|
-
if (match) {
|
|
89959
|
-
return match[1] ?? match[2] ?? match[3] ?? null;
|
|
89960
|
-
}
|
|
89961
|
-
}
|
|
89962
|
-
return null;
|
|
89963
|
-
}
|
|
89964
|
-
async function getGlobalNpmPackageVersion(packageName) {
|
|
89965
|
-
const result = await runCommandCaptureOptional("npm", ["list", "-g", packageName, "--depth=0", "--json"]);
|
|
89966
|
-
if (!result.ok) {
|
|
89967
|
-
return null;
|
|
89968
|
-
}
|
|
89969
|
-
try {
|
|
89970
|
-
const parsed = JSON.parse(result.stdout);
|
|
89971
|
-
return parsed.dependencies?.[packageName]?.version ?? null;
|
|
89972
|
-
} catch {
|
|
89973
|
-
return null;
|
|
89974
|
-
}
|
|
89975
|
-
}
|
|
89976
|
-
async function runCommandCaptureOptional(command, args) {
|
|
89977
|
-
return await new Promise((resolvePromise) => {
|
|
89978
|
-
const child = (0, import_node_child_process6.spawn)(command, args, { stdio: ["ignore", "pipe", "ignore"] });
|
|
89979
|
-
let stdout = "";
|
|
89980
|
-
child.stdout.setEncoding("utf8");
|
|
89981
|
-
child.stdout.on("data", (chunk) => {
|
|
89982
|
-
stdout += chunk;
|
|
89983
|
-
});
|
|
89984
|
-
child.on("error", () => {
|
|
89985
|
-
resolvePromise({ ok: false, stdout });
|
|
89986
|
-
});
|
|
89987
|
-
child.on("close", (code2) => {
|
|
89988
|
-
resolvePromise({ ok: code2 === 0, stdout });
|
|
89989
|
-
});
|
|
89990
|
-
});
|
|
89991
|
-
}
|
|
89992
|
-
|
|
89993
|
-
// src/forced-update.ts
|
|
89994
|
-
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-]+)*)?$/;
|
|
89995
|
-
function normalizeSemverInput2(value) {
|
|
89996
|
-
return value.trim().replace(/^v/, "");
|
|
89997
|
-
}
|
|
89998
|
-
function parseSemver2(value) {
|
|
89999
|
-
const match = SEMVER_RE2.exec(normalizeSemverInput2(value));
|
|
90000
|
-
if (!match) {
|
|
90001
|
-
return null;
|
|
90002
|
-
}
|
|
90003
|
-
return {
|
|
90004
|
-
major: Number(match[1]),
|
|
90005
|
-
minor: Number(match[2]),
|
|
90006
|
-
patch: Number(match[3]),
|
|
90007
|
-
prerelease: match[4] ? match[4].split(".") : []
|
|
90008
|
-
};
|
|
90009
|
-
}
|
|
90010
|
-
function comparePrereleaseId2(a, b) {
|
|
90011
|
-
const aIsNumber = /^\d+$/.test(a);
|
|
90012
|
-
const bIsNumber = /^\d+$/.test(b);
|
|
90013
|
-
if (aIsNumber && bIsNumber) {
|
|
90014
|
-
const an = Number(a);
|
|
90015
|
-
const bn = Number(b);
|
|
90016
|
-
return an < bn ? -1 : an > bn ? 1 : 0;
|
|
90017
|
-
}
|
|
90018
|
-
if (aIsNumber) {
|
|
90019
|
-
return -1;
|
|
90020
|
-
}
|
|
90021
|
-
if (bIsNumber) {
|
|
90022
|
-
return 1;
|
|
90023
|
-
}
|
|
90024
|
-
return a < b ? -1 : a > b ? 1 : 0;
|
|
90025
|
-
}
|
|
90026
|
-
function compareSemver2(a, b) {
|
|
90027
|
-
if (a.major !== b.major) {
|
|
90028
|
-
return a.major < b.major ? -1 : 1;
|
|
90029
|
-
}
|
|
90030
|
-
if (a.minor !== b.minor) {
|
|
90031
|
-
return a.minor < b.minor ? -1 : 1;
|
|
90032
|
-
}
|
|
90033
|
-
if (a.patch !== b.patch) {
|
|
90034
|
-
return a.patch < b.patch ? -1 : 1;
|
|
90035
|
-
}
|
|
90036
|
-
if (a.prerelease.length === 0 && b.prerelease.length === 0) {
|
|
90037
|
-
return 0;
|
|
90038
|
-
}
|
|
90039
|
-
if (a.prerelease.length === 0) {
|
|
90040
|
-
return 1;
|
|
90041
|
-
}
|
|
90042
|
-
if (b.prerelease.length === 0) {
|
|
90043
|
-
return -1;
|
|
90044
|
-
}
|
|
90045
|
-
const len = Math.min(a.prerelease.length, b.prerelease.length);
|
|
90046
|
-
for (let i = 0; i < len; i++) {
|
|
90047
|
-
const diff = comparePrereleaseId2(a.prerelease[i], b.prerelease[i]);
|
|
90048
|
-
if (diff !== 0) {
|
|
90049
|
-
return diff;
|
|
90050
|
-
}
|
|
90051
|
-
}
|
|
90052
|
-
if (a.prerelease.length !== b.prerelease.length) {
|
|
90053
|
-
return a.prerelease.length < b.prerelease.length ? -1 : 1;
|
|
90054
|
-
}
|
|
90055
|
-
return 0;
|
|
90056
|
-
}
|
|
90057
|
-
function isBelowRequiredVersion(currentVersion, minVersion) {
|
|
90058
|
-
const min = minVersion?.trim();
|
|
90059
|
-
if (!min) {
|
|
90060
|
-
return false;
|
|
90061
|
-
}
|
|
90062
|
-
const parsedMin = parseSemver2(min);
|
|
90063
|
-
if (!parsedMin) {
|
|
90064
|
-
logWithTimestamp(`[okx-agent-task] ignoring invalid forced minVersion=${min}`);
|
|
90065
|
-
return false;
|
|
90066
|
-
}
|
|
90067
|
-
const current = currentVersion?.trim();
|
|
90068
|
-
if (!current) {
|
|
90069
|
-
return true;
|
|
90070
|
-
}
|
|
90071
|
-
const parsedCurrent = parseSemver2(current);
|
|
90072
|
-
if (!parsedCurrent) {
|
|
90073
|
-
logWithTimestamp(`[okx-agent-task] current version is invalid, forcing update current=${current} min=${min}`);
|
|
90074
|
-
return true;
|
|
90075
|
-
}
|
|
90076
|
-
return compareSemver2(parsedCurrent, parsedMin) < 0;
|
|
90077
|
-
}
|
|
90078
|
-
async function ensureCommunicationMinVersions(input) {
|
|
90079
|
-
const runUpdate = input.runUpdate ?? runOkxA2aForcedUpdate;
|
|
90080
|
-
const cliMinVersion = input.systemConfig.minVersion.cli;
|
|
90081
|
-
const currentCliVersion = input.currentCliVersion ?? "0.0.14";
|
|
90082
|
-
if (isBelowRequiredVersion(currentCliVersion, cliMinVersion)) {
|
|
90083
|
-
await forceUpdate({
|
|
90084
|
-
target: "cli",
|
|
90085
|
-
currentVersion: currentCliVersion,
|
|
90086
|
-
minVersion: cliMinVersion,
|
|
90087
|
-
stage: input.stage,
|
|
90088
|
-
runUpdate
|
|
90089
|
-
});
|
|
90090
|
-
return { updated: true, target: "cli", currentVersion: currentCliVersion, minVersion: cliMinVersion };
|
|
90091
|
-
}
|
|
90092
|
-
const provider = resolveConfiguredAiProvider({ store: input.sessionStore, env: input.env });
|
|
90093
|
-
const gatewayTarget = providerToGatewayTarget(provider);
|
|
90094
|
-
if (!gatewayTarget) {
|
|
90095
|
-
logWithTimestamp(`[okx-agent-task] forced minVersion gateway check skipped provider=${provider ?? "(not set)"}`);
|
|
90096
|
-
return { updated: false };
|
|
90097
|
-
}
|
|
90098
|
-
const minVersion = input.systemConfig.minVersion[gatewayTarget];
|
|
90099
|
-
if (!minVersion) {
|
|
90100
|
-
return { updated: false, target: gatewayTarget };
|
|
90101
|
-
}
|
|
90102
|
-
const getGatewayVersion = input.getGatewayVersion ?? getInstalledGatewayPluginVersion;
|
|
90103
|
-
const currentVersion = await getGatewayVersion(gatewayTarget);
|
|
90104
|
-
if (!isBelowRequiredVersion(currentVersion, minVersion)) {
|
|
90105
|
-
return { updated: false, target: gatewayTarget, currentVersion, minVersion };
|
|
90106
|
-
}
|
|
90107
|
-
await forceUpdate({
|
|
90108
|
-
target: gatewayTarget,
|
|
90109
|
-
currentVersion,
|
|
90110
|
-
minVersion,
|
|
90111
|
-
stage: input.stage,
|
|
90112
|
-
runUpdate
|
|
90113
|
-
});
|
|
90114
|
-
return { updated: true, target: gatewayTarget, currentVersion, minVersion };
|
|
90115
|
-
}
|
|
90116
|
-
function providerToGatewayTarget(provider) {
|
|
90117
|
-
return provider === "openclaw" || provider === "hermes" ? provider : null;
|
|
90118
|
-
}
|
|
90119
|
-
async function forceUpdate(input) {
|
|
90120
|
-
const startedAt = Date.now();
|
|
90121
|
-
logWithTimestamp(
|
|
90122
|
-
`[okx-agent-task] forced update required target=${input.target} current=${input.currentVersion ?? "(unknown)"} min=${input.minVersion} stage=${input.stage}`
|
|
90123
|
-
);
|
|
90124
|
-
logger.info(LogEvent.FORCED_UPDATE_STARTED, forcedUpdateSentryExtra(input, startedAt, {
|
|
90125
|
-
status: "started",
|
|
90126
|
-
reason: "forced_update_required"
|
|
90127
|
-
}));
|
|
90128
|
-
try {
|
|
90129
|
-
await input.runUpdate(input.target);
|
|
90130
|
-
logger.info(LogEvent.FORCED_UPDATE_SUCCEEDED, forcedUpdateSentryExtra(input, startedAt, {
|
|
90131
|
-
status: "succeeded",
|
|
90132
|
-
reason: "update_completed"
|
|
90133
|
-
}));
|
|
90134
|
-
} catch (err2) {
|
|
90135
|
-
const error = err2 instanceof Error ? err2 : new Error(String(err2));
|
|
90136
|
-
logger.error(LogEvent.FORCED_UPDATE_FAILED, error, forcedUpdateSentryExtra(input, startedAt, {
|
|
90137
|
-
status: "failed",
|
|
90138
|
-
reason: "update_failed",
|
|
90139
|
-
errorName: error.name,
|
|
90140
|
-
errorMessage: error.message,
|
|
90141
|
-
errorStack: error.stack ?? "",
|
|
90142
|
-
...forcedUpdateErrorDetails(err2)
|
|
90143
|
-
}));
|
|
90144
|
-
throw err2;
|
|
90145
|
-
}
|
|
90146
|
-
}
|
|
90147
|
-
function forcedUpdateSentryExtra(input, startedAt, extra) {
|
|
90148
|
-
return {
|
|
90149
|
-
component: "node_listener",
|
|
90150
|
-
stage: input.stage,
|
|
90151
|
-
updateTarget: input.target,
|
|
90152
|
-
currentVersion: input.currentVersion ?? "",
|
|
90153
|
-
minVersion: input.minVersion,
|
|
90154
|
-
durationMs: String(Date.now() - startedAt),
|
|
90155
|
-
...extra
|
|
90156
|
-
};
|
|
90157
|
-
}
|
|
90158
|
-
function forcedUpdateErrorDetails(err2) {
|
|
90159
|
-
if (!err2 || typeof err2 !== "object") {
|
|
90160
|
-
return {};
|
|
90161
|
-
}
|
|
90162
|
-
const record = err2;
|
|
90163
|
-
return {
|
|
90164
|
-
exitCode: record.exitCode ?? record.code ?? "",
|
|
90165
|
-
signal: record.signal ?? ""
|
|
90166
|
-
};
|
|
90167
|
-
}
|
|
90168
|
-
function runOkxA2aForcedUpdate(target) {
|
|
90169
|
-
const args = [
|
|
90170
|
-
"update",
|
|
90171
|
-
...target === "cli" ? [] : [target],
|
|
90172
|
-
"--release",
|
|
90173
|
-
"latest",
|
|
90174
|
-
"--restart",
|
|
90175
|
-
"--yes"
|
|
90176
|
-
];
|
|
90177
|
-
return new Promise((resolvePromise, reject) => {
|
|
90178
|
-
const child = (0, import_node_child_process7.spawn)("okx-a2a", args, {
|
|
90179
|
-
stdio: "inherit",
|
|
90180
|
-
env: {
|
|
90181
|
-
...process.env,
|
|
90182
|
-
OKX_A2A_FORCED_UPDATE_TARGET: target
|
|
90183
|
-
}
|
|
90184
|
-
});
|
|
90185
|
-
child.on("error", reject);
|
|
90186
|
-
child.on("close", (code2, signal) => {
|
|
90187
|
-
if (code2 === 0) {
|
|
90188
|
-
resolvePromise();
|
|
90189
|
-
return;
|
|
90190
|
-
}
|
|
90191
|
-
reject(Object.assign(
|
|
90192
|
-
new Error(`okx-a2a ${args.join(" ")} failed with ${signal ? `signal=${signal}` : `code=${code2}`}`),
|
|
90193
|
-
{ exitCode: code2, signal }
|
|
90194
|
-
));
|
|
90195
|
-
});
|
|
90196
|
-
});
|
|
90197
|
-
}
|
|
90198
|
-
|
|
90199
89657
|
// src/listener.ts
|
|
90200
89658
|
var OFFLINE_REPLAY_SYNC_INTERVAL = 5;
|
|
90201
89659
|
function shouldRunOfflineReplay(syncCount, interval = OFFLINE_REPLAY_SYNC_INTERVAL) {
|
|
@@ -90313,23 +89771,13 @@ async function runListenerWithLock(options, paths) {
|
|
|
90313
89771
|
}));
|
|
90314
89772
|
}
|
|
90315
89773
|
});
|
|
90316
|
-
service.
|
|
89774
|
+
service.setPluginVersion("0.0.15-beta-1d2e01866f-260623014705");
|
|
90317
89775
|
await service.init();
|
|
90318
|
-
const
|
|
90319
|
-
|
|
90320
|
-
|
|
90321
|
-
|
|
90322
|
-
});
|
|
90323
|
-
if (startupVersionCheck.updated) {
|
|
90324
|
-
logWithTimestamp(
|
|
90325
|
-
`[okx-agent-task] forced update executed during startup target=${startupVersionCheck.target}; exiting current listener so restarted daemon can take over`
|
|
89776
|
+
const pluginVersionStatus = service.pluginVersionStatus;
|
|
89777
|
+
if (pluginVersionStatus.unavailable) {
|
|
89778
|
+
throw new Error(
|
|
89779
|
+
`@okxweb3/a2a-node v${"0.0.15-beta-1d2e01866f-260623014705"} is below the required minimum v${pluginVersionStatus.minVersion}`
|
|
90326
89780
|
);
|
|
90327
|
-
await watcherCoordinator.stop();
|
|
90328
|
-
await userAttentionEvents?.close();
|
|
90329
|
-
stopClients(service);
|
|
90330
|
-
sessionStore.close();
|
|
90331
|
-
commands.close();
|
|
90332
|
-
return;
|
|
90333
89781
|
}
|
|
90334
89782
|
const systemConfig = service.getSystemConfig();
|
|
90335
89783
|
if (systemConfig.sentryDsn) {
|
|
@@ -90346,7 +89794,7 @@ async function runListenerWithLock(options, paths) {
|
|
|
90346
89794
|
onchainosAgentId: "*",
|
|
90347
89795
|
reason: "system-config missing sentryDsn",
|
|
90348
89796
|
pluginId: "@okxweb3/a2a-node",
|
|
90349
|
-
pluginVersion: "0.0.
|
|
89797
|
+
pluginVersion: "0.0.15-beta-1d2e01866f-260623014705"
|
|
90350
89798
|
});
|
|
90351
89799
|
}
|
|
90352
89800
|
logWithTimestamp(
|
|
@@ -90438,18 +89886,6 @@ async function runListenerWithLock(options, paths) {
|
|
|
90438
89886
|
if (stopping) {
|
|
90439
89887
|
return;
|
|
90440
89888
|
}
|
|
90441
|
-
const versionCheck = await ensureCommunicationMinVersions({
|
|
90442
|
-
systemConfig: service.getSystemConfig(),
|
|
90443
|
-
sessionStore,
|
|
90444
|
-
stage: "system_config_refresh"
|
|
90445
|
-
});
|
|
90446
|
-
if (versionCheck.updated) {
|
|
90447
|
-
logWithTimestamp(
|
|
90448
|
-
`[okx-agent-task] forced update executed after system-config refresh target=${versionCheck.target}; stopping current listener`
|
|
90449
|
-
);
|
|
90450
|
-
process.kill(process.pid, "SIGTERM");
|
|
90451
|
-
return;
|
|
90452
|
-
}
|
|
90453
89889
|
const nextIntervalSec = Math.max(10, service.getSystemConfig().heartbeatInterval);
|
|
90454
89890
|
if (nextIntervalSec !== previousIntervalSec) {
|
|
90455
89891
|
logWithTimestamp(
|
|
@@ -90524,6 +89960,202 @@ async function timeSettled(fn) {
|
|
|
90524
89960
|
return { durationMs: Date.now() - startedAt, error };
|
|
90525
89961
|
}
|
|
90526
89962
|
}
|
|
89963
|
+
|
|
89964
|
+
// src/update-cli.ts
|
|
89965
|
+
var import_promises6 = require("node:fs/promises");
|
|
89966
|
+
var import_node_os5 = require("node:os");
|
|
89967
|
+
var import_node_path17 = require("node:path");
|
|
89968
|
+
function isPrereleaseVersion(version2) {
|
|
89969
|
+
return /\d+\.\d+\.\d+-[0-9A-Za-z.-]+/.test(version2);
|
|
89970
|
+
}
|
|
89971
|
+
async function normalizeHermesOkxA2aPluginConfig(configFile = resolveHermesConfigPath()) {
|
|
89972
|
+
let content3;
|
|
89973
|
+
try {
|
|
89974
|
+
content3 = await (0, import_promises6.readFile)(configFile, "utf8");
|
|
89975
|
+
} catch (error) {
|
|
89976
|
+
if (isNodeError(error) && error.code === "ENOENT") {
|
|
89977
|
+
return false;
|
|
89978
|
+
}
|
|
89979
|
+
throw error;
|
|
89980
|
+
}
|
|
89981
|
+
const normalized = normalizeHermesPluginConfigContent(content3);
|
|
89982
|
+
if (!normalized.changed) {
|
|
89983
|
+
return false;
|
|
89984
|
+
}
|
|
89985
|
+
await (0, import_promises6.writeFile)(configFile, normalized.content);
|
|
89986
|
+
console.log(`[update] normalized Hermes plugins.enabled okx-a2a entry in ${configFile}`);
|
|
89987
|
+
return true;
|
|
89988
|
+
}
|
|
89989
|
+
function normalizeHermesPluginConfigContent(content3) {
|
|
89990
|
+
const trailingNewline = content3.endsWith("\n");
|
|
89991
|
+
const duplicateRepair = removeDuplicateInlineEnabledHeaders(content3.replace(/\n$/, "").split(/\n/));
|
|
89992
|
+
const lines = duplicateRepair.lines;
|
|
89993
|
+
let changed = duplicateRepair.changed;
|
|
89994
|
+
let hasOkxA2a = false;
|
|
89995
|
+
let inPlugins = false;
|
|
89996
|
+
let pluginsIndent = -1;
|
|
89997
|
+
let inEnabled = false;
|
|
89998
|
+
let enabledIndent = -1;
|
|
89999
|
+
let emittedOkxA2a = false;
|
|
90000
|
+
const output = [];
|
|
90001
|
+
for (const line of lines) {
|
|
90002
|
+
const currentIndent = lineIndent(line);
|
|
90003
|
+
const significant = line.trim() !== "" && !line.trimStart().startsWith("#");
|
|
90004
|
+
const parsedListValue = parseYamlListValue(line);
|
|
90005
|
+
if (inEnabled && significant && (currentIndent < enabledIndent || currentIndent === enabledIndent && !parsedListValue)) {
|
|
90006
|
+
inEnabled = false;
|
|
90007
|
+
emittedOkxA2a = false;
|
|
90008
|
+
}
|
|
90009
|
+
if (inPlugins && significant && currentIndent <= pluginsIndent && !isPluginsHeader(line)) {
|
|
90010
|
+
inPlugins = false;
|
|
90011
|
+
inEnabled = false;
|
|
90012
|
+
emittedOkxA2a = false;
|
|
90013
|
+
}
|
|
90014
|
+
if (isPluginsHeader(line)) {
|
|
90015
|
+
inPlugins = true;
|
|
90016
|
+
pluginsIndent = currentIndent;
|
|
90017
|
+
output.push(line);
|
|
90018
|
+
continue;
|
|
90019
|
+
}
|
|
90020
|
+
if (inPlugins && isEnabledHeader(line) && currentIndent > pluginsIndent) {
|
|
90021
|
+
inEnabled = true;
|
|
90022
|
+
enabledIndent = currentIndent;
|
|
90023
|
+
emittedOkxA2a = false;
|
|
90024
|
+
output.push(line);
|
|
90025
|
+
continue;
|
|
90026
|
+
}
|
|
90027
|
+
const inlineEnabled = inPlugins ? parseInlineEnabledList(line) : null;
|
|
90028
|
+
if (inlineEnabled && currentIndent > pluginsIndent) {
|
|
90029
|
+
const normalized = normalizeInlineEnabledList(inlineEnabled);
|
|
90030
|
+
output.push(...normalized.lines);
|
|
90031
|
+
changed ||= normalized.changed;
|
|
90032
|
+
hasOkxA2a ||= normalized.hasOkxA2a;
|
|
90033
|
+
continue;
|
|
90034
|
+
}
|
|
90035
|
+
if (inEnabled) {
|
|
90036
|
+
const parsed = parsedListValue;
|
|
90037
|
+
if (parsed && (parsed.value === "okx-a2a" || parsed.value === "platforms/okx-a2a")) {
|
|
90038
|
+
hasOkxA2a = true;
|
|
90039
|
+
if (!emittedOkxA2a) {
|
|
90040
|
+
const normalized = `${parsed.indent}- okx-a2a`;
|
|
90041
|
+
output.push(normalized);
|
|
90042
|
+
changed ||= normalized !== line;
|
|
90043
|
+
emittedOkxA2a = true;
|
|
90044
|
+
} else {
|
|
90045
|
+
changed = true;
|
|
90046
|
+
}
|
|
90047
|
+
continue;
|
|
90048
|
+
}
|
|
90049
|
+
}
|
|
90050
|
+
output.push(line);
|
|
90051
|
+
}
|
|
90052
|
+
return { content: `${output.join("\n")}${trailingNewline ? "\n" : ""}`, changed, hasOkxA2a };
|
|
90053
|
+
}
|
|
90054
|
+
function removeDuplicateInlineEnabledHeaders(lines) {
|
|
90055
|
+
let changed = false;
|
|
90056
|
+
let inPlugins = false;
|
|
90057
|
+
let pluginsIndent = -1;
|
|
90058
|
+
const output = [];
|
|
90059
|
+
for (let i = 0; i < lines.length; i++) {
|
|
90060
|
+
const line = lines[i];
|
|
90061
|
+
const currentIndent = lineIndent(line);
|
|
90062
|
+
const significant = line.trim() !== "" && !line.trimStart().startsWith("#");
|
|
90063
|
+
if (inPlugins && significant && currentIndent <= pluginsIndent && !isPluginsHeader(line)) {
|
|
90064
|
+
inPlugins = false;
|
|
90065
|
+
}
|
|
90066
|
+
if (isPluginsHeader(line)) {
|
|
90067
|
+
inPlugins = true;
|
|
90068
|
+
pluginsIndent = currentIndent;
|
|
90069
|
+
output.push(line);
|
|
90070
|
+
continue;
|
|
90071
|
+
}
|
|
90072
|
+
if (inPlugins && isEmptyInlineEnabledList(line) && hasLaterEnabledHeaderInPlugins(lines, i + 1, pluginsIndent)) {
|
|
90073
|
+
changed = true;
|
|
90074
|
+
continue;
|
|
90075
|
+
}
|
|
90076
|
+
output.push(line);
|
|
90077
|
+
}
|
|
90078
|
+
return { lines: output, changed };
|
|
90079
|
+
}
|
|
90080
|
+
function hasLaterEnabledHeaderInPlugins(lines, startIndex, pluginsIndent) {
|
|
90081
|
+
for (let i = startIndex; i < lines.length; i++) {
|
|
90082
|
+
const line = lines[i];
|
|
90083
|
+
const significant = line.trim() !== "" && !line.trimStart().startsWith("#");
|
|
90084
|
+
if (significant && lineIndent(line) <= pluginsIndent) {
|
|
90085
|
+
return false;
|
|
90086
|
+
}
|
|
90087
|
+
if (isEnabledHeader(line) || parseInlineEnabledList(line)) {
|
|
90088
|
+
return true;
|
|
90089
|
+
}
|
|
90090
|
+
}
|
|
90091
|
+
return false;
|
|
90092
|
+
}
|
|
90093
|
+
function isEmptyInlineEnabledList(line) {
|
|
90094
|
+
const inline = parseInlineEnabledList(line);
|
|
90095
|
+
return !!inline && inline.values.length === 0;
|
|
90096
|
+
}
|
|
90097
|
+
function resolveHermesConfigPath() {
|
|
90098
|
+
return (0, import_node_path17.join)(process.env.HERMES_HOME ?? (0, import_node_path17.join)((0, import_node_os5.homedir)(), ".hermes"), "config.yaml");
|
|
90099
|
+
}
|
|
90100
|
+
function lineIndent(line) {
|
|
90101
|
+
const match = line.match(/^\s*/);
|
|
90102
|
+
return match?.[0].length ?? 0;
|
|
90103
|
+
}
|
|
90104
|
+
function isPluginsHeader(line) {
|
|
90105
|
+
return /^[\s]*plugins:[\s]*(?:#.*)?$/.test(line);
|
|
90106
|
+
}
|
|
90107
|
+
function isEnabledHeader(line) {
|
|
90108
|
+
return /^[\s]*enabled:[\s]*(?:#.*)?$/.test(line);
|
|
90109
|
+
}
|
|
90110
|
+
function parseInlineEnabledList(line) {
|
|
90111
|
+
const match = line.match(/^(\s*)enabled:\s*\[(.*)\]\s*(?:#.*)?$/);
|
|
90112
|
+
if (!match) {
|
|
90113
|
+
return null;
|
|
90114
|
+
}
|
|
90115
|
+
const values = (match[2] ?? "").split(",").map((value) => value.trim().replace(/^["']|["']$/g, "")).filter(Boolean);
|
|
90116
|
+
return { indent: match[1] ?? "", values };
|
|
90117
|
+
}
|
|
90118
|
+
function normalizeInlineEnabledList(input) {
|
|
90119
|
+
let hasOkxA2a = false;
|
|
90120
|
+
const values = [];
|
|
90121
|
+
for (const value of input.values) {
|
|
90122
|
+
if (value === "okx-a2a" || value === "platforms/okx-a2a") {
|
|
90123
|
+
hasOkxA2a = true;
|
|
90124
|
+
if (!values.includes("okx-a2a")) {
|
|
90125
|
+
values.push("okx-a2a");
|
|
90126
|
+
}
|
|
90127
|
+
continue;
|
|
90128
|
+
}
|
|
90129
|
+
values.push(value);
|
|
90130
|
+
}
|
|
90131
|
+
return {
|
|
90132
|
+
lines: values.length > 0 ? [`${input.indent}enabled:`, ...values.map((value) => `${input.indent} - ${value}`)] : [`${input.indent}enabled: []`],
|
|
90133
|
+
changed: hasOkxA2a,
|
|
90134
|
+
hasOkxA2a
|
|
90135
|
+
};
|
|
90136
|
+
}
|
|
90137
|
+
function parseYamlListValue(line) {
|
|
90138
|
+
const match = line.match(/^(\s*)-\s*(?:"([^"]*)"|'([^']*)'|([^#\s]+))(?:\s*(?:#.*)?)?$/);
|
|
90139
|
+
if (!match) {
|
|
90140
|
+
return null;
|
|
90141
|
+
}
|
|
90142
|
+
return {
|
|
90143
|
+
indent: match[1] ?? "",
|
|
90144
|
+
value: match[2] ?? match[3] ?? match[4] ?? ""
|
|
90145
|
+
};
|
|
90146
|
+
}
|
|
90147
|
+
function isNodeError(error) {
|
|
90148
|
+
return error instanceof Error && "code" in error;
|
|
90149
|
+
}
|
|
90150
|
+
function parsePluginYamlVersion(content3) {
|
|
90151
|
+
for (const line of content3.split(/\r?\n/)) {
|
|
90152
|
+
const match = line.match(/^\s*version:\s*(?:"([^"]+)"|'([^']+)'|([^#\s]+))/);
|
|
90153
|
+
if (match) {
|
|
90154
|
+
return match[1] ?? match[2] ?? match[3] ?? null;
|
|
90155
|
+
}
|
|
90156
|
+
}
|
|
90157
|
+
return null;
|
|
90158
|
+
}
|
|
90527
90159
|
// Annotate the CommonJS export names for ESM import in node:
|
|
90528
90160
|
0 && (module.exports = {
|
|
90529
90161
|
AI_PROVIDERS,
|
|
@@ -90572,7 +90204,6 @@ async function timeSettled(fn) {
|
|
|
90572
90204
|
detectCurrentAiProvider,
|
|
90573
90205
|
detectGatewayInvocation,
|
|
90574
90206
|
detectRuntime,
|
|
90575
|
-
ensureCommunicationMinVersions,
|
|
90576
90207
|
ensureDefaultAiProvider,
|
|
90577
90208
|
extractAiSessionId,
|
|
90578
90209
|
extractXmtpSentAtMs,
|
|
@@ -90580,7 +90211,6 @@ async function timeSettled(fn) {
|
|
|
90580
90211
|
handleXmtpSendCommand,
|
|
90581
90212
|
hasAiRuntimeMarker,
|
|
90582
90213
|
heartbeatUserAttentionWatcher,
|
|
90583
|
-
isBelowRequiredVersion,
|
|
90584
90214
|
isOriginalParentProcessAlive,
|
|
90585
90215
|
isPrereleaseVersion,
|
|
90586
90216
|
isRetryableOpenClawGatewayError,
|