@okxweb3/a2a-node 0.2.16 → 0.2.17-beta-ab42219842-261020165552
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 +1805 -253
- package/dist/index.js +1730 -167
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -114,7 +114,8 @@ function resolveTaskPaths(homeDir = resolveTaskHome()) {
|
|
|
114
114
|
completedCommandsDir: (0, import_node_path2.join)(homeDir, "commands", "completed"),
|
|
115
115
|
pidPath: (0, import_node_path2.join)(homeDir, "run", "listener.pid"),
|
|
116
116
|
daemonLockPath: (0, import_node_path2.join)(homeDir, "run", "daemon.lock"),
|
|
117
|
-
listenerLogPath: (0, import_node_path2.join)(homeDir, "logs", "listener.log")
|
|
117
|
+
listenerLogPath: (0, import_node_path2.join)(homeDir, "logs", "listener.log"),
|
|
118
|
+
devkitServerDbPath: (0, import_node_path2.join)(homeDir, "sqlite", DEVKIT_SERVER_DB_NAME)
|
|
118
119
|
};
|
|
119
120
|
}
|
|
120
121
|
function ensureTaskHome(homeDir) {
|
|
@@ -126,13 +127,14 @@ function encodeJobIdForFile(jobId) {
|
|
|
126
127
|
function ensureTaskDir(dir) {
|
|
127
128
|
return ensureA2aTaskDir(dir);
|
|
128
129
|
}
|
|
129
|
-
var import_node_path2, BACKUP_JOB_ID;
|
|
130
|
+
var import_node_path2, BACKUP_JOB_ID, DEVKIT_SERVER_DB_NAME;
|
|
130
131
|
var init_paths = __esm({
|
|
131
132
|
"src/paths.ts"() {
|
|
132
133
|
"use strict";
|
|
133
134
|
import_node_path2 = require("node:path");
|
|
134
135
|
init_a2a_paths();
|
|
135
136
|
BACKUP_JOB_ID = "backup";
|
|
137
|
+
DEVKIT_SERVER_DB_NAME = "devkit-server.sqlite";
|
|
136
138
|
}
|
|
137
139
|
});
|
|
138
140
|
|
|
@@ -4256,8 +4258,8 @@ var require_worldwide = __commonJS({
|
|
|
4256
4258
|
function getGlobalSingleton(name, creator, obj) {
|
|
4257
4259
|
const gbl = obj || GLOBAL_OBJ;
|
|
4258
4260
|
const __SENTRY__ = gbl.__SENTRY__ = gbl.__SENTRY__ || {};
|
|
4259
|
-
const
|
|
4260
|
-
return
|
|
4261
|
+
const singleton3 = __SENTRY__[name] || (__SENTRY__[name] = creator());
|
|
4262
|
+
return singleton3;
|
|
4261
4263
|
}
|
|
4262
4264
|
exports2.GLOBAL_OBJ = GLOBAL_OBJ;
|
|
4263
4265
|
exports2.getGlobalObject = getGlobalObject;
|
|
@@ -19302,6 +19304,14 @@ var init_events = __esm({
|
|
|
19302
19304
|
SYSTEM_NOTIFICATION_ROUTED: "System notification routed",
|
|
19303
19305
|
HERMES_SESSION_ROUTE_BINDING: "Hermes session route binding",
|
|
19304
19306
|
DOCTOR_REPORT: "Doctor report",
|
|
19307
|
+
// XMTP creation rate-limit cooldown (DEXMARKET-9116). All four are logger.info,
|
|
19308
|
+
// so each one must also be listed in SENTRY_INFO_ALLOWLIST (index.ts) or info()
|
|
19309
|
+
// drops it silently. Extras are bounded tokens/ints/bools only — never raw SDK
|
|
19310
|
+
// error text (no-content-leak invariant).
|
|
19311
|
+
XMTP_RATE_LIMIT_COOLDOWN_STARTED: "XMTP rate limit cooldown started",
|
|
19312
|
+
XMTP_RATE_LIMIT_CREATE_SUPPRESSED: "XMTP rate limit create suppressed",
|
|
19313
|
+
XMTP_RATE_LIMIT_PROBE: "XMTP rate limit probe",
|
|
19314
|
+
XMTP_RATE_LIMIT_RECOVERED: "XMTP rate limit recovered",
|
|
19305
19315
|
// ── error ─────────────────────────────────────────────────────
|
|
19306
19316
|
XMTP_CONNECTION_FAILED: "XMTP connection failed",
|
|
19307
19317
|
CONVERSATIONS_STREAM_FAILED: "conversations.stream failed",
|
|
@@ -19367,7 +19377,28 @@ var init_events = __esm({
|
|
|
19367
19377
|
AGENT_DB_DIR_CREATE_FAILED: "Agent DB dir create failed",
|
|
19368
19378
|
AGENT_INSTALLATION_LIMIT_NEAR: "Agent installation limit near",
|
|
19369
19379
|
XMTP_HISTORY_SYNC_REQUEST_FAILED: "XMTP history sync request failed",
|
|
19370
|
-
XMTP_DEBUG_SYNC_FAILED: "XMTP debug sync failed"
|
|
19380
|
+
XMTP_DEBUG_SYNC_FAILED: "XMTP debug sync failed",
|
|
19381
|
+
// Underlying XMTP SDK client close failed during recycle/removal/shutdown
|
|
19382
|
+
// (DEXMARKET-9116). Error-level → NOT added to SENTRY_INFO_ALLOWLIST.
|
|
19383
|
+
XMTP_CLIENT_CLOSE_FAILED: "XMTP client close failed",
|
|
19384
|
+
// ── devkit custom-server registry + delivery (DEXMARKET-9165) ──────────────
|
|
19385
|
+
// info-level (registered in SENTRY_INFO_ALLOWLIST below):
|
|
19386
|
+
DEVKIT_REGISTER_REQUESTED: "Devkit register requested",
|
|
19387
|
+
DEVKIT_REGISTER_COMPLETED: "Devkit register completed",
|
|
19388
|
+
DEVKIT_UNREGISTER_REQUESTED: "Devkit unregister requested",
|
|
19389
|
+
DEVKIT_UNREGISTER_COMPLETED: "Devkit unregister completed",
|
|
19390
|
+
DEVKIT_DAEMON_STATUS_UNKNOWN: "Devkit daemon status unknown",
|
|
19391
|
+
DEVKIT_ROUTE_DEFAULT_AI: "Devkit route default AI",
|
|
19392
|
+
DEVKIT_ROUTE_CUSTOM_SERVER: "Devkit route custom server",
|
|
19393
|
+
DEVKIT_DELIVERY_ACCEPTED: "Devkit delivery accepted",
|
|
19394
|
+
DEVKIT_DELIVERY_HTTP_ACCEPTED: "Devkit delivery http accepted",
|
|
19395
|
+
DEVKIT_DELIVERY_DROPPED: "Devkit delivery dropped",
|
|
19396
|
+
DEVKIT_DELIVERY_CANCELLED: "Devkit delivery cancelled",
|
|
19397
|
+
// error-level (NOT allowlisted — logger.error):
|
|
19398
|
+
DEVKIT_REGISTER_REJECTED: "Devkit register rejected",
|
|
19399
|
+
DEVKIT_CONFIG_PERSIST_FAILED: "Devkit config persist failed",
|
|
19400
|
+
DEVKIT_ROUTE_CONFIG_READ_FAILED: "Devkit route config read failed",
|
|
19401
|
+
DEVKIT_DELIVERY_HTTP_FAILED: "Devkit delivery http failed"
|
|
19371
19402
|
};
|
|
19372
19403
|
}
|
|
19373
19404
|
});
|
|
@@ -20212,7 +20243,26 @@ var init_sentry_logger = __esm({
|
|
|
20212
20243
|
LogEvent.PENDING_LIST_QUERIED,
|
|
20213
20244
|
LogEvent.SESSION_KEY_DERIVED,
|
|
20214
20245
|
LogEvent.SESSIONS_QUERIED,
|
|
20215
|
-
LogEvent.SYNC_TICK_COMPLETED
|
|
20246
|
+
LogEvent.SYNC_TICK_COMPLETED,
|
|
20247
|
+
// XMTP creation rate-limit cooldown checkpoints (DEXMARKET-9116). info() drops
|
|
20248
|
+
// any event not listed here, so these must stay registered.
|
|
20249
|
+
LogEvent.XMTP_RATE_LIMIT_COOLDOWN_STARTED,
|
|
20250
|
+
LogEvent.XMTP_RATE_LIMIT_CREATE_SUPPRESSED,
|
|
20251
|
+
LogEvent.XMTP_RATE_LIMIT_PROBE,
|
|
20252
|
+
LogEvent.XMTP_RATE_LIMIT_RECOVERED,
|
|
20253
|
+
// devkit custom-server registry + delivery info checkpoints (DEXMARKET-9165).
|
|
20254
|
+
// info() drops any event not listed here, so these must stay registered.
|
|
20255
|
+
LogEvent.DEVKIT_REGISTER_REQUESTED,
|
|
20256
|
+
LogEvent.DEVKIT_REGISTER_COMPLETED,
|
|
20257
|
+
LogEvent.DEVKIT_UNREGISTER_REQUESTED,
|
|
20258
|
+
LogEvent.DEVKIT_UNREGISTER_COMPLETED,
|
|
20259
|
+
LogEvent.DEVKIT_DAEMON_STATUS_UNKNOWN,
|
|
20260
|
+
LogEvent.DEVKIT_ROUTE_DEFAULT_AI,
|
|
20261
|
+
LogEvent.DEVKIT_ROUTE_CUSTOM_SERVER,
|
|
20262
|
+
LogEvent.DEVKIT_DELIVERY_ACCEPTED,
|
|
20263
|
+
LogEvent.DEVKIT_DELIVERY_HTTP_ACCEPTED,
|
|
20264
|
+
LogEvent.DEVKIT_DELIVERY_DROPPED,
|
|
20265
|
+
LogEvent.DEVKIT_DELIVERY_CANCELLED
|
|
20216
20266
|
]);
|
|
20217
20267
|
MAX_EXTRA_STRING_LENGTH = 256;
|
|
20218
20268
|
MAX_TAG_VALUE_LENGTH = 128;
|
|
@@ -32448,7 +32498,7 @@ var init_sentry_config = __esm({
|
|
|
32448
32498
|
environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
|
|
32449
32499
|
SENTRY_CONFIG = {
|
|
32450
32500
|
projectName: "okx/openclaw-okx-a2a-extension",
|
|
32451
|
-
release: "0.2.
|
|
32501
|
+
release: "0.2.17-beta-ab42219842-261020165552",
|
|
32452
32502
|
environment,
|
|
32453
32503
|
runtimeContainer: normalizeRuntimeContainer(process.env.OKX_A2A_RUNTIME_CONTAINER)
|
|
32454
32504
|
};
|
|
@@ -32482,7 +32532,7 @@ function isPostjectRunnable() {
|
|
|
32482
32532
|
function resolvePostjectCommand() {
|
|
32483
32533
|
try {
|
|
32484
32534
|
const cliPath = (0, import_node_module.createRequire)(__filename).resolve("postject/dist/cli.js");
|
|
32485
|
-
if ((0,
|
|
32535
|
+
if ((0, import_node_fs22.existsSync)(cliPath)) {
|
|
32486
32536
|
return { command: process.execPath, prefixArgs: [cliPath] };
|
|
32487
32537
|
}
|
|
32488
32538
|
} catch {
|
|
@@ -32553,26 +32603,26 @@ function buildSeaConfig(entryPath, blobPath) {
|
|
|
32553
32603
|
}
|
|
32554
32604
|
async function installWindowsNativeLauncher(options) {
|
|
32555
32605
|
const nodeExe = options.nodeExe ?? process.execPath;
|
|
32556
|
-
if (!(0,
|
|
32606
|
+
if (!(0, import_node_fs22.existsSync)(options.cliPath)) {
|
|
32557
32607
|
throw new Error(`cannot build okx-a2a.exe: CLI entry not found at ${options.cliPath}`);
|
|
32558
32608
|
}
|
|
32559
|
-
if (!(0,
|
|
32609
|
+
if (!(0, import_node_fs22.existsSync)(nodeExe)) {
|
|
32560
32610
|
throw new Error(`cannot build okx-a2a.exe: node executable not found at ${nodeExe}`);
|
|
32561
32611
|
}
|
|
32562
32612
|
const exePath = (0, import_node_path28.join)(options.targetDir, NATIVE_LAUNCHER_EXE_NAME);
|
|
32563
|
-
(0,
|
|
32564
|
-
const work = (0,
|
|
32613
|
+
(0, import_node_fs22.mkdirSync)(options.targetDir, { recursive: true });
|
|
32614
|
+
const work = (0, import_node_fs22.mkdtempSync)((0, import_node_path28.join)((0, import_node_os9.tmpdir)(), "okx-a2a-sea-"));
|
|
32565
32615
|
try {
|
|
32566
32616
|
const entryPath = (0, import_node_path28.join)(work, "launcher-entry.js");
|
|
32567
32617
|
const blobPath = (0, import_node_path28.join)(work, "okx-a2a.blob");
|
|
32568
32618
|
const configPath = (0, import_node_path28.join)(work, "sea-config.json");
|
|
32569
|
-
(0,
|
|
32570
|
-
(0,
|
|
32619
|
+
(0, import_node_fs22.writeFileSync)(entryPath, buildLauncherEntryJs(options.cliPath), "utf8");
|
|
32620
|
+
(0, import_node_fs22.writeFileSync)(configPath, buildSeaConfig(entryPath, blobPath), "utf8");
|
|
32571
32621
|
(0, import_node_child_process7.execFileSync)(nodeExe, ["--experimental-sea-config", configPath], {
|
|
32572
32622
|
stdio: "ignore",
|
|
32573
32623
|
windowsHide: true
|
|
32574
32624
|
});
|
|
32575
|
-
(0,
|
|
32625
|
+
(0, import_node_fs22.copyFileSync)(nodeExe, exePath);
|
|
32576
32626
|
const isMac = process.platform === "darwin";
|
|
32577
32627
|
if (isMac) {
|
|
32578
32628
|
try {
|
|
@@ -32592,10 +32642,10 @@ async function installWindowsNativeLauncher(options) {
|
|
|
32592
32642
|
);
|
|
32593
32643
|
return { exePath, cliPath: options.cliPath, nodeExe };
|
|
32594
32644
|
} finally {
|
|
32595
|
-
(0,
|
|
32645
|
+
(0, import_node_fs22.rmSync)(work, { recursive: true, force: true });
|
|
32596
32646
|
}
|
|
32597
32647
|
}
|
|
32598
|
-
function findWindowsNativeOkxA2aExe(pathValue, appData, userProfile, fileExists2 =
|
|
32648
|
+
function findWindowsNativeOkxA2aExe(pathValue, appData, userProfile, fileExists2 = import_node_fs22.existsSync) {
|
|
32599
32649
|
const dirs = pathValue.split(";").map((d) => d.trim()).filter(Boolean);
|
|
32600
32650
|
if (appData) {
|
|
32601
32651
|
dirs.push((0, import_node_path28.join)(appData, "npm"));
|
|
@@ -32613,11 +32663,11 @@ function findWindowsNativeOkxA2aExe(pathValue, appData, userProfile, fileExists2
|
|
|
32613
32663
|
}
|
|
32614
32664
|
function resolveRunningCliPath() {
|
|
32615
32665
|
const fromArgv = process.argv[1];
|
|
32616
|
-
if (fromArgv && /(?:^|[\\/])cli\.js$/.test(fromArgv) && (0,
|
|
32666
|
+
if (fromArgv && /(?:^|[\\/])cli\.js$/.test(fromArgv) && (0, import_node_fs22.existsSync)(fromArgv)) {
|
|
32617
32667
|
return fromArgv;
|
|
32618
32668
|
}
|
|
32619
32669
|
const beside = (0, import_node_path28.join)(__dirname, "cli.js");
|
|
32620
|
-
if ((0,
|
|
32670
|
+
if ((0, import_node_fs22.existsSync)(beside)) {
|
|
32621
32671
|
return beside;
|
|
32622
32672
|
}
|
|
32623
32673
|
if (fromArgv) {
|
|
@@ -32639,12 +32689,12 @@ async function ensureWindowsNativeLauncher(options = {}) {
|
|
|
32639
32689
|
const result = await installWindowsNativeLauncher({ cliPath: resolveRunningCliPath(), targetDir });
|
|
32640
32690
|
return { exePath: result.exePath, installed: true };
|
|
32641
32691
|
}
|
|
32642
|
-
var import_node_child_process7,
|
|
32692
|
+
var import_node_child_process7, import_node_fs22, import_node_module, import_node_os9, import_node_path28, SEA_SENTINEL_FUSE, NATIVE_LAUNCHER_EXE_NAME, POSTJECT_SPEC, POSTJECT_BIN;
|
|
32643
32693
|
var init_win_native_launcher = __esm({
|
|
32644
32694
|
"src/win-native-launcher.ts"() {
|
|
32645
32695
|
"use strict";
|
|
32646
32696
|
import_node_child_process7 = require("node:child_process");
|
|
32647
|
-
|
|
32697
|
+
import_node_fs22 = require("node:fs");
|
|
32648
32698
|
import_node_module = require("node:module");
|
|
32649
32699
|
import_node_os9 = require("node:os");
|
|
32650
32700
|
import_node_path28 = require("node:path");
|
|
@@ -32786,7 +32836,7 @@ function buildProviderMismatchWarning(target, provider) {
|
|
|
32786
32836
|
].join("\n");
|
|
32787
32837
|
}
|
|
32788
32838
|
async function handleUpdateCommand(args) {
|
|
32789
|
-
if (args.some(
|
|
32839
|
+
if (args.some(isHelpArg2)) {
|
|
32790
32840
|
printUpdateUsage();
|
|
32791
32841
|
return;
|
|
32792
32842
|
}
|
|
@@ -32827,7 +32877,7 @@ function resolveUpdateTarget(target) {
|
|
|
32827
32877
|
return detectGatewayInvocation() ?? "node";
|
|
32828
32878
|
}
|
|
32829
32879
|
async function handleSetupCommand(args) {
|
|
32830
|
-
if (args.some(
|
|
32880
|
+
if (args.some(isHelpArg2)) {
|
|
32831
32881
|
printSetupUsage();
|
|
32832
32882
|
return;
|
|
32833
32883
|
}
|
|
@@ -33404,7 +33454,7 @@ async function getCurrentNodeCliVersion() {
|
|
|
33404
33454
|
return await getGlobalNpmPackageVersion(UPDATE_PACKAGES.node) ?? getBundledNodeCliVersion();
|
|
33405
33455
|
}
|
|
33406
33456
|
function getBundledNodeCliVersion() {
|
|
33407
|
-
return true ? "0.2.
|
|
33457
|
+
return true ? "0.2.17-beta-ab42219842-261020165552" : null;
|
|
33408
33458
|
}
|
|
33409
33459
|
function readConfiguredAiProvider() {
|
|
33410
33460
|
const explicit = process.env.OKX_A2A_AI_PROVIDER || process.env.OKX_AGENT_TASK_AI_CLI;
|
|
@@ -33589,7 +33639,7 @@ async function updateHermes(release, options) {
|
|
|
33589
33639
|
assertNotRunningInsideGateway("hermes");
|
|
33590
33640
|
}
|
|
33591
33641
|
const spec = buildNpmPackageSpec("hermes", release);
|
|
33592
|
-
const workDir = await (0,
|
|
33642
|
+
const workDir = await (0, import_promises12.mkdtemp)((0, import_node_path29.join)((0, import_node_os10.tmpdir)(), `okx-a2a-${label}-hermes-`));
|
|
33593
33643
|
try {
|
|
33594
33644
|
console.log(`[${label}] downloading ${spec}`);
|
|
33595
33645
|
const npmTarball = await npmPack(spec, workDir);
|
|
@@ -33610,11 +33660,11 @@ async function updateHermes(release, options) {
|
|
|
33610
33660
|
}
|
|
33611
33661
|
console.log(`[${label}] hermes ${label} done`);
|
|
33612
33662
|
} finally {
|
|
33613
|
-
await (0,
|
|
33663
|
+
await (0, import_promises12.rm)(workDir, { recursive: true, force: true });
|
|
33614
33664
|
}
|
|
33615
33665
|
}
|
|
33616
33666
|
async function installGatewayPluginForDoctor(target) {
|
|
33617
|
-
const release = isPrereleaseVersion("0.2.
|
|
33667
|
+
const release = isPrereleaseVersion("0.2.17-beta-ab42219842-261020165552") ? "beta" : "latest";
|
|
33618
33668
|
const insideTargetGateway = detectGatewayInvocation() === target;
|
|
33619
33669
|
const options = {
|
|
33620
33670
|
restart: !insideTargetGateway,
|
|
@@ -33641,7 +33691,7 @@ function setupReadyMessage(target) {
|
|
|
33641
33691
|
async function normalizeHermesOkxA2aPluginConfig(configFile = resolveHermesConfigPath()) {
|
|
33642
33692
|
let content;
|
|
33643
33693
|
try {
|
|
33644
|
-
content = await (0,
|
|
33694
|
+
content = await (0, import_promises12.readFile)(configFile, "utf8");
|
|
33645
33695
|
} catch (error) {
|
|
33646
33696
|
if (isNodeError(error) && error.code === "ENOENT") {
|
|
33647
33697
|
return false;
|
|
@@ -33652,21 +33702,21 @@ async function normalizeHermesOkxA2aPluginConfig(configFile = resolveHermesConfi
|
|
|
33652
33702
|
if (!normalized.changed) {
|
|
33653
33703
|
return false;
|
|
33654
33704
|
}
|
|
33655
|
-
await (0,
|
|
33705
|
+
await (0, import_promises12.writeFile)(configFile, normalized.content);
|
|
33656
33706
|
console.log(`[update] normalized Hermes plugins.enabled okx-a2a entry in ${configFile}`);
|
|
33657
33707
|
return true;
|
|
33658
33708
|
}
|
|
33659
33709
|
async function ensureHermesOkxA2aPluginConfig(configFile = resolveHermesConfigPath(), options = {}) {
|
|
33660
33710
|
let content;
|
|
33661
33711
|
try {
|
|
33662
|
-
content = await (0,
|
|
33712
|
+
content = await (0, import_promises12.readFile)(configFile, "utf8");
|
|
33663
33713
|
} catch (error) {
|
|
33664
33714
|
if (isNodeError(error) && error.code === "ENOENT") {
|
|
33665
33715
|
if (options.dryRun) {
|
|
33666
33716
|
return true;
|
|
33667
33717
|
}
|
|
33668
|
-
await (0,
|
|
33669
|
-
await (0,
|
|
33718
|
+
await (0, import_promises12.mkdir)((0, import_node_path29.resolve)(configFile, ".."), { recursive: true });
|
|
33719
|
+
await (0, import_promises12.writeFile)(configFile, "plugins:\n enabled:\n - okx-a2a\n");
|
|
33670
33720
|
console.log(`[update] added Hermes plugins.enabled okx-a2a entry in ${configFile}`);
|
|
33671
33721
|
return true;
|
|
33672
33722
|
}
|
|
@@ -33677,7 +33727,7 @@ async function ensureHermesOkxA2aPluginConfig(configFile = resolveHermesConfigPa
|
|
|
33677
33727
|
if (options.dryRun) {
|
|
33678
33728
|
return true;
|
|
33679
33729
|
}
|
|
33680
|
-
await (0,
|
|
33730
|
+
await (0, import_promises12.writeFile)(configFile, normalized.content);
|
|
33681
33731
|
console.log(`[update] normalized Hermes plugins.enabled okx-a2a entry in ${configFile}`);
|
|
33682
33732
|
return true;
|
|
33683
33733
|
}
|
|
@@ -33688,7 +33738,7 @@ async function ensureHermesOkxA2aPluginConfig(configFile = resolveHermesConfigPa
|
|
|
33688
33738
|
return true;
|
|
33689
33739
|
}
|
|
33690
33740
|
const updated = addHermesOkxA2aEnabled(content);
|
|
33691
|
-
await (0,
|
|
33741
|
+
await (0, import_promises12.writeFile)(configFile, updated);
|
|
33692
33742
|
console.log(`[update] added Hermes plugins.enabled okx-a2a entry in ${configFile}`);
|
|
33693
33743
|
return true;
|
|
33694
33744
|
}
|
|
@@ -33989,7 +34039,7 @@ async function isGatewayPluginInstalled(target) {
|
|
|
33989
34039
|
if (target === "openclaw") {
|
|
33990
34040
|
return (await getInstalledOpenClawPluginInfo()).installed;
|
|
33991
34041
|
}
|
|
33992
|
-
return (0,
|
|
34042
|
+
return (0, import_node_fs23.existsSync)(resolveHermesPluginYamlPath());
|
|
33993
34043
|
}
|
|
33994
34044
|
async function getInstalledGatewayPluginVersion(target) {
|
|
33995
34045
|
if (target === "hermes") {
|
|
@@ -34078,7 +34128,7 @@ function parsePackageVersionFromText(output) {
|
|
|
34078
34128
|
async function getInstalledHermesPluginVersion() {
|
|
34079
34129
|
const pluginYaml = (0, import_node_path29.join)(process.env.HERMES_HOME ?? (0, import_node_path29.join)((0, import_node_os10.homedir)(), ".hermes"), "plugins", "platforms", "okx-a2a", "plugin.yaml");
|
|
34080
34130
|
try {
|
|
34081
|
-
const content = await (0,
|
|
34131
|
+
const content = await (0, import_promises12.readFile)(pluginYaml, "utf8");
|
|
34082
34132
|
return parsePluginYamlVersion(content);
|
|
34083
34133
|
} catch (error) {
|
|
34084
34134
|
if (isNodeError(error) && error.code === "ENOENT") {
|
|
@@ -34137,7 +34187,7 @@ async function npmPack(spec, destination) {
|
|
|
34137
34187
|
return (0, import_node_path29.resolve)(destination, (0, import_node_path29.basename)(tarballName));
|
|
34138
34188
|
}
|
|
34139
34189
|
async function findHermesPluginTarball(distDir) {
|
|
34140
|
-
const entries = await (0,
|
|
34190
|
+
const entries = await (0, import_promises12.readdir)(distDir);
|
|
34141
34191
|
const tarball = entries.find((entry) => /^okx-a2a-hermes-plugin-.+\.tar\.gz$/.test(entry));
|
|
34142
34192
|
if (!tarball) {
|
|
34143
34193
|
throw new Error(`Hermes npm package did not contain dist/okx-a2a-hermes-plugin-*.tar.gz`);
|
|
@@ -34145,7 +34195,7 @@ async function findHermesPluginTarball(distDir) {
|
|
|
34145
34195
|
return (0, import_node_path29.join)(distDir, tarball);
|
|
34146
34196
|
}
|
|
34147
34197
|
async function findFirstDirectory(parent) {
|
|
34148
|
-
const entries = await (0,
|
|
34198
|
+
const entries = await (0, import_promises12.readdir)(parent, { withFileTypes: true });
|
|
34149
34199
|
const dir = entries.find((entry) => entry.isDirectory());
|
|
34150
34200
|
if (!dir) {
|
|
34151
34201
|
throw new Error(`No unpacked plugin directory found under ${parent}`);
|
|
@@ -34162,7 +34212,7 @@ function readOption2(args, name) {
|
|
|
34162
34212
|
function hasFlag(args, name) {
|
|
34163
34213
|
return args.includes(name);
|
|
34164
34214
|
}
|
|
34165
|
-
function
|
|
34215
|
+
function isHelpArg2(value) {
|
|
34166
34216
|
return value === "-h" || value === "--help" || value === "help";
|
|
34167
34217
|
}
|
|
34168
34218
|
function isSupportedRelease(value) {
|
|
@@ -34371,13 +34421,13 @@ function buildExternalCommandInvocation(command, args, platform = process.platfo
|
|
|
34371
34421
|
function formatExternalCommand(command, args) {
|
|
34372
34422
|
return [command, ...args].join(" ");
|
|
34373
34423
|
}
|
|
34374
|
-
var import_node_child_process8,
|
|
34424
|
+
var import_node_child_process8, import_node_fs23, import_promises12, import_node_os10, import_node_path29, UPDATE_PACKAGES, CODEX_NPM_PACKAGE, OPENCLAW_FORCE_INSTALL_FLAG, OPENCLAW_UNSAFE_INSTALL_FLAG, OKX_A2A_PLUGIN_ID, OPENCLAW_SESSION_DM_SCOPE_CONFIG_PATH, OPENCLAW_SESSION_DM_SCOPE_CONFIG_VALUE, OPENCLAW_PLUGIN_ALLOW_CONFIG_PATH, OPENCLAW_OKX_A2A_CONVERSATION_HOOK_ACCESS_CONFIG_PATH, DEFAULT_AI_PROVIDER_LOGIN_TIMEOUT_MS, PROVIDER_CLI_AUTH_PROBE_TIMEOUT_MS, SetupBlockedError, redirectCommandStdoutToStderr;
|
|
34375
34425
|
var init_update_cli = __esm({
|
|
34376
34426
|
"src/update-cli.ts"() {
|
|
34377
34427
|
"use strict";
|
|
34378
34428
|
import_node_child_process8 = require("node:child_process");
|
|
34379
|
-
|
|
34380
|
-
|
|
34429
|
+
import_node_fs23 = require("node:fs");
|
|
34430
|
+
import_promises12 = require("node:fs/promises");
|
|
34381
34431
|
import_node_os10 = require("node:os");
|
|
34382
34432
|
import_node_path29 = require("node:path");
|
|
34383
34433
|
init_ai_command();
|
|
@@ -44330,7 +44380,22 @@ __export(index_exports, {
|
|
|
44330
44380
|
DEFAULT_LOG_TAIL_LIMIT: () => DEFAULT_LOG_TAIL_LIMIT,
|
|
44331
44381
|
DEFAULT_OFFLINE_REPLAY_INTERVAL_SEC: () => DEFAULT_OFFLINE_REPLAY_INTERVAL_SEC,
|
|
44332
44382
|
DEFAULT_XMTP_CLIENT_RECYCLE_INTERVAL_SEC: () => DEFAULT_XMTP_CLIENT_RECYCLE_INTERVAL_SEC,
|
|
44383
|
+
DEVKIT_DROP_REASON: () => DEVKIT_DROP_REASON,
|
|
44384
|
+
DEVKIT_MAX_CONCURRENCY: () => DEVKIT_MAX_CONCURRENCY,
|
|
44385
|
+
DEVKIT_MAX_MESSAGE_BYTES: () => DEVKIT_MAX_MESSAGE_BYTES,
|
|
44386
|
+
DEVKIT_MAX_PENDING: () => DEVKIT_MAX_PENDING,
|
|
44387
|
+
DEVKIT_MAX_PENDING_BYTES: () => DEVKIT_MAX_PENDING_BYTES,
|
|
44388
|
+
DEVKIT_OUTCOME: () => DEVKIT_OUTCOME,
|
|
44389
|
+
DEVKIT_REQUEST_BUDGET_MS: () => DEVKIT_REQUEST_BUDGET_MS,
|
|
44390
|
+
DEVKIT_RESPONSE_DIAGNOSTIC_MAX_BYTES: () => DEVKIT_RESPONSE_DIAGNOSTIC_MAX_BYTES,
|
|
44391
|
+
DEVKIT_RESPONSE_SUMMARY_MAX_CHARS: () => DEVKIT_RESPONSE_SUMMARY_MAX_CHARS,
|
|
44392
|
+
DEVKIT_SERVER_APPLICATION_ID: () => DEVKIT_SERVER_APPLICATION_ID,
|
|
44393
|
+
DEVKIT_SERVER_DB_NAME: () => DEVKIT_SERVER_DB_NAME,
|
|
44394
|
+
DEVKIT_SERVER_SCHEMA_VERSION: () => DEVKIT_SERVER_SCHEMA_VERSION,
|
|
44333
44395
|
DOCTOR_MIN_NODE_VERSION: () => DOCTOR_MIN_NODE_VERSION,
|
|
44396
|
+
DevkitDeliveryDispatcher: () => DevkitDeliveryDispatcher,
|
|
44397
|
+
DevkitServerStore: () => DevkitServerStore,
|
|
44398
|
+
DevkitServerStoreError: () => DevkitServerStoreError,
|
|
44334
44399
|
GatewayOutboundBehavior: () => GatewayOutboundBehavior,
|
|
44335
44400
|
HEARTBEAT_GATEWAY_CHECK_TIMEOUT_MS: () => HEARTBEAT_GATEWAY_CHECK_TIMEOUT_MS,
|
|
44336
44401
|
InboundReplayGate: () => InboundReplayGate,
|
|
@@ -44359,6 +44424,9 @@ __export(index_exports, {
|
|
|
44359
44424
|
UserCancelledAiProviderSelectionError: () => UserCancelledAiProviderSelectionError,
|
|
44360
44425
|
WALLET_STATUS_TIMEOUT_MS: () => WALLET_STATUS_TIMEOUT_MS,
|
|
44361
44426
|
XMTP_CLIENT_RECYCLE_INTERVAL_ENV: () => XMTP_CLIENT_RECYCLE_INTERVAL_ENV,
|
|
44427
|
+
XMTP_CREATION_COOLDOWN_MS: () => XMTP_CREATION_COOLDOWN_MS,
|
|
44428
|
+
XmtpCreationCooldown: () => XmtpCreationCooldown,
|
|
44429
|
+
XmtpCreationCooldownSkipError: () => XmtpCreationCooldownSkipError,
|
|
44362
44430
|
XmtpDm: () => Dm,
|
|
44363
44431
|
XmtpGroup: () => Group,
|
|
44364
44432
|
XmtpService: () => XmtpService,
|
|
@@ -44385,6 +44453,7 @@ __export(index_exports, {
|
|
|
44385
44453
|
buildExternalCommandInvocation: () => buildExternalCommandInvocation,
|
|
44386
44454
|
buildGatewayOutboundExtra: () => buildGatewayOutboundExtra,
|
|
44387
44455
|
buildInboundTerminalExtras: () => buildInboundTerminalExtras,
|
|
44456
|
+
buildJobEnvelope: () => buildJobEnvelope,
|
|
44388
44457
|
buildLaunchdPlist: () => buildLaunchdPlist,
|
|
44389
44458
|
buildLauncherEntryJs: () => buildLauncherEntryJs,
|
|
44390
44459
|
buildMessageEligibleArgs: () => buildMessageEligibleArgs,
|
|
@@ -44395,6 +44464,7 @@ __export(index_exports, {
|
|
|
44395
44464
|
buildSchtasksRunArgs: () => buildSchtasksRunArgs,
|
|
44396
44465
|
buildSeaConfig: () => buildSeaConfig,
|
|
44397
44466
|
buildServicePath: () => buildServicePath,
|
|
44467
|
+
buildSessionEnvelope: () => buildSessionEnvelope,
|
|
44398
44468
|
buildSessionKey: () => buildSessionKey,
|
|
44399
44469
|
buildSystemMessageNotice: () => buildSystemMessageNotice,
|
|
44400
44470
|
buildSystemStoredMessage: () => buildSystemStoredMessage,
|
|
@@ -44412,6 +44482,8 @@ __export(index_exports, {
|
|
|
44412
44482
|
checkCodexCliAuthStatus: () => checkCodexCliAuthStatus,
|
|
44413
44483
|
checkCodexReadiness: () => checkCodexReadiness,
|
|
44414
44484
|
claimActiveDaemon: () => claimActiveDaemon,
|
|
44485
|
+
classifyFetchFailure: () => classifyFetchFailure,
|
|
44486
|
+
classifyHttpOutcome: () => classifyHttpOutcome,
|
|
44415
44487
|
classifyJobBindingSource: () => classifyJobBindingSource,
|
|
44416
44488
|
clearCodexReadinessCache: () => clearCodexReadinessCache,
|
|
44417
44489
|
codexCommandResolvesWithoutOverride: () => codexCommandResolvesWithoutOverride,
|
|
@@ -44420,6 +44492,7 @@ __export(index_exports, {
|
|
|
44420
44492
|
collectCodexCommandCandidates: () => collectCodexCommandCandidates,
|
|
44421
44493
|
commandExists: () => commandExists,
|
|
44422
44494
|
createAiToolFailureTracker: () => createAiToolFailureTracker,
|
|
44495
|
+
createDevkitAutoRouter: () => createDevkitAutoRouter,
|
|
44423
44496
|
createFileMessageHandler: () => createFileMessageHandler,
|
|
44424
44497
|
createOutboundBehavior: () => createOutboundBehavior,
|
|
44425
44498
|
createUserAttentionWatchParentMonitor: () => createUserAttentionWatchParentMonitor,
|
|
@@ -44430,6 +44503,7 @@ __export(index_exports, {
|
|
|
44430
44503
|
detectGatewayInvocation: () => detectGatewayInvocation,
|
|
44431
44504
|
detectMessageEligibleOfflineReplaySupport: () => detectMessageEligibleOfflineReplaySupport,
|
|
44432
44505
|
detectRuntime: () => detectRuntime,
|
|
44506
|
+
devkitServerDbExists: () => devkitServerDbExists,
|
|
44433
44507
|
ensureDaemonReady: () => ensureDaemonReady,
|
|
44434
44508
|
ensureDefaultAiProvider: () => ensureDefaultAiProvider,
|
|
44435
44509
|
ensureOpenClawOkxA2aPluginConfig: () => ensureOpenClawOkxA2aPluginConfig,
|
|
@@ -44439,6 +44513,7 @@ __export(index_exports, {
|
|
|
44439
44513
|
exportDiagnosticLogs: () => exportDiagnosticLogs,
|
|
44440
44514
|
extractAiSessionId: () => extractAiSessionId,
|
|
44441
44515
|
extractDirectToUserNotification: () => extractDirectToUserNotification,
|
|
44516
|
+
extractRateLimitEndpoint: () => extractRateLimitEndpoint,
|
|
44442
44517
|
extractXmtpSentAtMs: () => extractXmtpSentAtMs2,
|
|
44443
44518
|
findWindowsNativeOkxA2aExe: () => findWindowsNativeOkxA2aExe,
|
|
44444
44519
|
followFile: () => followFile,
|
|
@@ -44449,7 +44524,9 @@ __export(index_exports, {
|
|
|
44449
44524
|
getResolvedOnchainosBinForTests: () => getResolvedOnchainosBinForTests,
|
|
44450
44525
|
getRuntimeMetadata: () => getRuntimeMetadata,
|
|
44451
44526
|
getSessionBusyTracker: () => getSessionBusyTracker,
|
|
44527
|
+
getXmtpCreationCooldown: () => getXmtpCreationCooldown,
|
|
44452
44528
|
handleCapabilitiesCommand: () => handleCapabilitiesCommand,
|
|
44529
|
+
handleDevkitCommand: () => handleDevkitCommand,
|
|
44453
44530
|
handleDoctorCommand: () => handleDoctorCommand,
|
|
44454
44531
|
handleXmtpDebugCommand: () => handleXmtpDebugCommand,
|
|
44455
44532
|
handleXmtpSendCommand: () => handleXmtpSendCommand,
|
|
@@ -44479,6 +44556,7 @@ __export(index_exports, {
|
|
|
44479
44556
|
isTagKey: () => isTagKey,
|
|
44480
44557
|
isValidExternalJobId: () => isValidExternalJobId,
|
|
44481
44558
|
isWindowsElevated: () => isWindowsElevated,
|
|
44559
|
+
isXmtpRateLimitError: () => isXmtpRateLimitError,
|
|
44482
44560
|
killProcessTree: () => killProcessTree,
|
|
44483
44561
|
launchdPlistHasCurrentRestartPolicy: () => launchdPlistHasCurrentRestartPolicy,
|
|
44484
44562
|
listAllAgentsWithMetadata: () => listAllAgentsWithMetadata,
|
|
@@ -44506,6 +44584,7 @@ __export(index_exports, {
|
|
|
44506
44584
|
persistCurrentRuntimeSelectionForNewJob: () => persistCurrentRuntimeSelectionForNewJob,
|
|
44507
44585
|
pickOnchainosWin32Candidate: () => pickOnchainosWin32Candidate,
|
|
44508
44586
|
prepareAndBindCurrentRuntimeForNewJob: () => prepareAndBindCurrentRuntimeForNewJob,
|
|
44587
|
+
printDevkitUsage: () => printDevkitUsage,
|
|
44509
44588
|
printLogsExportUsage: () => printLogsExportUsage,
|
|
44510
44589
|
printXmtpTestUsage: () => printXmtpTestUsage,
|
|
44511
44590
|
probeCodexAuthStatus: () => probeCodexAuthStatus,
|
|
@@ -44517,6 +44596,7 @@ __export(index_exports, {
|
|
|
44517
44596
|
readLastLines: () => readLastLines,
|
|
44518
44597
|
readParentProcessCommandForPlatform: () => readParentProcessCommandForPlatform,
|
|
44519
44598
|
readUserAttentionWatcherEvent: () => readUserAttentionWatcherEvent,
|
|
44599
|
+
redactSummary: () => redactSummary,
|
|
44520
44600
|
refreshAgentsAndWait: () => refreshAgentsAndWait,
|
|
44521
44601
|
refreshOnchainosVersionMetadata: () => refreshOnchainosVersionMetadata,
|
|
44522
44602
|
registerUserAttentionWatcher: () => registerUserAttentionWatcher,
|
|
@@ -44528,6 +44608,7 @@ __export(index_exports, {
|
|
|
44528
44608
|
reportUserNotificationFailure: () => reportUserNotificationFailure,
|
|
44529
44609
|
resetMessageEligibleOfflineReplayCapabilityForTests: () => resetMessageEligibleOfflineReplayCapabilityForTests,
|
|
44530
44610
|
resetResolvedOnchainosBinForTests: () => resetResolvedOnchainosBinForTests,
|
|
44611
|
+
resetXmtpCreationCooldownForTests: () => resetXmtpCreationCooldownForTests,
|
|
44531
44612
|
resolveAiPermissionPreset: () => resolveAiPermissionPreset,
|
|
44532
44613
|
resolveAiProviderCommand: () => resolveAiProviderCommand,
|
|
44533
44614
|
resolveAiProviderCommandWithSource: () => resolveAiProviderCommandWithSource,
|
|
@@ -44538,6 +44619,7 @@ __export(index_exports, {
|
|
|
44538
44619
|
resolveCodexCommandSource: () => resolveCodexCommandSource,
|
|
44539
44620
|
resolveConfiguredAiProvider: () => resolveConfiguredAiProvider,
|
|
44540
44621
|
resolveConfiguredAiProviderForJob: () => resolveConfiguredAiProviderForJob,
|
|
44622
|
+
resolveDevkitServerDbPath: () => resolveDevkitServerDbPath,
|
|
44541
44623
|
resolveDirectCommunicationSessionTarget: () => resolveDirectCommunicationSessionTarget,
|
|
44542
44624
|
resolveDoctorTarget: () => resolveDoctorTarget,
|
|
44543
44625
|
resolveEnvelopePayload: () => resolveEnvelopePayload,
|
|
@@ -44575,6 +44657,7 @@ __export(index_exports, {
|
|
|
44575
44657
|
startDaemonRespectingSupervisor: () => startDaemonRespectingSupervisor,
|
|
44576
44658
|
startUserAttentionEventServer: () => startUserAttentionEventServer,
|
|
44577
44659
|
startUserAttentionWatcherCoordinator: () => startUserAttentionWatcherCoordinator,
|
|
44660
|
+
stopAndCloseXmtpClient: () => stopAndCloseXmtpClient,
|
|
44578
44661
|
stopDaemon: () => stopDaemon,
|
|
44579
44662
|
stopOpenClawGateway: () => stopOpenClawGateway,
|
|
44580
44663
|
stopSystemdAutostart: () => stopSystemdAutostart,
|
|
@@ -56467,6 +56550,188 @@ function reportSessionExpired(command) {
|
|
|
56467
56550
|
);
|
|
56468
56551
|
}
|
|
56469
56552
|
|
|
56553
|
+
// ../core/src/xmtp-sdk/rate-limit-cooldown.ts
|
|
56554
|
+
var MAX_CAUSE_DEPTH2 = 4;
|
|
56555
|
+
var XMTP_CREATION_COOLDOWN_MS = 33e4;
|
|
56556
|
+
var RATE_LIMIT_PATTERNS = [
|
|
56557
|
+
/some resource has been exhausted/i,
|
|
56558
|
+
/exceeds rate limit/i,
|
|
56559
|
+
/resource_exhausted/i
|
|
56560
|
+
];
|
|
56561
|
+
var KNOWN_RATE_LIMIT_ENDPOINTS = [
|
|
56562
|
+
/\bGetInboxIds\b/i,
|
|
56563
|
+
/\bGetIdentityUpdates\b/i
|
|
56564
|
+
];
|
|
56565
|
+
function asErrorLike2(value) {
|
|
56566
|
+
return value instanceof Error ? value : void 0;
|
|
56567
|
+
}
|
|
56568
|
+
function causeChain2(err) {
|
|
56569
|
+
const chain = [];
|
|
56570
|
+
const seen = /* @__PURE__ */ new Set();
|
|
56571
|
+
let current = err;
|
|
56572
|
+
while (chain.length < MAX_CAUSE_DEPTH2) {
|
|
56573
|
+
chain.push(current);
|
|
56574
|
+
const errorLike = asErrorLike2(current);
|
|
56575
|
+
if (!errorLike || seen.has(errorLike)) {
|
|
56576
|
+
break;
|
|
56577
|
+
}
|
|
56578
|
+
seen.add(errorLike);
|
|
56579
|
+
current = errorLike.cause;
|
|
56580
|
+
if (current === void 0) {
|
|
56581
|
+
break;
|
|
56582
|
+
}
|
|
56583
|
+
}
|
|
56584
|
+
return chain;
|
|
56585
|
+
}
|
|
56586
|
+
function messageOf(node) {
|
|
56587
|
+
return (node instanceof Error ? node.message : String(node)).toLowerCase();
|
|
56588
|
+
}
|
|
56589
|
+
function isXmtpRateLimitError(err) {
|
|
56590
|
+
if (err === void 0 || err === null) {
|
|
56591
|
+
return false;
|
|
56592
|
+
}
|
|
56593
|
+
const chain = causeChain2(err);
|
|
56594
|
+
return chain.some(
|
|
56595
|
+
(node) => RATE_LIMIT_PATTERNS.some((pattern) => pattern.test(messageOf(node)))
|
|
56596
|
+
);
|
|
56597
|
+
}
|
|
56598
|
+
function extractRateLimitEndpoint(err) {
|
|
56599
|
+
if (err === void 0 || err === null) {
|
|
56600
|
+
return void 0;
|
|
56601
|
+
}
|
|
56602
|
+
const chain = causeChain2(err);
|
|
56603
|
+
for (const node of chain) {
|
|
56604
|
+
const message = messageOf(node);
|
|
56605
|
+
for (const pattern of KNOWN_RATE_LIMIT_ENDPOINTS) {
|
|
56606
|
+
const match = pattern.exec(message);
|
|
56607
|
+
if (match) {
|
|
56608
|
+
return /GetInboxIds/i.test(match[0]) ? "GetInboxIds" : "GetIdentityUpdates";
|
|
56609
|
+
}
|
|
56610
|
+
}
|
|
56611
|
+
}
|
|
56612
|
+
return void 0;
|
|
56613
|
+
}
|
|
56614
|
+
var XmtpCreationCooldownSkipError = class extends Error {
|
|
56615
|
+
remainingMs;
|
|
56616
|
+
address;
|
|
56617
|
+
agentId;
|
|
56618
|
+
constructor(remainingMs, address, agentId) {
|
|
56619
|
+
super("xmtp creation suppressed during rate-limit cooldown");
|
|
56620
|
+
this.name = "XmtpCreationCooldownSkipError";
|
|
56621
|
+
this.remainingMs = remainingMs;
|
|
56622
|
+
this.address = address;
|
|
56623
|
+
this.agentId = agentId;
|
|
56624
|
+
}
|
|
56625
|
+
};
|
|
56626
|
+
var XmtpCreationCooldown = class {
|
|
56627
|
+
cooldownUntilMs = null;
|
|
56628
|
+
probeInFlight = false;
|
|
56629
|
+
suppressedCreateCount = 0;
|
|
56630
|
+
rateLimitHitCount = 0;
|
|
56631
|
+
probeCount = 0;
|
|
56632
|
+
inFlightCreateCount = 0;
|
|
56633
|
+
beginCreateAttempt(nowMs = Date.now()) {
|
|
56634
|
+
if (this.cooldownUntilMs === null) {
|
|
56635
|
+
this.inFlightCreateCount++;
|
|
56636
|
+
return { allowed: true, mode: "normal" };
|
|
56637
|
+
}
|
|
56638
|
+
if (nowMs < this.cooldownUntilMs) {
|
|
56639
|
+
this.suppressedCreateCount++;
|
|
56640
|
+
return {
|
|
56641
|
+
allowed: false,
|
|
56642
|
+
mode: "blocked",
|
|
56643
|
+
remainingMs: Math.max(0, this.cooldownUntilMs - nowMs)
|
|
56644
|
+
};
|
|
56645
|
+
}
|
|
56646
|
+
if (this.probeInFlight) {
|
|
56647
|
+
this.suppressedCreateCount++;
|
|
56648
|
+
return { allowed: false, mode: "blocked", remainingMs: 0 };
|
|
56649
|
+
}
|
|
56650
|
+
this.probeInFlight = true;
|
|
56651
|
+
this.inFlightCreateCount++;
|
|
56652
|
+
this.probeCount++;
|
|
56653
|
+
return { allowed: true, mode: "probe" };
|
|
56654
|
+
}
|
|
56655
|
+
recordCreateSuccess(decision, _nowMs = Date.now()) {
|
|
56656
|
+
this.inFlightCreateCount = Math.max(0, this.inFlightCreateCount - 1);
|
|
56657
|
+
if (decision.mode === "probe") {
|
|
56658
|
+
this.cooldownUntilMs = null;
|
|
56659
|
+
this.probeInFlight = false;
|
|
56660
|
+
}
|
|
56661
|
+
}
|
|
56662
|
+
recordRateLimit(decision, nowMs = Date.now()) {
|
|
56663
|
+
this.inFlightCreateCount = Math.max(0, this.inFlightCreateCount - 1);
|
|
56664
|
+
this.cooldownUntilMs = nowMs + XMTP_CREATION_COOLDOWN_MS;
|
|
56665
|
+
this.rateLimitHitCount++;
|
|
56666
|
+
this.probeInFlight = false;
|
|
56667
|
+
void decision;
|
|
56668
|
+
}
|
|
56669
|
+
recordCreateFailure(decision, nowMs = Date.now()) {
|
|
56670
|
+
this.inFlightCreateCount = Math.max(0, this.inFlightCreateCount - 1);
|
|
56671
|
+
if (decision.mode === "probe") {
|
|
56672
|
+
this.cooldownUntilMs = nowMs + XMTP_CREATION_COOLDOWN_MS;
|
|
56673
|
+
this.probeInFlight = false;
|
|
56674
|
+
}
|
|
56675
|
+
}
|
|
56676
|
+
isCoolingDown(nowMs = Date.now()) {
|
|
56677
|
+
return this.cooldownUntilMs !== null && nowMs < this.cooldownUntilMs;
|
|
56678
|
+
}
|
|
56679
|
+
remainingMs(nowMs = Date.now()) {
|
|
56680
|
+
return this.cooldownUntilMs === null ? 0 : Math.max(0, this.cooldownUntilMs - nowMs);
|
|
56681
|
+
}
|
|
56682
|
+
snapshot(nowMs = Date.now()) {
|
|
56683
|
+
return {
|
|
56684
|
+
coolingDown: this.isCoolingDown(nowMs),
|
|
56685
|
+
cooldownUntilMs: this.cooldownUntilMs,
|
|
56686
|
+
remainingMs: this.remainingMs(nowMs),
|
|
56687
|
+
probeInFlight: this.probeInFlight,
|
|
56688
|
+
suppressedCreateCount: this.suppressedCreateCount,
|
|
56689
|
+
rateLimitHitCount: this.rateLimitHitCount,
|
|
56690
|
+
probeCount: this.probeCount,
|
|
56691
|
+
inFlightCreateCount: this.inFlightCreateCount
|
|
56692
|
+
};
|
|
56693
|
+
}
|
|
56694
|
+
resetForTests() {
|
|
56695
|
+
this.cooldownUntilMs = null;
|
|
56696
|
+
this.probeInFlight = false;
|
|
56697
|
+
this.suppressedCreateCount = 0;
|
|
56698
|
+
this.rateLimitHitCount = 0;
|
|
56699
|
+
this.probeCount = 0;
|
|
56700
|
+
this.inFlightCreateCount = 0;
|
|
56701
|
+
}
|
|
56702
|
+
};
|
|
56703
|
+
var singleton;
|
|
56704
|
+
function getXmtpCreationCooldown() {
|
|
56705
|
+
if (!singleton) {
|
|
56706
|
+
singleton = new XmtpCreationCooldown();
|
|
56707
|
+
}
|
|
56708
|
+
return singleton;
|
|
56709
|
+
}
|
|
56710
|
+
function resetXmtpCreationCooldownForTests() {
|
|
56711
|
+
getXmtpCreationCooldown().resetForTests();
|
|
56712
|
+
}
|
|
56713
|
+
|
|
56714
|
+
// ../core/src/xmtp-sdk/client-lifecycle.ts
|
|
56715
|
+
async function stopAndCloseXmtpClient(agent, ctx) {
|
|
56716
|
+
let stopped = true;
|
|
56717
|
+
try {
|
|
56718
|
+
await Promise.resolve(agent.stop());
|
|
56719
|
+
} catch {
|
|
56720
|
+
stopped = false;
|
|
56721
|
+
}
|
|
56722
|
+
const close2 = agent.client?.close;
|
|
56723
|
+
if (typeof close2 !== "function") {
|
|
56724
|
+
return { stopped, closed: false, closeFailed: false };
|
|
56725
|
+
}
|
|
56726
|
+
try {
|
|
56727
|
+
await Promise.resolve(close2.call(agent.client));
|
|
56728
|
+
return { stopped, closed: true, closeFailed: false };
|
|
56729
|
+
} catch (err) {
|
|
56730
|
+
ctx.onCloseError?.(err);
|
|
56731
|
+
return { stopped, closed: false, closeFailed: true };
|
|
56732
|
+
}
|
|
56733
|
+
}
|
|
56734
|
+
|
|
56470
56735
|
// ../core/src/xmtp-sdk/index.ts
|
|
56471
56736
|
var DEFAULT_DATA_DIR = resolveA2aTaskPaths().xmtpDir;
|
|
56472
56737
|
var XMTP_INSTALLATION_WARNING_THRESHOLD = 2;
|
|
@@ -57150,21 +57415,78 @@ var XmtpService = class _XmtpService {
|
|
|
57150
57415
|
}
|
|
57151
57416
|
async createClientForAgent(agentInfo, options = {}) {
|
|
57152
57417
|
const address = agentInfo.communicationAddress;
|
|
57153
|
-
const
|
|
57154
|
-
const
|
|
57155
|
-
const
|
|
57156
|
-
|
|
57157
|
-
|
|
57158
|
-
|
|
57159
|
-
|
|
57160
|
-
|
|
57161
|
-
|
|
57162
|
-
|
|
57163
|
-
|
|
57164
|
-
|
|
57165
|
-
|
|
57166
|
-
|
|
57167
|
-
|
|
57418
|
+
const phase = options.logPrefix ?? "[xmtp-sdk]";
|
|
57419
|
+
const cooldown = getXmtpCreationCooldown();
|
|
57420
|
+
const decision = cooldown.beginCreateAttempt();
|
|
57421
|
+
if (!decision.allowed) {
|
|
57422
|
+
logger.info(LogEvent.XMTP_RATE_LIMIT_CREATE_SUPPRESSED, {
|
|
57423
|
+
onchainosAgentId: agentInfo.agentId,
|
|
57424
|
+
walletAddress: address,
|
|
57425
|
+
cooldownRemainingMs: String(decision.remainingMs ?? 0),
|
|
57426
|
+
phase
|
|
57427
|
+
});
|
|
57428
|
+
throw new XmtpCreationCooldownSkipError(
|
|
57429
|
+
decision.remainingMs ?? 0,
|
|
57430
|
+
address,
|
|
57431
|
+
agentInfo.agentId
|
|
57432
|
+
);
|
|
57433
|
+
}
|
|
57434
|
+
if (decision.mode === "probe") {
|
|
57435
|
+
logger.info(LogEvent.XMTP_RATE_LIMIT_PROBE, {
|
|
57436
|
+
onchainosAgentId: agentInfo.agentId,
|
|
57437
|
+
walletAddress: address,
|
|
57438
|
+
phase: "probe-start",
|
|
57439
|
+
probeCount: String(cooldown.snapshot().probeCount)
|
|
57440
|
+
});
|
|
57441
|
+
}
|
|
57442
|
+
try {
|
|
57443
|
+
const signer = this.tools.createSigner(agentInfo);
|
|
57444
|
+
const dbPath = (inboxId2) => `${this.dataDir}/${inboxId2}-${this.env}.db3`;
|
|
57445
|
+
const agent = await createAgentWithInstallationPrune(signer, {
|
|
57446
|
+
dbPath,
|
|
57447
|
+
env: this.env
|
|
57448
|
+
}, {
|
|
57449
|
+
address,
|
|
57450
|
+
agentId: agentInfo.agentId,
|
|
57451
|
+
logPrefix: options.logPrefix
|
|
57452
|
+
});
|
|
57453
|
+
cooldown.recordCreateSuccess(decision);
|
|
57454
|
+
if (decision.mode === "probe") {
|
|
57455
|
+
logger.info(LogEvent.XMTP_RATE_LIMIT_RECOVERED, {
|
|
57456
|
+
onchainosAgentId: agentInfo.agentId,
|
|
57457
|
+
walletAddress: address,
|
|
57458
|
+
phase: "probe-success"
|
|
57459
|
+
});
|
|
57460
|
+
}
|
|
57461
|
+
const inboxId = agent.client?.inboxId ?? "";
|
|
57462
|
+
logWithTimestamp(
|
|
57463
|
+
`[xmtp-sdk] xmtp_client_ready agentId=${agentInfo.agentId} address=${address} inboxId=${inboxId} dbPath=${inboxId ? dbPath(inboxId) : "(unknown)"} lastSync=${formatLogTimestamp2(this.syncByAddress.get(address))}`
|
|
57464
|
+
);
|
|
57465
|
+
return { address, agent, agentInfo };
|
|
57466
|
+
} catch (err) {
|
|
57467
|
+
if (isXmtpRateLimitError(err)) {
|
|
57468
|
+
cooldown.recordRateLimit(decision);
|
|
57469
|
+
logger.info(LogEvent.XMTP_RATE_LIMIT_COOLDOWN_STARTED, {
|
|
57470
|
+
...agentExtras({ walletAddress: address, onchainosAgentId: agentInfo.agentId }),
|
|
57471
|
+
rateLimitIdentified: "true",
|
|
57472
|
+
endpoint: extractRateLimitEndpoint(err) ?? "unknown",
|
|
57473
|
+
cooldownMs: String(XMTP_CREATION_COOLDOWN_MS),
|
|
57474
|
+
cooldownExpiresAtMs: String(cooldown.snapshot().cooldownUntilMs ?? ""),
|
|
57475
|
+
inFlightCreateCount: String(cooldown.snapshot().inFlightCreateCount),
|
|
57476
|
+
probe: String(decision.mode === "probe")
|
|
57477
|
+
});
|
|
57478
|
+
} else {
|
|
57479
|
+
cooldown.recordCreateFailure(decision);
|
|
57480
|
+
if (decision.mode === "probe") {
|
|
57481
|
+
logger.info(LogEvent.XMTP_RATE_LIMIT_PROBE, {
|
|
57482
|
+
onchainosAgentId: agentInfo.agentId,
|
|
57483
|
+
walletAddress: address,
|
|
57484
|
+
phase: "probe-failed-nonratelimit"
|
|
57485
|
+
});
|
|
57486
|
+
}
|
|
57487
|
+
}
|
|
57488
|
+
throw err;
|
|
57489
|
+
}
|
|
57168
57490
|
}
|
|
57169
57491
|
async recordInstallationHealth(params) {
|
|
57170
57492
|
const { address, agent, agentInfo, phase, attempt } = params;
|
|
@@ -57315,22 +57637,28 @@ var XmtpService = class _XmtpService {
|
|
|
57315
57637
|
});
|
|
57316
57638
|
} else {
|
|
57317
57639
|
failedAgents.push(agents[i]);
|
|
57318
|
-
|
|
57319
|
-
|
|
57320
|
-
|
|
57321
|
-
|
|
57322
|
-
|
|
57323
|
-
|
|
57324
|
-
|
|
57325
|
-
|
|
57326
|
-
|
|
57327
|
-
|
|
57328
|
-
|
|
57329
|
-
|
|
57330
|
-
|
|
57640
|
+
if (r.reason instanceof XmtpCreationCooldownSkipError) {
|
|
57641
|
+
logWithTimestamp(
|
|
57642
|
+
`[xmtp-sdk] identity init suppressed (rate-limit cooldown): ${agents[i].communicationAddress} (agentId=${agents[i].agentId})`
|
|
57643
|
+
);
|
|
57644
|
+
} else {
|
|
57645
|
+
logWithTimestamp(
|
|
57646
|
+
`[xmtp-sdk] identity init failed: ${agents[i].communicationAddress} (agentId=${agents[i].agentId})`,
|
|
57647
|
+
r.reason
|
|
57648
|
+
);
|
|
57649
|
+
logger.error(
|
|
57650
|
+
LogEvent.XMTP_CONNECTION_FAILED,
|
|
57651
|
+
r.reason instanceof Error ? r.reason : new Error(String(r.reason)),
|
|
57652
|
+
{
|
|
57653
|
+
walletAddress: agents[i].communicationAddress,
|
|
57654
|
+
onchainosAgentId: agents[i].agentId,
|
|
57655
|
+
attempt: "1"
|
|
57656
|
+
}
|
|
57657
|
+
);
|
|
57658
|
+
}
|
|
57331
57659
|
}
|
|
57332
57660
|
}
|
|
57333
|
-
if (failedAgents.length > 0) {
|
|
57661
|
+
if (failedAgents.length > 0 && !getXmtpCreationCooldown().isCoolingDown()) {
|
|
57334
57662
|
logWithTimestamp(
|
|
57335
57663
|
`[xmtp-sdk] ${failedAgents.length} client(s) failed to initialize, retrying in 1s...`
|
|
57336
57664
|
);
|
|
@@ -57370,6 +57698,11 @@ var XmtpService = class _XmtpService {
|
|
|
57370
57698
|
phase: "init",
|
|
57371
57699
|
attempt: "2"
|
|
57372
57700
|
});
|
|
57701
|
+
} else if (r.reason instanceof XmtpCreationCooldownSkipError) {
|
|
57702
|
+
const info = failedAgents[i];
|
|
57703
|
+
logWithTimestamp(
|
|
57704
|
+
`[xmtp-sdk] retry suppressed (rate-limit cooldown): ${info.communicationAddress} (agentId=${info.agentId})`
|
|
57705
|
+
);
|
|
57373
57706
|
} else {
|
|
57374
57707
|
const info = failedAgents[i];
|
|
57375
57708
|
logWithTimestamp(
|
|
@@ -57465,7 +57798,16 @@ var XmtpService = class _XmtpService {
|
|
|
57465
57798
|
try {
|
|
57466
57799
|
this.cancelStreamRecoveryForAddress(address);
|
|
57467
57800
|
this.stoppedAddresses.add(address.toLowerCase());
|
|
57468
|
-
client
|
|
57801
|
+
await stopAndCloseXmtpClient(client, {
|
|
57802
|
+
address,
|
|
57803
|
+
agentId: agentInfo.agentId,
|
|
57804
|
+
phase: "refresh/remove",
|
|
57805
|
+
onCloseError: (err) => logger.error(
|
|
57806
|
+
LogEvent.XMTP_CLIENT_CLOSE_FAILED,
|
|
57807
|
+
err instanceof Error ? err : new Error(String(err)),
|
|
57808
|
+
{ walletAddress: address, onchainosAgentId: agentInfo.agentId, phase: "refresh/remove" }
|
|
57809
|
+
)
|
|
57810
|
+
});
|
|
57469
57811
|
logWithTimestamp(
|
|
57470
57812
|
`[xmtp-sdk] refresh: stopped client: ${address} (agentId=${agentInfo.agentId})`
|
|
57471
57813
|
);
|
|
@@ -57552,23 +57894,29 @@ var XmtpService = class _XmtpService {
|
|
|
57552
57894
|
});
|
|
57553
57895
|
} else {
|
|
57554
57896
|
failedAgents.push(added[i]);
|
|
57555
|
-
|
|
57556
|
-
|
|
57557
|
-
|
|
57558
|
-
|
|
57559
|
-
|
|
57560
|
-
|
|
57561
|
-
|
|
57562
|
-
|
|
57563
|
-
|
|
57564
|
-
|
|
57565
|
-
|
|
57566
|
-
|
|
57567
|
-
|
|
57568
|
-
|
|
57897
|
+
if (r.reason instanceof XmtpCreationCooldownSkipError) {
|
|
57898
|
+
logWithTimestamp(
|
|
57899
|
+
`[xmtp-sdk] refresh: identity init suppressed (rate-limit cooldown): ${added[i].communicationAddress} (agentId=${added[i].agentId})`
|
|
57900
|
+
);
|
|
57901
|
+
} else {
|
|
57902
|
+
logWithTimestamp(
|
|
57903
|
+
`[xmtp-sdk] refresh: identity init failed: ${added[i].communicationAddress} (agentId=${added[i].agentId})`,
|
|
57904
|
+
r.reason
|
|
57905
|
+
);
|
|
57906
|
+
logger.error(
|
|
57907
|
+
LogEvent.XMTP_CONNECTION_FAILED,
|
|
57908
|
+
r.reason instanceof Error ? r.reason : new Error(String(r.reason)),
|
|
57909
|
+
{
|
|
57910
|
+
walletAddress: added[i].communicationAddress,
|
|
57911
|
+
onchainosAgentId: added[i].agentId,
|
|
57912
|
+
phase: "refresh",
|
|
57913
|
+
attempt: "1"
|
|
57914
|
+
}
|
|
57915
|
+
);
|
|
57916
|
+
}
|
|
57569
57917
|
}
|
|
57570
57918
|
}
|
|
57571
|
-
if (failedAgents.length > 0) {
|
|
57919
|
+
if (failedAgents.length > 0 && !getXmtpCreationCooldown().isCoolingDown()) {
|
|
57572
57920
|
logWithTimestamp(
|
|
57573
57921
|
`[xmtp-sdk] refresh: ${failedAgents.length} client(s) failed to initialize, retrying in 1s...`
|
|
57574
57922
|
);
|
|
@@ -57611,6 +57959,11 @@ var XmtpService = class _XmtpService {
|
|
|
57611
57959
|
phase: "refresh",
|
|
57612
57960
|
attempt: "2"
|
|
57613
57961
|
});
|
|
57962
|
+
} else if (r.reason instanceof XmtpCreationCooldownSkipError) {
|
|
57963
|
+
const info = failedAgents[i];
|
|
57964
|
+
logWithTimestamp(
|
|
57965
|
+
`[xmtp-sdk] refresh: retry suppressed (rate-limit cooldown): ${info.communicationAddress} (agentId=${info.agentId})`
|
|
57966
|
+
);
|
|
57614
57967
|
} else {
|
|
57615
57968
|
const info = failedAgents[i];
|
|
57616
57969
|
logWithTimestamp(
|
|
@@ -57674,6 +58027,18 @@ var XmtpService = class _XmtpService {
|
|
|
57674
58027
|
async recycleXmtpClients() {
|
|
57675
58028
|
await this._backupReady;
|
|
57676
58029
|
const startedAt = Date.now();
|
|
58030
|
+
if (getXmtpCreationCooldown().isCoolingDown()) {
|
|
58031
|
+
logWithTimestamp("[xmtp-sdk] recycle skipped \u2014 rate-limit cooldown active");
|
|
58032
|
+
return {
|
|
58033
|
+
clients: this.clients.size,
|
|
58034
|
+
recycled: 0,
|
|
58035
|
+
failed: 0,
|
|
58036
|
+
replayed: 0,
|
|
58037
|
+
skipped: 0,
|
|
58038
|
+
durationMs: Date.now() - startedAt,
|
|
58039
|
+
addresses: []
|
|
58040
|
+
};
|
|
58041
|
+
}
|
|
57677
58042
|
const addresses = [];
|
|
57678
58043
|
let recycled = 0;
|
|
57679
58044
|
let failed = 0;
|
|
@@ -57692,7 +58057,16 @@ var XmtpService = class _XmtpService {
|
|
|
57692
58057
|
try {
|
|
57693
58058
|
this.cancelStreamRecoveryForAddress(address);
|
|
57694
58059
|
this.stoppedAddresses.add(addressKey);
|
|
57695
|
-
await
|
|
58060
|
+
await stopAndCloseXmtpClient(oldClient, {
|
|
58061
|
+
address,
|
|
58062
|
+
agentId: agentInfo.agentId,
|
|
58063
|
+
phase: "recycle",
|
|
58064
|
+
onCloseError: (err) => logger.error(
|
|
58065
|
+
LogEvent.XMTP_CLIENT_CLOSE_FAILED,
|
|
58066
|
+
err instanceof Error ? err : new Error(String(err)),
|
|
58067
|
+
{ walletAddress: address, onchainosAgentId: agentInfo.agentId, phase: "recycle" }
|
|
58068
|
+
)
|
|
58069
|
+
});
|
|
57696
58070
|
this.clients.delete(address);
|
|
57697
58071
|
this.inboundReplayGates.delete(addressKey);
|
|
57698
58072
|
this.replayScanFailuresByAddress.delete(addressKey);
|
|
@@ -57779,6 +58153,12 @@ var XmtpService = class _XmtpService {
|
|
|
57779
58153
|
phase: "recycle/create-client"
|
|
57780
58154
|
}
|
|
57781
58155
|
);
|
|
58156
|
+
if (isXmtpRateLimitError(err)) {
|
|
58157
|
+
logWithTimestamp(
|
|
58158
|
+
"[xmtp-sdk] recycle: rate-limit on recreate \u2014 stopping remaining recycles"
|
|
58159
|
+
);
|
|
58160
|
+
break;
|
|
58161
|
+
}
|
|
57782
58162
|
}
|
|
57783
58163
|
}
|
|
57784
58164
|
return {
|
|
@@ -60854,12 +61234,12 @@ var SessionBusyTracker = class {
|
|
|
60854
61234
|
}
|
|
60855
61235
|
}
|
|
60856
61236
|
};
|
|
60857
|
-
var
|
|
61237
|
+
var singleton2 = null;
|
|
60858
61238
|
function getSessionBusyTracker() {
|
|
60859
|
-
if (!
|
|
60860
|
-
|
|
61239
|
+
if (!singleton2) {
|
|
61240
|
+
singleton2 = new SessionBusyTracker();
|
|
60861
61241
|
}
|
|
60862
|
-
return
|
|
61242
|
+
return singleton2;
|
|
60863
61243
|
}
|
|
60864
61244
|
|
|
60865
61245
|
// src/openclaw-gateway.ts
|
|
@@ -61394,7 +61774,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
|
|
|
61394
61774
|
client: {
|
|
61395
61775
|
id: "gateway-client",
|
|
61396
61776
|
displayName: "okx-a2a-node",
|
|
61397
|
-
version: "0.2.
|
|
61777
|
+
version: "0.2.17-beta-ab42219842-261020165552",
|
|
61398
61778
|
platform: "node",
|
|
61399
61779
|
mode: "backend",
|
|
61400
61780
|
instanceId
|
|
@@ -61405,7 +61785,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
|
|
|
61405
61785
|
commands: [],
|
|
61406
61786
|
permissions: {},
|
|
61407
61787
|
locale: Intl.DateTimeFormat().resolvedOptions().locale || "en-US",
|
|
61408
|
-
userAgent: `okx-a2a-node/${"0.2.
|
|
61788
|
+
userAgent: `okx-a2a-node/${"0.2.17-beta-ab42219842-261020165552"}`,
|
|
61409
61789
|
auth: {
|
|
61410
61790
|
...config.token ? { token: config.token } : {},
|
|
61411
61791
|
...config.password ? { password: config.password } : {}
|
|
@@ -66998,8 +67378,8 @@ function isA2AEnvelope(payload) {
|
|
|
66998
67378
|
|
|
66999
67379
|
// src/listener.ts
|
|
67000
67380
|
init_log();
|
|
67001
|
-
var
|
|
67002
|
-
var
|
|
67381
|
+
var import_node_fs20 = require("node:fs");
|
|
67382
|
+
var import_promises9 = require("node:fs/promises");
|
|
67003
67383
|
var import_node_os8 = require("node:os");
|
|
67004
67384
|
var import_node_path25 = require("node:path");
|
|
67005
67385
|
|
|
@@ -67110,6 +67490,398 @@ function createOnchainosSigner(agent) {
|
|
|
67110
67490
|
// src/listener.ts
|
|
67111
67491
|
init_session_store();
|
|
67112
67492
|
|
|
67493
|
+
// src/devkit-delivery.ts
|
|
67494
|
+
var import_node_net2 = require("node:net");
|
|
67495
|
+
var import_promises8 = require("node:dns/promises");
|
|
67496
|
+
init_sentry_logger();
|
|
67497
|
+
init_error_diagnostics();
|
|
67498
|
+
|
|
67499
|
+
// src/devkit-types.ts
|
|
67500
|
+
var DEVKIT_MAX_CONCURRENCY = 16;
|
|
67501
|
+
var DEVKIT_MAX_PENDING = 256;
|
|
67502
|
+
var DEVKIT_MAX_PENDING_BYTES = 16 * 1024 * 1024;
|
|
67503
|
+
var DEVKIT_MAX_MESSAGE_BYTES = 1 * 1024 * 1024;
|
|
67504
|
+
var DEVKIT_REQUEST_BUDGET_MS = 5e3;
|
|
67505
|
+
var DEVKIT_RESPONSE_DIAGNOSTIC_MAX_BYTES = 4 * 1024;
|
|
67506
|
+
var DEVKIT_RESPONSE_SUMMARY_MAX_CHARS = 256;
|
|
67507
|
+
var DEVKIT_OUTCOME = {
|
|
67508
|
+
HTTP_ACCEPTED: "http_accepted",
|
|
67509
|
+
DROPPED: "dropped"
|
|
67510
|
+
};
|
|
67511
|
+
var DEVKIT_DROP_REASON = {
|
|
67512
|
+
REQUEST_TOO_LARGE: "request_too_large",
|
|
67513
|
+
// serialized > 1 MiB (FR-3-AC-6)
|
|
67514
|
+
PENDING_OVERFLOW: "pending_overflow",
|
|
67515
|
+
// > 256 items or > 16 MiB total pending (NFR-2-AC-1)
|
|
67516
|
+
CONFIG_CHANGED: "config_changed",
|
|
67517
|
+
// snapshot version changed/removed before send (FR-2-AC-6)
|
|
67518
|
+
CONFIG_READ_FAILED: "config_read_failed",
|
|
67519
|
+
// snapshot unreadable/corrupt (FR-2-AC-5)
|
|
67520
|
+
HTTP_STATUS: "http_status",
|
|
67521
|
+
// non-2xx response (FR-3-AC-3)
|
|
67522
|
+
REDIRECT_BLOCKED: "redirect_blocked",
|
|
67523
|
+
// 3xx response, not followed (NFR-3-AC-2)
|
|
67524
|
+
CONNECTION_FAILED: "connection_failed",
|
|
67525
|
+
// ECONNREFUSED / reset / unreachable (FR-3-AC-4)
|
|
67526
|
+
TIMEOUT: "timeout",
|
|
67527
|
+
// exceeded the 5 s budget (FR-3-AC-4)
|
|
67528
|
+
REQUEST_BUILD_ERROR: "request_build_error",
|
|
67529
|
+
// serialization / target build failure
|
|
67530
|
+
RESPONSE_READ_ERROR: "response_read_error",
|
|
67531
|
+
// diagnostic read failure
|
|
67532
|
+
SHUTDOWN_CANCELLED: "shutdown_cancelled"
|
|
67533
|
+
// daemon stopped before send (NFR-2-AC-3)
|
|
67534
|
+
};
|
|
67535
|
+
|
|
67536
|
+
// src/devkit-delivery.ts
|
|
67537
|
+
var COMPONENT = "node_devkit";
|
|
67538
|
+
var SECRET_KEYS = "authorization|bearer|basic|jwt|password|api[_-]?key|secret|token";
|
|
67539
|
+
var SECRET_SCHEME_PATTERN = new RegExp(`\\b(?:${SECRET_KEYS})\\s+\\S+`, "gi");
|
|
67540
|
+
var SECRET_KV_PATTERN = new RegExp(
|
|
67541
|
+
`("?)(${SECRET_KEYS})("?)\\s*([:=])\\s*"?[^"\\s,}]+`,
|
|
67542
|
+
"gi"
|
|
67543
|
+
);
|
|
67544
|
+
function fallbackDeliveryId(parts) {
|
|
67545
|
+
return `devkit-${parts.jobId ?? "none"}-${parts.sessionKey ?? "none"}-${parts.receivedAt}`;
|
|
67546
|
+
}
|
|
67547
|
+
function buildSessionEnvelope(ev, ctx = {}) {
|
|
67548
|
+
const now = ctx.now ?? Date.now;
|
|
67549
|
+
const receivedAt = Math.floor(now() / 1e3);
|
|
67550
|
+
const jobId = ev.jobId ?? null;
|
|
67551
|
+
const agentId = ev.agentId ?? null;
|
|
67552
|
+
const deliveryId = ev.messageId ?? fallbackDeliveryId({ jobId, sessionKey: ev.sessionKey, receivedAt });
|
|
67553
|
+
const messageId = ev.messageId ?? deliveryId;
|
|
67554
|
+
return {
|
|
67555
|
+
deliveryId,
|
|
67556
|
+
receivedAt,
|
|
67557
|
+
kind: "session",
|
|
67558
|
+
agentId,
|
|
67559
|
+
event: {
|
|
67560
|
+
sessionKey: ev.sessionKey,
|
|
67561
|
+
content: ev.content,
|
|
67562
|
+
messageId,
|
|
67563
|
+
jobId,
|
|
67564
|
+
agentId
|
|
67565
|
+
}
|
|
67566
|
+
};
|
|
67567
|
+
}
|
|
67568
|
+
function buildJobEnvelope(ev, _ctx = {}) {
|
|
67569
|
+
const sessionAgentId = ev.sessionAgentId ?? null;
|
|
67570
|
+
const receivedAt = Math.floor(ev.message.receivedAtMs / 1e3);
|
|
67571
|
+
return {
|
|
67572
|
+
deliveryId: ev.message.id,
|
|
67573
|
+
receivedAt,
|
|
67574
|
+
kind: "job",
|
|
67575
|
+
agentId: sessionAgentId,
|
|
67576
|
+
event: {
|
|
67577
|
+
jobId: ev.jobId,
|
|
67578
|
+
sessionAgentId,
|
|
67579
|
+
message: {
|
|
67580
|
+
...ev.message,
|
|
67581
|
+
content: ev.message.rawText
|
|
67582
|
+
}
|
|
67583
|
+
}
|
|
67584
|
+
};
|
|
67585
|
+
}
|
|
67586
|
+
function classifyHttpOutcome(status) {
|
|
67587
|
+
if (status >= 200 && status < 300) {
|
|
67588
|
+
return { outcome: DEVKIT_OUTCOME.HTTP_ACCEPTED };
|
|
67589
|
+
}
|
|
67590
|
+
if (status >= 300 && status < 400) {
|
|
67591
|
+
return { outcome: DEVKIT_OUTCOME.DROPPED, reason: DEVKIT_DROP_REASON.REDIRECT_BLOCKED };
|
|
67592
|
+
}
|
|
67593
|
+
return { outcome: DEVKIT_OUTCOME.DROPPED, reason: DEVKIT_DROP_REASON.HTTP_STATUS };
|
|
67594
|
+
}
|
|
67595
|
+
function classifyFetchFailure(params) {
|
|
67596
|
+
if (params.cancelledByShutdown) {
|
|
67597
|
+
return DEVKIT_DROP_REASON.SHUTDOWN_CANCELLED;
|
|
67598
|
+
}
|
|
67599
|
+
if (params.timedOut || params.errorCategory === "timeout") {
|
|
67600
|
+
return DEVKIT_DROP_REASON.TIMEOUT;
|
|
67601
|
+
}
|
|
67602
|
+
return DEVKIT_DROP_REASON.CONNECTION_FAILED;
|
|
67603
|
+
}
|
|
67604
|
+
function redactSummary(raw) {
|
|
67605
|
+
const collapsed = raw.replace(/\s+/g, " ").trim();
|
|
67606
|
+
const redacted = collapsed.replace(SECRET_SCHEME_PATTERN, "[REDACTED]").replace(
|
|
67607
|
+
SECRET_KV_PATTERN,
|
|
67608
|
+
(_match, keyQuote, key, keyQuoteClose, sep3) => `${keyQuote}${key}${keyQuoteClose}${sep3}[REDACTED]`
|
|
67609
|
+
);
|
|
67610
|
+
const truncated = redacted.length > DEVKIT_RESPONSE_SUMMARY_MAX_CHARS;
|
|
67611
|
+
return { text: redacted.slice(0, DEVKIT_RESPONSE_SUMMARY_MAX_CHARS), truncated };
|
|
67612
|
+
}
|
|
67613
|
+
async function readRedactedResponse(response) {
|
|
67614
|
+
let bodyText;
|
|
67615
|
+
try {
|
|
67616
|
+
bodyText = await response.text();
|
|
67617
|
+
} catch {
|
|
67618
|
+
return { responseBytesRead: 0, responseTruncated: false, responseSummary: "" };
|
|
67619
|
+
}
|
|
67620
|
+
const bytes = Buffer.from(bodyText, "utf8");
|
|
67621
|
+
const diagnosticSlice = bytes.subarray(0, DEVKIT_RESPONSE_DIAGNOSTIC_MAX_BYTES);
|
|
67622
|
+
const sliceTruncated = bytes.byteLength > DEVKIT_RESPONSE_DIAGNOSTIC_MAX_BYTES;
|
|
67623
|
+
const summary = redactSummary(diagnosticSlice.toString("utf8"));
|
|
67624
|
+
return {
|
|
67625
|
+
responseBytesRead: diagnosticSlice.byteLength,
|
|
67626
|
+
responseTruncated: sliceTruncated || summary.truncated,
|
|
67627
|
+
responseSummary: summary.text
|
|
67628
|
+
};
|
|
67629
|
+
}
|
|
67630
|
+
async function isLoopbackTarget(origin) {
|
|
67631
|
+
let hostname;
|
|
67632
|
+
try {
|
|
67633
|
+
hostname = new URL(origin).hostname;
|
|
67634
|
+
} catch {
|
|
67635
|
+
return false;
|
|
67636
|
+
}
|
|
67637
|
+
const version3 = (0, import_node_net2.isIP)(hostname);
|
|
67638
|
+
if (version3 === 4) {
|
|
67639
|
+
return hostname.startsWith("127.");
|
|
67640
|
+
}
|
|
67641
|
+
if (version3 === 6) {
|
|
67642
|
+
return hostname === "::1";
|
|
67643
|
+
}
|
|
67644
|
+
if (hostname.toLowerCase() !== "localhost") {
|
|
67645
|
+
return false;
|
|
67646
|
+
}
|
|
67647
|
+
try {
|
|
67648
|
+
const resolved = await (0, import_promises8.lookup)(hostname);
|
|
67649
|
+
return resolved.family === 4 ? resolved.address.startsWith("127.") : resolved.address === "::1";
|
|
67650
|
+
} catch {
|
|
67651
|
+
return false;
|
|
67652
|
+
}
|
|
67653
|
+
}
|
|
67654
|
+
function orderingKeyFor(envelope) {
|
|
67655
|
+
if (envelope.kind === "session") {
|
|
67656
|
+
return `session:${envelope.event.sessionKey}`;
|
|
67657
|
+
}
|
|
67658
|
+
return `job:${envelope.event.jobId}`;
|
|
67659
|
+
}
|
|
67660
|
+
function sleep4(ms) {
|
|
67661
|
+
return new Promise((resolve11) => setTimeout(resolve11, Math.max(0, ms)));
|
|
67662
|
+
}
|
|
67663
|
+
var DevkitDeliveryDispatcher = class {
|
|
67664
|
+
readSnapshot;
|
|
67665
|
+
now;
|
|
67666
|
+
fetchImpl;
|
|
67667
|
+
pendingQueue = [];
|
|
67668
|
+
pendingBytes = 0;
|
|
67669
|
+
activeKeys = /* @__PURE__ */ new Set();
|
|
67670
|
+
inFlight = /* @__PURE__ */ new Set();
|
|
67671
|
+
activeControllers = /* @__PURE__ */ new Map();
|
|
67672
|
+
shuttingDown = false;
|
|
67673
|
+
constructor(options) {
|
|
67674
|
+
this.readSnapshot = options.readSnapshot;
|
|
67675
|
+
this.now = options.now ?? Date.now;
|
|
67676
|
+
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
67677
|
+
}
|
|
67678
|
+
enqueue(input) {
|
|
67679
|
+
const serialized = JSON.stringify(input.envelope);
|
|
67680
|
+
const bytes = Buffer.byteLength(serialized, "utf8");
|
|
67681
|
+
const kind = input.envelope.kind;
|
|
67682
|
+
const deliveryId = input.envelope.deliveryId;
|
|
67683
|
+
if (bytes > DEVKIT_MAX_MESSAGE_BYTES) {
|
|
67684
|
+
this.emitDropped({ deliveryId, kind, reason: DEVKIT_DROP_REASON.REQUEST_TOO_LARGE, durationMs: 0 });
|
|
67685
|
+
return true;
|
|
67686
|
+
}
|
|
67687
|
+
if (this.pendingQueue.length >= DEVKIT_MAX_PENDING || this.pendingBytes + bytes > DEVKIT_MAX_PENDING_BYTES) {
|
|
67688
|
+
this.emitDropped({ deliveryId, kind, reason: DEVKIT_DROP_REASON.PENDING_OVERFLOW, durationMs: 0 });
|
|
67689
|
+
return false;
|
|
67690
|
+
}
|
|
67691
|
+
this.pendingQueue.push({
|
|
67692
|
+
envelope: input.envelope,
|
|
67693
|
+
config: input.config,
|
|
67694
|
+
serialized,
|
|
67695
|
+
bytes,
|
|
67696
|
+
cancelledByShutdown: false,
|
|
67697
|
+
timedOut: false
|
|
67698
|
+
});
|
|
67699
|
+
this.pendingBytes += bytes;
|
|
67700
|
+
logger.info(LogEvent.DEVKIT_DELIVERY_ACCEPTED, {
|
|
67701
|
+
component: COMPONENT,
|
|
67702
|
+
deliveryId,
|
|
67703
|
+
kind,
|
|
67704
|
+
agentId: input.envelope.agentId ?? void 0
|
|
67705
|
+
});
|
|
67706
|
+
this.pump();
|
|
67707
|
+
return true;
|
|
67708
|
+
}
|
|
67709
|
+
pump() {
|
|
67710
|
+
if (this.shuttingDown) {
|
|
67711
|
+
return;
|
|
67712
|
+
}
|
|
67713
|
+
while (this.activeKeys.size < DEVKIT_MAX_CONCURRENCY) {
|
|
67714
|
+
const index2 = this.pendingQueue.findIndex((item2) => !this.activeKeys.has(orderingKeyFor(item2.envelope)));
|
|
67715
|
+
if (index2 === -1) {
|
|
67716
|
+
break;
|
|
67717
|
+
}
|
|
67718
|
+
const [item] = this.pendingQueue.splice(index2, 1);
|
|
67719
|
+
this.pendingBytes -= item.bytes;
|
|
67720
|
+
const key = orderingKeyFor(item.envelope);
|
|
67721
|
+
this.activeKeys.add(key);
|
|
67722
|
+
const promise = this.send(item).finally(() => {
|
|
67723
|
+
this.activeKeys.delete(key);
|
|
67724
|
+
this.inFlight.delete(promise);
|
|
67725
|
+
this.pump();
|
|
67726
|
+
});
|
|
67727
|
+
this.inFlight.add(promise);
|
|
67728
|
+
}
|
|
67729
|
+
}
|
|
67730
|
+
async send(item) {
|
|
67731
|
+
const startedAt = this.now();
|
|
67732
|
+
const { envelope } = item;
|
|
67733
|
+
let snapshot;
|
|
67734
|
+
try {
|
|
67735
|
+
snapshot = this.readSnapshot();
|
|
67736
|
+
} catch {
|
|
67737
|
+
this.emitDropped({
|
|
67738
|
+
deliveryId: envelope.deliveryId,
|
|
67739
|
+
kind: envelope.kind,
|
|
67740
|
+
reason: DEVKIT_DROP_REASON.CONFIG_READ_FAILED,
|
|
67741
|
+
durationMs: this.now() - startedAt
|
|
67742
|
+
});
|
|
67743
|
+
return;
|
|
67744
|
+
}
|
|
67745
|
+
if (snapshot?.configVersion !== item.config.configVersion) {
|
|
67746
|
+
this.emitDropped({
|
|
67747
|
+
deliveryId: envelope.deliveryId,
|
|
67748
|
+
kind: envelope.kind,
|
|
67749
|
+
reason: DEVKIT_DROP_REASON.CONFIG_CHANGED,
|
|
67750
|
+
durationMs: this.now() - startedAt
|
|
67751
|
+
});
|
|
67752
|
+
return;
|
|
67753
|
+
}
|
|
67754
|
+
const loopbackOk = await isLoopbackTarget(snapshot.origin);
|
|
67755
|
+
if (!loopbackOk) {
|
|
67756
|
+
this.emitHttpFailed(
|
|
67757
|
+
item,
|
|
67758
|
+
DEVKIT_DROP_REASON.CONNECTION_FAILED,
|
|
67759
|
+
{ errorCategory: "network_unavailable" },
|
|
67760
|
+
this.now() - startedAt
|
|
67761
|
+
);
|
|
67762
|
+
return;
|
|
67763
|
+
}
|
|
67764
|
+
const url = `${snapshot.origin}:${snapshot.port}${snapshot.eventPath}`;
|
|
67765
|
+
const controller = new AbortController();
|
|
67766
|
+
this.activeControllers.set(item, controller);
|
|
67767
|
+
const timeoutTimer = setTimeout(() => {
|
|
67768
|
+
item.timedOut = true;
|
|
67769
|
+
controller.abort();
|
|
67770
|
+
}, DEVKIT_REQUEST_BUDGET_MS);
|
|
67771
|
+
let response;
|
|
67772
|
+
try {
|
|
67773
|
+
response = await this.fetchImpl(url, {
|
|
67774
|
+
method: "POST",
|
|
67775
|
+
headers: { "content-type": "application/json" },
|
|
67776
|
+
body: item.serialized,
|
|
67777
|
+
redirect: "manual",
|
|
67778
|
+
signal: controller.signal
|
|
67779
|
+
});
|
|
67780
|
+
} catch (err) {
|
|
67781
|
+
clearTimeout(timeoutTimer);
|
|
67782
|
+
this.activeControllers.delete(item);
|
|
67783
|
+
const durationMs2 = this.now() - startedAt;
|
|
67784
|
+
if (item.cancelledByShutdown) {
|
|
67785
|
+
this.emitCancelled(item, durationMs2);
|
|
67786
|
+
return;
|
|
67787
|
+
}
|
|
67788
|
+
const diagnostics = buildErrorDiagnostics(
|
|
67789
|
+
LogEvent.DEVKIT_DELIVERY_HTTP_FAILED,
|
|
67790
|
+
err instanceof Error ? err : void 0,
|
|
67791
|
+
{}
|
|
67792
|
+
);
|
|
67793
|
+
const reason = classifyFetchFailure({
|
|
67794
|
+
cancelledByShutdown: item.cancelledByShutdown,
|
|
67795
|
+
timedOut: item.timedOut,
|
|
67796
|
+
errorCategory: diagnostics.errorCategory
|
|
67797
|
+
});
|
|
67798
|
+
this.emitHttpFailed(item, reason, diagnostics, durationMs2, err instanceof Error ? err : void 0);
|
|
67799
|
+
return;
|
|
67800
|
+
}
|
|
67801
|
+
clearTimeout(timeoutTimer);
|
|
67802
|
+
this.activeControllers.delete(item);
|
|
67803
|
+
const durationMs = this.now() - startedAt;
|
|
67804
|
+
if (item.cancelledByShutdown) {
|
|
67805
|
+
this.emitCancelled(item, durationMs);
|
|
67806
|
+
return;
|
|
67807
|
+
}
|
|
67808
|
+
const status = response.status;
|
|
67809
|
+
const classified = classifyHttpOutcome(status);
|
|
67810
|
+
if (classified.outcome === DEVKIT_OUTCOME.HTTP_ACCEPTED) {
|
|
67811
|
+
logger.info(LogEvent.DEVKIT_DELIVERY_HTTP_ACCEPTED, {
|
|
67812
|
+
component: COMPONENT,
|
|
67813
|
+
deliveryId: envelope.deliveryId,
|
|
67814
|
+
kind: envelope.kind,
|
|
67815
|
+
statusCode: status,
|
|
67816
|
+
durationMs
|
|
67817
|
+
});
|
|
67818
|
+
return;
|
|
67819
|
+
}
|
|
67820
|
+
const redaction = await readRedactedResponse(response);
|
|
67821
|
+
this.emitDropped({
|
|
67822
|
+
deliveryId: envelope.deliveryId,
|
|
67823
|
+
kind: envelope.kind,
|
|
67824
|
+
reason: classified.reason,
|
|
67825
|
+
statusCode: status,
|
|
67826
|
+
durationMs,
|
|
67827
|
+
...redaction
|
|
67828
|
+
});
|
|
67829
|
+
}
|
|
67830
|
+
async shutdown(deadlineMs) {
|
|
67831
|
+
this.shuttingDown = true;
|
|
67832
|
+
const deadline = this.now() + Math.max(0, deadlineMs);
|
|
67833
|
+
if (this.inFlight.size > 0) {
|
|
67834
|
+
const remaining = Math.max(0, deadline - this.now());
|
|
67835
|
+
await Promise.race([Promise.allSettled(Array.from(this.inFlight)), sleep4(remaining)]);
|
|
67836
|
+
}
|
|
67837
|
+
for (const [item, controller] of this.activeControllers) {
|
|
67838
|
+
item.cancelledByShutdown = true;
|
|
67839
|
+
controller.abort();
|
|
67840
|
+
}
|
|
67841
|
+
const stillPending = this.pendingQueue.splice(0, this.pendingQueue.length);
|
|
67842
|
+
this.pendingBytes = 0;
|
|
67843
|
+
for (const item of stillPending) {
|
|
67844
|
+
this.emitCancelled(item, 0);
|
|
67845
|
+
}
|
|
67846
|
+
}
|
|
67847
|
+
emitDropped(params) {
|
|
67848
|
+
logger.info(LogEvent.DEVKIT_DELIVERY_DROPPED, {
|
|
67849
|
+
component: COMPONENT,
|
|
67850
|
+
outcome: DEVKIT_OUTCOME.DROPPED,
|
|
67851
|
+
deliveryId: params.deliveryId,
|
|
67852
|
+
kind: params.kind,
|
|
67853
|
+
reason: params.reason,
|
|
67854
|
+
durationMs: params.durationMs,
|
|
67855
|
+
...params.statusCode !== void 0 ? { statusCode: params.statusCode } : {},
|
|
67856
|
+
...params.responseBytesRead !== void 0 ? { responseBytesRead: params.responseBytesRead } : {},
|
|
67857
|
+
...params.responseTruncated !== void 0 ? { responseTruncated: params.responseTruncated } : {},
|
|
67858
|
+
...params.responseSummary !== void 0 ? { responseSummary: params.responseSummary } : {}
|
|
67859
|
+
});
|
|
67860
|
+
}
|
|
67861
|
+
emitHttpFailed(item, reason, diagnostics, durationMs, err) {
|
|
67862
|
+
logger.error(LogEvent.DEVKIT_DELIVERY_HTTP_FAILED, err, {
|
|
67863
|
+
component: COMPONENT,
|
|
67864
|
+
outcome: DEVKIT_OUTCOME.DROPPED,
|
|
67865
|
+
deliveryId: item.envelope.deliveryId,
|
|
67866
|
+
kind: item.envelope.kind,
|
|
67867
|
+
reason,
|
|
67868
|
+
durationMs,
|
|
67869
|
+
...diagnostics.errorCategory ? { errorCategory: diagnostics.errorCategory } : {},
|
|
67870
|
+
...diagnostics.errorCode ? { errorCode: diagnostics.errorCode } : {}
|
|
67871
|
+
});
|
|
67872
|
+
}
|
|
67873
|
+
emitCancelled(item, durationMs) {
|
|
67874
|
+
logger.info(LogEvent.DEVKIT_DELIVERY_CANCELLED, {
|
|
67875
|
+
component: COMPONENT,
|
|
67876
|
+
outcome: DEVKIT_OUTCOME.DROPPED,
|
|
67877
|
+
deliveryId: item.envelope.deliveryId,
|
|
67878
|
+
kind: item.envelope.kind,
|
|
67879
|
+
reason: DEVKIT_DROP_REASON.SHUTDOWN_CANCELLED,
|
|
67880
|
+
durationMs
|
|
67881
|
+
});
|
|
67882
|
+
}
|
|
67883
|
+
};
|
|
67884
|
+
|
|
67113
67885
|
// src/ai-dispatch-queue.ts
|
|
67114
67886
|
async function enqueueAiJobMessageDispatch(params) {
|
|
67115
67887
|
const commands = params.commands ?? new CommandStore(params.homeDir);
|
|
@@ -67135,6 +67907,381 @@ async function enqueueAiSessionMessageDispatch(params) {
|
|
|
67135
67907
|
return command;
|
|
67136
67908
|
}
|
|
67137
67909
|
|
|
67910
|
+
// src/devkit-router.ts
|
|
67911
|
+
init_sentry_logger();
|
|
67912
|
+
function createDevkitAutoRouter(deps) {
|
|
67913
|
+
const { commands, dispatcher, readSnapshot } = deps;
|
|
67914
|
+
function readConfigOrNull(phase) {
|
|
67915
|
+
try {
|
|
67916
|
+
return { ok: true, config: readSnapshot() };
|
|
67917
|
+
} catch (err) {
|
|
67918
|
+
logger.error(
|
|
67919
|
+
LogEvent.DEVKIT_ROUTE_CONFIG_READ_FAILED,
|
|
67920
|
+
err instanceof Error ? err : new Error(String(err)),
|
|
67921
|
+
{
|
|
67922
|
+
component: "node_devkit",
|
|
67923
|
+
phase,
|
|
67924
|
+
outcome: "dropped",
|
|
67925
|
+
reason: "config_read_failed"
|
|
67926
|
+
}
|
|
67927
|
+
);
|
|
67928
|
+
return { ok: false };
|
|
67929
|
+
}
|
|
67930
|
+
}
|
|
67931
|
+
async function routeSession(event) {
|
|
67932
|
+
const read = readConfigOrNull("session");
|
|
67933
|
+
if (!read.ok) {
|
|
67934
|
+
return;
|
|
67935
|
+
}
|
|
67936
|
+
if (read.config === null) {
|
|
67937
|
+
await enqueueAiSessionMessageDispatch({ commands, event });
|
|
67938
|
+
logger.info(LogEvent.DEVKIT_ROUTE_DEFAULT_AI, {
|
|
67939
|
+
component: "node_devkit",
|
|
67940
|
+
phase: "session",
|
|
67941
|
+
kind: "session",
|
|
67942
|
+
messageId: event.messageId ?? "",
|
|
67943
|
+
jobId: event.jobId ?? "",
|
|
67944
|
+
agentId: event.agentId ?? ""
|
|
67945
|
+
});
|
|
67946
|
+
return;
|
|
67947
|
+
}
|
|
67948
|
+
const config = read.config;
|
|
67949
|
+
const envelope = buildSessionEnvelope(event);
|
|
67950
|
+
dispatcher.enqueue({ envelope, config });
|
|
67951
|
+
logger.info(LogEvent.DEVKIT_ROUTE_CUSTOM_SERVER, {
|
|
67952
|
+
component: "node_devkit",
|
|
67953
|
+
phase: "session",
|
|
67954
|
+
kind: "session",
|
|
67955
|
+
deliveryId: envelope.deliveryId,
|
|
67956
|
+
messageId: event.messageId ?? "",
|
|
67957
|
+
jobId: event.jobId ?? "",
|
|
67958
|
+
agentId: event.agentId ?? ""
|
|
67959
|
+
});
|
|
67960
|
+
}
|
|
67961
|
+
async function routeJob(event) {
|
|
67962
|
+
const read = readConfigOrNull("job");
|
|
67963
|
+
if (!read.ok) {
|
|
67964
|
+
return;
|
|
67965
|
+
}
|
|
67966
|
+
if (read.config === null) {
|
|
67967
|
+
await enqueueAiJobMessageDispatch({ commands, event });
|
|
67968
|
+
logger.info(LogEvent.DEVKIT_ROUTE_DEFAULT_AI, {
|
|
67969
|
+
component: "node_devkit",
|
|
67970
|
+
phase: "job",
|
|
67971
|
+
kind: "job",
|
|
67972
|
+
jobId: event.jobId,
|
|
67973
|
+
agentId: event.sessionAgentId ?? ""
|
|
67974
|
+
});
|
|
67975
|
+
return;
|
|
67976
|
+
}
|
|
67977
|
+
const config = read.config;
|
|
67978
|
+
const envelope = buildJobEnvelope(event);
|
|
67979
|
+
dispatcher.enqueue({ envelope, config });
|
|
67980
|
+
logger.info(LogEvent.DEVKIT_ROUTE_CUSTOM_SERVER, {
|
|
67981
|
+
component: "node_devkit",
|
|
67982
|
+
phase: "job",
|
|
67983
|
+
kind: "job",
|
|
67984
|
+
deliveryId: envelope.deliveryId,
|
|
67985
|
+
jobId: event.jobId,
|
|
67986
|
+
agentId: event.sessionAgentId ?? ""
|
|
67987
|
+
});
|
|
67988
|
+
}
|
|
67989
|
+
return { routeJob, routeSession };
|
|
67990
|
+
}
|
|
67991
|
+
|
|
67992
|
+
// src/devkit-server-store.ts
|
|
67993
|
+
var import_node_fs19 = require("node:fs");
|
|
67994
|
+
init_paths();
|
|
67995
|
+
init_session_store();
|
|
67996
|
+
var { DatabaseSync: DatabaseSync4 } = loadSqlite4();
|
|
67997
|
+
var DEVKIT_SERVER_APPLICATION_ID = 1329677395;
|
|
67998
|
+
var DEVKIT_SERVER_SCHEMA_VERSION = 1;
|
|
67999
|
+
var TABLE_NAME = `"devkit-server"`;
|
|
68000
|
+
var WRITE_RETRY_ATTEMPTS = 6;
|
|
68001
|
+
var DevkitServerStoreError = class extends Error {
|
|
68002
|
+
code;
|
|
68003
|
+
constructor(code, message) {
|
|
68004
|
+
super(message);
|
|
68005
|
+
this.name = "DevkitServerStoreError";
|
|
68006
|
+
this.code = code;
|
|
68007
|
+
}
|
|
68008
|
+
};
|
|
68009
|
+
function resolveDevkitServerDbPath(homeDir) {
|
|
68010
|
+
return resolveTaskPaths(homeDir).devkitServerDbPath;
|
|
68011
|
+
}
|
|
68012
|
+
function devkitServerDbExists(homeDir) {
|
|
68013
|
+
return (0, import_node_fs19.existsSync)(resolveDevkitServerDbPath(homeDir));
|
|
68014
|
+
}
|
|
68015
|
+
var DevkitServerStore = class _DevkitServerStore {
|
|
68016
|
+
dbPath;
|
|
68017
|
+
db;
|
|
68018
|
+
constructor(dbPath, db) {
|
|
68019
|
+
this.dbPath = dbPath;
|
|
68020
|
+
this.db = db;
|
|
68021
|
+
}
|
|
68022
|
+
static openForWrite(homeDir) {
|
|
68023
|
+
const paths = resolveTaskPaths(homeDir);
|
|
68024
|
+
const dbPath = paths.devkitServerDbPath;
|
|
68025
|
+
assertNotSymlink(paths.sqliteDir, "devkit server directory");
|
|
68026
|
+
ensureTaskDir(paths.sqliteDir);
|
|
68027
|
+
assertNotSymlink(paths.sqliteDir, "devkit server directory");
|
|
68028
|
+
assertSafeDatabasePath(dbPath);
|
|
68029
|
+
const db = new DatabaseSync4(dbPath);
|
|
68030
|
+
const store = new _DevkitServerStore(dbPath, db);
|
|
68031
|
+
try {
|
|
68032
|
+
store.configureConnectionForWrite();
|
|
68033
|
+
store.ensureSchemaForWrite();
|
|
68034
|
+
return store;
|
|
68035
|
+
} catch (error) {
|
|
68036
|
+
db.close();
|
|
68037
|
+
throw error;
|
|
68038
|
+
}
|
|
68039
|
+
}
|
|
68040
|
+
static openForRead(homeDir) {
|
|
68041
|
+
const dbPath = resolveDevkitServerDbPath(homeDir);
|
|
68042
|
+
if (!(0, import_node_fs19.existsSync)(dbPath)) {
|
|
68043
|
+
return null;
|
|
68044
|
+
}
|
|
68045
|
+
assertSafeDatabaseFile(dbPath);
|
|
68046
|
+
const db = new DatabaseSync4(dbPath, { readOnly: true });
|
|
68047
|
+
const store = new _DevkitServerStore(dbPath, db);
|
|
68048
|
+
try {
|
|
68049
|
+
db.exec("PRAGMA query_only=ON");
|
|
68050
|
+
store.assertReadableSchema();
|
|
68051
|
+
return store;
|
|
68052
|
+
} catch (error) {
|
|
68053
|
+
db.close();
|
|
68054
|
+
throw error;
|
|
68055
|
+
}
|
|
68056
|
+
}
|
|
68057
|
+
close() {
|
|
68058
|
+
this.db.close();
|
|
68059
|
+
}
|
|
68060
|
+
register(input) {
|
|
68061
|
+
return this.withWriteTransaction(() => {
|
|
68062
|
+
const existing = this.db.prepare(`SELECT config_version FROM ${TABLE_NAME} WHERE id = 1`).get();
|
|
68063
|
+
const configVersion = (existing?.config_version ?? 0) + 1;
|
|
68064
|
+
const updatedAt = Date.now();
|
|
68065
|
+
this.db.prepare(`
|
|
68066
|
+
INSERT INTO ${TABLE_NAME} (
|
|
68067
|
+
id, origin, port, event_path, health_path, config_version, updated_at
|
|
68068
|
+
) VALUES (1, ?, ?, ?, ?, ?, ?)
|
|
68069
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
68070
|
+
origin = excluded.origin,
|
|
68071
|
+
port = excluded.port,
|
|
68072
|
+
event_path = excluded.event_path,
|
|
68073
|
+
health_path = excluded.health_path,
|
|
68074
|
+
config_version = excluded.config_version,
|
|
68075
|
+
updated_at = excluded.updated_at
|
|
68076
|
+
`).run(input.origin, input.port, input.eventPath, input.healthPath, configVersion, updatedAt);
|
|
68077
|
+
return {
|
|
68078
|
+
origin: input.origin,
|
|
68079
|
+
port: input.port,
|
|
68080
|
+
eventPath: input.eventPath,
|
|
68081
|
+
healthPath: input.healthPath,
|
|
68082
|
+
configVersion,
|
|
68083
|
+
updatedAt
|
|
68084
|
+
};
|
|
68085
|
+
});
|
|
68086
|
+
}
|
|
68087
|
+
unregister() {
|
|
68088
|
+
return this.withWriteTransaction(() => {
|
|
68089
|
+
const result = this.db.prepare(`DELETE FROM ${TABLE_NAME} WHERE id = 1`).run();
|
|
68090
|
+
return { removed: Number(result.changes) > 0 };
|
|
68091
|
+
});
|
|
68092
|
+
}
|
|
68093
|
+
readSnapshot() {
|
|
68094
|
+
let row;
|
|
68095
|
+
try {
|
|
68096
|
+
row = this.db.prepare(`
|
|
68097
|
+
SELECT origin, port, event_path, health_path, config_version, updated_at
|
|
68098
|
+
FROM ${TABLE_NAME} WHERE id = 1
|
|
68099
|
+
`).get();
|
|
68100
|
+
} catch (error) {
|
|
68101
|
+
throw new DevkitServerStoreError(
|
|
68102
|
+
"DATABASE_READ_FAILED",
|
|
68103
|
+
`failed to read devkit server config: ${error instanceof Error ? error.message : String(error)}`
|
|
68104
|
+
);
|
|
68105
|
+
}
|
|
68106
|
+
if (!row) {
|
|
68107
|
+
return null;
|
|
68108
|
+
}
|
|
68109
|
+
return {
|
|
68110
|
+
origin: row.origin,
|
|
68111
|
+
port: row.port,
|
|
68112
|
+
eventPath: row.event_path,
|
|
68113
|
+
healthPath: row.health_path,
|
|
68114
|
+
configVersion: row.config_version,
|
|
68115
|
+
updatedAt: row.updated_at
|
|
68116
|
+
};
|
|
68117
|
+
}
|
|
68118
|
+
configureConnectionForWrite() {
|
|
68119
|
+
this.db.exec("PRAGMA busy_timeout=5000");
|
|
68120
|
+
}
|
|
68121
|
+
ensureSchemaForWrite() {
|
|
68122
|
+
withBusyRetry(() => {
|
|
68123
|
+
this.db.exec("BEGIN IMMEDIATE");
|
|
68124
|
+
try {
|
|
68125
|
+
const applicationId = readPragmaNumber(this.db, "application_id");
|
|
68126
|
+
const userVersion = readPragmaNumber(this.db, "user_version");
|
|
68127
|
+
const hasTables = Boolean(
|
|
68128
|
+
this.db.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' LIMIT 1").get()
|
|
68129
|
+
);
|
|
68130
|
+
if (applicationId === 0 && !hasTables && userVersion === 0) {
|
|
68131
|
+
this.db.exec(`PRAGMA application_id=${DEVKIT_SERVER_APPLICATION_ID}`);
|
|
68132
|
+
} else if (applicationId !== DEVKIT_SERVER_APPLICATION_ID) {
|
|
68133
|
+
throw new DevkitServerStoreError(
|
|
68134
|
+
"DATABASE_IDENTITY_MISMATCH",
|
|
68135
|
+
"devkit server database identity does not match"
|
|
68136
|
+
);
|
|
68137
|
+
}
|
|
68138
|
+
if (userVersion > DEVKIT_SERVER_SCHEMA_VERSION) {
|
|
68139
|
+
throw new DevkitServerStoreError(
|
|
68140
|
+
"DATABASE_SCHEMA_TOO_NEW",
|
|
68141
|
+
`devkit server schema version ${userVersion} is newer than supported ${DEVKIT_SERVER_SCHEMA_VERSION}`
|
|
68142
|
+
);
|
|
68143
|
+
}
|
|
68144
|
+
if (userVersion < 1) {
|
|
68145
|
+
applyMigrationV1(this.db);
|
|
68146
|
+
this.db.exec("PRAGMA user_version=1");
|
|
68147
|
+
}
|
|
68148
|
+
this.db.exec("COMMIT");
|
|
68149
|
+
} catch (error) {
|
|
68150
|
+
rollbackQuietly(this.db);
|
|
68151
|
+
throw error;
|
|
68152
|
+
}
|
|
68153
|
+
});
|
|
68154
|
+
withBusyRetry(() => {
|
|
68155
|
+
this.db.exec("PRAGMA journal_mode=WAL");
|
|
68156
|
+
this.db.exec("PRAGMA synchronous=FULL");
|
|
68157
|
+
});
|
|
68158
|
+
}
|
|
68159
|
+
assertReadableSchema() {
|
|
68160
|
+
const applicationId = readPragmaNumber(this.db, "application_id");
|
|
68161
|
+
if (applicationId !== DEVKIT_SERVER_APPLICATION_ID) {
|
|
68162
|
+
throw new DevkitServerStoreError(
|
|
68163
|
+
"DATABASE_IDENTITY_MISMATCH",
|
|
68164
|
+
"devkit server database identity does not match"
|
|
68165
|
+
);
|
|
68166
|
+
}
|
|
68167
|
+
const userVersion = readPragmaNumber(this.db, "user_version");
|
|
68168
|
+
if (userVersion > DEVKIT_SERVER_SCHEMA_VERSION) {
|
|
68169
|
+
throw new DevkitServerStoreError(
|
|
68170
|
+
"DATABASE_SCHEMA_TOO_NEW",
|
|
68171
|
+
`devkit server schema version ${userVersion} is newer than supported ${DEVKIT_SERVER_SCHEMA_VERSION}`
|
|
68172
|
+
);
|
|
68173
|
+
}
|
|
68174
|
+
if (userVersion < DEVKIT_SERVER_SCHEMA_VERSION) {
|
|
68175
|
+
throw new DevkitServerStoreError(
|
|
68176
|
+
"DATABASE_MIGRATION_REQUIRED",
|
|
68177
|
+
"devkit server database requires a write command to finish migration"
|
|
68178
|
+
);
|
|
68179
|
+
}
|
|
68180
|
+
}
|
|
68181
|
+
withWriteTransaction(operation) {
|
|
68182
|
+
return withBusyRetry(() => {
|
|
68183
|
+
this.db.exec("BEGIN IMMEDIATE");
|
|
68184
|
+
try {
|
|
68185
|
+
const result = operation();
|
|
68186
|
+
this.db.exec("COMMIT");
|
|
68187
|
+
return result;
|
|
68188
|
+
} catch (error) {
|
|
68189
|
+
rollbackQuietly(this.db);
|
|
68190
|
+
throw error;
|
|
68191
|
+
}
|
|
68192
|
+
});
|
|
68193
|
+
}
|
|
68194
|
+
};
|
|
68195
|
+
function applyMigrationV1(db) {
|
|
68196
|
+
db.exec(`
|
|
68197
|
+
CREATE TABLE ${TABLE_NAME} (
|
|
68198
|
+
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
68199
|
+
origin TEXT NOT NULL,
|
|
68200
|
+
port INTEGER NOT NULL CHECK (port >= 1 AND port <= 65535),
|
|
68201
|
+
event_path TEXT NOT NULL,
|
|
68202
|
+
health_path TEXT NOT NULL,
|
|
68203
|
+
config_version INTEGER NOT NULL,
|
|
68204
|
+
updated_at INTEGER NOT NULL,
|
|
68205
|
+
CHECK (length(origin) > 0),
|
|
68206
|
+
CHECK (substr(event_path,1,1) = '/'),
|
|
68207
|
+
CHECK (substr(health_path,1,1) = '/')
|
|
68208
|
+
)
|
|
68209
|
+
`);
|
|
68210
|
+
}
|
|
68211
|
+
function readPragmaNumber(db, name) {
|
|
68212
|
+
const row = db.prepare(`PRAGMA ${name}`).get();
|
|
68213
|
+
return Number(row[name] ?? 0);
|
|
68214
|
+
}
|
|
68215
|
+
function assertNotSymlink(path2, label) {
|
|
68216
|
+
if (!(0, import_node_fs19.existsSync)(path2)) {
|
|
68217
|
+
return;
|
|
68218
|
+
}
|
|
68219
|
+
if ((0, import_node_fs19.lstatSync)(path2).isSymbolicLink()) {
|
|
68220
|
+
throw new DevkitServerStoreError("DATABASE_PATH_UNSAFE", `${label} must not be a symbolic link`);
|
|
68221
|
+
}
|
|
68222
|
+
}
|
|
68223
|
+
function assertSafeDatabasePath(dbPath) {
|
|
68224
|
+
assertSafeDatabaseFile(dbPath);
|
|
68225
|
+
for (const suffix of ["-journal", "-wal", "-shm"]) {
|
|
68226
|
+
assertNotSymlink(`${dbPath}${suffix}`, `devkit server database sidecar ${suffix}`);
|
|
68227
|
+
}
|
|
68228
|
+
}
|
|
68229
|
+
function assertSafeDatabaseFile(dbPath) {
|
|
68230
|
+
if (!(0, import_node_fs19.existsSync)(dbPath)) {
|
|
68231
|
+
return;
|
|
68232
|
+
}
|
|
68233
|
+
const stat4 = (0, import_node_fs19.lstatSync)(dbPath);
|
|
68234
|
+
if (stat4.isSymbolicLink()) {
|
|
68235
|
+
throw new DevkitServerStoreError(
|
|
68236
|
+
"DATABASE_PATH_UNSAFE",
|
|
68237
|
+
"devkit server database must not be a symbolic link"
|
|
68238
|
+
);
|
|
68239
|
+
}
|
|
68240
|
+
if (!stat4.isFile() || stat4.nlink !== 1) {
|
|
68241
|
+
throw new DevkitServerStoreError(
|
|
68242
|
+
"DATABASE_PATH_UNSAFE",
|
|
68243
|
+
"devkit server database must be a regular file with one hard link"
|
|
68244
|
+
);
|
|
68245
|
+
}
|
|
68246
|
+
}
|
|
68247
|
+
function rollbackQuietly(db) {
|
|
68248
|
+
try {
|
|
68249
|
+
db.exec("ROLLBACK");
|
|
68250
|
+
} catch {
|
|
68251
|
+
}
|
|
68252
|
+
}
|
|
68253
|
+
function withBusyRetry(operation) {
|
|
68254
|
+
for (let attempt = 1; ; attempt += 1) {
|
|
68255
|
+
try {
|
|
68256
|
+
return operation();
|
|
68257
|
+
} catch (error) {
|
|
68258
|
+
if (!isSqliteBusyError(error) || attempt >= WRITE_RETRY_ATTEMPTS) {
|
|
68259
|
+
throw error;
|
|
68260
|
+
}
|
|
68261
|
+
sleepSyncMs2(Math.min(100 * 2 ** (attempt - 1), 1600));
|
|
68262
|
+
}
|
|
68263
|
+
}
|
|
68264
|
+
}
|
|
68265
|
+
function sleepSyncMs2(ms) {
|
|
68266
|
+
const buffer2 = new Int32Array(new SharedArrayBuffer(4));
|
|
68267
|
+
Atomics.wait(buffer2, 0, 0, ms);
|
|
68268
|
+
}
|
|
68269
|
+
function loadSqlite4() {
|
|
68270
|
+
const originalEmitWarning = process.emitWarning;
|
|
68271
|
+
process.emitWarning = ((warning, ...args) => {
|
|
68272
|
+
const message = typeof warning === "string" ? warning : warning.message;
|
|
68273
|
+
if (message.includes("SQLite is an experimental feature") && args.some((arg) => arg === "ExperimentalWarning")) {
|
|
68274
|
+
return;
|
|
68275
|
+
}
|
|
68276
|
+
return originalEmitWarning.call(process, warning, ...args);
|
|
68277
|
+
});
|
|
68278
|
+
try {
|
|
68279
|
+
return require("node:sqlite");
|
|
68280
|
+
} finally {
|
|
68281
|
+
process.emitWarning = originalEmitWarning;
|
|
68282
|
+
}
|
|
68283
|
+
}
|
|
68284
|
+
|
|
67138
68285
|
// src/listener.ts
|
|
67139
68286
|
init_paths();
|
|
67140
68287
|
|
|
@@ -67509,13 +68656,13 @@ async function getHermesGatewayPluginStatus(options = {}) {
|
|
|
67509
68656
|
const env = options.env ?? process.env;
|
|
67510
68657
|
const hermesHome = env.HERMES_HOME?.trim() || (0, import_node_path25.join)((0, import_node_os8.homedir)(), ".hermes");
|
|
67511
68658
|
const pluginYamlPath = (0, import_node_path25.join)(hermesHome, "plugins", "platforms", "okx-a2a", "plugin.yaml");
|
|
67512
|
-
if (!(0,
|
|
68659
|
+
if (!(0, import_node_fs20.existsSync)(pluginYamlPath)) {
|
|
67513
68660
|
return { enabled: false, reason: "plugin_yaml_missing", hermesHome, checkedPath: pluginYamlPath };
|
|
67514
68661
|
}
|
|
67515
68662
|
const configPath = (0, import_node_path25.join)(hermesHome, "config.yaml");
|
|
67516
68663
|
let content;
|
|
67517
68664
|
try {
|
|
67518
|
-
content = await (0,
|
|
68665
|
+
content = await (0, import_promises9.readFile)(configPath, "utf8");
|
|
67519
68666
|
} catch {
|
|
67520
68667
|
return { enabled: false, reason: "config_read_error", hermesHome, checkedPath: configPath };
|
|
67521
68668
|
}
|
|
@@ -67600,12 +68747,12 @@ function parseYamlInlineEnabledList(line) {
|
|
|
67600
68747
|
var SHUTDOWN_FORCE_RESOLVE_MS = 5e3;
|
|
67601
68748
|
function stopClients(service) {
|
|
67602
68749
|
for (const [address, client] of service.getClients()) {
|
|
67603
|
-
|
|
67604
|
-
|
|
67605
|
-
|
|
67606
|
-
|
|
67607
|
-
logWithTimestamp(`[okx-agent-task] failed to
|
|
67608
|
-
}
|
|
68750
|
+
void stopAndCloseXmtpClient(client, {
|
|
68751
|
+
address,
|
|
68752
|
+
agentId: "",
|
|
68753
|
+
phase: "shutdown",
|
|
68754
|
+
onCloseError: (err) => logWithTimestamp(`[okx-agent-task] failed to close XMTP client ${address}:`, err)
|
|
68755
|
+
}).then(() => logWithTimestamp(`[okx-agent-task] stopped XMTP client ${address}`)).catch((err) => logWithTimestamp(`[okx-agent-task] failed to stop XMTP client ${address}:`, err));
|
|
67609
68756
|
}
|
|
67610
68757
|
}
|
|
67611
68758
|
async function runListener(options = {}) {
|
|
@@ -67637,6 +68784,27 @@ async function runListenerWithLock(options, paths) {
|
|
|
67637
68784
|
const store = new TaskMessageStore(options.homeDir);
|
|
67638
68785
|
const sessionStore = new SessionStore({ homeDir: options.homeDir });
|
|
67639
68786
|
const commands = new CommandStore(options.homeDir);
|
|
68787
|
+
const devkitReadSnapshot = () => {
|
|
68788
|
+
const snapshotStore = DevkitServerStore.openForRead(options.homeDir);
|
|
68789
|
+
if (!snapshotStore) {
|
|
68790
|
+
return null;
|
|
68791
|
+
}
|
|
68792
|
+
try {
|
|
68793
|
+
return snapshotStore.readSnapshot();
|
|
68794
|
+
} finally {
|
|
68795
|
+
snapshotStore.close();
|
|
68796
|
+
}
|
|
68797
|
+
};
|
|
68798
|
+
const devkitDispatcher = new DevkitDeliveryDispatcher({
|
|
68799
|
+
homeDir: options.homeDir,
|
|
68800
|
+
readSnapshot: devkitReadSnapshot
|
|
68801
|
+
});
|
|
68802
|
+
const devkitRouter = createDevkitAutoRouter({
|
|
68803
|
+
homeDir: options.homeDir,
|
|
68804
|
+
commands,
|
|
68805
|
+
dispatcher: devkitDispatcher,
|
|
68806
|
+
readSnapshot: devkitReadSnapshot
|
|
68807
|
+
});
|
|
67640
68808
|
await store.ensureReady();
|
|
67641
68809
|
let userAttentionEvents = null;
|
|
67642
68810
|
try {
|
|
@@ -67700,20 +68868,20 @@ async function runListenerWithLock(options, paths) {
|
|
|
67700
68868
|
createInboundMiddleware: (deps) => createMiddlewareFromCoreDeps(store, deps, {
|
|
67701
68869
|
sessionStore,
|
|
67702
68870
|
onJobMessageStored: async (event) => {
|
|
67703
|
-
await
|
|
68871
|
+
await devkitRouter.routeJob(event);
|
|
67704
68872
|
},
|
|
67705
68873
|
onSessionMessage: async (event) => {
|
|
67706
|
-
await
|
|
68874
|
+
await devkitRouter.routeSession(event);
|
|
67707
68875
|
}
|
|
67708
68876
|
}),
|
|
67709
68877
|
processOfflineMessage: (ctx, deps, replayOptions) => processOfflineFromCoreDeps(store, ctx, deps, {
|
|
67710
68878
|
...replayOptions,
|
|
67711
68879
|
sessionStore,
|
|
67712
68880
|
onJobMessageStored: async (event) => {
|
|
67713
|
-
await
|
|
68881
|
+
await devkitRouter.routeJob(event);
|
|
67714
68882
|
},
|
|
67715
68883
|
onSessionMessage: async (event) => {
|
|
67716
|
-
await
|
|
68884
|
+
await devkitRouter.routeSession(event);
|
|
67717
68885
|
}
|
|
67718
68886
|
}),
|
|
67719
68887
|
notifySessionExpired: (command) => {
|
|
@@ -67745,12 +68913,12 @@ async function runListenerWithLock(options, paths) {
|
|
|
67745
68913
|
});
|
|
67746
68914
|
}
|
|
67747
68915
|
});
|
|
67748
|
-
service.setPluginVersion("0.2.
|
|
68916
|
+
service.setPluginVersion("0.2.17-beta-ab42219842-261020165552");
|
|
67749
68917
|
await service.init();
|
|
67750
68918
|
const pluginVersionStatus = service.pluginVersionStatus;
|
|
67751
68919
|
if (pluginVersionStatus.unavailable) {
|
|
67752
68920
|
throw new Error(
|
|
67753
|
-
`@okxweb3/a2a-node v${"0.2.
|
|
68921
|
+
`@okxweb3/a2a-node v${"0.2.17-beta-ab42219842-261020165552"} is below the required minimum v${pluginVersionStatus.minVersion}`
|
|
67754
68922
|
);
|
|
67755
68923
|
}
|
|
67756
68924
|
const systemConfig = service.getSystemConfig();
|
|
@@ -67778,7 +68946,7 @@ async function runListenerWithLock(options, paths) {
|
|
|
67778
68946
|
onchainosAgentId: "*",
|
|
67779
68947
|
reason: "system-config missing sentryDsn",
|
|
67780
68948
|
pluginId: "@okxweb3/a2a-node",
|
|
67781
|
-
pluginVersion: "0.2.
|
|
68949
|
+
pluginVersion: "0.2.17-beta-ab42219842-261020165552"
|
|
67782
68950
|
});
|
|
67783
68951
|
}
|
|
67784
68952
|
logWithTimestamp(
|
|
@@ -68110,6 +69278,7 @@ async function runListenerWithLock(options, paths) {
|
|
|
68110
69278
|
logWithTimestamp("[okx-agent-task] failed to close user_attention IPC wake:", err);
|
|
68111
69279
|
}
|
|
68112
69280
|
stopClients(service);
|
|
69281
|
+
await devkitDispatcher.shutdown(SHUTDOWN_FORCE_RESOLVE_MS);
|
|
68113
69282
|
sessionStore.close();
|
|
68114
69283
|
clearTimeout(forceResolve);
|
|
68115
69284
|
resolve11();
|
|
@@ -68132,14 +69301,375 @@ async function timeSettled(fn) {
|
|
|
68132
69301
|
// src/index.ts
|
|
68133
69302
|
init_paths();
|
|
68134
69303
|
|
|
69304
|
+
// src/devkit-cli.ts
|
|
69305
|
+
var import_node_crypto14 = require("node:crypto");
|
|
69306
|
+
init_daemon();
|
|
69307
|
+
init_sentry_logger();
|
|
69308
|
+
var DAEMON_NOT_RUNNING_MESSAGE = "\u5F53\u524D daemon \u672A\u8FD0\u884C,\u8BF7\u4F7F\u7528 okx-a2a start \u542F\u52A8 daemon";
|
|
69309
|
+
var DAEMON_STATUS_UNKNOWN_MESSAGE = "\u914D\u7F6E\u5DF2\u5199\u5165,\u4F46\u65E0\u6CD5\u786E\u8BA4 daemon \u8FD0\u884C\u72B6\u6001";
|
|
69310
|
+
var LOOPBACK_IPV4_PATTERN = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
|
|
69311
|
+
var DevkitCliError = class extends Error {
|
|
69312
|
+
field;
|
|
69313
|
+
constructor(field, reason) {
|
|
69314
|
+
super(reason);
|
|
69315
|
+
this.name = "DevkitCliError";
|
|
69316
|
+
this.field = field;
|
|
69317
|
+
}
|
|
69318
|
+
toValidationError() {
|
|
69319
|
+
return { field: this.field, reason: this.message };
|
|
69320
|
+
}
|
|
69321
|
+
};
|
|
69322
|
+
async function handleDevkitCommand(args) {
|
|
69323
|
+
const wantsJson = args.includes("--json");
|
|
69324
|
+
const subcommand = args[0];
|
|
69325
|
+
if (!subcommand || isHelpArg(subcommand)) {
|
|
69326
|
+
printDevkitUsage();
|
|
69327
|
+
return;
|
|
69328
|
+
}
|
|
69329
|
+
if (args.slice(1).some(isHelpArg)) {
|
|
69330
|
+
printDevkitUsage();
|
|
69331
|
+
return;
|
|
69332
|
+
}
|
|
69333
|
+
if (subcommand === "register") {
|
|
69334
|
+
await handleRegister(args.slice(1), wantsJson);
|
|
69335
|
+
return;
|
|
69336
|
+
}
|
|
69337
|
+
if (subcommand === "unregister") {
|
|
69338
|
+
await handleUnregister(args.slice(1), wantsJson);
|
|
69339
|
+
return;
|
|
69340
|
+
}
|
|
69341
|
+
outputError(wantsJson, { field: "command", reason: `unknown devkit command: ${subcommand}` });
|
|
69342
|
+
process.exitCode = 1;
|
|
69343
|
+
}
|
|
69344
|
+
function printDevkitUsage() {
|
|
69345
|
+
console.log(`Usage: okx-a2a devkit <register|unregister> [options]
|
|
69346
|
+
|
|
69347
|
+
Commands:
|
|
69348
|
+
register Register a local custom server for daemon auto-message delivery.
|
|
69349
|
+
--url <origin> --port <n> --paths '{"event":"/path","health":"/path"}'
|
|
69350
|
+
unregister Remove the registered custom server; daemon reverts to default AI delivery.
|
|
69351
|
+
|
|
69352
|
+
Options:
|
|
69353
|
+
--json Print machine-readable output.`);
|
|
69354
|
+
}
|
|
69355
|
+
async function handleRegister(args, wantsJson) {
|
|
69356
|
+
const operationId = (0, import_node_crypto14.randomUUID)();
|
|
69357
|
+
const startedAt = Date.now();
|
|
69358
|
+
logger.info(LogEvent.DEVKIT_REGISTER_REQUESTED, devkitSentryExtra({ operationId, phase: "requested" }));
|
|
69359
|
+
try {
|
|
69360
|
+
const parsed = parseArgs(args, { options: /* @__PURE__ */ new Set(["url", "port", "paths"]), flags: /* @__PURE__ */ new Set(["json"]) });
|
|
69361
|
+
const origin = validateUrl(requireOption(parsed, "url"));
|
|
69362
|
+
const port = validatePort(requireOption(parsed, "port"));
|
|
69363
|
+
const { eventPath, healthPath } = validatePaths(requireOption(parsed, "paths"));
|
|
69364
|
+
let config;
|
|
69365
|
+
try {
|
|
69366
|
+
const store = DevkitServerStore.openForWrite();
|
|
69367
|
+
try {
|
|
69368
|
+
config = store.register({ origin, port, eventPath, healthPath });
|
|
69369
|
+
} finally {
|
|
69370
|
+
store.close();
|
|
69371
|
+
}
|
|
69372
|
+
} catch (error) {
|
|
69373
|
+
logger.error(
|
|
69374
|
+
LogEvent.DEVKIT_CONFIG_PERSIST_FAILED,
|
|
69375
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
69376
|
+
devkitSentryExtra({ operationId, phase: "persist_failed", durationMs: Date.now() - startedAt })
|
|
69377
|
+
);
|
|
69378
|
+
outputError(wantsJson, {
|
|
69379
|
+
field: "config",
|
|
69380
|
+
reason: error instanceof DevkitServerStoreError ? error.message : "failed to persist devkit configuration"
|
|
69381
|
+
});
|
|
69382
|
+
process.exitCode = 1;
|
|
69383
|
+
return;
|
|
69384
|
+
}
|
|
69385
|
+
const outcome = config.configVersion === 1 ? "created" : "replaced";
|
|
69386
|
+
const { daemonRunning, warning } = await resolveDaemonStatus(operationId);
|
|
69387
|
+
logger.info(
|
|
69388
|
+
LogEvent.DEVKIT_REGISTER_COMPLETED,
|
|
69389
|
+
devkitSentryExtra({
|
|
69390
|
+
operationId,
|
|
69391
|
+
phase: "completed",
|
|
69392
|
+
outcome,
|
|
69393
|
+
registrationId: String(config.configVersion),
|
|
69394
|
+
daemonRunning: String(daemonRunning),
|
|
69395
|
+
durationMs: Date.now() - startedAt
|
|
69396
|
+
})
|
|
69397
|
+
);
|
|
69398
|
+
outputSuccess(wantsJson, { daemonRunning, warning, configVersion: config.configVersion });
|
|
69399
|
+
} catch (error) {
|
|
69400
|
+
const detail = normalizeError(error);
|
|
69401
|
+
logger.error(
|
|
69402
|
+
LogEvent.DEVKIT_REGISTER_REJECTED,
|
|
69403
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
69404
|
+
devkitSentryExtra({ operationId, phase: "rejected", reason: detail.field, durationMs: Date.now() - startedAt })
|
|
69405
|
+
);
|
|
69406
|
+
outputError(wantsJson, detail);
|
|
69407
|
+
process.exitCode = 1;
|
|
69408
|
+
}
|
|
69409
|
+
}
|
|
69410
|
+
async function handleUnregister(args, wantsJson) {
|
|
69411
|
+
const operationId = (0, import_node_crypto14.randomUUID)();
|
|
69412
|
+
const startedAt = Date.now();
|
|
69413
|
+
logger.info(LogEvent.DEVKIT_UNREGISTER_REQUESTED, devkitSentryExtra({ operationId, phase: "requested" }));
|
|
69414
|
+
try {
|
|
69415
|
+
parseArgs(args, { options: /* @__PURE__ */ new Set(), flags: /* @__PURE__ */ new Set(["json"]) });
|
|
69416
|
+
let removed;
|
|
69417
|
+
try {
|
|
69418
|
+
const store = DevkitServerStore.openForWrite();
|
|
69419
|
+
try {
|
|
69420
|
+
removed = store.unregister().removed;
|
|
69421
|
+
} finally {
|
|
69422
|
+
store.close();
|
|
69423
|
+
}
|
|
69424
|
+
} catch (error) {
|
|
69425
|
+
logger.error(
|
|
69426
|
+
LogEvent.DEVKIT_CONFIG_PERSIST_FAILED,
|
|
69427
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
69428
|
+
devkitSentryExtra({ operationId, phase: "persist_failed", durationMs: Date.now() - startedAt })
|
|
69429
|
+
);
|
|
69430
|
+
outputError(wantsJson, {
|
|
69431
|
+
field: "config",
|
|
69432
|
+
reason: error instanceof DevkitServerStoreError ? error.message : "failed to persist devkit configuration"
|
|
69433
|
+
});
|
|
69434
|
+
process.exitCode = 1;
|
|
69435
|
+
return;
|
|
69436
|
+
}
|
|
69437
|
+
const outcome = removed ? "removed" : "noop";
|
|
69438
|
+
const { daemonRunning, warning } = await resolveDaemonStatus(operationId);
|
|
69439
|
+
logger.info(
|
|
69440
|
+
LogEvent.DEVKIT_UNREGISTER_COMPLETED,
|
|
69441
|
+
devkitSentryExtra({
|
|
69442
|
+
operationId,
|
|
69443
|
+
phase: "completed",
|
|
69444
|
+
outcome,
|
|
69445
|
+
daemonRunning: String(daemonRunning),
|
|
69446
|
+
durationMs: Date.now() - startedAt
|
|
69447
|
+
})
|
|
69448
|
+
);
|
|
69449
|
+
outputSuccess(wantsJson, { daemonRunning, warning });
|
|
69450
|
+
} catch (error) {
|
|
69451
|
+
const detail = normalizeError(error);
|
|
69452
|
+
logger.error(
|
|
69453
|
+
LogEvent.DEVKIT_REGISTER_REJECTED,
|
|
69454
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
69455
|
+
devkitSentryExtra({ operationId, phase: "rejected", reason: detail.field, durationMs: Date.now() - startedAt })
|
|
69456
|
+
);
|
|
69457
|
+
outputError(wantsJson, detail);
|
|
69458
|
+
process.exitCode = 1;
|
|
69459
|
+
}
|
|
69460
|
+
}
|
|
69461
|
+
async function resolveDaemonStatus(operationId) {
|
|
69462
|
+
try {
|
|
69463
|
+
const status = await getDaemonStatus();
|
|
69464
|
+
if (status.running) {
|
|
69465
|
+
return { daemonRunning: true };
|
|
69466
|
+
}
|
|
69467
|
+
return {
|
|
69468
|
+
daemonRunning: false,
|
|
69469
|
+
warning: { code: "DAEMON_NOT_RUNNING", message: DAEMON_NOT_RUNNING_MESSAGE }
|
|
69470
|
+
};
|
|
69471
|
+
} catch {
|
|
69472
|
+
logger.info(LogEvent.DEVKIT_DAEMON_STATUS_UNKNOWN, devkitSentryExtra({ operationId, phase: "status_unknown" }));
|
|
69473
|
+
return {
|
|
69474
|
+
daemonRunning: null,
|
|
69475
|
+
warning: { code: "DAEMON_STATUS_UNKNOWN", message: DAEMON_STATUS_UNKNOWN_MESSAGE }
|
|
69476
|
+
};
|
|
69477
|
+
}
|
|
69478
|
+
}
|
|
69479
|
+
function validateUrl(raw) {
|
|
69480
|
+
if (raw.includes("\\")) {
|
|
69481
|
+
throw new DevkitCliError("url", "--url must not contain a backslash");
|
|
69482
|
+
}
|
|
69483
|
+
let url;
|
|
69484
|
+
try {
|
|
69485
|
+
url = new URL(raw);
|
|
69486
|
+
} catch {
|
|
69487
|
+
throw new DevkitCliError("url", "--url must be a valid HTTP/HTTPS origin");
|
|
69488
|
+
}
|
|
69489
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
69490
|
+
throw new DevkitCliError("url", "--url scheme must be http or https");
|
|
69491
|
+
}
|
|
69492
|
+
if (url.username !== "" || url.password !== "") {
|
|
69493
|
+
throw new DevkitCliError("url", "--url must not contain userinfo");
|
|
69494
|
+
}
|
|
69495
|
+
if (url.port !== "") {
|
|
69496
|
+
throw new DevkitCliError("url", "--url must not contain an embedded port; use --port");
|
|
69497
|
+
}
|
|
69498
|
+
if (url.pathname !== "/" && url.pathname !== "") {
|
|
69499
|
+
throw new DevkitCliError("url", "--url must not contain a path");
|
|
69500
|
+
}
|
|
69501
|
+
if (url.search !== "") {
|
|
69502
|
+
throw new DevkitCliError("url", "--url must not contain a query");
|
|
69503
|
+
}
|
|
69504
|
+
if (url.hash !== "") {
|
|
69505
|
+
throw new DevkitCliError("url", "--url must not contain a fragment");
|
|
69506
|
+
}
|
|
69507
|
+
const hostname = url.hostname.toLowerCase();
|
|
69508
|
+
if (!isLoopbackHostname(hostname)) {
|
|
69509
|
+
throw new DevkitCliError(
|
|
69510
|
+
"url",
|
|
69511
|
+
"--url host must be a loopback address (127.0.0.0/8, ::1, or localhost)"
|
|
69512
|
+
);
|
|
69513
|
+
}
|
|
69514
|
+
return `${url.protocol}//${hostname}`;
|
|
69515
|
+
}
|
|
69516
|
+
function isLoopbackHostname(hostname) {
|
|
69517
|
+
if (hostname === "localhost") {
|
|
69518
|
+
return true;
|
|
69519
|
+
}
|
|
69520
|
+
if (hostname === "::1") {
|
|
69521
|
+
return true;
|
|
69522
|
+
}
|
|
69523
|
+
const match = LOOPBACK_IPV4_PATTERN.exec(hostname);
|
|
69524
|
+
if (!match) {
|
|
69525
|
+
return false;
|
|
69526
|
+
}
|
|
69527
|
+
const octets = match.slice(1, 5).map((segment) => Number(segment));
|
|
69528
|
+
if (octets.some((octet) => !Number.isInteger(octet) || octet < 0 || octet > 255)) {
|
|
69529
|
+
return false;
|
|
69530
|
+
}
|
|
69531
|
+
return octets[0] === 127;
|
|
69532
|
+
}
|
|
69533
|
+
function validatePort(raw) {
|
|
69534
|
+
if (!/^[1-9][0-9]{0,4}$/.test(raw)) {
|
|
69535
|
+
throw new DevkitCliError("port", "--port must be an integer between 1 and 65535");
|
|
69536
|
+
}
|
|
69537
|
+
const port = Number(raw);
|
|
69538
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
69539
|
+
throw new DevkitCliError("port", "--port must be an integer between 1 and 65535");
|
|
69540
|
+
}
|
|
69541
|
+
return port;
|
|
69542
|
+
}
|
|
69543
|
+
function validatePaths(raw) {
|
|
69544
|
+
let parsed;
|
|
69545
|
+
try {
|
|
69546
|
+
parsed = JSON.parse(raw);
|
|
69547
|
+
} catch {
|
|
69548
|
+
throw new DevkitCliError("paths", "--paths must be valid JSON");
|
|
69549
|
+
}
|
|
69550
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
69551
|
+
throw new DevkitCliError("paths", "--paths must be a JSON object");
|
|
69552
|
+
}
|
|
69553
|
+
const record = parsed;
|
|
69554
|
+
const keys = Object.keys(record);
|
|
69555
|
+
if (keys.length !== 2 || !keys.includes("event") || !keys.includes("health")) {
|
|
69556
|
+
throw new DevkitCliError("paths", '--paths must contain exactly the keys "event" and "health"');
|
|
69557
|
+
}
|
|
69558
|
+
const eventPath = validatePathValue(record.event, "event");
|
|
69559
|
+
const healthPath = validatePathValue(record.health, "health");
|
|
69560
|
+
return { eventPath, healthPath };
|
|
69561
|
+
}
|
|
69562
|
+
function validatePathValue(value, key) {
|
|
69563
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
69564
|
+
throw new DevkitCliError("paths", `--paths.${key} must be a non-empty string`);
|
|
69565
|
+
}
|
|
69566
|
+
if (!value.startsWith("/") || value.startsWith("//")) {
|
|
69567
|
+
throw new DevkitCliError("paths", `--paths.${key} must start with a single "/"`);
|
|
69568
|
+
}
|
|
69569
|
+
if (value.includes("\\") || value.includes("?") || value.includes("#") || value.includes("..")) {
|
|
69570
|
+
throw new DevkitCliError(
|
|
69571
|
+
"paths",
|
|
69572
|
+
`--paths.${key} must not contain a query, fragment, backslash, "..", or an absolute URL`
|
|
69573
|
+
);
|
|
69574
|
+
}
|
|
69575
|
+
if (/^\/[a-zA-Z][a-zA-Z0-9+.-]*:/.test(value)) {
|
|
69576
|
+
throw new DevkitCliError("paths", `--paths.${key} must not be an absolute URL`);
|
|
69577
|
+
}
|
|
69578
|
+
return value;
|
|
69579
|
+
}
|
|
69580
|
+
function parseArgs(args, spec) {
|
|
69581
|
+
const options = /* @__PURE__ */ new Map();
|
|
69582
|
+
const flags = /* @__PURE__ */ new Set();
|
|
69583
|
+
for (let index2 = 0; index2 < args.length; index2 += 1) {
|
|
69584
|
+
const token = args[index2];
|
|
69585
|
+
if (!token.startsWith("--")) {
|
|
69586
|
+
throw new DevkitCliError("command", `unexpected positional argument: ${token}`);
|
|
69587
|
+
}
|
|
69588
|
+
const name = token.slice(2);
|
|
69589
|
+
if (spec.flags.has(name)) {
|
|
69590
|
+
if (flags.has(name)) {
|
|
69591
|
+
throw new DevkitCliError("command", `${token} must not be repeated`);
|
|
69592
|
+
}
|
|
69593
|
+
flags.add(name);
|
|
69594
|
+
continue;
|
|
69595
|
+
}
|
|
69596
|
+
if (!spec.options.has(name)) {
|
|
69597
|
+
throw new DevkitCliError("command", `unknown option ${token}`);
|
|
69598
|
+
}
|
|
69599
|
+
if (index2 + 1 >= args.length) {
|
|
69600
|
+
throw new DevkitCliError("command", `${token} requires a value`);
|
|
69601
|
+
}
|
|
69602
|
+
const value = args[++index2];
|
|
69603
|
+
if (value.startsWith("--")) {
|
|
69604
|
+
throw new DevkitCliError("command", `${token} requires a value`);
|
|
69605
|
+
}
|
|
69606
|
+
if (options.has(name)) {
|
|
69607
|
+
throw new DevkitCliError("command", `${token} must not be repeated`);
|
|
69608
|
+
}
|
|
69609
|
+
options.set(name, [value]);
|
|
69610
|
+
}
|
|
69611
|
+
return { options, flags };
|
|
69612
|
+
}
|
|
69613
|
+
function requireOption(parsed, name) {
|
|
69614
|
+
const value = parsed.options.get(name)?.[0];
|
|
69615
|
+
if (value === void 0 || value.length === 0) {
|
|
69616
|
+
throw new DevkitCliError(name, `--${name} is required`);
|
|
69617
|
+
}
|
|
69618
|
+
return value;
|
|
69619
|
+
}
|
|
69620
|
+
function outputSuccess(json, result) {
|
|
69621
|
+
if (json) {
|
|
69622
|
+
console.log(JSON.stringify({
|
|
69623
|
+
ok: true,
|
|
69624
|
+
daemonRunning: result.daemonRunning,
|
|
69625
|
+
...result.warning ? { warning: result.warning } : {},
|
|
69626
|
+
...result.configVersion === void 0 ? {} : { configVersion: result.configVersion }
|
|
69627
|
+
}));
|
|
69628
|
+
return;
|
|
69629
|
+
}
|
|
69630
|
+
const daemonText = result.daemonRunning === null ? "unknown" : String(result.daemonRunning);
|
|
69631
|
+
console.log(`ok=true daemonRunning=${daemonText}${result.warning ? ` warning=${result.warning.code}` : ""}`);
|
|
69632
|
+
if (result.warning) {
|
|
69633
|
+
console.log(result.warning.message);
|
|
69634
|
+
}
|
|
69635
|
+
}
|
|
69636
|
+
function outputError(json, detail) {
|
|
69637
|
+
if (json) {
|
|
69638
|
+
console.log(JSON.stringify({ ok: false, error: detail.reason }));
|
|
69639
|
+
return;
|
|
69640
|
+
}
|
|
69641
|
+
console.error(`ok=false field=${detail.field} error=${detail.reason}`);
|
|
69642
|
+
}
|
|
69643
|
+
function normalizeError(error) {
|
|
69644
|
+
if (error instanceof DevkitCliError) {
|
|
69645
|
+
return error.toValidationError();
|
|
69646
|
+
}
|
|
69647
|
+
if (error instanceof DevkitServerStoreError) {
|
|
69648
|
+
return { field: "config", reason: error.message };
|
|
69649
|
+
}
|
|
69650
|
+
return { field: "unknown", reason: error instanceof Error ? error.message : String(error) };
|
|
69651
|
+
}
|
|
69652
|
+
function devkitSentryExtra(extra) {
|
|
69653
|
+
const normalized = { component: "node_devkit" };
|
|
69654
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
69655
|
+
if (value !== void 0) {
|
|
69656
|
+
normalized[key] = String(value);
|
|
69657
|
+
}
|
|
69658
|
+
}
|
|
69659
|
+
return normalized;
|
|
69660
|
+
}
|
|
69661
|
+
function isHelpArg(value) {
|
|
69662
|
+
return value === "help" || value === "-h" || value === "--help";
|
|
69663
|
+
}
|
|
69664
|
+
|
|
68135
69665
|
// src/xmtp-test-cli.ts
|
|
68136
|
-
var
|
|
69666
|
+
var import_promises11 = require("node:fs/promises");
|
|
68137
69667
|
var import_node_path27 = require("node:path");
|
|
68138
69668
|
init_daemon();
|
|
68139
69669
|
|
|
68140
69670
|
// src/log-tail.ts
|
|
68141
|
-
var
|
|
68142
|
-
var
|
|
69671
|
+
var import_node_fs21 = require("node:fs");
|
|
69672
|
+
var import_promises10 = require("node:fs/promises");
|
|
68143
69673
|
var import_node_path26 = require("node:path");
|
|
68144
69674
|
var import_node_string_decoder = require("node:string_decoder");
|
|
68145
69675
|
init_win_spawn();
|
|
@@ -68234,7 +69764,7 @@ async function followFile(filePath, onData, options = {}) {
|
|
|
68234
69764
|
let handle;
|
|
68235
69765
|
try {
|
|
68236
69766
|
try {
|
|
68237
|
-
handle = await (0,
|
|
69767
|
+
handle = await (0, import_promises10.open)(filePath, "r");
|
|
68238
69768
|
} catch (error) {
|
|
68239
69769
|
if (error.code === "ENOENT") {
|
|
68240
69770
|
markMissing();
|
|
@@ -68299,7 +69829,7 @@ async function followFile(filePath, onData, options = {}) {
|
|
|
68299
69829
|
}, pollIntervalMs);
|
|
68300
69830
|
const targetName = (0, import_node_path26.basename)(filePath);
|
|
68301
69831
|
try {
|
|
68302
|
-
watcher = (0,
|
|
69832
|
+
watcher = (0, import_node_fs21.watch)((0, import_node_path26.dirname)(filePath), (_eventType, filename) => {
|
|
68303
69833
|
if (filename === null || filename.toString() === targetName) {
|
|
68304
69834
|
void check();
|
|
68305
69835
|
}
|
|
@@ -68340,7 +69870,7 @@ async function readTailSnapshot(filePath, maxLines) {
|
|
|
68340
69870
|
async function readTailSnapshotOnce(filePath, maxLines) {
|
|
68341
69871
|
let handle;
|
|
68342
69872
|
try {
|
|
68343
|
-
handle = await (0,
|
|
69873
|
+
handle = await (0, import_promises10.open)(filePath, "r");
|
|
68344
69874
|
} catch (error) {
|
|
68345
69875
|
if (error.code === "ENOENT") {
|
|
68346
69876
|
return { text: "", offset: 0, fileIdentity: null };
|
|
@@ -68397,7 +69927,7 @@ async function readTailSnapshotOnce(filePath, maxLines) {
|
|
|
68397
69927
|
}
|
|
68398
69928
|
async function currentPositionOrMissing(filePath) {
|
|
68399
69929
|
try {
|
|
68400
|
-
const stats = await (0,
|
|
69930
|
+
const stats = await (0, import_promises10.stat)(filePath);
|
|
68401
69931
|
return { offset: stats.size, fileIdentity: identityForStats(stats) };
|
|
68402
69932
|
} catch (error) {
|
|
68403
69933
|
if (error.code === "ENOENT") {
|
|
@@ -68494,7 +70024,7 @@ async function startXmtpTest(args, releaseInfo) {
|
|
|
68494
70024
|
const runId = requestedRunId ? validateRunId(requestedRunId) : createRunId(requestedName);
|
|
68495
70025
|
const files = resolveRunFiles(testsDir, runId);
|
|
68496
70026
|
try {
|
|
68497
|
-
await (0,
|
|
70027
|
+
await (0, import_promises11.stat)(files.runDir);
|
|
68498
70028
|
throw new Error(`XMTP test run already exists: ${runId}`);
|
|
68499
70029
|
} catch (error) {
|
|
68500
70030
|
if (error.code !== "ENOENT") {
|
|
@@ -68502,7 +70032,7 @@ async function startXmtpTest(args, releaseInfo) {
|
|
|
68502
70032
|
}
|
|
68503
70033
|
}
|
|
68504
70034
|
await ensurePrivateDir(files.runDir);
|
|
68505
|
-
await (0,
|
|
70035
|
+
await (0, import_promises11.writeFile)(files.eventsPath, "", { encoding: "utf8", mode: 384 });
|
|
68506
70036
|
const manifest = {
|
|
68507
70037
|
runId,
|
|
68508
70038
|
name: requestedName,
|
|
@@ -68546,7 +70076,7 @@ async function stopXmtpTest(args) {
|
|
|
68546
70076
|
}
|
|
68547
70077
|
const runId = validateRunId(active.runId);
|
|
68548
70078
|
const files = resolveRunFiles(testsDir, runId);
|
|
68549
|
-
await (0,
|
|
70079
|
+
await (0, import_promises11.unlink)(activePath);
|
|
68550
70080
|
const manifest = await readRequiredJson(files.manifestPath);
|
|
68551
70081
|
const completed = {
|
|
68552
70082
|
...manifest,
|
|
@@ -68864,7 +70394,7 @@ async function resolveRequestedRunId(testsDir, args, preferActive = false) {
|
|
|
68864
70394
|
async function findLatestRunId(testsDir) {
|
|
68865
70395
|
let entries;
|
|
68866
70396
|
try {
|
|
68867
|
-
entries = await (0,
|
|
70397
|
+
entries = await (0, import_promises11.readdir)(testsDir, { withFileTypes: true });
|
|
68868
70398
|
} catch (error) {
|
|
68869
70399
|
if (error.code === "ENOENT") {
|
|
68870
70400
|
return null;
|
|
@@ -68889,7 +70419,7 @@ async function findLatestRunId(testsDir) {
|
|
|
68889
70419
|
async function readMetricEvents(path2) {
|
|
68890
70420
|
let text;
|
|
68891
70421
|
try {
|
|
68892
|
-
text = await (0,
|
|
70422
|
+
text = await (0, import_promises11.readFile)(path2, "utf8");
|
|
68893
70423
|
} catch (error) {
|
|
68894
70424
|
if (error.code === "ENOENT") {
|
|
68895
70425
|
return [];
|
|
@@ -68913,9 +70443,9 @@ function parseMetricEvent(line) {
|
|
|
68913
70443
|
}
|
|
68914
70444
|
}
|
|
68915
70445
|
async function ensurePrivateDir(path2) {
|
|
68916
|
-
await (0,
|
|
70446
|
+
await (0, import_promises11.mkdir)(path2, { recursive: true, mode: 448 });
|
|
68917
70447
|
try {
|
|
68918
|
-
await (0,
|
|
70448
|
+
await (0, import_promises11.chmod)(path2, 448);
|
|
68919
70449
|
} catch (error) {
|
|
68920
70450
|
const code = error.code;
|
|
68921
70451
|
if (code !== "EPERM" && code !== "EACCES") {
|
|
@@ -68925,12 +70455,12 @@ async function ensurePrivateDir(path2) {
|
|
|
68925
70455
|
}
|
|
68926
70456
|
async function writeJson(path2, value) {
|
|
68927
70457
|
const temporary = `${path2}.${process.pid}.tmp`;
|
|
68928
|
-
await (0,
|
|
70458
|
+
await (0, import_promises11.writeFile)(temporary, `${JSON.stringify(value, null, 2)}
|
|
68929
70459
|
`, {
|
|
68930
70460
|
encoding: "utf8",
|
|
68931
70461
|
mode: 384
|
|
68932
70462
|
});
|
|
68933
|
-
await (0,
|
|
70463
|
+
await (0, import_promises11.rename)(temporary, path2);
|
|
68934
70464
|
}
|
|
68935
70465
|
async function readRequiredJson(path2) {
|
|
68936
70466
|
const value = await readJsonIfExists(path2);
|
|
@@ -68941,7 +70471,7 @@ async function readRequiredJson(path2) {
|
|
|
68941
70471
|
}
|
|
68942
70472
|
async function readJsonIfExists(path2) {
|
|
68943
70473
|
try {
|
|
68944
|
-
return JSON.parse(await (0,
|
|
70474
|
+
return JSON.parse(await (0, import_promises11.readFile)(path2, "utf8"));
|
|
68945
70475
|
} catch (error) {
|
|
68946
70476
|
if (error.code === "ENOENT") {
|
|
68947
70477
|
return null;
|
|
@@ -69233,21 +70763,21 @@ function parseLogsTailArgs(args, subcommand) {
|
|
|
69233
70763
|
|
|
69234
70764
|
// src/logs-export.ts
|
|
69235
70765
|
var import_node_child_process10 = require("node:child_process");
|
|
69236
|
-
var
|
|
69237
|
-
var
|
|
70766
|
+
var import_node_fs28 = require("node:fs");
|
|
70767
|
+
var import_promises16 = require("node:fs/promises");
|
|
69238
70768
|
var import_node_os12 = require("node:os");
|
|
69239
70769
|
var import_node_path34 = require("node:path");
|
|
69240
70770
|
var import_jszip = __toESM(require_lib3());
|
|
69241
70771
|
|
|
69242
70772
|
// src/logs-export-archive.ts
|
|
69243
|
-
var
|
|
69244
|
-
var
|
|
69245
|
-
var
|
|
70773
|
+
var import_node_crypto15 = require("node:crypto");
|
|
70774
|
+
var import_node_fs25 = require("node:fs");
|
|
70775
|
+
var import_promises14 = require("node:fs/promises");
|
|
69246
70776
|
var import_node_path31 = require("node:path");
|
|
69247
70777
|
|
|
69248
70778
|
// src/logs-export-filter.ts
|
|
69249
|
-
var
|
|
69250
|
-
var
|
|
70779
|
+
var import_node_fs24 = require("node:fs");
|
|
70780
|
+
var import_promises13 = require("node:fs/promises");
|
|
69251
70781
|
var import_node_path30 = require("node:path");
|
|
69252
70782
|
var import_node_readline2 = require("node:readline");
|
|
69253
70783
|
var MAX_SINGLE_RECORD_BYTES = 2 * 1024 * 1024;
|
|
@@ -69357,7 +70887,7 @@ async function readFilteredLog(path2, options, correlationIds, requireCorrelatio
|
|
|
69357
70887
|
};
|
|
69358
70888
|
}
|
|
69359
70889
|
async function* streamLogRecords(path2, mode) {
|
|
69360
|
-
const input = (0,
|
|
70890
|
+
const input = (0, import_node_fs24.createReadStream)(path2, { encoding: "utf8" });
|
|
69361
70891
|
const lines = (0, import_node_readline2.createInterface)({ input, crlfDelay: Infinity });
|
|
69362
70892
|
let current = null;
|
|
69363
70893
|
try {
|
|
@@ -69774,7 +71304,7 @@ function escapeRegExp2(value) {
|
|
|
69774
71304
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
69775
71305
|
}
|
|
69776
71306
|
async function assertRegularFile(path2) {
|
|
69777
|
-
const file = await (0,
|
|
71307
|
+
const file = await (0, import_promises13.lstat)(path2);
|
|
69778
71308
|
if (file.isSymbolicLink() || !file.isFile()) {
|
|
69779
71309
|
throw Object.assign(
|
|
69780
71310
|
new Error(`Refusing non-regular diagnostic source: ${(0, import_node_path30.basename)(path2)}`),
|
|
@@ -69859,7 +71389,7 @@ function recordCollector(state, result) {
|
|
|
69859
71389
|
async function resolveOutputPath(requested, input) {
|
|
69860
71390
|
if (requested) {
|
|
69861
71391
|
const output2 = (0, import_node_path31.isAbsolute)(requested) ? requested : (0, import_node_path31.resolve)(input.cwd, requested);
|
|
69862
|
-
if ((0,
|
|
71392
|
+
if ((0, import_node_fs25.existsSync)(output2) && !input.overwrite) {
|
|
69863
71393
|
throw new Error(`Output already exists: ${output2}. Pass --overwrite to replace it.`);
|
|
69864
71394
|
}
|
|
69865
71395
|
return output2;
|
|
@@ -69867,42 +71397,42 @@ async function resolveOutputPath(requested, input) {
|
|
|
69867
71397
|
const stamp = input.now.toISOString().replace(/[-:]/g, "").replace(/\.\d{3}Z$/, "Z");
|
|
69868
71398
|
const base = `okx-a2a-diagnostics-${stamp}.zip`;
|
|
69869
71399
|
let output = (0, import_node_path31.join)(input.cwd, base);
|
|
69870
|
-
for (let suffix = 2; (0,
|
|
71400
|
+
for (let suffix = 2; (0, import_node_fs25.existsSync)(output); suffix += 1) {
|
|
69871
71401
|
output = (0, import_node_path31.join)(input.cwd, `okx-a2a-diagnostics-${stamp}-${suffix}.zip`);
|
|
69872
71402
|
}
|
|
69873
71403
|
return output;
|
|
69874
71404
|
}
|
|
69875
71405
|
async function writeArchiveAtomically(outputPath, archive, overwrite) {
|
|
69876
|
-
await (0,
|
|
71406
|
+
await (0, import_promises14.mkdir)((0, import_node_path31.dirname)(outputPath), { recursive: true });
|
|
69877
71407
|
const temporaryPath = (0, import_node_path31.join)(
|
|
69878
71408
|
(0, import_node_path31.dirname)(outputPath),
|
|
69879
|
-
`.${(0, import_node_path31.basename)(outputPath)}.${(0,
|
|
71409
|
+
`.${(0, import_node_path31.basename)(outputPath)}.${(0, import_node_crypto15.randomUUID)()}.tmp`
|
|
69880
71410
|
);
|
|
69881
71411
|
try {
|
|
69882
|
-
await (0,
|
|
71412
|
+
await (0, import_promises14.writeFile)(temporaryPath, archive, { flag: "wx", mode: 384 });
|
|
69883
71413
|
if (overwrite) {
|
|
69884
|
-
if ((0,
|
|
69885
|
-
await (0,
|
|
71414
|
+
if ((0, import_node_fs25.existsSync)(outputPath)) {
|
|
71415
|
+
await (0, import_promises14.rm)(outputPath, { force: true });
|
|
69886
71416
|
}
|
|
69887
|
-
await (0,
|
|
71417
|
+
await (0, import_promises14.rename)(temporaryPath, outputPath);
|
|
69888
71418
|
} else {
|
|
69889
|
-
await (0,
|
|
69890
|
-
await (0,
|
|
71419
|
+
await (0, import_promises14.link)(temporaryPath, outputPath);
|
|
71420
|
+
await (0, import_promises14.rm)(temporaryPath, { force: true });
|
|
69891
71421
|
}
|
|
69892
71422
|
} catch (err) {
|
|
69893
|
-
await (0,
|
|
71423
|
+
await (0, import_promises14.rm)(temporaryPath, { force: true }).catch(() => void 0);
|
|
69894
71424
|
throw err;
|
|
69895
71425
|
}
|
|
69896
71426
|
}
|
|
69897
71427
|
function hashDiagnosticFileContent(content) {
|
|
69898
|
-
return (0,
|
|
71428
|
+
return (0, import_node_crypto15.createHash)("sha256").update(content).digest("hex");
|
|
69899
71429
|
}
|
|
69900
71430
|
function isUnavailableError(err) {
|
|
69901
71431
|
return !!err && typeof err === "object" && "diagnosticUnavailable" in err;
|
|
69902
71432
|
}
|
|
69903
71433
|
|
|
69904
71434
|
// src/logs-export-database.ts
|
|
69905
|
-
var
|
|
71435
|
+
var import_node_fs26 = require("node:fs");
|
|
69906
71436
|
var PROVIDERS = ["codex", "claude", "openclaw", "hermes"];
|
|
69907
71437
|
function readSessionSqliteSnapshot(dbPath, options, selectedJobIds) {
|
|
69908
71438
|
const hasTimeWindow2 = options.fromMs !== void 0 && options.toMs !== void 0;
|
|
@@ -70000,11 +71530,11 @@ function readSessionSqliteSnapshot(dbPath, options, selectedJobIds) {
|
|
|
70000
71530
|
};
|
|
70001
71531
|
}
|
|
70002
71532
|
function readSqliteRows(dbPath, sql, params = []) {
|
|
70003
|
-
if (!(0,
|
|
71533
|
+
if (!(0, import_node_fs26.existsSync)(dbPath)) {
|
|
70004
71534
|
throw unavailable(`SQLite database not found: ${dbPath}`);
|
|
70005
71535
|
}
|
|
70006
|
-
const { DatabaseSync:
|
|
70007
|
-
const db = new
|
|
71536
|
+
const { DatabaseSync: DatabaseSync5 } = loadSqlite5();
|
|
71537
|
+
const db = new DatabaseSync5(dbPath, { readOnly: true });
|
|
70008
71538
|
try {
|
|
70009
71539
|
return db.prepare(sql).all(...params);
|
|
70010
71540
|
} finally {
|
|
@@ -70022,7 +71552,7 @@ function emptySqliteSnapshot() {
|
|
|
70022
71552
|
storedProviderCommands: {}
|
|
70023
71553
|
};
|
|
70024
71554
|
}
|
|
70025
|
-
function
|
|
71555
|
+
function loadSqlite5() {
|
|
70026
71556
|
const originalEmitWarning = process.emitWarning;
|
|
70027
71557
|
process.emitWarning = ((warning, ...args) => {
|
|
70028
71558
|
const message = typeof warning === "string" ? warning : warning.message;
|
|
@@ -70155,9 +71685,9 @@ function isProvider2(value) {
|
|
|
70155
71685
|
}
|
|
70156
71686
|
|
|
70157
71687
|
// src/logs-export-utils.ts
|
|
70158
|
-
var
|
|
70159
|
-
var
|
|
70160
|
-
var
|
|
71688
|
+
var import_node_crypto16 = require("node:crypto");
|
|
71689
|
+
var import_node_fs27 = require("node:fs");
|
|
71690
|
+
var import_promises15 = require("node:fs/promises");
|
|
70161
71691
|
var import_node_path33 = require("node:path");
|
|
70162
71692
|
var MAX_JSON_FILE_BYTES = 20 * 1024 * 1024;
|
|
70163
71693
|
var STRONG_CORRELATION_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -70273,7 +71803,7 @@ function collectCorrelationIds(value, output, key = "", depth = 0) {
|
|
|
70273
71803
|
}
|
|
70274
71804
|
async function safeReadDir(path2) {
|
|
70275
71805
|
try {
|
|
70276
|
-
return await (0,
|
|
71806
|
+
return await (0, import_promises15.readdir)(path2);
|
|
70277
71807
|
} catch (err) {
|
|
70278
71808
|
if (err.code === "ENOENT") {
|
|
70279
71809
|
return [];
|
|
@@ -70286,11 +71816,11 @@ async function readJsonObject(path2) {
|
|
|
70286
71816
|
if (file.size > MAX_JSON_FILE_BYTES) {
|
|
70287
71817
|
throw unavailable2(`JSON source exceeds ${MAX_JSON_FILE_BYTES} bytes`);
|
|
70288
71818
|
}
|
|
70289
|
-
const value = parseJsonValue3(await (0,
|
|
71819
|
+
const value = parseJsonValue3(await (0, import_promises15.readFile)(path2, "utf8"));
|
|
70290
71820
|
return isRecord7(value) ? value : null;
|
|
70291
71821
|
}
|
|
70292
71822
|
async function assertRegularFile2(path2) {
|
|
70293
|
-
const file = await (0,
|
|
71823
|
+
const file = await (0, import_promises15.lstat)(path2);
|
|
70294
71824
|
if (file.isSymbolicLink() || !file.isFile()) {
|
|
70295
71825
|
throw unavailable2(`Refusing non-regular diagnostic source: ${(0, import_node_path33.basename)(path2)}`);
|
|
70296
71826
|
}
|
|
@@ -70298,8 +71828,8 @@ async function assertRegularFile2(path2) {
|
|
|
70298
71828
|
}
|
|
70299
71829
|
async function inspectRegularFile(path2) {
|
|
70300
71830
|
const file = await assertRegularFile2(path2);
|
|
70301
|
-
const hash2 = (0,
|
|
70302
|
-
for await (const chunk of (0,
|
|
71831
|
+
const hash2 = (0, import_node_crypto16.createHash)("sha256");
|
|
71832
|
+
for await (const chunk of (0, import_node_fs27.createReadStream)(path2)) {
|
|
70303
71833
|
hash2.update(chunk);
|
|
70304
71834
|
}
|
|
70305
71835
|
return {
|
|
@@ -70551,7 +72081,7 @@ async function exportDiagnosticLogs(options) {
|
|
|
70551
72081
|
node: process.version,
|
|
70552
72082
|
platform: process.platform,
|
|
70553
72083
|
arch: process.arch,
|
|
70554
|
-
packageVersion: true ? "0.2.
|
|
72084
|
+
packageVersion: true ? "0.2.17-beta-ab42219842-261020165552" : "unknown",
|
|
70555
72085
|
sensitiveContentIncluded: options.includeSensitiveContent,
|
|
70556
72086
|
listenerAndLlmContentIncluded: true,
|
|
70557
72087
|
credentialsAlwaysRedacted: true,
|
|
@@ -70968,7 +72498,7 @@ async function collectProviderDiagnostics(state, provider, storedCommand, option
|
|
|
70968
72498
|
const configCandidates = providerConfigCandidates(provider, paths.taskHome);
|
|
70969
72499
|
const configNotes = [];
|
|
70970
72500
|
for (const candidate of configCandidates) {
|
|
70971
|
-
if (!(0,
|
|
72501
|
+
if (!(0, import_node_fs28.existsSync)(candidate.path)) {
|
|
70972
72502
|
continue;
|
|
70973
72503
|
}
|
|
70974
72504
|
let info;
|
|
@@ -71019,7 +72549,7 @@ async function collectOpenClawSessionStore(state, options) {
|
|
|
71019
72549
|
for (const agentId of allAgentNames.slice(0, MAX_OPENCLAW_AGENTS)) {
|
|
71020
72550
|
const sessionsDir = (0, import_node_path34.join)(agentsDir, agentId, "sessions");
|
|
71021
72551
|
try {
|
|
71022
|
-
const info = await (0,
|
|
72552
|
+
const info = await (0, import_promises16.lstat)(sessionsDir);
|
|
71023
72553
|
if (info.isSymbolicLink() || !info.isDirectory()) {
|
|
71024
72554
|
skippedSources += 1;
|
|
71025
72555
|
continue;
|
|
@@ -71196,7 +72726,7 @@ async function collectGatewayLogs(state, provider, paths, options, correlationId
|
|
|
71196
72726
|
async function collectDoctorSnapshot(state, options) {
|
|
71197
72727
|
await runCollector(state, "doctor", async () => {
|
|
71198
72728
|
const cliPath = process.argv[1];
|
|
71199
|
-
if (!cliPath || !(0,
|
|
72729
|
+
if (!cliPath || !(0, import_node_fs28.existsSync)(cliPath)) {
|
|
71200
72730
|
throw unavailable2("Unable to resolve the running okx-a2a CLI path");
|
|
71201
72731
|
}
|
|
71202
72732
|
const result = (0, import_node_child_process10.spawnSync)(process.execPath, [
|
|
@@ -72463,7 +73993,7 @@ async function runDoctor(options = {}) {
|
|
|
72463
73993
|
platform: options.platform ?? process.platform,
|
|
72464
73994
|
env: options.env ?? process.env,
|
|
72465
73995
|
target: options.target ?? resolveDoctorTarget(options.env ?? process.env),
|
|
72466
|
-
cliVersion: options.cliVersion ?? (true ? "0.2.
|
|
73996
|
+
cliVersion: options.cliVersion ?? (true ? "0.2.17-beta-ab42219842-261020165552" : "0.0.0"),
|
|
72467
73997
|
fixMode: options.fix === true,
|
|
72468
73998
|
nonInteractive: options.nonInteractive === true,
|
|
72469
73999
|
packageChanged: false,
|
|
@@ -72704,7 +74234,22 @@ init_autostart_windows();
|
|
|
72704
74234
|
DEFAULT_LOG_TAIL_LIMIT,
|
|
72705
74235
|
DEFAULT_OFFLINE_REPLAY_INTERVAL_SEC,
|
|
72706
74236
|
DEFAULT_XMTP_CLIENT_RECYCLE_INTERVAL_SEC,
|
|
74237
|
+
DEVKIT_DROP_REASON,
|
|
74238
|
+
DEVKIT_MAX_CONCURRENCY,
|
|
74239
|
+
DEVKIT_MAX_MESSAGE_BYTES,
|
|
74240
|
+
DEVKIT_MAX_PENDING,
|
|
74241
|
+
DEVKIT_MAX_PENDING_BYTES,
|
|
74242
|
+
DEVKIT_OUTCOME,
|
|
74243
|
+
DEVKIT_REQUEST_BUDGET_MS,
|
|
74244
|
+
DEVKIT_RESPONSE_DIAGNOSTIC_MAX_BYTES,
|
|
74245
|
+
DEVKIT_RESPONSE_SUMMARY_MAX_CHARS,
|
|
74246
|
+
DEVKIT_SERVER_APPLICATION_ID,
|
|
74247
|
+
DEVKIT_SERVER_DB_NAME,
|
|
74248
|
+
DEVKIT_SERVER_SCHEMA_VERSION,
|
|
72707
74249
|
DOCTOR_MIN_NODE_VERSION,
|
|
74250
|
+
DevkitDeliveryDispatcher,
|
|
74251
|
+
DevkitServerStore,
|
|
74252
|
+
DevkitServerStoreError,
|
|
72708
74253
|
GatewayOutboundBehavior,
|
|
72709
74254
|
HEARTBEAT_GATEWAY_CHECK_TIMEOUT_MS,
|
|
72710
74255
|
InboundReplayGate,
|
|
@@ -72733,6 +74278,9 @@ init_autostart_windows();
|
|
|
72733
74278
|
UserCancelledAiProviderSelectionError,
|
|
72734
74279
|
WALLET_STATUS_TIMEOUT_MS,
|
|
72735
74280
|
XMTP_CLIENT_RECYCLE_INTERVAL_ENV,
|
|
74281
|
+
XMTP_CREATION_COOLDOWN_MS,
|
|
74282
|
+
XmtpCreationCooldown,
|
|
74283
|
+
XmtpCreationCooldownSkipError,
|
|
72736
74284
|
XmtpDm,
|
|
72737
74285
|
XmtpGroup,
|
|
72738
74286
|
XmtpService,
|
|
@@ -72759,6 +74307,7 @@ init_autostart_windows();
|
|
|
72759
74307
|
buildExternalCommandInvocation,
|
|
72760
74308
|
buildGatewayOutboundExtra,
|
|
72761
74309
|
buildInboundTerminalExtras,
|
|
74310
|
+
buildJobEnvelope,
|
|
72762
74311
|
buildLaunchdPlist,
|
|
72763
74312
|
buildLauncherEntryJs,
|
|
72764
74313
|
buildMessageEligibleArgs,
|
|
@@ -72769,6 +74318,7 @@ init_autostart_windows();
|
|
|
72769
74318
|
buildSchtasksRunArgs,
|
|
72770
74319
|
buildSeaConfig,
|
|
72771
74320
|
buildServicePath,
|
|
74321
|
+
buildSessionEnvelope,
|
|
72772
74322
|
buildSessionKey,
|
|
72773
74323
|
buildSystemMessageNotice,
|
|
72774
74324
|
buildSystemStoredMessage,
|
|
@@ -72786,6 +74336,8 @@ init_autostart_windows();
|
|
|
72786
74336
|
checkCodexCliAuthStatus,
|
|
72787
74337
|
checkCodexReadiness,
|
|
72788
74338
|
claimActiveDaemon,
|
|
74339
|
+
classifyFetchFailure,
|
|
74340
|
+
classifyHttpOutcome,
|
|
72789
74341
|
classifyJobBindingSource,
|
|
72790
74342
|
clearCodexReadinessCache,
|
|
72791
74343
|
codexCommandResolvesWithoutOverride,
|
|
@@ -72794,6 +74346,7 @@ init_autostart_windows();
|
|
|
72794
74346
|
collectCodexCommandCandidates,
|
|
72795
74347
|
commandExists,
|
|
72796
74348
|
createAiToolFailureTracker,
|
|
74349
|
+
createDevkitAutoRouter,
|
|
72797
74350
|
createFileMessageHandler,
|
|
72798
74351
|
createOutboundBehavior,
|
|
72799
74352
|
createUserAttentionWatchParentMonitor,
|
|
@@ -72804,6 +74357,7 @@ init_autostart_windows();
|
|
|
72804
74357
|
detectGatewayInvocation,
|
|
72805
74358
|
detectMessageEligibleOfflineReplaySupport,
|
|
72806
74359
|
detectRuntime,
|
|
74360
|
+
devkitServerDbExists,
|
|
72807
74361
|
ensureDaemonReady,
|
|
72808
74362
|
ensureDefaultAiProvider,
|
|
72809
74363
|
ensureOpenClawOkxA2aPluginConfig,
|
|
@@ -72813,6 +74367,7 @@ init_autostart_windows();
|
|
|
72813
74367
|
exportDiagnosticLogs,
|
|
72814
74368
|
extractAiSessionId,
|
|
72815
74369
|
extractDirectToUserNotification,
|
|
74370
|
+
extractRateLimitEndpoint,
|
|
72816
74371
|
extractXmtpSentAtMs,
|
|
72817
74372
|
findWindowsNativeOkxA2aExe,
|
|
72818
74373
|
followFile,
|
|
@@ -72823,7 +74378,9 @@ init_autostart_windows();
|
|
|
72823
74378
|
getResolvedOnchainosBinForTests,
|
|
72824
74379
|
getRuntimeMetadata,
|
|
72825
74380
|
getSessionBusyTracker,
|
|
74381
|
+
getXmtpCreationCooldown,
|
|
72826
74382
|
handleCapabilitiesCommand,
|
|
74383
|
+
handleDevkitCommand,
|
|
72827
74384
|
handleDoctorCommand,
|
|
72828
74385
|
handleXmtpDebugCommand,
|
|
72829
74386
|
handleXmtpSendCommand,
|
|
@@ -72853,6 +74410,7 @@ init_autostart_windows();
|
|
|
72853
74410
|
isTagKey,
|
|
72854
74411
|
isValidExternalJobId,
|
|
72855
74412
|
isWindowsElevated,
|
|
74413
|
+
isXmtpRateLimitError,
|
|
72856
74414
|
killProcessTree,
|
|
72857
74415
|
launchdPlistHasCurrentRestartPolicy,
|
|
72858
74416
|
listAllAgentsWithMetadata,
|
|
@@ -72880,6 +74438,7 @@ init_autostart_windows();
|
|
|
72880
74438
|
persistCurrentRuntimeSelectionForNewJob,
|
|
72881
74439
|
pickOnchainosWin32Candidate,
|
|
72882
74440
|
prepareAndBindCurrentRuntimeForNewJob,
|
|
74441
|
+
printDevkitUsage,
|
|
72883
74442
|
printLogsExportUsage,
|
|
72884
74443
|
printXmtpTestUsage,
|
|
72885
74444
|
probeCodexAuthStatus,
|
|
@@ -72891,6 +74450,7 @@ init_autostart_windows();
|
|
|
72891
74450
|
readLastLines,
|
|
72892
74451
|
readParentProcessCommandForPlatform,
|
|
72893
74452
|
readUserAttentionWatcherEvent,
|
|
74453
|
+
redactSummary,
|
|
72894
74454
|
refreshAgentsAndWait,
|
|
72895
74455
|
refreshOnchainosVersionMetadata,
|
|
72896
74456
|
registerUserAttentionWatcher,
|
|
@@ -72902,6 +74462,7 @@ init_autostart_windows();
|
|
|
72902
74462
|
reportUserNotificationFailure,
|
|
72903
74463
|
resetMessageEligibleOfflineReplayCapabilityForTests,
|
|
72904
74464
|
resetResolvedOnchainosBinForTests,
|
|
74465
|
+
resetXmtpCreationCooldownForTests,
|
|
72905
74466
|
resolveAiPermissionPreset,
|
|
72906
74467
|
resolveAiProviderCommand,
|
|
72907
74468
|
resolveAiProviderCommandWithSource,
|
|
@@ -72912,6 +74473,7 @@ init_autostart_windows();
|
|
|
72912
74473
|
resolveCodexCommandSource,
|
|
72913
74474
|
resolveConfiguredAiProvider,
|
|
72914
74475
|
resolveConfiguredAiProviderForJob,
|
|
74476
|
+
resolveDevkitServerDbPath,
|
|
72915
74477
|
resolveDirectCommunicationSessionTarget,
|
|
72916
74478
|
resolveDoctorTarget,
|
|
72917
74479
|
resolveEnvelopePayload,
|
|
@@ -72949,6 +74511,7 @@ init_autostart_windows();
|
|
|
72949
74511
|
startDaemonRespectingSupervisor,
|
|
72950
74512
|
startUserAttentionEventServer,
|
|
72951
74513
|
startUserAttentionWatcherCoordinator,
|
|
74514
|
+
stopAndCloseXmtpClient,
|
|
72952
74515
|
stopDaemon,
|
|
72953
74516
|
stopOpenClawGateway,
|
|
72954
74517
|
stopSystemdAutostart,
|