@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/cli.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
|
|
|
@@ -4935,8 +4937,8 @@ var require_worldwide = __commonJS({
|
|
|
4935
4937
|
function getGlobalSingleton(name, creator, obj) {
|
|
4936
4938
|
const gbl = obj || GLOBAL_OBJ;
|
|
4937
4939
|
const __SENTRY__ = gbl.__SENTRY__ = gbl.__SENTRY__ || {};
|
|
4938
|
-
const
|
|
4939
|
-
return
|
|
4940
|
+
const singleton3 = __SENTRY__[name] || (__SENTRY__[name] = creator());
|
|
4941
|
+
return singleton3;
|
|
4940
4942
|
}
|
|
4941
4943
|
exports2.GLOBAL_OBJ = GLOBAL_OBJ;
|
|
4942
4944
|
exports2.getGlobalObject = getGlobalObject;
|
|
@@ -19981,6 +19983,14 @@ var init_events = __esm({
|
|
|
19981
19983
|
SYSTEM_NOTIFICATION_ROUTED: "System notification routed",
|
|
19982
19984
|
HERMES_SESSION_ROUTE_BINDING: "Hermes session route binding",
|
|
19983
19985
|
DOCTOR_REPORT: "Doctor report",
|
|
19986
|
+
// XMTP creation rate-limit cooldown (DEXMARKET-9116). All four are logger.info,
|
|
19987
|
+
// so each one must also be listed in SENTRY_INFO_ALLOWLIST (index.ts) or info()
|
|
19988
|
+
// drops it silently. Extras are bounded tokens/ints/bools only — never raw SDK
|
|
19989
|
+
// error text (no-content-leak invariant).
|
|
19990
|
+
XMTP_RATE_LIMIT_COOLDOWN_STARTED: "XMTP rate limit cooldown started",
|
|
19991
|
+
XMTP_RATE_LIMIT_CREATE_SUPPRESSED: "XMTP rate limit create suppressed",
|
|
19992
|
+
XMTP_RATE_LIMIT_PROBE: "XMTP rate limit probe",
|
|
19993
|
+
XMTP_RATE_LIMIT_RECOVERED: "XMTP rate limit recovered",
|
|
19984
19994
|
// ── error ─────────────────────────────────────────────────────
|
|
19985
19995
|
XMTP_CONNECTION_FAILED: "XMTP connection failed",
|
|
19986
19996
|
CONVERSATIONS_STREAM_FAILED: "conversations.stream failed",
|
|
@@ -20046,7 +20056,28 @@ var init_events = __esm({
|
|
|
20046
20056
|
AGENT_DB_DIR_CREATE_FAILED: "Agent DB dir create failed",
|
|
20047
20057
|
AGENT_INSTALLATION_LIMIT_NEAR: "Agent installation limit near",
|
|
20048
20058
|
XMTP_HISTORY_SYNC_REQUEST_FAILED: "XMTP history sync request failed",
|
|
20049
|
-
XMTP_DEBUG_SYNC_FAILED: "XMTP debug sync failed"
|
|
20059
|
+
XMTP_DEBUG_SYNC_FAILED: "XMTP debug sync failed",
|
|
20060
|
+
// Underlying XMTP SDK client close failed during recycle/removal/shutdown
|
|
20061
|
+
// (DEXMARKET-9116). Error-level → NOT added to SENTRY_INFO_ALLOWLIST.
|
|
20062
|
+
XMTP_CLIENT_CLOSE_FAILED: "XMTP client close failed",
|
|
20063
|
+
// ── devkit custom-server registry + delivery (DEXMARKET-9165) ──────────────
|
|
20064
|
+
// info-level (registered in SENTRY_INFO_ALLOWLIST below):
|
|
20065
|
+
DEVKIT_REGISTER_REQUESTED: "Devkit register requested",
|
|
20066
|
+
DEVKIT_REGISTER_COMPLETED: "Devkit register completed",
|
|
20067
|
+
DEVKIT_UNREGISTER_REQUESTED: "Devkit unregister requested",
|
|
20068
|
+
DEVKIT_UNREGISTER_COMPLETED: "Devkit unregister completed",
|
|
20069
|
+
DEVKIT_DAEMON_STATUS_UNKNOWN: "Devkit daemon status unknown",
|
|
20070
|
+
DEVKIT_ROUTE_DEFAULT_AI: "Devkit route default AI",
|
|
20071
|
+
DEVKIT_ROUTE_CUSTOM_SERVER: "Devkit route custom server",
|
|
20072
|
+
DEVKIT_DELIVERY_ACCEPTED: "Devkit delivery accepted",
|
|
20073
|
+
DEVKIT_DELIVERY_HTTP_ACCEPTED: "Devkit delivery http accepted",
|
|
20074
|
+
DEVKIT_DELIVERY_DROPPED: "Devkit delivery dropped",
|
|
20075
|
+
DEVKIT_DELIVERY_CANCELLED: "Devkit delivery cancelled",
|
|
20076
|
+
// error-level (NOT allowlisted — logger.error):
|
|
20077
|
+
DEVKIT_REGISTER_REJECTED: "Devkit register rejected",
|
|
20078
|
+
DEVKIT_CONFIG_PERSIST_FAILED: "Devkit config persist failed",
|
|
20079
|
+
DEVKIT_ROUTE_CONFIG_READ_FAILED: "Devkit route config read failed",
|
|
20080
|
+
DEVKIT_DELIVERY_HTTP_FAILED: "Devkit delivery http failed"
|
|
20050
20081
|
};
|
|
20051
20082
|
}
|
|
20052
20083
|
});
|
|
@@ -20885,7 +20916,26 @@ var init_sentry_logger = __esm({
|
|
|
20885
20916
|
LogEvent.PENDING_LIST_QUERIED,
|
|
20886
20917
|
LogEvent.SESSION_KEY_DERIVED,
|
|
20887
20918
|
LogEvent.SESSIONS_QUERIED,
|
|
20888
|
-
LogEvent.SYNC_TICK_COMPLETED
|
|
20919
|
+
LogEvent.SYNC_TICK_COMPLETED,
|
|
20920
|
+
// XMTP creation rate-limit cooldown checkpoints (DEXMARKET-9116). info() drops
|
|
20921
|
+
// any event not listed here, so these must stay registered.
|
|
20922
|
+
LogEvent.XMTP_RATE_LIMIT_COOLDOWN_STARTED,
|
|
20923
|
+
LogEvent.XMTP_RATE_LIMIT_CREATE_SUPPRESSED,
|
|
20924
|
+
LogEvent.XMTP_RATE_LIMIT_PROBE,
|
|
20925
|
+
LogEvent.XMTP_RATE_LIMIT_RECOVERED,
|
|
20926
|
+
// devkit custom-server registry + delivery info checkpoints (DEXMARKET-9165).
|
|
20927
|
+
// info() drops any event not listed here, so these must stay registered.
|
|
20928
|
+
LogEvent.DEVKIT_REGISTER_REQUESTED,
|
|
20929
|
+
LogEvent.DEVKIT_REGISTER_COMPLETED,
|
|
20930
|
+
LogEvent.DEVKIT_UNREGISTER_REQUESTED,
|
|
20931
|
+
LogEvent.DEVKIT_UNREGISTER_COMPLETED,
|
|
20932
|
+
LogEvent.DEVKIT_DAEMON_STATUS_UNKNOWN,
|
|
20933
|
+
LogEvent.DEVKIT_ROUTE_DEFAULT_AI,
|
|
20934
|
+
LogEvent.DEVKIT_ROUTE_CUSTOM_SERVER,
|
|
20935
|
+
LogEvent.DEVKIT_DELIVERY_ACCEPTED,
|
|
20936
|
+
LogEvent.DEVKIT_DELIVERY_HTTP_ACCEPTED,
|
|
20937
|
+
LogEvent.DEVKIT_DELIVERY_DROPPED,
|
|
20938
|
+
LogEvent.DEVKIT_DELIVERY_CANCELLED
|
|
20889
20939
|
]);
|
|
20890
20940
|
MAX_EXTRA_STRING_LENGTH = 256;
|
|
20891
20941
|
MAX_TAG_VALUE_LENGTH = 128;
|
|
@@ -27001,7 +27051,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
|
|
|
27001
27051
|
client: {
|
|
27002
27052
|
id: "gateway-client",
|
|
27003
27053
|
displayName: "okx-a2a-node",
|
|
27004
|
-
version: "0.2.
|
|
27054
|
+
version: "0.2.17-beta-ab42219842-261020165552",
|
|
27005
27055
|
platform: "node",
|
|
27006
27056
|
mode: "backend",
|
|
27007
27057
|
instanceId
|
|
@@ -27012,7 +27062,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
|
|
|
27012
27062
|
commands: [],
|
|
27013
27063
|
permissions: {},
|
|
27014
27064
|
locale: Intl.DateTimeFormat().resolvedOptions().locale || "en-US",
|
|
27015
|
-
userAgent: `okx-a2a-node/${"0.2.
|
|
27065
|
+
userAgent: `okx-a2a-node/${"0.2.17-beta-ab42219842-261020165552"}`,
|
|
27016
27066
|
auth: {
|
|
27017
27067
|
...config.token ? { token: config.token } : {},
|
|
27018
27068
|
...config.password ? { password: config.password } : {}
|
|
@@ -29072,7 +29122,7 @@ var init_sentry_config = __esm({
|
|
|
29072
29122
|
environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
|
|
29073
29123
|
SENTRY_CONFIG = {
|
|
29074
29124
|
projectName: "okx/openclaw-okx-a2a-extension",
|
|
29075
|
-
release: "0.2.
|
|
29125
|
+
release: "0.2.17-beta-ab42219842-261020165552",
|
|
29076
29126
|
environment,
|
|
29077
29127
|
runtimeContainer: normalizeRuntimeContainer(process.env.OKX_A2A_RUNTIME_CONTAINER)
|
|
29078
29128
|
};
|
|
@@ -39642,8 +39692,8 @@ function readSqliteRows(dbPath, sql, params = []) {
|
|
|
39642
39692
|
if (!(0, import_node_fs17.existsSync)(dbPath)) {
|
|
39643
39693
|
throw unavailable(`SQLite database not found: ${dbPath}`);
|
|
39644
39694
|
}
|
|
39645
|
-
const { DatabaseSync:
|
|
39646
|
-
const db = new
|
|
39695
|
+
const { DatabaseSync: DatabaseSync6 } = loadSqlite3();
|
|
39696
|
+
const db = new DatabaseSync6(dbPath, { readOnly: true });
|
|
39647
39697
|
try {
|
|
39648
39698
|
return db.prepare(sql).all(...params);
|
|
39649
39699
|
} finally {
|
|
@@ -40242,7 +40292,7 @@ async function exportDiagnosticLogs(options) {
|
|
|
40242
40292
|
node: process.version,
|
|
40243
40293
|
platform: process.platform,
|
|
40244
40294
|
arch: process.arch,
|
|
40245
|
-
packageVersion: true ? "0.2.
|
|
40295
|
+
packageVersion: true ? "0.2.17-beta-ab42219842-261020165552" : "unknown",
|
|
40246
40296
|
sensitiveContentIncluded: options.includeSensitiveContent,
|
|
40247
40297
|
listenerAndLlmContentIncluded: true,
|
|
40248
40298
|
credentialsAlwaysRedacted: true,
|
|
@@ -42221,6 +42271,701 @@ var init_trade_records_cli = __esm({
|
|
|
42221
42271
|
}
|
|
42222
42272
|
});
|
|
42223
42273
|
|
|
42274
|
+
// src/devkit-server-store.ts
|
|
42275
|
+
function resolveDevkitServerDbPath(homeDir) {
|
|
42276
|
+
return resolveTaskPaths(homeDir).devkitServerDbPath;
|
|
42277
|
+
}
|
|
42278
|
+
function applyMigrationV12(db) {
|
|
42279
|
+
db.exec(`
|
|
42280
|
+
CREATE TABLE ${TABLE_NAME2} (
|
|
42281
|
+
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
42282
|
+
origin TEXT NOT NULL,
|
|
42283
|
+
port INTEGER NOT NULL CHECK (port >= 1 AND port <= 65535),
|
|
42284
|
+
event_path TEXT NOT NULL,
|
|
42285
|
+
health_path TEXT NOT NULL,
|
|
42286
|
+
config_version INTEGER NOT NULL,
|
|
42287
|
+
updated_at INTEGER NOT NULL,
|
|
42288
|
+
CHECK (length(origin) > 0),
|
|
42289
|
+
CHECK (substr(event_path,1,1) = '/'),
|
|
42290
|
+
CHECK (substr(health_path,1,1) = '/')
|
|
42291
|
+
)
|
|
42292
|
+
`);
|
|
42293
|
+
}
|
|
42294
|
+
function readPragmaNumber2(db, name) {
|
|
42295
|
+
const row = db.prepare(`PRAGMA ${name}`).get();
|
|
42296
|
+
return Number(row[name] ?? 0);
|
|
42297
|
+
}
|
|
42298
|
+
function assertNotSymlink2(path2, label) {
|
|
42299
|
+
if (!(0, import_node_fs22.existsSync)(path2)) {
|
|
42300
|
+
return;
|
|
42301
|
+
}
|
|
42302
|
+
if ((0, import_node_fs22.lstatSync)(path2).isSymbolicLink()) {
|
|
42303
|
+
throw new DevkitServerStoreError("DATABASE_PATH_UNSAFE", `${label} must not be a symbolic link`);
|
|
42304
|
+
}
|
|
42305
|
+
}
|
|
42306
|
+
function assertSafeDatabasePath2(dbPath) {
|
|
42307
|
+
assertSafeDatabaseFile2(dbPath);
|
|
42308
|
+
for (const suffix of ["-journal", "-wal", "-shm"]) {
|
|
42309
|
+
assertNotSymlink2(`${dbPath}${suffix}`, `devkit server database sidecar ${suffix}`);
|
|
42310
|
+
}
|
|
42311
|
+
}
|
|
42312
|
+
function assertSafeDatabaseFile2(dbPath) {
|
|
42313
|
+
if (!(0, import_node_fs22.existsSync)(dbPath)) {
|
|
42314
|
+
return;
|
|
42315
|
+
}
|
|
42316
|
+
const stat4 = (0, import_node_fs22.lstatSync)(dbPath);
|
|
42317
|
+
if (stat4.isSymbolicLink()) {
|
|
42318
|
+
throw new DevkitServerStoreError(
|
|
42319
|
+
"DATABASE_PATH_UNSAFE",
|
|
42320
|
+
"devkit server database must not be a symbolic link"
|
|
42321
|
+
);
|
|
42322
|
+
}
|
|
42323
|
+
if (!stat4.isFile() || stat4.nlink !== 1) {
|
|
42324
|
+
throw new DevkitServerStoreError(
|
|
42325
|
+
"DATABASE_PATH_UNSAFE",
|
|
42326
|
+
"devkit server database must be a regular file with one hard link"
|
|
42327
|
+
);
|
|
42328
|
+
}
|
|
42329
|
+
}
|
|
42330
|
+
function rollbackQuietly2(db) {
|
|
42331
|
+
try {
|
|
42332
|
+
db.exec("ROLLBACK");
|
|
42333
|
+
} catch {
|
|
42334
|
+
}
|
|
42335
|
+
}
|
|
42336
|
+
function withBusyRetry2(operation) {
|
|
42337
|
+
for (let attempt = 1; ; attempt += 1) {
|
|
42338
|
+
try {
|
|
42339
|
+
return operation();
|
|
42340
|
+
} catch (error) {
|
|
42341
|
+
if (!isSqliteBusyError(error) || attempt >= WRITE_RETRY_ATTEMPTS2) {
|
|
42342
|
+
throw error;
|
|
42343
|
+
}
|
|
42344
|
+
sleepSyncMs3(Math.min(100 * 2 ** (attempt - 1), 1600));
|
|
42345
|
+
}
|
|
42346
|
+
}
|
|
42347
|
+
}
|
|
42348
|
+
function sleepSyncMs3(ms) {
|
|
42349
|
+
const buffer2 = new Int32Array(new SharedArrayBuffer(4));
|
|
42350
|
+
Atomics.wait(buffer2, 0, 0, ms);
|
|
42351
|
+
}
|
|
42352
|
+
function loadSqlite5() {
|
|
42353
|
+
const originalEmitWarning = process.emitWarning;
|
|
42354
|
+
process.emitWarning = ((warning, ...args) => {
|
|
42355
|
+
const message = typeof warning === "string" ? warning : warning.message;
|
|
42356
|
+
if (message.includes("SQLite is an experimental feature") && args.some((arg) => arg === "ExperimentalWarning")) {
|
|
42357
|
+
return;
|
|
42358
|
+
}
|
|
42359
|
+
return originalEmitWarning.call(process, warning, ...args);
|
|
42360
|
+
});
|
|
42361
|
+
try {
|
|
42362
|
+
return require("node:sqlite");
|
|
42363
|
+
} finally {
|
|
42364
|
+
process.emitWarning = originalEmitWarning;
|
|
42365
|
+
}
|
|
42366
|
+
}
|
|
42367
|
+
var import_node_fs22, DatabaseSync4, DEVKIT_SERVER_APPLICATION_ID, DEVKIT_SERVER_SCHEMA_VERSION, TABLE_NAME2, WRITE_RETRY_ATTEMPTS2, DevkitServerStoreError, DevkitServerStore;
|
|
42368
|
+
var init_devkit_server_store = __esm({
|
|
42369
|
+
"src/devkit-server-store.ts"() {
|
|
42370
|
+
"use strict";
|
|
42371
|
+
import_node_fs22 = require("node:fs");
|
|
42372
|
+
init_paths();
|
|
42373
|
+
init_session_store();
|
|
42374
|
+
({ DatabaseSync: DatabaseSync4 } = loadSqlite5());
|
|
42375
|
+
DEVKIT_SERVER_APPLICATION_ID = 1329677395;
|
|
42376
|
+
DEVKIT_SERVER_SCHEMA_VERSION = 1;
|
|
42377
|
+
TABLE_NAME2 = `"devkit-server"`;
|
|
42378
|
+
WRITE_RETRY_ATTEMPTS2 = 6;
|
|
42379
|
+
DevkitServerStoreError = class extends Error {
|
|
42380
|
+
code;
|
|
42381
|
+
constructor(code, message) {
|
|
42382
|
+
super(message);
|
|
42383
|
+
this.name = "DevkitServerStoreError";
|
|
42384
|
+
this.code = code;
|
|
42385
|
+
}
|
|
42386
|
+
};
|
|
42387
|
+
DevkitServerStore = class _DevkitServerStore {
|
|
42388
|
+
dbPath;
|
|
42389
|
+
db;
|
|
42390
|
+
constructor(dbPath, db) {
|
|
42391
|
+
this.dbPath = dbPath;
|
|
42392
|
+
this.db = db;
|
|
42393
|
+
}
|
|
42394
|
+
static openForWrite(homeDir) {
|
|
42395
|
+
const paths = resolveTaskPaths(homeDir);
|
|
42396
|
+
const dbPath = paths.devkitServerDbPath;
|
|
42397
|
+
assertNotSymlink2(paths.sqliteDir, "devkit server directory");
|
|
42398
|
+
ensureTaskDir(paths.sqliteDir);
|
|
42399
|
+
assertNotSymlink2(paths.sqliteDir, "devkit server directory");
|
|
42400
|
+
assertSafeDatabasePath2(dbPath);
|
|
42401
|
+
const db = new DatabaseSync4(dbPath);
|
|
42402
|
+
const store = new _DevkitServerStore(dbPath, db);
|
|
42403
|
+
try {
|
|
42404
|
+
store.configureConnectionForWrite();
|
|
42405
|
+
store.ensureSchemaForWrite();
|
|
42406
|
+
return store;
|
|
42407
|
+
} catch (error) {
|
|
42408
|
+
db.close();
|
|
42409
|
+
throw error;
|
|
42410
|
+
}
|
|
42411
|
+
}
|
|
42412
|
+
static openForRead(homeDir) {
|
|
42413
|
+
const dbPath = resolveDevkitServerDbPath(homeDir);
|
|
42414
|
+
if (!(0, import_node_fs22.existsSync)(dbPath)) {
|
|
42415
|
+
return null;
|
|
42416
|
+
}
|
|
42417
|
+
assertSafeDatabaseFile2(dbPath);
|
|
42418
|
+
const db = new DatabaseSync4(dbPath, { readOnly: true });
|
|
42419
|
+
const store = new _DevkitServerStore(dbPath, db);
|
|
42420
|
+
try {
|
|
42421
|
+
db.exec("PRAGMA query_only=ON");
|
|
42422
|
+
store.assertReadableSchema();
|
|
42423
|
+
return store;
|
|
42424
|
+
} catch (error) {
|
|
42425
|
+
db.close();
|
|
42426
|
+
throw error;
|
|
42427
|
+
}
|
|
42428
|
+
}
|
|
42429
|
+
close() {
|
|
42430
|
+
this.db.close();
|
|
42431
|
+
}
|
|
42432
|
+
register(input) {
|
|
42433
|
+
return this.withWriteTransaction(() => {
|
|
42434
|
+
const existing = this.db.prepare(`SELECT config_version FROM ${TABLE_NAME2} WHERE id = 1`).get();
|
|
42435
|
+
const configVersion = (existing?.config_version ?? 0) + 1;
|
|
42436
|
+
const updatedAt = Date.now();
|
|
42437
|
+
this.db.prepare(`
|
|
42438
|
+
INSERT INTO ${TABLE_NAME2} (
|
|
42439
|
+
id, origin, port, event_path, health_path, config_version, updated_at
|
|
42440
|
+
) VALUES (1, ?, ?, ?, ?, ?, ?)
|
|
42441
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
42442
|
+
origin = excluded.origin,
|
|
42443
|
+
port = excluded.port,
|
|
42444
|
+
event_path = excluded.event_path,
|
|
42445
|
+
health_path = excluded.health_path,
|
|
42446
|
+
config_version = excluded.config_version,
|
|
42447
|
+
updated_at = excluded.updated_at
|
|
42448
|
+
`).run(input.origin, input.port, input.eventPath, input.healthPath, configVersion, updatedAt);
|
|
42449
|
+
return {
|
|
42450
|
+
origin: input.origin,
|
|
42451
|
+
port: input.port,
|
|
42452
|
+
eventPath: input.eventPath,
|
|
42453
|
+
healthPath: input.healthPath,
|
|
42454
|
+
configVersion,
|
|
42455
|
+
updatedAt
|
|
42456
|
+
};
|
|
42457
|
+
});
|
|
42458
|
+
}
|
|
42459
|
+
unregister() {
|
|
42460
|
+
return this.withWriteTransaction(() => {
|
|
42461
|
+
const result = this.db.prepare(`DELETE FROM ${TABLE_NAME2} WHERE id = 1`).run();
|
|
42462
|
+
return { removed: Number(result.changes) > 0 };
|
|
42463
|
+
});
|
|
42464
|
+
}
|
|
42465
|
+
readSnapshot() {
|
|
42466
|
+
let row;
|
|
42467
|
+
try {
|
|
42468
|
+
row = this.db.prepare(`
|
|
42469
|
+
SELECT origin, port, event_path, health_path, config_version, updated_at
|
|
42470
|
+
FROM ${TABLE_NAME2} WHERE id = 1
|
|
42471
|
+
`).get();
|
|
42472
|
+
} catch (error) {
|
|
42473
|
+
throw new DevkitServerStoreError(
|
|
42474
|
+
"DATABASE_READ_FAILED",
|
|
42475
|
+
`failed to read devkit server config: ${error instanceof Error ? error.message : String(error)}`
|
|
42476
|
+
);
|
|
42477
|
+
}
|
|
42478
|
+
if (!row) {
|
|
42479
|
+
return null;
|
|
42480
|
+
}
|
|
42481
|
+
return {
|
|
42482
|
+
origin: row.origin,
|
|
42483
|
+
port: row.port,
|
|
42484
|
+
eventPath: row.event_path,
|
|
42485
|
+
healthPath: row.health_path,
|
|
42486
|
+
configVersion: row.config_version,
|
|
42487
|
+
updatedAt: row.updated_at
|
|
42488
|
+
};
|
|
42489
|
+
}
|
|
42490
|
+
configureConnectionForWrite() {
|
|
42491
|
+
this.db.exec("PRAGMA busy_timeout=5000");
|
|
42492
|
+
}
|
|
42493
|
+
ensureSchemaForWrite() {
|
|
42494
|
+
withBusyRetry2(() => {
|
|
42495
|
+
this.db.exec("BEGIN IMMEDIATE");
|
|
42496
|
+
try {
|
|
42497
|
+
const applicationId = readPragmaNumber2(this.db, "application_id");
|
|
42498
|
+
const userVersion = readPragmaNumber2(this.db, "user_version");
|
|
42499
|
+
const hasTables = Boolean(
|
|
42500
|
+
this.db.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' LIMIT 1").get()
|
|
42501
|
+
);
|
|
42502
|
+
if (applicationId === 0 && !hasTables && userVersion === 0) {
|
|
42503
|
+
this.db.exec(`PRAGMA application_id=${DEVKIT_SERVER_APPLICATION_ID}`);
|
|
42504
|
+
} else if (applicationId !== DEVKIT_SERVER_APPLICATION_ID) {
|
|
42505
|
+
throw new DevkitServerStoreError(
|
|
42506
|
+
"DATABASE_IDENTITY_MISMATCH",
|
|
42507
|
+
"devkit server database identity does not match"
|
|
42508
|
+
);
|
|
42509
|
+
}
|
|
42510
|
+
if (userVersion > DEVKIT_SERVER_SCHEMA_VERSION) {
|
|
42511
|
+
throw new DevkitServerStoreError(
|
|
42512
|
+
"DATABASE_SCHEMA_TOO_NEW",
|
|
42513
|
+
`devkit server schema version ${userVersion} is newer than supported ${DEVKIT_SERVER_SCHEMA_VERSION}`
|
|
42514
|
+
);
|
|
42515
|
+
}
|
|
42516
|
+
if (userVersion < 1) {
|
|
42517
|
+
applyMigrationV12(this.db);
|
|
42518
|
+
this.db.exec("PRAGMA user_version=1");
|
|
42519
|
+
}
|
|
42520
|
+
this.db.exec("COMMIT");
|
|
42521
|
+
} catch (error) {
|
|
42522
|
+
rollbackQuietly2(this.db);
|
|
42523
|
+
throw error;
|
|
42524
|
+
}
|
|
42525
|
+
});
|
|
42526
|
+
withBusyRetry2(() => {
|
|
42527
|
+
this.db.exec("PRAGMA journal_mode=WAL");
|
|
42528
|
+
this.db.exec("PRAGMA synchronous=FULL");
|
|
42529
|
+
});
|
|
42530
|
+
}
|
|
42531
|
+
assertReadableSchema() {
|
|
42532
|
+
const applicationId = readPragmaNumber2(this.db, "application_id");
|
|
42533
|
+
if (applicationId !== DEVKIT_SERVER_APPLICATION_ID) {
|
|
42534
|
+
throw new DevkitServerStoreError(
|
|
42535
|
+
"DATABASE_IDENTITY_MISMATCH",
|
|
42536
|
+
"devkit server database identity does not match"
|
|
42537
|
+
);
|
|
42538
|
+
}
|
|
42539
|
+
const userVersion = readPragmaNumber2(this.db, "user_version");
|
|
42540
|
+
if (userVersion > DEVKIT_SERVER_SCHEMA_VERSION) {
|
|
42541
|
+
throw new DevkitServerStoreError(
|
|
42542
|
+
"DATABASE_SCHEMA_TOO_NEW",
|
|
42543
|
+
`devkit server schema version ${userVersion} is newer than supported ${DEVKIT_SERVER_SCHEMA_VERSION}`
|
|
42544
|
+
);
|
|
42545
|
+
}
|
|
42546
|
+
if (userVersion < DEVKIT_SERVER_SCHEMA_VERSION) {
|
|
42547
|
+
throw new DevkitServerStoreError(
|
|
42548
|
+
"DATABASE_MIGRATION_REQUIRED",
|
|
42549
|
+
"devkit server database requires a write command to finish migration"
|
|
42550
|
+
);
|
|
42551
|
+
}
|
|
42552
|
+
}
|
|
42553
|
+
withWriteTransaction(operation) {
|
|
42554
|
+
return withBusyRetry2(() => {
|
|
42555
|
+
this.db.exec("BEGIN IMMEDIATE");
|
|
42556
|
+
try {
|
|
42557
|
+
const result = operation();
|
|
42558
|
+
this.db.exec("COMMIT");
|
|
42559
|
+
return result;
|
|
42560
|
+
} catch (error) {
|
|
42561
|
+
rollbackQuietly2(this.db);
|
|
42562
|
+
throw error;
|
|
42563
|
+
}
|
|
42564
|
+
});
|
|
42565
|
+
}
|
|
42566
|
+
};
|
|
42567
|
+
}
|
|
42568
|
+
});
|
|
42569
|
+
|
|
42570
|
+
// src/devkit-cli.ts
|
|
42571
|
+
var devkit_cli_exports = {};
|
|
42572
|
+
__export(devkit_cli_exports, {
|
|
42573
|
+
handleDevkitCommand: () => handleDevkitCommand,
|
|
42574
|
+
printDevkitUsage: () => printDevkitUsage
|
|
42575
|
+
});
|
|
42576
|
+
async function handleDevkitCommand(args) {
|
|
42577
|
+
const wantsJson = args.includes("--json");
|
|
42578
|
+
const subcommand = args[0];
|
|
42579
|
+
if (!subcommand || isHelpArg2(subcommand)) {
|
|
42580
|
+
printDevkitUsage();
|
|
42581
|
+
return;
|
|
42582
|
+
}
|
|
42583
|
+
if (args.slice(1).some(isHelpArg2)) {
|
|
42584
|
+
printDevkitUsage();
|
|
42585
|
+
return;
|
|
42586
|
+
}
|
|
42587
|
+
if (subcommand === "register") {
|
|
42588
|
+
await handleRegister(args.slice(1), wantsJson);
|
|
42589
|
+
return;
|
|
42590
|
+
}
|
|
42591
|
+
if (subcommand === "unregister") {
|
|
42592
|
+
await handleUnregister(args.slice(1), wantsJson);
|
|
42593
|
+
return;
|
|
42594
|
+
}
|
|
42595
|
+
outputError2(wantsJson, { field: "command", reason: `unknown devkit command: ${subcommand}` });
|
|
42596
|
+
process.exitCode = 1;
|
|
42597
|
+
}
|
|
42598
|
+
function printDevkitUsage() {
|
|
42599
|
+
console.log(`Usage: okx-a2a devkit <register|unregister> [options]
|
|
42600
|
+
|
|
42601
|
+
Commands:
|
|
42602
|
+
register Register a local custom server for daemon auto-message delivery.
|
|
42603
|
+
--url <origin> --port <n> --paths '{"event":"/path","health":"/path"}'
|
|
42604
|
+
unregister Remove the registered custom server; daemon reverts to default AI delivery.
|
|
42605
|
+
|
|
42606
|
+
Options:
|
|
42607
|
+
--json Print machine-readable output.`);
|
|
42608
|
+
}
|
|
42609
|
+
async function handleRegister(args, wantsJson) {
|
|
42610
|
+
const operationId = (0, import_node_crypto9.randomUUID)();
|
|
42611
|
+
const startedAt = Date.now();
|
|
42612
|
+
logger.info(LogEvent.DEVKIT_REGISTER_REQUESTED, devkitSentryExtra({ operationId, phase: "requested" }));
|
|
42613
|
+
try {
|
|
42614
|
+
const parsed = parseArgs2(args, { options: /* @__PURE__ */ new Set(["url", "port", "paths"]), flags: /* @__PURE__ */ new Set(["json"]) });
|
|
42615
|
+
const origin = validateUrl(requireOption(parsed, "url"));
|
|
42616
|
+
const port = validatePort(requireOption(parsed, "port"));
|
|
42617
|
+
const { eventPath, healthPath } = validatePaths(requireOption(parsed, "paths"));
|
|
42618
|
+
let config;
|
|
42619
|
+
try {
|
|
42620
|
+
const store = DevkitServerStore.openForWrite();
|
|
42621
|
+
try {
|
|
42622
|
+
config = store.register({ origin, port, eventPath, healthPath });
|
|
42623
|
+
} finally {
|
|
42624
|
+
store.close();
|
|
42625
|
+
}
|
|
42626
|
+
} catch (error) {
|
|
42627
|
+
logger.error(
|
|
42628
|
+
LogEvent.DEVKIT_CONFIG_PERSIST_FAILED,
|
|
42629
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
42630
|
+
devkitSentryExtra({ operationId, phase: "persist_failed", durationMs: Date.now() - startedAt })
|
|
42631
|
+
);
|
|
42632
|
+
outputError2(wantsJson, {
|
|
42633
|
+
field: "config",
|
|
42634
|
+
reason: error instanceof DevkitServerStoreError ? error.message : "failed to persist devkit configuration"
|
|
42635
|
+
});
|
|
42636
|
+
process.exitCode = 1;
|
|
42637
|
+
return;
|
|
42638
|
+
}
|
|
42639
|
+
const outcome = config.configVersion === 1 ? "created" : "replaced";
|
|
42640
|
+
const { daemonRunning, warning } = await resolveDaemonStatus(operationId);
|
|
42641
|
+
logger.info(
|
|
42642
|
+
LogEvent.DEVKIT_REGISTER_COMPLETED,
|
|
42643
|
+
devkitSentryExtra({
|
|
42644
|
+
operationId,
|
|
42645
|
+
phase: "completed",
|
|
42646
|
+
outcome,
|
|
42647
|
+
registrationId: String(config.configVersion),
|
|
42648
|
+
daemonRunning: String(daemonRunning),
|
|
42649
|
+
durationMs: Date.now() - startedAt
|
|
42650
|
+
})
|
|
42651
|
+
);
|
|
42652
|
+
outputSuccess(wantsJson, { daemonRunning, warning, configVersion: config.configVersion });
|
|
42653
|
+
} catch (error) {
|
|
42654
|
+
const detail = normalizeError2(error);
|
|
42655
|
+
logger.error(
|
|
42656
|
+
LogEvent.DEVKIT_REGISTER_REJECTED,
|
|
42657
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
42658
|
+
devkitSentryExtra({ operationId, phase: "rejected", reason: detail.field, durationMs: Date.now() - startedAt })
|
|
42659
|
+
);
|
|
42660
|
+
outputError2(wantsJson, detail);
|
|
42661
|
+
process.exitCode = 1;
|
|
42662
|
+
}
|
|
42663
|
+
}
|
|
42664
|
+
async function handleUnregister(args, wantsJson) {
|
|
42665
|
+
const operationId = (0, import_node_crypto9.randomUUID)();
|
|
42666
|
+
const startedAt = Date.now();
|
|
42667
|
+
logger.info(LogEvent.DEVKIT_UNREGISTER_REQUESTED, devkitSentryExtra({ operationId, phase: "requested" }));
|
|
42668
|
+
try {
|
|
42669
|
+
parseArgs2(args, { options: /* @__PURE__ */ new Set(), flags: /* @__PURE__ */ new Set(["json"]) });
|
|
42670
|
+
let removed;
|
|
42671
|
+
try {
|
|
42672
|
+
const store = DevkitServerStore.openForWrite();
|
|
42673
|
+
try {
|
|
42674
|
+
removed = store.unregister().removed;
|
|
42675
|
+
} finally {
|
|
42676
|
+
store.close();
|
|
42677
|
+
}
|
|
42678
|
+
} catch (error) {
|
|
42679
|
+
logger.error(
|
|
42680
|
+
LogEvent.DEVKIT_CONFIG_PERSIST_FAILED,
|
|
42681
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
42682
|
+
devkitSentryExtra({ operationId, phase: "persist_failed", durationMs: Date.now() - startedAt })
|
|
42683
|
+
);
|
|
42684
|
+
outputError2(wantsJson, {
|
|
42685
|
+
field: "config",
|
|
42686
|
+
reason: error instanceof DevkitServerStoreError ? error.message : "failed to persist devkit configuration"
|
|
42687
|
+
});
|
|
42688
|
+
process.exitCode = 1;
|
|
42689
|
+
return;
|
|
42690
|
+
}
|
|
42691
|
+
const outcome = removed ? "removed" : "noop";
|
|
42692
|
+
const { daemonRunning, warning } = await resolveDaemonStatus(operationId);
|
|
42693
|
+
logger.info(
|
|
42694
|
+
LogEvent.DEVKIT_UNREGISTER_COMPLETED,
|
|
42695
|
+
devkitSentryExtra({
|
|
42696
|
+
operationId,
|
|
42697
|
+
phase: "completed",
|
|
42698
|
+
outcome,
|
|
42699
|
+
daemonRunning: String(daemonRunning),
|
|
42700
|
+
durationMs: Date.now() - startedAt
|
|
42701
|
+
})
|
|
42702
|
+
);
|
|
42703
|
+
outputSuccess(wantsJson, { daemonRunning, warning });
|
|
42704
|
+
} catch (error) {
|
|
42705
|
+
const detail = normalizeError2(error);
|
|
42706
|
+
logger.error(
|
|
42707
|
+
LogEvent.DEVKIT_REGISTER_REJECTED,
|
|
42708
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
42709
|
+
devkitSentryExtra({ operationId, phase: "rejected", reason: detail.field, durationMs: Date.now() - startedAt })
|
|
42710
|
+
);
|
|
42711
|
+
outputError2(wantsJson, detail);
|
|
42712
|
+
process.exitCode = 1;
|
|
42713
|
+
}
|
|
42714
|
+
}
|
|
42715
|
+
async function resolveDaemonStatus(operationId) {
|
|
42716
|
+
try {
|
|
42717
|
+
const status = await getDaemonStatus();
|
|
42718
|
+
if (status.running) {
|
|
42719
|
+
return { daemonRunning: true };
|
|
42720
|
+
}
|
|
42721
|
+
return {
|
|
42722
|
+
daemonRunning: false,
|
|
42723
|
+
warning: { code: "DAEMON_NOT_RUNNING", message: DAEMON_NOT_RUNNING_MESSAGE }
|
|
42724
|
+
};
|
|
42725
|
+
} catch {
|
|
42726
|
+
logger.info(LogEvent.DEVKIT_DAEMON_STATUS_UNKNOWN, devkitSentryExtra({ operationId, phase: "status_unknown" }));
|
|
42727
|
+
return {
|
|
42728
|
+
daemonRunning: null,
|
|
42729
|
+
warning: { code: "DAEMON_STATUS_UNKNOWN", message: DAEMON_STATUS_UNKNOWN_MESSAGE }
|
|
42730
|
+
};
|
|
42731
|
+
}
|
|
42732
|
+
}
|
|
42733
|
+
function validateUrl(raw) {
|
|
42734
|
+
if (raw.includes("\\")) {
|
|
42735
|
+
throw new DevkitCliError("url", "--url must not contain a backslash");
|
|
42736
|
+
}
|
|
42737
|
+
let url;
|
|
42738
|
+
try {
|
|
42739
|
+
url = new URL(raw);
|
|
42740
|
+
} catch {
|
|
42741
|
+
throw new DevkitCliError("url", "--url must be a valid HTTP/HTTPS origin");
|
|
42742
|
+
}
|
|
42743
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
42744
|
+
throw new DevkitCliError("url", "--url scheme must be http or https");
|
|
42745
|
+
}
|
|
42746
|
+
if (url.username !== "" || url.password !== "") {
|
|
42747
|
+
throw new DevkitCliError("url", "--url must not contain userinfo");
|
|
42748
|
+
}
|
|
42749
|
+
if (url.port !== "") {
|
|
42750
|
+
throw new DevkitCliError("url", "--url must not contain an embedded port; use --port");
|
|
42751
|
+
}
|
|
42752
|
+
if (url.pathname !== "/" && url.pathname !== "") {
|
|
42753
|
+
throw new DevkitCliError("url", "--url must not contain a path");
|
|
42754
|
+
}
|
|
42755
|
+
if (url.search !== "") {
|
|
42756
|
+
throw new DevkitCliError("url", "--url must not contain a query");
|
|
42757
|
+
}
|
|
42758
|
+
if (url.hash !== "") {
|
|
42759
|
+
throw new DevkitCliError("url", "--url must not contain a fragment");
|
|
42760
|
+
}
|
|
42761
|
+
const hostname = url.hostname.toLowerCase();
|
|
42762
|
+
if (!isLoopbackHostname(hostname)) {
|
|
42763
|
+
throw new DevkitCliError(
|
|
42764
|
+
"url",
|
|
42765
|
+
"--url host must be a loopback address (127.0.0.0/8, ::1, or localhost)"
|
|
42766
|
+
);
|
|
42767
|
+
}
|
|
42768
|
+
return `${url.protocol}//${hostname}`;
|
|
42769
|
+
}
|
|
42770
|
+
function isLoopbackHostname(hostname) {
|
|
42771
|
+
if (hostname === "localhost") {
|
|
42772
|
+
return true;
|
|
42773
|
+
}
|
|
42774
|
+
if (hostname === "::1") {
|
|
42775
|
+
return true;
|
|
42776
|
+
}
|
|
42777
|
+
const match = LOOPBACK_IPV4_PATTERN.exec(hostname);
|
|
42778
|
+
if (!match) {
|
|
42779
|
+
return false;
|
|
42780
|
+
}
|
|
42781
|
+
const octets = match.slice(1, 5).map((segment) => Number(segment));
|
|
42782
|
+
if (octets.some((octet) => !Number.isInteger(octet) || octet < 0 || octet > 255)) {
|
|
42783
|
+
return false;
|
|
42784
|
+
}
|
|
42785
|
+
return octets[0] === 127;
|
|
42786
|
+
}
|
|
42787
|
+
function validatePort(raw) {
|
|
42788
|
+
if (!/^[1-9][0-9]{0,4}$/.test(raw)) {
|
|
42789
|
+
throw new DevkitCliError("port", "--port must be an integer between 1 and 65535");
|
|
42790
|
+
}
|
|
42791
|
+
const port = Number(raw);
|
|
42792
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
42793
|
+
throw new DevkitCliError("port", "--port must be an integer between 1 and 65535");
|
|
42794
|
+
}
|
|
42795
|
+
return port;
|
|
42796
|
+
}
|
|
42797
|
+
function validatePaths(raw) {
|
|
42798
|
+
let parsed;
|
|
42799
|
+
try {
|
|
42800
|
+
parsed = JSON.parse(raw);
|
|
42801
|
+
} catch {
|
|
42802
|
+
throw new DevkitCliError("paths", "--paths must be valid JSON");
|
|
42803
|
+
}
|
|
42804
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
42805
|
+
throw new DevkitCliError("paths", "--paths must be a JSON object");
|
|
42806
|
+
}
|
|
42807
|
+
const record = parsed;
|
|
42808
|
+
const keys = Object.keys(record);
|
|
42809
|
+
if (keys.length !== 2 || !keys.includes("event") || !keys.includes("health")) {
|
|
42810
|
+
throw new DevkitCliError("paths", '--paths must contain exactly the keys "event" and "health"');
|
|
42811
|
+
}
|
|
42812
|
+
const eventPath = validatePathValue(record.event, "event");
|
|
42813
|
+
const healthPath = validatePathValue(record.health, "health");
|
|
42814
|
+
return { eventPath, healthPath };
|
|
42815
|
+
}
|
|
42816
|
+
function validatePathValue(value, key) {
|
|
42817
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
42818
|
+
throw new DevkitCliError("paths", `--paths.${key} must be a non-empty string`);
|
|
42819
|
+
}
|
|
42820
|
+
if (!value.startsWith("/") || value.startsWith("//")) {
|
|
42821
|
+
throw new DevkitCliError("paths", `--paths.${key} must start with a single "/"`);
|
|
42822
|
+
}
|
|
42823
|
+
if (value.includes("\\") || value.includes("?") || value.includes("#") || value.includes("..")) {
|
|
42824
|
+
throw new DevkitCliError(
|
|
42825
|
+
"paths",
|
|
42826
|
+
`--paths.${key} must not contain a query, fragment, backslash, "..", or an absolute URL`
|
|
42827
|
+
);
|
|
42828
|
+
}
|
|
42829
|
+
if (/^\/[a-zA-Z][a-zA-Z0-9+.-]*:/.test(value)) {
|
|
42830
|
+
throw new DevkitCliError("paths", `--paths.${key} must not be an absolute URL`);
|
|
42831
|
+
}
|
|
42832
|
+
return value;
|
|
42833
|
+
}
|
|
42834
|
+
function parseArgs2(args, spec) {
|
|
42835
|
+
const options = /* @__PURE__ */ new Map();
|
|
42836
|
+
const flags = /* @__PURE__ */ new Set();
|
|
42837
|
+
for (let index2 = 0; index2 < args.length; index2 += 1) {
|
|
42838
|
+
const token = args[index2];
|
|
42839
|
+
if (!token.startsWith("--")) {
|
|
42840
|
+
throw new DevkitCliError("command", `unexpected positional argument: ${token}`);
|
|
42841
|
+
}
|
|
42842
|
+
const name = token.slice(2);
|
|
42843
|
+
if (spec.flags.has(name)) {
|
|
42844
|
+
if (flags.has(name)) {
|
|
42845
|
+
throw new DevkitCliError("command", `${token} must not be repeated`);
|
|
42846
|
+
}
|
|
42847
|
+
flags.add(name);
|
|
42848
|
+
continue;
|
|
42849
|
+
}
|
|
42850
|
+
if (!spec.options.has(name)) {
|
|
42851
|
+
throw new DevkitCliError("command", `unknown option ${token}`);
|
|
42852
|
+
}
|
|
42853
|
+
if (index2 + 1 >= args.length) {
|
|
42854
|
+
throw new DevkitCliError("command", `${token} requires a value`);
|
|
42855
|
+
}
|
|
42856
|
+
const value = args[++index2];
|
|
42857
|
+
if (value.startsWith("--")) {
|
|
42858
|
+
throw new DevkitCliError("command", `${token} requires a value`);
|
|
42859
|
+
}
|
|
42860
|
+
if (options.has(name)) {
|
|
42861
|
+
throw new DevkitCliError("command", `${token} must not be repeated`);
|
|
42862
|
+
}
|
|
42863
|
+
options.set(name, [value]);
|
|
42864
|
+
}
|
|
42865
|
+
return { options, flags };
|
|
42866
|
+
}
|
|
42867
|
+
function requireOption(parsed, name) {
|
|
42868
|
+
const value = parsed.options.get(name)?.[0];
|
|
42869
|
+
if (value === void 0 || value.length === 0) {
|
|
42870
|
+
throw new DevkitCliError(name, `--${name} is required`);
|
|
42871
|
+
}
|
|
42872
|
+
return value;
|
|
42873
|
+
}
|
|
42874
|
+
function outputSuccess(json, result) {
|
|
42875
|
+
if (json) {
|
|
42876
|
+
console.log(JSON.stringify({
|
|
42877
|
+
ok: true,
|
|
42878
|
+
daemonRunning: result.daemonRunning,
|
|
42879
|
+
...result.warning ? { warning: result.warning } : {},
|
|
42880
|
+
...result.configVersion === void 0 ? {} : { configVersion: result.configVersion }
|
|
42881
|
+
}));
|
|
42882
|
+
return;
|
|
42883
|
+
}
|
|
42884
|
+
const daemonText = result.daemonRunning === null ? "unknown" : String(result.daemonRunning);
|
|
42885
|
+
console.log(`ok=true daemonRunning=${daemonText}${result.warning ? ` warning=${result.warning.code}` : ""}`);
|
|
42886
|
+
if (result.warning) {
|
|
42887
|
+
console.log(result.warning.message);
|
|
42888
|
+
}
|
|
42889
|
+
}
|
|
42890
|
+
function outputError2(json, detail) {
|
|
42891
|
+
if (json) {
|
|
42892
|
+
console.log(JSON.stringify({ ok: false, error: detail.reason }));
|
|
42893
|
+
return;
|
|
42894
|
+
}
|
|
42895
|
+
console.error(`ok=false field=${detail.field} error=${detail.reason}`);
|
|
42896
|
+
}
|
|
42897
|
+
function normalizeError2(error) {
|
|
42898
|
+
if (error instanceof DevkitCliError) {
|
|
42899
|
+
return error.toValidationError();
|
|
42900
|
+
}
|
|
42901
|
+
if (error instanceof DevkitServerStoreError) {
|
|
42902
|
+
return { field: "config", reason: error.message };
|
|
42903
|
+
}
|
|
42904
|
+
return { field: "unknown", reason: error instanceof Error ? error.message : String(error) };
|
|
42905
|
+
}
|
|
42906
|
+
function devkitSentryExtra(extra) {
|
|
42907
|
+
const normalized = { component: "node_devkit" };
|
|
42908
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
42909
|
+
if (value !== void 0) {
|
|
42910
|
+
normalized[key] = String(value);
|
|
42911
|
+
}
|
|
42912
|
+
}
|
|
42913
|
+
return normalized;
|
|
42914
|
+
}
|
|
42915
|
+
function isHelpArg2(value) {
|
|
42916
|
+
return value === "help" || value === "-h" || value === "--help";
|
|
42917
|
+
}
|
|
42918
|
+
var import_node_crypto9, DAEMON_NOT_RUNNING_MESSAGE, DAEMON_STATUS_UNKNOWN_MESSAGE, LOOPBACK_IPV4_PATTERN, DevkitCliError;
|
|
42919
|
+
var init_devkit_cli = __esm({
|
|
42920
|
+
"src/devkit-cli.ts"() {
|
|
42921
|
+
"use strict";
|
|
42922
|
+
import_node_crypto9 = require("node:crypto");
|
|
42923
|
+
init_daemon();
|
|
42924
|
+
init_devkit_server_store();
|
|
42925
|
+
init_sentry_logger();
|
|
42926
|
+
DAEMON_NOT_RUNNING_MESSAGE = "\u5F53\u524D daemon \u672A\u8FD0\u884C,\u8BF7\u4F7F\u7528 okx-a2a start \u542F\u52A8 daemon";
|
|
42927
|
+
DAEMON_STATUS_UNKNOWN_MESSAGE = "\u914D\u7F6E\u5DF2\u5199\u5165,\u4F46\u65E0\u6CD5\u786E\u8BA4 daemon \u8FD0\u884C\u72B6\u6001";
|
|
42928
|
+
LOOPBACK_IPV4_PATTERN = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
|
|
42929
|
+
DevkitCliError = class extends Error {
|
|
42930
|
+
field;
|
|
42931
|
+
constructor(field, reason) {
|
|
42932
|
+
super(reason);
|
|
42933
|
+
this.name = "DevkitCliError";
|
|
42934
|
+
this.field = field;
|
|
42935
|
+
}
|
|
42936
|
+
toValidationError() {
|
|
42937
|
+
return { field: this.field, reason: this.message };
|
|
42938
|
+
}
|
|
42939
|
+
};
|
|
42940
|
+
}
|
|
42941
|
+
});
|
|
42942
|
+
|
|
42943
|
+
// ../core/src/xmtp-sdk/client-lifecycle.ts
|
|
42944
|
+
async function stopAndCloseXmtpClient(agent, ctx) {
|
|
42945
|
+
let stopped = true;
|
|
42946
|
+
try {
|
|
42947
|
+
await Promise.resolve(agent.stop());
|
|
42948
|
+
} catch {
|
|
42949
|
+
stopped = false;
|
|
42950
|
+
}
|
|
42951
|
+
const close2 = agent.client?.close;
|
|
42952
|
+
if (typeof close2 !== "function") {
|
|
42953
|
+
return { stopped, closed: false, closeFailed: false };
|
|
42954
|
+
}
|
|
42955
|
+
try {
|
|
42956
|
+
await Promise.resolve(close2.call(agent.client));
|
|
42957
|
+
return { stopped, closed: true, closeFailed: false };
|
|
42958
|
+
} catch (err2) {
|
|
42959
|
+
ctx.onCloseError?.(err2);
|
|
42960
|
+
return { stopped, closed: false, closeFailed: true };
|
|
42961
|
+
}
|
|
42962
|
+
}
|
|
42963
|
+
var init_client_lifecycle = __esm({
|
|
42964
|
+
"../core/src/xmtp-sdk/client-lifecycle.ts"() {
|
|
42965
|
+
"use strict";
|
|
42966
|
+
}
|
|
42967
|
+
});
|
|
42968
|
+
|
|
42224
42969
|
// ../core/src/xmtp-sdk/onchainos/bin.ts
|
|
42225
42970
|
async function refreshOnchainosVersionMetadata(options = {}) {
|
|
42226
42971
|
const now = options.now ?? Date.now;
|
|
@@ -42340,7 +43085,7 @@ function isResolvedBinUsable(bin) {
|
|
|
42340
43085
|
if (!isPathLikeCommand(bin)) {
|
|
42341
43086
|
return true;
|
|
42342
43087
|
}
|
|
42343
|
-
return process.platform === "win32" ? (0,
|
|
43088
|
+
return process.platform === "win32" ? (0, import_node_fs23.existsSync)(bin) : isExecutable2(bin);
|
|
42344
43089
|
}
|
|
42345
43090
|
function resolvePosixBareCommand(command, pathValue) {
|
|
42346
43091
|
for (const dir of pathValue.split(":")) {
|
|
@@ -42677,7 +43422,7 @@ function isWindowsAppsAlias(candidate) {
|
|
|
42677
43422
|
return candidate.toLowerCase().includes(WINDOWS_APPS_ALIAS_MARKER);
|
|
42678
43423
|
}
|
|
42679
43424
|
function win32FileExists(path2) {
|
|
42680
|
-
return (0,
|
|
43425
|
+
return (0, import_node_fs23.existsSync)(path2);
|
|
42681
43426
|
}
|
|
42682
43427
|
function pickOnchainosWin32Candidate(lines, fileExists2 = win32FileExists) {
|
|
42683
43428
|
const candidates = lines.map((line) => {
|
|
@@ -42733,7 +43478,7 @@ function extractExecutablePath(stdout) {
|
|
|
42733
43478
|
}
|
|
42734
43479
|
function isExecutable2(path2) {
|
|
42735
43480
|
try {
|
|
42736
|
-
(0,
|
|
43481
|
+
(0, import_node_fs23.accessSync)(path2, import_node_fs23.constants.X_OK);
|
|
42737
43482
|
return true;
|
|
42738
43483
|
} catch {
|
|
42739
43484
|
return false;
|
|
@@ -42838,12 +43583,12 @@ async function exec(args, options = {}) {
|
|
|
42838
43583
|
}
|
|
42839
43584
|
throw new Error("OnchainOS command retry exhausted");
|
|
42840
43585
|
}
|
|
42841
|
-
var
|
|
43586
|
+
var import_node_fs23, import_node_child_process8, import_node_path25, import_node_util2, execFileAsync2, resolvedBin, resolvedForEnvBin, resolverRevision, versionProbeInFlight, posixDiscoveryFlights, REDACTED_VALUE_FLAGS, COMMAND_UNAVAILABLE_CODES, ONCHAINOS_VERSION_PROBE_TIMEOUT_MS, ONCHAINOS_BIN_RESOLVE_TIMEOUT_MS, WINDOWS_APPS_ALIAS_MARKER;
|
|
42842
43587
|
var init_bin = __esm({
|
|
42843
43588
|
"../core/src/xmtp-sdk/onchainos/bin.ts"() {
|
|
42844
43589
|
"use strict";
|
|
42845
43590
|
init_log();
|
|
42846
|
-
|
|
43591
|
+
import_node_fs23 = require("node:fs");
|
|
42847
43592
|
import_node_child_process8 = require("node:child_process");
|
|
42848
43593
|
import_node_path25 = require("node:path");
|
|
42849
43594
|
import_node_util2 = require("node:util");
|
|
@@ -42907,12 +43652,12 @@ function createAsyncStreamProxy(stream) {
|
|
|
42907
43652
|
}
|
|
42908
43653
|
});
|
|
42909
43654
|
}
|
|
42910
|
-
var import_node_bindings, import_node_bindings2,
|
|
43655
|
+
var import_node_bindings, import_node_bindings2, import_node_crypto10, import_types, import_node_path26, import_node_process, HistorySyncUrls, envMap, reverseEnvMap, envToString, createBackend, InboxReassignError, AccountAlreadyAssociatedError, MissingContentTypeError, SignerUnavailableError, ClientNotInitializedError, StreamFailedError, StreamInvalidRetryAttemptsError, generateInboxId, getInboxIdForIdentifier, isReaction, isReply, isText, isRemoteAttachment, isAttachment, isMultiRemoteAttachment, isTransactionReference, isGroupUpdated, isReadReceipt, isLeaveRequest, isWalletSendCalls, isIntent, isActions, isMarkdown, CodecRegistry, getContentFromDecodedMessageContent, getContentTypeFromDecodedMessageContent, DecodedMessage, AsyncStream, usableProperties, isUsableProperty, wait, DEFAULT_RETRY_DELAY, DEFAULT_RETRY_ATTEMPTS, createStream, Conversation, Dm, Group, Conversations, DebugInformation, Preferences, networkOptionKeys, hasBackend, resolveBackend$1, createClient, resolveBackend, createEphemeralIdentifier, toInboxUpdatesCountMap, Client;
|
|
42911
43656
|
var init_dist2 = __esm({
|
|
42912
43657
|
"../../node_modules/@xmtp/node-sdk/dist/index.js"() {
|
|
42913
43658
|
import_node_bindings = require("@xmtp/node-bindings");
|
|
42914
43659
|
import_node_bindings2 = require("@xmtp/node-bindings");
|
|
42915
|
-
|
|
43660
|
+
import_node_crypto10 = require("node:crypto");
|
|
42916
43661
|
init_dist();
|
|
42917
43662
|
import_types = require("node:util/types");
|
|
42918
43663
|
import_node_path26 = require("node:path");
|
|
@@ -44596,7 +45341,7 @@ var init_dist2 = __esm({
|
|
|
44596
45341
|
return createBackend({ env: envOrBackend, gatewayHost });
|
|
44597
45342
|
};
|
|
44598
45343
|
createEphemeralIdentifier = () => ({
|
|
44599
|
-
identifier: `0x${(0,
|
|
45344
|
+
identifier: `0x${(0, import_node_crypto10.randomBytes)(20).toString("hex")}`,
|
|
44600
45345
|
identifierKind: 0
|
|
44601
45346
|
});
|
|
44602
45347
|
toInboxUpdatesCountMap = (value) => {
|
|
@@ -56845,20 +57590,20 @@ async function createRemoteAttachmentFromFile(unencryptedFile, uploadCallback) {
|
|
|
56845
57590
|
const fileUrl = await uploadCallback(encryptedAttachment);
|
|
56846
57591
|
return createRemoteAttachment(encryptedAttachment, fileUrl);
|
|
56847
57592
|
}
|
|
56848
|
-
var import_node_events,
|
|
57593
|
+
var import_node_events, import_node_fs24, import_node_path27, import_ts_retry_promise, import_node_crypto11, version2, fromSelf, hasContent, isDM, isGroup, isGroupAdmin, isGroupSuperAdmin, usesCodec, filter, validLogLevels, isLogLevel, getValidLogLevels, parseLogLevel, logDetails, getInstallationInfo, createUser, createIdentifier, createSigner, AgentError, AgentStreamingError, ClientContext, ConversationContext, MessageContext, Agent, CANCEL_ACTION_ID, LimitedMap, cache;
|
|
56849
57594
|
var init_dist4 = __esm({
|
|
56850
57595
|
"../../node_modules/@xmtp/agent-sdk/dist/index.js"() {
|
|
56851
57596
|
init_dist2();
|
|
56852
57597
|
init_dist2();
|
|
56853
57598
|
import_node_events = __toESM(require("node:events"), 1);
|
|
56854
|
-
|
|
57599
|
+
import_node_fs24 = __toESM(require("node:fs"), 1);
|
|
56855
57600
|
import_node_path27 = __toESM(require("node:path"), 1);
|
|
56856
57601
|
import_ts_retry_promise = __toESM(require_retry_promise(), 1);
|
|
56857
57602
|
init_dist3();
|
|
56858
57603
|
init_esm();
|
|
56859
57604
|
init_accounts();
|
|
56860
57605
|
init_chains();
|
|
56861
|
-
|
|
57606
|
+
import_node_crypto11 = require("node:crypto");
|
|
56862
57607
|
version2 = "2.3.0";
|
|
56863
57608
|
fromSelf = (message, client) => {
|
|
56864
57609
|
return message.senderInboxId === client.inboxId;
|
|
@@ -57218,7 +57963,7 @@ var init_dist4 = __esm({
|
|
|
57218
57963
|
initializedOptions.gatewayHost = XMTP_GATEWAY_HOST;
|
|
57219
57964
|
}
|
|
57220
57965
|
if (typeof XMTP_DB_DIRECTORY === "string") {
|
|
57221
|
-
|
|
57966
|
+
import_node_fs24.default.mkdirSync(XMTP_DB_DIRECTORY, { recursive: true, mode: 448 });
|
|
57222
57967
|
initializedOptions.dbPath = (inboxId) => {
|
|
57223
57968
|
const dbPath = import_node_path27.default.join(XMTP_DB_DIRECTORY, `xmtp-${inboxId}.db3`);
|
|
57224
57969
|
console.info(`Saving local database to "${dbPath}"`);
|
|
@@ -57528,7 +58273,7 @@ var init_dist4 = __esm({
|
|
|
57528
58273
|
return this.#client.accountIdentifier?.identifier;
|
|
57529
58274
|
}
|
|
57530
58275
|
};
|
|
57531
|
-
CANCEL_ACTION_ID = (0,
|
|
58276
|
+
CANCEL_ACTION_ID = (0, import_node_crypto11.randomUUID)();
|
|
57532
58277
|
LimitedMap = class {
|
|
57533
58278
|
#map = /* @__PURE__ */ new Map();
|
|
57534
58279
|
#limit;
|
|
@@ -58261,6 +59006,169 @@ var init_session_expired = __esm({
|
|
|
58261
59006
|
}
|
|
58262
59007
|
});
|
|
58263
59008
|
|
|
59009
|
+
// ../core/src/xmtp-sdk/rate-limit-cooldown.ts
|
|
59010
|
+
function asErrorLike2(value) {
|
|
59011
|
+
return value instanceof Error ? value : void 0;
|
|
59012
|
+
}
|
|
59013
|
+
function causeChain2(err2) {
|
|
59014
|
+
const chain = [];
|
|
59015
|
+
const seen = /* @__PURE__ */ new Set();
|
|
59016
|
+
let current = err2;
|
|
59017
|
+
while (chain.length < MAX_CAUSE_DEPTH2) {
|
|
59018
|
+
chain.push(current);
|
|
59019
|
+
const errorLike = asErrorLike2(current);
|
|
59020
|
+
if (!errorLike || seen.has(errorLike)) {
|
|
59021
|
+
break;
|
|
59022
|
+
}
|
|
59023
|
+
seen.add(errorLike);
|
|
59024
|
+
current = errorLike.cause;
|
|
59025
|
+
if (current === void 0) {
|
|
59026
|
+
break;
|
|
59027
|
+
}
|
|
59028
|
+
}
|
|
59029
|
+
return chain;
|
|
59030
|
+
}
|
|
59031
|
+
function messageOf(node) {
|
|
59032
|
+
return (node instanceof Error ? node.message : String(node)).toLowerCase();
|
|
59033
|
+
}
|
|
59034
|
+
function isXmtpRateLimitError(err2) {
|
|
59035
|
+
if (err2 === void 0 || err2 === null) {
|
|
59036
|
+
return false;
|
|
59037
|
+
}
|
|
59038
|
+
const chain = causeChain2(err2);
|
|
59039
|
+
return chain.some(
|
|
59040
|
+
(node) => RATE_LIMIT_PATTERNS.some((pattern) => pattern.test(messageOf(node)))
|
|
59041
|
+
);
|
|
59042
|
+
}
|
|
59043
|
+
function extractRateLimitEndpoint(err2) {
|
|
59044
|
+
if (err2 === void 0 || err2 === null) {
|
|
59045
|
+
return void 0;
|
|
59046
|
+
}
|
|
59047
|
+
const chain = causeChain2(err2);
|
|
59048
|
+
for (const node of chain) {
|
|
59049
|
+
const message = messageOf(node);
|
|
59050
|
+
for (const pattern of KNOWN_RATE_LIMIT_ENDPOINTS) {
|
|
59051
|
+
const match = pattern.exec(message);
|
|
59052
|
+
if (match) {
|
|
59053
|
+
return /GetInboxIds/i.test(match[0]) ? "GetInboxIds" : "GetIdentityUpdates";
|
|
59054
|
+
}
|
|
59055
|
+
}
|
|
59056
|
+
}
|
|
59057
|
+
return void 0;
|
|
59058
|
+
}
|
|
59059
|
+
function getXmtpCreationCooldown() {
|
|
59060
|
+
if (!singleton2) {
|
|
59061
|
+
singleton2 = new XmtpCreationCooldown();
|
|
59062
|
+
}
|
|
59063
|
+
return singleton2;
|
|
59064
|
+
}
|
|
59065
|
+
var MAX_CAUSE_DEPTH2, XMTP_CREATION_COOLDOWN_MS, RATE_LIMIT_PATTERNS, KNOWN_RATE_LIMIT_ENDPOINTS, XmtpCreationCooldownSkipError, XmtpCreationCooldown, singleton2;
|
|
59066
|
+
var init_rate_limit_cooldown = __esm({
|
|
59067
|
+
"../core/src/xmtp-sdk/rate-limit-cooldown.ts"() {
|
|
59068
|
+
"use strict";
|
|
59069
|
+
MAX_CAUSE_DEPTH2 = 4;
|
|
59070
|
+
XMTP_CREATION_COOLDOWN_MS = 33e4;
|
|
59071
|
+
RATE_LIMIT_PATTERNS = [
|
|
59072
|
+
/some resource has been exhausted/i,
|
|
59073
|
+
/exceeds rate limit/i,
|
|
59074
|
+
/resource_exhausted/i
|
|
59075
|
+
];
|
|
59076
|
+
KNOWN_RATE_LIMIT_ENDPOINTS = [
|
|
59077
|
+
/\bGetInboxIds\b/i,
|
|
59078
|
+
/\bGetIdentityUpdates\b/i
|
|
59079
|
+
];
|
|
59080
|
+
XmtpCreationCooldownSkipError = class extends Error {
|
|
59081
|
+
remainingMs;
|
|
59082
|
+
address;
|
|
59083
|
+
agentId;
|
|
59084
|
+
constructor(remainingMs, address, agentId) {
|
|
59085
|
+
super("xmtp creation suppressed during rate-limit cooldown");
|
|
59086
|
+
this.name = "XmtpCreationCooldownSkipError";
|
|
59087
|
+
this.remainingMs = remainingMs;
|
|
59088
|
+
this.address = address;
|
|
59089
|
+
this.agentId = agentId;
|
|
59090
|
+
}
|
|
59091
|
+
};
|
|
59092
|
+
XmtpCreationCooldown = class {
|
|
59093
|
+
cooldownUntilMs = null;
|
|
59094
|
+
probeInFlight = false;
|
|
59095
|
+
suppressedCreateCount = 0;
|
|
59096
|
+
rateLimitHitCount = 0;
|
|
59097
|
+
probeCount = 0;
|
|
59098
|
+
inFlightCreateCount = 0;
|
|
59099
|
+
beginCreateAttempt(nowMs = Date.now()) {
|
|
59100
|
+
if (this.cooldownUntilMs === null) {
|
|
59101
|
+
this.inFlightCreateCount++;
|
|
59102
|
+
return { allowed: true, mode: "normal" };
|
|
59103
|
+
}
|
|
59104
|
+
if (nowMs < this.cooldownUntilMs) {
|
|
59105
|
+
this.suppressedCreateCount++;
|
|
59106
|
+
return {
|
|
59107
|
+
allowed: false,
|
|
59108
|
+
mode: "blocked",
|
|
59109
|
+
remainingMs: Math.max(0, this.cooldownUntilMs - nowMs)
|
|
59110
|
+
};
|
|
59111
|
+
}
|
|
59112
|
+
if (this.probeInFlight) {
|
|
59113
|
+
this.suppressedCreateCount++;
|
|
59114
|
+
return { allowed: false, mode: "blocked", remainingMs: 0 };
|
|
59115
|
+
}
|
|
59116
|
+
this.probeInFlight = true;
|
|
59117
|
+
this.inFlightCreateCount++;
|
|
59118
|
+
this.probeCount++;
|
|
59119
|
+
return { allowed: true, mode: "probe" };
|
|
59120
|
+
}
|
|
59121
|
+
recordCreateSuccess(decision, _nowMs = Date.now()) {
|
|
59122
|
+
this.inFlightCreateCount = Math.max(0, this.inFlightCreateCount - 1);
|
|
59123
|
+
if (decision.mode === "probe") {
|
|
59124
|
+
this.cooldownUntilMs = null;
|
|
59125
|
+
this.probeInFlight = false;
|
|
59126
|
+
}
|
|
59127
|
+
}
|
|
59128
|
+
recordRateLimit(decision, nowMs = Date.now()) {
|
|
59129
|
+
this.inFlightCreateCount = Math.max(0, this.inFlightCreateCount - 1);
|
|
59130
|
+
this.cooldownUntilMs = nowMs + XMTP_CREATION_COOLDOWN_MS;
|
|
59131
|
+
this.rateLimitHitCount++;
|
|
59132
|
+
this.probeInFlight = false;
|
|
59133
|
+
void decision;
|
|
59134
|
+
}
|
|
59135
|
+
recordCreateFailure(decision, nowMs = Date.now()) {
|
|
59136
|
+
this.inFlightCreateCount = Math.max(0, this.inFlightCreateCount - 1);
|
|
59137
|
+
if (decision.mode === "probe") {
|
|
59138
|
+
this.cooldownUntilMs = nowMs + XMTP_CREATION_COOLDOWN_MS;
|
|
59139
|
+
this.probeInFlight = false;
|
|
59140
|
+
}
|
|
59141
|
+
}
|
|
59142
|
+
isCoolingDown(nowMs = Date.now()) {
|
|
59143
|
+
return this.cooldownUntilMs !== null && nowMs < this.cooldownUntilMs;
|
|
59144
|
+
}
|
|
59145
|
+
remainingMs(nowMs = Date.now()) {
|
|
59146
|
+
return this.cooldownUntilMs === null ? 0 : Math.max(0, this.cooldownUntilMs - nowMs);
|
|
59147
|
+
}
|
|
59148
|
+
snapshot(nowMs = Date.now()) {
|
|
59149
|
+
return {
|
|
59150
|
+
coolingDown: this.isCoolingDown(nowMs),
|
|
59151
|
+
cooldownUntilMs: this.cooldownUntilMs,
|
|
59152
|
+
remainingMs: this.remainingMs(nowMs),
|
|
59153
|
+
probeInFlight: this.probeInFlight,
|
|
59154
|
+
suppressedCreateCount: this.suppressedCreateCount,
|
|
59155
|
+
rateLimitHitCount: this.rateLimitHitCount,
|
|
59156
|
+
probeCount: this.probeCount,
|
|
59157
|
+
inFlightCreateCount: this.inFlightCreateCount
|
|
59158
|
+
};
|
|
59159
|
+
}
|
|
59160
|
+
resetForTests() {
|
|
59161
|
+
this.cooldownUntilMs = null;
|
|
59162
|
+
this.probeInFlight = false;
|
|
59163
|
+
this.suppressedCreateCount = 0;
|
|
59164
|
+
this.rateLimitHitCount = 0;
|
|
59165
|
+
this.probeCount = 0;
|
|
59166
|
+
this.inFlightCreateCount = 0;
|
|
59167
|
+
}
|
|
59168
|
+
};
|
|
59169
|
+
}
|
|
59170
|
+
});
|
|
59171
|
+
|
|
58264
59172
|
// ../core/src/xmtp-sdk/index.ts
|
|
58265
59173
|
function cachePath(dataDir, fileName) {
|
|
58266
59174
|
return (0, import_node_path28.join)(dataDir, fileName);
|
|
@@ -58291,10 +59199,10 @@ function ensureCacheDir(dataDir) {
|
|
|
58291
59199
|
function loadSensitiveWordsFromCache(dataDir) {
|
|
58292
59200
|
try {
|
|
58293
59201
|
const path2 = cachePath(dataDir, "sensitive-words.json");
|
|
58294
|
-
if (!(0,
|
|
59202
|
+
if (!(0, import_node_fs25.existsSync)(path2)) {
|
|
58295
59203
|
return null;
|
|
58296
59204
|
}
|
|
58297
|
-
const data = JSON.parse((0,
|
|
59205
|
+
const data = JSON.parse((0, import_node_fs25.readFileSync)(path2, "utf-8"));
|
|
58298
59206
|
if (Array.isArray(data)) {
|
|
58299
59207
|
return data;
|
|
58300
59208
|
}
|
|
@@ -58308,7 +59216,7 @@ function loadSensitiveWordsFromCache(dataDir) {
|
|
|
58308
59216
|
function saveSensitiveWordsToCache(dataDir, words) {
|
|
58309
59217
|
try {
|
|
58310
59218
|
ensureCacheDir(dataDir);
|
|
58311
|
-
(0,
|
|
59219
|
+
(0, import_node_fs25.writeFileSync)(cachePath(dataDir, "sensitive-words.json"), JSON.stringify(words));
|
|
58312
59220
|
} catch (err2) {
|
|
58313
59221
|
logWithTimestamp(`[xmtp-sdk] failed to write sensitive-words.json:`, err2);
|
|
58314
59222
|
logger.error(LogEvent.CACHE_WRITE_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), { cacheName: "sensitive-words" });
|
|
@@ -58350,10 +59258,10 @@ async function loadSensitiveWordsWith(dataDir, fetcher) {
|
|
|
58350
59258
|
function loadSystemConfigFromCache(dataDir) {
|
|
58351
59259
|
try {
|
|
58352
59260
|
const path2 = cachePath(dataDir, "system-config.json");
|
|
58353
|
-
if (!(0,
|
|
59261
|
+
if (!(0, import_node_fs25.existsSync)(path2)) {
|
|
58354
59262
|
return null;
|
|
58355
59263
|
}
|
|
58356
|
-
const data = JSON.parse((0,
|
|
59264
|
+
const data = JSON.parse((0, import_node_fs25.readFileSync)(path2, "utf-8"));
|
|
58357
59265
|
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
58358
59266
|
return data;
|
|
58359
59267
|
}
|
|
@@ -58367,7 +59275,7 @@ function loadSystemConfigFromCache(dataDir) {
|
|
|
58367
59275
|
function saveSystemConfigToCache(dataDir, config) {
|
|
58368
59276
|
try {
|
|
58369
59277
|
ensureCacheDir(dataDir);
|
|
58370
|
-
(0,
|
|
59278
|
+
(0, import_node_fs25.writeFileSync)(cachePath(dataDir, "system-config.json"), JSON.stringify(config));
|
|
58371
59279
|
} catch (err2) {
|
|
58372
59280
|
logWithTimestamp(`[xmtp-sdk] failed to write system-config.json:`, err2);
|
|
58373
59281
|
logger.error(LogEvent.CACHE_WRITE_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), { cacheName: "system-config" });
|
|
@@ -58417,10 +59325,10 @@ function loadSyncByAddress(dataDir) {
|
|
|
58417
59325
|
const map = /* @__PURE__ */ new Map();
|
|
58418
59326
|
try {
|
|
58419
59327
|
const path2 = cachePath(dataDir, "last-sync.json");
|
|
58420
|
-
if (!(0,
|
|
59328
|
+
if (!(0, import_node_fs25.existsSync)(path2)) {
|
|
58421
59329
|
return map;
|
|
58422
59330
|
}
|
|
58423
|
-
const data = JSON.parse((0,
|
|
59331
|
+
const data = JSON.parse((0, import_node_fs25.readFileSync)(path2, "utf-8"));
|
|
58424
59332
|
const obj = data?.syncByAddress;
|
|
58425
59333
|
if (obj && typeof obj === "object" && !Array.isArray(obj)) {
|
|
58426
59334
|
for (const [addr, ts] of Object.entries(obj)) {
|
|
@@ -58439,9 +59347,9 @@ function saveSyncForAddress(dataDir, address, timestampMs) {
|
|
|
58439
59347
|
try {
|
|
58440
59348
|
let data = {};
|
|
58441
59349
|
const path2 = cachePath(dataDir, "last-sync.json");
|
|
58442
|
-
if ((0,
|
|
59350
|
+
if ((0, import_node_fs25.existsSync)(path2)) {
|
|
58443
59351
|
try {
|
|
58444
|
-
const raw = JSON.parse((0,
|
|
59352
|
+
const raw = JSON.parse((0, import_node_fs25.readFileSync)(path2, "utf-8"));
|
|
58445
59353
|
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
58446
59354
|
data = raw;
|
|
58447
59355
|
}
|
|
@@ -58452,7 +59360,7 @@ function saveSyncForAddress(dataDir, address, timestampMs) {
|
|
|
58452
59360
|
data.syncByAddress = {};
|
|
58453
59361
|
}
|
|
58454
59362
|
data.syncByAddress[address] = timestampMs;
|
|
58455
|
-
(0,
|
|
59363
|
+
(0, import_node_fs25.writeFileSync)(path2, JSON.stringify(data, null, 2));
|
|
58456
59364
|
} catch (err2) {
|
|
58457
59365
|
logWithTimestamp(
|
|
58458
59366
|
`[xmtp-sdk] failed to write last-sync.json (address=${address}):`,
|
|
@@ -58671,12 +59579,12 @@ function createOfflineReplayAddressSummary(address) {
|
|
|
58671
59579
|
durationMs: 0
|
|
58672
59580
|
};
|
|
58673
59581
|
}
|
|
58674
|
-
var
|
|
59582
|
+
var import_node_fs25, import_node_path28, DEFAULT_DATA_DIR, XMTP_INSTALLATION_WARNING_THRESHOLD, XMTP_INSTALLATION_NEAR_LIMIT_THRESHOLD, REPLAY_SCAN_INITIAL_BACKOFF_MS, REPLAY_SCAN_MAX_BACKOFF_MS, SENSITIVE_WORDS_LAZY_RETRY_COOLDOWN_MS, InboundReplayGate, SYSTEM_CONFIG_DEFAULTS, STREAM_RECOVERY_ALERT_THRESHOLD_MS, STREAM_RECOVERY_STABILITY_WINDOW_MS, REPLAY_GATE_DRAIN_MAX_ATTEMPTS, REPLAY_GATE_DRAIN_RETRY_DELAY_MS, SEMVER_RE, isRecord5, isPositiveNumber, SYSTEM_CONFIG_VALIDATORS, XmtpService;
|
|
58675
59583
|
var init_xmtp_sdk = __esm({
|
|
58676
59584
|
"../core/src/xmtp-sdk/index.ts"() {
|
|
58677
59585
|
"use strict";
|
|
58678
59586
|
init_log();
|
|
58679
|
-
|
|
59587
|
+
import_node_fs25 = require("node:fs");
|
|
58680
59588
|
import_node_path28 = require("node:path");
|
|
58681
59589
|
init_dist4();
|
|
58682
59590
|
init_dist2();
|
|
@@ -58690,6 +59598,8 @@ var init_xmtp_sdk = __esm({
|
|
|
58690
59598
|
init_a2a_paths();
|
|
58691
59599
|
init_installation_prune();
|
|
58692
59600
|
init_session_expired();
|
|
59601
|
+
init_rate_limit_cooldown();
|
|
59602
|
+
init_client_lifecycle();
|
|
58693
59603
|
DEFAULT_DATA_DIR = resolveA2aTaskPaths().xmtpDir;
|
|
58694
59604
|
XMTP_INSTALLATION_WARNING_THRESHOLD = 2;
|
|
58695
59605
|
XMTP_INSTALLATION_NEAR_LIMIT_THRESHOLD = 8;
|
|
@@ -58987,21 +59897,78 @@ var init_xmtp_sdk = __esm({
|
|
|
58987
59897
|
}
|
|
58988
59898
|
async createClientForAgent(agentInfo, options = {}) {
|
|
58989
59899
|
const address = agentInfo.communicationAddress;
|
|
58990
|
-
const
|
|
58991
|
-
const
|
|
58992
|
-
const
|
|
58993
|
-
|
|
58994
|
-
|
|
58995
|
-
|
|
58996
|
-
|
|
58997
|
-
|
|
58998
|
-
|
|
58999
|
-
|
|
59000
|
-
|
|
59001
|
-
|
|
59002
|
-
|
|
59003
|
-
|
|
59004
|
-
|
|
59900
|
+
const phase = options.logPrefix ?? "[xmtp-sdk]";
|
|
59901
|
+
const cooldown = getXmtpCreationCooldown();
|
|
59902
|
+
const decision = cooldown.beginCreateAttempt();
|
|
59903
|
+
if (!decision.allowed) {
|
|
59904
|
+
logger.info(LogEvent.XMTP_RATE_LIMIT_CREATE_SUPPRESSED, {
|
|
59905
|
+
onchainosAgentId: agentInfo.agentId,
|
|
59906
|
+
walletAddress: address,
|
|
59907
|
+
cooldownRemainingMs: String(decision.remainingMs ?? 0),
|
|
59908
|
+
phase
|
|
59909
|
+
});
|
|
59910
|
+
throw new XmtpCreationCooldownSkipError(
|
|
59911
|
+
decision.remainingMs ?? 0,
|
|
59912
|
+
address,
|
|
59913
|
+
agentInfo.agentId
|
|
59914
|
+
);
|
|
59915
|
+
}
|
|
59916
|
+
if (decision.mode === "probe") {
|
|
59917
|
+
logger.info(LogEvent.XMTP_RATE_LIMIT_PROBE, {
|
|
59918
|
+
onchainosAgentId: agentInfo.agentId,
|
|
59919
|
+
walletAddress: address,
|
|
59920
|
+
phase: "probe-start",
|
|
59921
|
+
probeCount: String(cooldown.snapshot().probeCount)
|
|
59922
|
+
});
|
|
59923
|
+
}
|
|
59924
|
+
try {
|
|
59925
|
+
const signer = this.tools.createSigner(agentInfo);
|
|
59926
|
+
const dbPath = (inboxId2) => `${this.dataDir}/${inboxId2}-${this.env}.db3`;
|
|
59927
|
+
const agent = await createAgentWithInstallationPrune(signer, {
|
|
59928
|
+
dbPath,
|
|
59929
|
+
env: this.env
|
|
59930
|
+
}, {
|
|
59931
|
+
address,
|
|
59932
|
+
agentId: agentInfo.agentId,
|
|
59933
|
+
logPrefix: options.logPrefix
|
|
59934
|
+
});
|
|
59935
|
+
cooldown.recordCreateSuccess(decision);
|
|
59936
|
+
if (decision.mode === "probe") {
|
|
59937
|
+
logger.info(LogEvent.XMTP_RATE_LIMIT_RECOVERED, {
|
|
59938
|
+
onchainosAgentId: agentInfo.agentId,
|
|
59939
|
+
walletAddress: address,
|
|
59940
|
+
phase: "probe-success"
|
|
59941
|
+
});
|
|
59942
|
+
}
|
|
59943
|
+
const inboxId = agent.client?.inboxId ?? "";
|
|
59944
|
+
logWithTimestamp(
|
|
59945
|
+
`[xmtp-sdk] xmtp_client_ready agentId=${agentInfo.agentId} address=${address} inboxId=${inboxId} dbPath=${inboxId ? dbPath(inboxId) : "(unknown)"} lastSync=${formatLogTimestamp2(this.syncByAddress.get(address))}`
|
|
59946
|
+
);
|
|
59947
|
+
return { address, agent, agentInfo };
|
|
59948
|
+
} catch (err2) {
|
|
59949
|
+
if (isXmtpRateLimitError(err2)) {
|
|
59950
|
+
cooldown.recordRateLimit(decision);
|
|
59951
|
+
logger.info(LogEvent.XMTP_RATE_LIMIT_COOLDOWN_STARTED, {
|
|
59952
|
+
...agentExtras({ walletAddress: address, onchainosAgentId: agentInfo.agentId }),
|
|
59953
|
+
rateLimitIdentified: "true",
|
|
59954
|
+
endpoint: extractRateLimitEndpoint(err2) ?? "unknown",
|
|
59955
|
+
cooldownMs: String(XMTP_CREATION_COOLDOWN_MS),
|
|
59956
|
+
cooldownExpiresAtMs: String(cooldown.snapshot().cooldownUntilMs ?? ""),
|
|
59957
|
+
inFlightCreateCount: String(cooldown.snapshot().inFlightCreateCount),
|
|
59958
|
+
probe: String(decision.mode === "probe")
|
|
59959
|
+
});
|
|
59960
|
+
} else {
|
|
59961
|
+
cooldown.recordCreateFailure(decision);
|
|
59962
|
+
if (decision.mode === "probe") {
|
|
59963
|
+
logger.info(LogEvent.XMTP_RATE_LIMIT_PROBE, {
|
|
59964
|
+
onchainosAgentId: agentInfo.agentId,
|
|
59965
|
+
walletAddress: address,
|
|
59966
|
+
phase: "probe-failed-nonratelimit"
|
|
59967
|
+
});
|
|
59968
|
+
}
|
|
59969
|
+
}
|
|
59970
|
+
throw err2;
|
|
59971
|
+
}
|
|
59005
59972
|
}
|
|
59006
59973
|
async recordInstallationHealth(params) {
|
|
59007
59974
|
const { address, agent, agentInfo, phase, attempt } = params;
|
|
@@ -59152,22 +60119,28 @@ var init_xmtp_sdk = __esm({
|
|
|
59152
60119
|
});
|
|
59153
60120
|
} else {
|
|
59154
60121
|
failedAgents.push(agents[i]);
|
|
59155
|
-
|
|
59156
|
-
|
|
59157
|
-
|
|
59158
|
-
|
|
59159
|
-
|
|
59160
|
-
|
|
59161
|
-
|
|
59162
|
-
|
|
59163
|
-
|
|
59164
|
-
|
|
59165
|
-
|
|
59166
|
-
|
|
59167
|
-
|
|
60122
|
+
if (r.reason instanceof XmtpCreationCooldownSkipError) {
|
|
60123
|
+
logWithTimestamp(
|
|
60124
|
+
`[xmtp-sdk] identity init suppressed (rate-limit cooldown): ${agents[i].communicationAddress} (agentId=${agents[i].agentId})`
|
|
60125
|
+
);
|
|
60126
|
+
} else {
|
|
60127
|
+
logWithTimestamp(
|
|
60128
|
+
`[xmtp-sdk] identity init failed: ${agents[i].communicationAddress} (agentId=${agents[i].agentId})`,
|
|
60129
|
+
r.reason
|
|
60130
|
+
);
|
|
60131
|
+
logger.error(
|
|
60132
|
+
LogEvent.XMTP_CONNECTION_FAILED,
|
|
60133
|
+
r.reason instanceof Error ? r.reason : new Error(String(r.reason)),
|
|
60134
|
+
{
|
|
60135
|
+
walletAddress: agents[i].communicationAddress,
|
|
60136
|
+
onchainosAgentId: agents[i].agentId,
|
|
60137
|
+
attempt: "1"
|
|
60138
|
+
}
|
|
60139
|
+
);
|
|
60140
|
+
}
|
|
59168
60141
|
}
|
|
59169
60142
|
}
|
|
59170
|
-
if (failedAgents.length > 0) {
|
|
60143
|
+
if (failedAgents.length > 0 && !getXmtpCreationCooldown().isCoolingDown()) {
|
|
59171
60144
|
logWithTimestamp(
|
|
59172
60145
|
`[xmtp-sdk] ${failedAgents.length} client(s) failed to initialize, retrying in 1s...`
|
|
59173
60146
|
);
|
|
@@ -59207,6 +60180,11 @@ var init_xmtp_sdk = __esm({
|
|
|
59207
60180
|
phase: "init",
|
|
59208
60181
|
attempt: "2"
|
|
59209
60182
|
});
|
|
60183
|
+
} else if (r.reason instanceof XmtpCreationCooldownSkipError) {
|
|
60184
|
+
const info = failedAgents[i];
|
|
60185
|
+
logWithTimestamp(
|
|
60186
|
+
`[xmtp-sdk] retry suppressed (rate-limit cooldown): ${info.communicationAddress} (agentId=${info.agentId})`
|
|
60187
|
+
);
|
|
59210
60188
|
} else {
|
|
59211
60189
|
const info = failedAgents[i];
|
|
59212
60190
|
logWithTimestamp(
|
|
@@ -59302,7 +60280,16 @@ var init_xmtp_sdk = __esm({
|
|
|
59302
60280
|
try {
|
|
59303
60281
|
this.cancelStreamRecoveryForAddress(address);
|
|
59304
60282
|
this.stoppedAddresses.add(address.toLowerCase());
|
|
59305
|
-
client
|
|
60283
|
+
await stopAndCloseXmtpClient(client, {
|
|
60284
|
+
address,
|
|
60285
|
+
agentId: agentInfo.agentId,
|
|
60286
|
+
phase: "refresh/remove",
|
|
60287
|
+
onCloseError: (err2) => logger.error(
|
|
60288
|
+
LogEvent.XMTP_CLIENT_CLOSE_FAILED,
|
|
60289
|
+
err2 instanceof Error ? err2 : new Error(String(err2)),
|
|
60290
|
+
{ walletAddress: address, onchainosAgentId: agentInfo.agentId, phase: "refresh/remove" }
|
|
60291
|
+
)
|
|
60292
|
+
});
|
|
59306
60293
|
logWithTimestamp(
|
|
59307
60294
|
`[xmtp-sdk] refresh: stopped client: ${address} (agentId=${agentInfo.agentId})`
|
|
59308
60295
|
);
|
|
@@ -59389,23 +60376,29 @@ var init_xmtp_sdk = __esm({
|
|
|
59389
60376
|
});
|
|
59390
60377
|
} else {
|
|
59391
60378
|
failedAgents.push(added[i]);
|
|
59392
|
-
|
|
59393
|
-
|
|
59394
|
-
|
|
59395
|
-
|
|
59396
|
-
|
|
59397
|
-
|
|
59398
|
-
|
|
59399
|
-
|
|
59400
|
-
|
|
59401
|
-
|
|
59402
|
-
|
|
59403
|
-
|
|
59404
|
-
|
|
59405
|
-
|
|
60379
|
+
if (r.reason instanceof XmtpCreationCooldownSkipError) {
|
|
60380
|
+
logWithTimestamp(
|
|
60381
|
+
`[xmtp-sdk] refresh: identity init suppressed (rate-limit cooldown): ${added[i].communicationAddress} (agentId=${added[i].agentId})`
|
|
60382
|
+
);
|
|
60383
|
+
} else {
|
|
60384
|
+
logWithTimestamp(
|
|
60385
|
+
`[xmtp-sdk] refresh: identity init failed: ${added[i].communicationAddress} (agentId=${added[i].agentId})`,
|
|
60386
|
+
r.reason
|
|
60387
|
+
);
|
|
60388
|
+
logger.error(
|
|
60389
|
+
LogEvent.XMTP_CONNECTION_FAILED,
|
|
60390
|
+
r.reason instanceof Error ? r.reason : new Error(String(r.reason)),
|
|
60391
|
+
{
|
|
60392
|
+
walletAddress: added[i].communicationAddress,
|
|
60393
|
+
onchainosAgentId: added[i].agentId,
|
|
60394
|
+
phase: "refresh",
|
|
60395
|
+
attempt: "1"
|
|
60396
|
+
}
|
|
60397
|
+
);
|
|
60398
|
+
}
|
|
59406
60399
|
}
|
|
59407
60400
|
}
|
|
59408
|
-
if (failedAgents.length > 0) {
|
|
60401
|
+
if (failedAgents.length > 0 && !getXmtpCreationCooldown().isCoolingDown()) {
|
|
59409
60402
|
logWithTimestamp(
|
|
59410
60403
|
`[xmtp-sdk] refresh: ${failedAgents.length} client(s) failed to initialize, retrying in 1s...`
|
|
59411
60404
|
);
|
|
@@ -59448,6 +60441,11 @@ var init_xmtp_sdk = __esm({
|
|
|
59448
60441
|
phase: "refresh",
|
|
59449
60442
|
attempt: "2"
|
|
59450
60443
|
});
|
|
60444
|
+
} else if (r.reason instanceof XmtpCreationCooldownSkipError) {
|
|
60445
|
+
const info = failedAgents[i];
|
|
60446
|
+
logWithTimestamp(
|
|
60447
|
+
`[xmtp-sdk] refresh: retry suppressed (rate-limit cooldown): ${info.communicationAddress} (agentId=${info.agentId})`
|
|
60448
|
+
);
|
|
59451
60449
|
} else {
|
|
59452
60450
|
const info = failedAgents[i];
|
|
59453
60451
|
logWithTimestamp(
|
|
@@ -59511,6 +60509,18 @@ var init_xmtp_sdk = __esm({
|
|
|
59511
60509
|
async recycleXmtpClients() {
|
|
59512
60510
|
await this._backupReady;
|
|
59513
60511
|
const startedAt = Date.now();
|
|
60512
|
+
if (getXmtpCreationCooldown().isCoolingDown()) {
|
|
60513
|
+
logWithTimestamp("[xmtp-sdk] recycle skipped \u2014 rate-limit cooldown active");
|
|
60514
|
+
return {
|
|
60515
|
+
clients: this.clients.size,
|
|
60516
|
+
recycled: 0,
|
|
60517
|
+
failed: 0,
|
|
60518
|
+
replayed: 0,
|
|
60519
|
+
skipped: 0,
|
|
60520
|
+
durationMs: Date.now() - startedAt,
|
|
60521
|
+
addresses: []
|
|
60522
|
+
};
|
|
60523
|
+
}
|
|
59514
60524
|
const addresses = [];
|
|
59515
60525
|
let recycled = 0;
|
|
59516
60526
|
let failed = 0;
|
|
@@ -59529,7 +60539,16 @@ var init_xmtp_sdk = __esm({
|
|
|
59529
60539
|
try {
|
|
59530
60540
|
this.cancelStreamRecoveryForAddress(address);
|
|
59531
60541
|
this.stoppedAddresses.add(addressKey);
|
|
59532
|
-
await
|
|
60542
|
+
await stopAndCloseXmtpClient(oldClient, {
|
|
60543
|
+
address,
|
|
60544
|
+
agentId: agentInfo.agentId,
|
|
60545
|
+
phase: "recycle",
|
|
60546
|
+
onCloseError: (err2) => logger.error(
|
|
60547
|
+
LogEvent.XMTP_CLIENT_CLOSE_FAILED,
|
|
60548
|
+
err2 instanceof Error ? err2 : new Error(String(err2)),
|
|
60549
|
+
{ walletAddress: address, onchainosAgentId: agentInfo.agentId, phase: "recycle" }
|
|
60550
|
+
)
|
|
60551
|
+
});
|
|
59533
60552
|
this.clients.delete(address);
|
|
59534
60553
|
this.inboundReplayGates.delete(addressKey);
|
|
59535
60554
|
this.replayScanFailuresByAddress.delete(addressKey);
|
|
@@ -59616,6 +60635,12 @@ var init_xmtp_sdk = __esm({
|
|
|
59616
60635
|
phase: "recycle/create-client"
|
|
59617
60636
|
}
|
|
59618
60637
|
);
|
|
60638
|
+
if (isXmtpRateLimitError(err2)) {
|
|
60639
|
+
logWithTimestamp(
|
|
60640
|
+
"[xmtp-sdk] recycle: rate-limit on recreate \u2014 stopping remaining recycles"
|
|
60641
|
+
);
|
|
60642
|
+
break;
|
|
60643
|
+
}
|
|
59619
60644
|
}
|
|
59620
60645
|
}
|
|
59621
60646
|
return {
|
|
@@ -61867,7 +62892,7 @@ var init_envelope = __esm({
|
|
|
61867
62892
|
});
|
|
61868
62893
|
|
|
61869
62894
|
// src/invalid-message-store.ts
|
|
61870
|
-
function
|
|
62895
|
+
function loadSqlite6() {
|
|
61871
62896
|
const originalEmitWarning = process.emitWarning;
|
|
61872
62897
|
process.emitWarning = ((warning, ...args) => {
|
|
61873
62898
|
const message = typeof warning === "string" ? warning : warning.message;
|
|
@@ -61882,22 +62907,22 @@ function loadSqlite5() {
|
|
|
61882
62907
|
process.emitWarning = originalEmitWarning;
|
|
61883
62908
|
}
|
|
61884
62909
|
}
|
|
61885
|
-
var
|
|
62910
|
+
var import_node_fs26, import_node_path29, DatabaseSync5, InvalidXmtpMessageStore;
|
|
61886
62911
|
var init_invalid_message_store = __esm({
|
|
61887
62912
|
"src/invalid-message-store.ts"() {
|
|
61888
62913
|
"use strict";
|
|
61889
|
-
|
|
62914
|
+
import_node_fs26 = require("node:fs");
|
|
61890
62915
|
import_node_path29 = require("node:path");
|
|
61891
62916
|
init_paths();
|
|
61892
|
-
({ DatabaseSync:
|
|
62917
|
+
({ DatabaseSync: DatabaseSync5 } = loadSqlite6());
|
|
61893
62918
|
InvalidXmtpMessageStore = class {
|
|
61894
62919
|
dbPath;
|
|
61895
62920
|
db;
|
|
61896
62921
|
constructor(homeDir) {
|
|
61897
62922
|
const paths = resolveTaskPaths(homeDir);
|
|
61898
62923
|
this.dbPath = (0, import_node_path29.join)(paths.sqliteDir, "invalid-xmtp-messages.sqlite");
|
|
61899
|
-
(0,
|
|
61900
|
-
this.db = new
|
|
62924
|
+
(0, import_node_fs26.mkdirSync)((0, import_node_path29.dirname)(this.dbPath), { recursive: true });
|
|
62925
|
+
this.db = new DatabaseSync5(this.dbPath);
|
|
61901
62926
|
this.ensureReady();
|
|
61902
62927
|
}
|
|
61903
62928
|
close() {
|
|
@@ -62273,14 +63298,14 @@ function buildSystemMessageIdempotencyKey(input) {
|
|
|
62273
63298
|
return `system-message:${identity}`;
|
|
62274
63299
|
}
|
|
62275
63300
|
function stableHash(value) {
|
|
62276
|
-
return (0,
|
|
63301
|
+
return (0, import_node_crypto12.createHash)("sha256").update(value).digest("hex").slice(0, 24);
|
|
62277
63302
|
}
|
|
62278
|
-
var
|
|
63303
|
+
var import_node_crypto12, DIRECTION_PREFIX, CONTENT_SEPARATOR, ADDRESS_SHORT_HEAD, ADDRESS_SHORT_TAIL, JOB_ID_HEAD, JOB_ID_TAIL, ELLIPSIS, CONTENT_MAX_LINES;
|
|
62279
63304
|
var init_agent_message_notice = __esm({
|
|
62280
63305
|
"src/agent-message-notice.ts"() {
|
|
62281
63306
|
"use strict";
|
|
62282
63307
|
init_log();
|
|
62283
|
-
|
|
63308
|
+
import_node_crypto12 = require("node:crypto");
|
|
62284
63309
|
init_session_store();
|
|
62285
63310
|
init_ai_provider();
|
|
62286
63311
|
init_outbound_behavior();
|
|
@@ -62763,7 +63788,7 @@ async function handleSqliteGroupSendCommand(params) {
|
|
|
62763
63788
|
role: senderAgent?.role,
|
|
62764
63789
|
sendDurationMs: Date.now() - sendStartMs
|
|
62765
63790
|
});
|
|
62766
|
-
const messageId = `outbound-${(0,
|
|
63791
|
+
const messageId = `outbound-${(0, import_node_crypto13.randomUUID)()}`;
|
|
62767
63792
|
await notifyAgentMessageToUserAttention({
|
|
62768
63793
|
direction: "outbound" /* OUTBOUND */,
|
|
62769
63794
|
sender: {
|
|
@@ -62884,7 +63909,7 @@ async function handleGroupSendCommand(params) {
|
|
|
62884
63909
|
sendDurationMs: Date.now() - sendStartMs
|
|
62885
63910
|
});
|
|
62886
63911
|
const now = Date.now();
|
|
62887
|
-
const messageId = `outbound-${(0,
|
|
63912
|
+
const messageId = `outbound-${(0, import_node_crypto13.randomUUID)()}`;
|
|
62888
63913
|
const stored = {
|
|
62889
63914
|
id: messageId,
|
|
62890
63915
|
direction: "outbound",
|
|
@@ -63103,7 +64128,7 @@ async function handleXmtpSendCommand(params) {
|
|
|
63103
64128
|
sendDurationMs: Date.now() - sendStartMs
|
|
63104
64129
|
});
|
|
63105
64130
|
const now = Date.now();
|
|
63106
|
-
const messageId = `outbound-${(0,
|
|
64131
|
+
const messageId = `outbound-${(0, import_node_crypto13.randomUUID)()}`;
|
|
63107
64132
|
const stored = {
|
|
63108
64133
|
id: messageId,
|
|
63109
64134
|
direction: "outbound",
|
|
@@ -63149,14 +64174,14 @@ async function handleXmtpSendCommand(params) {
|
|
|
63149
64174
|
ownedStore?.close();
|
|
63150
64175
|
}
|
|
63151
64176
|
}
|
|
63152
|
-
var
|
|
64177
|
+
var import_node_crypto13, TASK_MIN_VERSION, sqliteGroupSessionPromises, conversationSyncPromises, XMTP_SEND_CHECKPOINT, resolvedAgentByIdCache;
|
|
63153
64178
|
var init_xmtp_send = __esm({
|
|
63154
64179
|
"src/xmtp-send.ts"() {
|
|
63155
64180
|
"use strict";
|
|
63156
64181
|
init_log();
|
|
63157
64182
|
init_sentry_logger();
|
|
63158
64183
|
init_log_fields();
|
|
63159
|
-
|
|
64184
|
+
import_node_crypto13 = require("node:crypto");
|
|
63160
64185
|
init_dist2();
|
|
63161
64186
|
init_envelope();
|
|
63162
64187
|
init_concurrency2();
|
|
@@ -63695,7 +64720,7 @@ function safeProcessCwd() {
|
|
|
63695
64720
|
}
|
|
63696
64721
|
function isDirectory(path2) {
|
|
63697
64722
|
try {
|
|
63698
|
-
return (0,
|
|
64723
|
+
return (0, import_node_fs27.statSync)(path2).isDirectory();
|
|
63699
64724
|
} catch {
|
|
63700
64725
|
return false;
|
|
63701
64726
|
}
|
|
@@ -65021,7 +66046,7 @@ function normalizeAttentionProvider(provider) {
|
|
|
65021
66046
|
return provider === "unknown" ? null : provider;
|
|
65022
66047
|
}
|
|
65023
66048
|
function stableHash2(value) {
|
|
65024
|
-
return (0,
|
|
66049
|
+
return (0, import_node_crypto14.createHash)("sha256").update(value).digest("hex").slice(0, 24);
|
|
65025
66050
|
}
|
|
65026
66051
|
function formatCommand(args) {
|
|
65027
66052
|
return args.map(shellQuote).join(" ");
|
|
@@ -65045,13 +66070,13 @@ function shortenJobId2(jobId) {
|
|
|
65045
66070
|
}
|
|
65046
66071
|
return `${jobId.slice(0, 6)}\u2026${jobId.slice(-4)}`;
|
|
65047
66072
|
}
|
|
65048
|
-
var
|
|
66073
|
+
var import_node_crypto14, import_node_fs27, import_promises12, import_node_os9, import_node_path31, AiRunner, CODEX_TOOL_FAILURE_MARKER;
|
|
65049
66074
|
var init_ai_runner = __esm({
|
|
65050
66075
|
"src/ai-runner.ts"() {
|
|
65051
66076
|
"use strict";
|
|
65052
66077
|
init_log();
|
|
65053
|
-
|
|
65054
|
-
|
|
66078
|
+
import_node_crypto14 = require("node:crypto");
|
|
66079
|
+
import_node_fs27 = require("node:fs");
|
|
65055
66080
|
import_promises12 = require("node:fs/promises");
|
|
65056
66081
|
import_node_os9 = require("node:os");
|
|
65057
66082
|
import_node_path31 = require("node:path");
|
|
@@ -65199,7 +66224,7 @@ var init_ai_runner = __esm({
|
|
|
65199
66224
|
ensureTaskDir(this.logsDir);
|
|
65200
66225
|
const lifecycleLogsEnabled = isAiLifecycleLoggingEnabled();
|
|
65201
66226
|
const logPath = lifecycleLogsEnabled ? this.buildRunLogPath(request) : "";
|
|
65202
|
-
const log = lifecycleLogsEnabled ? (0,
|
|
66227
|
+
const log = lifecycleLogsEnabled ? (0, import_node_fs27.createWriteStream)(logPath, { flags: "a" }) : null;
|
|
65203
66228
|
let existing = null;
|
|
65204
66229
|
let storeReadStartedAt;
|
|
65205
66230
|
let storeReadEndedAt;
|
|
@@ -67671,6 +68696,409 @@ var init_command_processor = __esm({
|
|
|
67671
68696
|
}
|
|
67672
68697
|
});
|
|
67673
68698
|
|
|
68699
|
+
// src/devkit-types.ts
|
|
68700
|
+
var DEVKIT_MAX_CONCURRENCY, DEVKIT_MAX_PENDING, DEVKIT_MAX_PENDING_BYTES, DEVKIT_MAX_MESSAGE_BYTES, DEVKIT_REQUEST_BUDGET_MS, DEVKIT_RESPONSE_DIAGNOSTIC_MAX_BYTES, DEVKIT_RESPONSE_SUMMARY_MAX_CHARS, DEVKIT_OUTCOME, DEVKIT_DROP_REASON;
|
|
68701
|
+
var init_devkit_types = __esm({
|
|
68702
|
+
"src/devkit-types.ts"() {
|
|
68703
|
+
"use strict";
|
|
68704
|
+
DEVKIT_MAX_CONCURRENCY = 16;
|
|
68705
|
+
DEVKIT_MAX_PENDING = 256;
|
|
68706
|
+
DEVKIT_MAX_PENDING_BYTES = 16 * 1024 * 1024;
|
|
68707
|
+
DEVKIT_MAX_MESSAGE_BYTES = 1 * 1024 * 1024;
|
|
68708
|
+
DEVKIT_REQUEST_BUDGET_MS = 5e3;
|
|
68709
|
+
DEVKIT_RESPONSE_DIAGNOSTIC_MAX_BYTES = 4 * 1024;
|
|
68710
|
+
DEVKIT_RESPONSE_SUMMARY_MAX_CHARS = 256;
|
|
68711
|
+
DEVKIT_OUTCOME = {
|
|
68712
|
+
HTTP_ACCEPTED: "http_accepted",
|
|
68713
|
+
DROPPED: "dropped"
|
|
68714
|
+
};
|
|
68715
|
+
DEVKIT_DROP_REASON = {
|
|
68716
|
+
REQUEST_TOO_LARGE: "request_too_large",
|
|
68717
|
+
// serialized > 1 MiB (FR-3-AC-6)
|
|
68718
|
+
PENDING_OVERFLOW: "pending_overflow",
|
|
68719
|
+
// > 256 items or > 16 MiB total pending (NFR-2-AC-1)
|
|
68720
|
+
CONFIG_CHANGED: "config_changed",
|
|
68721
|
+
// snapshot version changed/removed before send (FR-2-AC-6)
|
|
68722
|
+
CONFIG_READ_FAILED: "config_read_failed",
|
|
68723
|
+
// snapshot unreadable/corrupt (FR-2-AC-5)
|
|
68724
|
+
HTTP_STATUS: "http_status",
|
|
68725
|
+
// non-2xx response (FR-3-AC-3)
|
|
68726
|
+
REDIRECT_BLOCKED: "redirect_blocked",
|
|
68727
|
+
// 3xx response, not followed (NFR-3-AC-2)
|
|
68728
|
+
CONNECTION_FAILED: "connection_failed",
|
|
68729
|
+
// ECONNREFUSED / reset / unreachable (FR-3-AC-4)
|
|
68730
|
+
TIMEOUT: "timeout",
|
|
68731
|
+
// exceeded the 5 s budget (FR-3-AC-4)
|
|
68732
|
+
REQUEST_BUILD_ERROR: "request_build_error",
|
|
68733
|
+
// serialization / target build failure
|
|
68734
|
+
RESPONSE_READ_ERROR: "response_read_error",
|
|
68735
|
+
// diagnostic read failure
|
|
68736
|
+
SHUTDOWN_CANCELLED: "shutdown_cancelled"
|
|
68737
|
+
// daemon stopped before send (NFR-2-AC-3)
|
|
68738
|
+
};
|
|
68739
|
+
}
|
|
68740
|
+
});
|
|
68741
|
+
|
|
68742
|
+
// src/devkit-delivery.ts
|
|
68743
|
+
function fallbackDeliveryId(parts) {
|
|
68744
|
+
return `devkit-${parts.jobId ?? "none"}-${parts.sessionKey ?? "none"}-${parts.receivedAt}`;
|
|
68745
|
+
}
|
|
68746
|
+
function buildSessionEnvelope(ev, ctx = {}) {
|
|
68747
|
+
const now = ctx.now ?? Date.now;
|
|
68748
|
+
const receivedAt = Math.floor(now() / 1e3);
|
|
68749
|
+
const jobId = ev.jobId ?? null;
|
|
68750
|
+
const agentId = ev.agentId ?? null;
|
|
68751
|
+
const deliveryId = ev.messageId ?? fallbackDeliveryId({ jobId, sessionKey: ev.sessionKey, receivedAt });
|
|
68752
|
+
const messageId = ev.messageId ?? deliveryId;
|
|
68753
|
+
return {
|
|
68754
|
+
deliveryId,
|
|
68755
|
+
receivedAt,
|
|
68756
|
+
kind: "session",
|
|
68757
|
+
agentId,
|
|
68758
|
+
event: {
|
|
68759
|
+
sessionKey: ev.sessionKey,
|
|
68760
|
+
content: ev.content,
|
|
68761
|
+
messageId,
|
|
68762
|
+
jobId,
|
|
68763
|
+
agentId
|
|
68764
|
+
}
|
|
68765
|
+
};
|
|
68766
|
+
}
|
|
68767
|
+
function buildJobEnvelope(ev, _ctx = {}) {
|
|
68768
|
+
const sessionAgentId = ev.sessionAgentId ?? null;
|
|
68769
|
+
const receivedAt = Math.floor(ev.message.receivedAtMs / 1e3);
|
|
68770
|
+
return {
|
|
68771
|
+
deliveryId: ev.message.id,
|
|
68772
|
+
receivedAt,
|
|
68773
|
+
kind: "job",
|
|
68774
|
+
agentId: sessionAgentId,
|
|
68775
|
+
event: {
|
|
68776
|
+
jobId: ev.jobId,
|
|
68777
|
+
sessionAgentId,
|
|
68778
|
+
message: {
|
|
68779
|
+
...ev.message,
|
|
68780
|
+
content: ev.message.rawText
|
|
68781
|
+
}
|
|
68782
|
+
}
|
|
68783
|
+
};
|
|
68784
|
+
}
|
|
68785
|
+
function classifyHttpOutcome(status) {
|
|
68786
|
+
if (status >= 200 && status < 300) {
|
|
68787
|
+
return { outcome: DEVKIT_OUTCOME.HTTP_ACCEPTED };
|
|
68788
|
+
}
|
|
68789
|
+
if (status >= 300 && status < 400) {
|
|
68790
|
+
return { outcome: DEVKIT_OUTCOME.DROPPED, reason: DEVKIT_DROP_REASON.REDIRECT_BLOCKED };
|
|
68791
|
+
}
|
|
68792
|
+
return { outcome: DEVKIT_OUTCOME.DROPPED, reason: DEVKIT_DROP_REASON.HTTP_STATUS };
|
|
68793
|
+
}
|
|
68794
|
+
function classifyFetchFailure(params) {
|
|
68795
|
+
if (params.cancelledByShutdown) {
|
|
68796
|
+
return DEVKIT_DROP_REASON.SHUTDOWN_CANCELLED;
|
|
68797
|
+
}
|
|
68798
|
+
if (params.timedOut || params.errorCategory === "timeout") {
|
|
68799
|
+
return DEVKIT_DROP_REASON.TIMEOUT;
|
|
68800
|
+
}
|
|
68801
|
+
return DEVKIT_DROP_REASON.CONNECTION_FAILED;
|
|
68802
|
+
}
|
|
68803
|
+
function redactSummary(raw) {
|
|
68804
|
+
const collapsed = raw.replace(/\s+/g, " ").trim();
|
|
68805
|
+
const redacted = collapsed.replace(SECRET_SCHEME_PATTERN, "[REDACTED]").replace(
|
|
68806
|
+
SECRET_KV_PATTERN,
|
|
68807
|
+
(_match, keyQuote, key, keyQuoteClose, sep4) => `${keyQuote}${key}${keyQuoteClose}${sep4}[REDACTED]`
|
|
68808
|
+
);
|
|
68809
|
+
const truncated = redacted.length > DEVKIT_RESPONSE_SUMMARY_MAX_CHARS;
|
|
68810
|
+
return { text: redacted.slice(0, DEVKIT_RESPONSE_SUMMARY_MAX_CHARS), truncated };
|
|
68811
|
+
}
|
|
68812
|
+
async function readRedactedResponse(response) {
|
|
68813
|
+
let bodyText;
|
|
68814
|
+
try {
|
|
68815
|
+
bodyText = await response.text();
|
|
68816
|
+
} catch {
|
|
68817
|
+
return { responseBytesRead: 0, responseTruncated: false, responseSummary: "" };
|
|
68818
|
+
}
|
|
68819
|
+
const bytes = Buffer.from(bodyText, "utf8");
|
|
68820
|
+
const diagnosticSlice = bytes.subarray(0, DEVKIT_RESPONSE_DIAGNOSTIC_MAX_BYTES);
|
|
68821
|
+
const sliceTruncated = bytes.byteLength > DEVKIT_RESPONSE_DIAGNOSTIC_MAX_BYTES;
|
|
68822
|
+
const summary = redactSummary(diagnosticSlice.toString("utf8"));
|
|
68823
|
+
return {
|
|
68824
|
+
responseBytesRead: diagnosticSlice.byteLength,
|
|
68825
|
+
responseTruncated: sliceTruncated || summary.truncated,
|
|
68826
|
+
responseSummary: summary.text
|
|
68827
|
+
};
|
|
68828
|
+
}
|
|
68829
|
+
async function isLoopbackTarget(origin) {
|
|
68830
|
+
let hostname;
|
|
68831
|
+
try {
|
|
68832
|
+
hostname = new URL(origin).hostname;
|
|
68833
|
+
} catch {
|
|
68834
|
+
return false;
|
|
68835
|
+
}
|
|
68836
|
+
const version3 = (0, import_node_net2.isIP)(hostname);
|
|
68837
|
+
if (version3 === 4) {
|
|
68838
|
+
return hostname.startsWith("127.");
|
|
68839
|
+
}
|
|
68840
|
+
if (version3 === 6) {
|
|
68841
|
+
return hostname === "::1";
|
|
68842
|
+
}
|
|
68843
|
+
if (hostname.toLowerCase() !== "localhost") {
|
|
68844
|
+
return false;
|
|
68845
|
+
}
|
|
68846
|
+
try {
|
|
68847
|
+
const resolved = await (0, import_promises13.lookup)(hostname);
|
|
68848
|
+
return resolved.family === 4 ? resolved.address.startsWith("127.") : resolved.address === "::1";
|
|
68849
|
+
} catch {
|
|
68850
|
+
return false;
|
|
68851
|
+
}
|
|
68852
|
+
}
|
|
68853
|
+
function orderingKeyFor(envelope) {
|
|
68854
|
+
if (envelope.kind === "session") {
|
|
68855
|
+
return `session:${envelope.event.sessionKey}`;
|
|
68856
|
+
}
|
|
68857
|
+
return `job:${envelope.event.jobId}`;
|
|
68858
|
+
}
|
|
68859
|
+
function sleep4(ms) {
|
|
68860
|
+
return new Promise((resolve14) => setTimeout(resolve14, Math.max(0, ms)));
|
|
68861
|
+
}
|
|
68862
|
+
var import_node_net2, import_promises13, COMPONENT, SECRET_KEYS, SECRET_SCHEME_PATTERN, SECRET_KV_PATTERN, DevkitDeliveryDispatcher;
|
|
68863
|
+
var init_devkit_delivery = __esm({
|
|
68864
|
+
"src/devkit-delivery.ts"() {
|
|
68865
|
+
"use strict";
|
|
68866
|
+
import_node_net2 = require("node:net");
|
|
68867
|
+
import_promises13 = require("node:dns/promises");
|
|
68868
|
+
init_sentry_logger();
|
|
68869
|
+
init_error_diagnostics();
|
|
68870
|
+
init_devkit_types();
|
|
68871
|
+
COMPONENT = "node_devkit";
|
|
68872
|
+
SECRET_KEYS = "authorization|bearer|basic|jwt|password|api[_-]?key|secret|token";
|
|
68873
|
+
SECRET_SCHEME_PATTERN = new RegExp(`\\b(?:${SECRET_KEYS})\\s+\\S+`, "gi");
|
|
68874
|
+
SECRET_KV_PATTERN = new RegExp(
|
|
68875
|
+
`("?)(${SECRET_KEYS})("?)\\s*([:=])\\s*"?[^"\\s,}]+`,
|
|
68876
|
+
"gi"
|
|
68877
|
+
);
|
|
68878
|
+
DevkitDeliveryDispatcher = class {
|
|
68879
|
+
readSnapshot;
|
|
68880
|
+
now;
|
|
68881
|
+
fetchImpl;
|
|
68882
|
+
pendingQueue = [];
|
|
68883
|
+
pendingBytes = 0;
|
|
68884
|
+
activeKeys = /* @__PURE__ */ new Set();
|
|
68885
|
+
inFlight = /* @__PURE__ */ new Set();
|
|
68886
|
+
activeControllers = /* @__PURE__ */ new Map();
|
|
68887
|
+
shuttingDown = false;
|
|
68888
|
+
constructor(options) {
|
|
68889
|
+
this.readSnapshot = options.readSnapshot;
|
|
68890
|
+
this.now = options.now ?? Date.now;
|
|
68891
|
+
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
68892
|
+
}
|
|
68893
|
+
enqueue(input) {
|
|
68894
|
+
const serialized = JSON.stringify(input.envelope);
|
|
68895
|
+
const bytes = Buffer.byteLength(serialized, "utf8");
|
|
68896
|
+
const kind = input.envelope.kind;
|
|
68897
|
+
const deliveryId = input.envelope.deliveryId;
|
|
68898
|
+
if (bytes > DEVKIT_MAX_MESSAGE_BYTES) {
|
|
68899
|
+
this.emitDropped({ deliveryId, kind, reason: DEVKIT_DROP_REASON.REQUEST_TOO_LARGE, durationMs: 0 });
|
|
68900
|
+
return true;
|
|
68901
|
+
}
|
|
68902
|
+
if (this.pendingQueue.length >= DEVKIT_MAX_PENDING || this.pendingBytes + bytes > DEVKIT_MAX_PENDING_BYTES) {
|
|
68903
|
+
this.emitDropped({ deliveryId, kind, reason: DEVKIT_DROP_REASON.PENDING_OVERFLOW, durationMs: 0 });
|
|
68904
|
+
return false;
|
|
68905
|
+
}
|
|
68906
|
+
this.pendingQueue.push({
|
|
68907
|
+
envelope: input.envelope,
|
|
68908
|
+
config: input.config,
|
|
68909
|
+
serialized,
|
|
68910
|
+
bytes,
|
|
68911
|
+
cancelledByShutdown: false,
|
|
68912
|
+
timedOut: false
|
|
68913
|
+
});
|
|
68914
|
+
this.pendingBytes += bytes;
|
|
68915
|
+
logger.info(LogEvent.DEVKIT_DELIVERY_ACCEPTED, {
|
|
68916
|
+
component: COMPONENT,
|
|
68917
|
+
deliveryId,
|
|
68918
|
+
kind,
|
|
68919
|
+
agentId: input.envelope.agentId ?? void 0
|
|
68920
|
+
});
|
|
68921
|
+
this.pump();
|
|
68922
|
+
return true;
|
|
68923
|
+
}
|
|
68924
|
+
pump() {
|
|
68925
|
+
if (this.shuttingDown) {
|
|
68926
|
+
return;
|
|
68927
|
+
}
|
|
68928
|
+
while (this.activeKeys.size < DEVKIT_MAX_CONCURRENCY) {
|
|
68929
|
+
const index2 = this.pendingQueue.findIndex((item2) => !this.activeKeys.has(orderingKeyFor(item2.envelope)));
|
|
68930
|
+
if (index2 === -1) {
|
|
68931
|
+
break;
|
|
68932
|
+
}
|
|
68933
|
+
const [item] = this.pendingQueue.splice(index2, 1);
|
|
68934
|
+
this.pendingBytes -= item.bytes;
|
|
68935
|
+
const key = orderingKeyFor(item.envelope);
|
|
68936
|
+
this.activeKeys.add(key);
|
|
68937
|
+
const promise = this.send(item).finally(() => {
|
|
68938
|
+
this.activeKeys.delete(key);
|
|
68939
|
+
this.inFlight.delete(promise);
|
|
68940
|
+
this.pump();
|
|
68941
|
+
});
|
|
68942
|
+
this.inFlight.add(promise);
|
|
68943
|
+
}
|
|
68944
|
+
}
|
|
68945
|
+
async send(item) {
|
|
68946
|
+
const startedAt = this.now();
|
|
68947
|
+
const { envelope } = item;
|
|
68948
|
+
let snapshot;
|
|
68949
|
+
try {
|
|
68950
|
+
snapshot = this.readSnapshot();
|
|
68951
|
+
} catch {
|
|
68952
|
+
this.emitDropped({
|
|
68953
|
+
deliveryId: envelope.deliveryId,
|
|
68954
|
+
kind: envelope.kind,
|
|
68955
|
+
reason: DEVKIT_DROP_REASON.CONFIG_READ_FAILED,
|
|
68956
|
+
durationMs: this.now() - startedAt
|
|
68957
|
+
});
|
|
68958
|
+
return;
|
|
68959
|
+
}
|
|
68960
|
+
if (snapshot?.configVersion !== item.config.configVersion) {
|
|
68961
|
+
this.emitDropped({
|
|
68962
|
+
deliveryId: envelope.deliveryId,
|
|
68963
|
+
kind: envelope.kind,
|
|
68964
|
+
reason: DEVKIT_DROP_REASON.CONFIG_CHANGED,
|
|
68965
|
+
durationMs: this.now() - startedAt
|
|
68966
|
+
});
|
|
68967
|
+
return;
|
|
68968
|
+
}
|
|
68969
|
+
const loopbackOk = await isLoopbackTarget(snapshot.origin);
|
|
68970
|
+
if (!loopbackOk) {
|
|
68971
|
+
this.emitHttpFailed(
|
|
68972
|
+
item,
|
|
68973
|
+
DEVKIT_DROP_REASON.CONNECTION_FAILED,
|
|
68974
|
+
{ errorCategory: "network_unavailable" },
|
|
68975
|
+
this.now() - startedAt
|
|
68976
|
+
);
|
|
68977
|
+
return;
|
|
68978
|
+
}
|
|
68979
|
+
const url = `${snapshot.origin}:${snapshot.port}${snapshot.eventPath}`;
|
|
68980
|
+
const controller = new AbortController();
|
|
68981
|
+
this.activeControllers.set(item, controller);
|
|
68982
|
+
const timeoutTimer = setTimeout(() => {
|
|
68983
|
+
item.timedOut = true;
|
|
68984
|
+
controller.abort();
|
|
68985
|
+
}, DEVKIT_REQUEST_BUDGET_MS);
|
|
68986
|
+
let response;
|
|
68987
|
+
try {
|
|
68988
|
+
response = await this.fetchImpl(url, {
|
|
68989
|
+
method: "POST",
|
|
68990
|
+
headers: { "content-type": "application/json" },
|
|
68991
|
+
body: item.serialized,
|
|
68992
|
+
redirect: "manual",
|
|
68993
|
+
signal: controller.signal
|
|
68994
|
+
});
|
|
68995
|
+
} catch (err2) {
|
|
68996
|
+
clearTimeout(timeoutTimer);
|
|
68997
|
+
this.activeControllers.delete(item);
|
|
68998
|
+
const durationMs2 = this.now() - startedAt;
|
|
68999
|
+
if (item.cancelledByShutdown) {
|
|
69000
|
+
this.emitCancelled(item, durationMs2);
|
|
69001
|
+
return;
|
|
69002
|
+
}
|
|
69003
|
+
const diagnostics = buildErrorDiagnostics(
|
|
69004
|
+
LogEvent.DEVKIT_DELIVERY_HTTP_FAILED,
|
|
69005
|
+
err2 instanceof Error ? err2 : void 0,
|
|
69006
|
+
{}
|
|
69007
|
+
);
|
|
69008
|
+
const reason = classifyFetchFailure({
|
|
69009
|
+
cancelledByShutdown: item.cancelledByShutdown,
|
|
69010
|
+
timedOut: item.timedOut,
|
|
69011
|
+
errorCategory: diagnostics.errorCategory
|
|
69012
|
+
});
|
|
69013
|
+
this.emitHttpFailed(item, reason, diagnostics, durationMs2, err2 instanceof Error ? err2 : void 0);
|
|
69014
|
+
return;
|
|
69015
|
+
}
|
|
69016
|
+
clearTimeout(timeoutTimer);
|
|
69017
|
+
this.activeControllers.delete(item);
|
|
69018
|
+
const durationMs = this.now() - startedAt;
|
|
69019
|
+
if (item.cancelledByShutdown) {
|
|
69020
|
+
this.emitCancelled(item, durationMs);
|
|
69021
|
+
return;
|
|
69022
|
+
}
|
|
69023
|
+
const status = response.status;
|
|
69024
|
+
const classified = classifyHttpOutcome(status);
|
|
69025
|
+
if (classified.outcome === DEVKIT_OUTCOME.HTTP_ACCEPTED) {
|
|
69026
|
+
logger.info(LogEvent.DEVKIT_DELIVERY_HTTP_ACCEPTED, {
|
|
69027
|
+
component: COMPONENT,
|
|
69028
|
+
deliveryId: envelope.deliveryId,
|
|
69029
|
+
kind: envelope.kind,
|
|
69030
|
+
statusCode: status,
|
|
69031
|
+
durationMs
|
|
69032
|
+
});
|
|
69033
|
+
return;
|
|
69034
|
+
}
|
|
69035
|
+
const redaction = await readRedactedResponse(response);
|
|
69036
|
+
this.emitDropped({
|
|
69037
|
+
deliveryId: envelope.deliveryId,
|
|
69038
|
+
kind: envelope.kind,
|
|
69039
|
+
reason: classified.reason,
|
|
69040
|
+
statusCode: status,
|
|
69041
|
+
durationMs,
|
|
69042
|
+
...redaction
|
|
69043
|
+
});
|
|
69044
|
+
}
|
|
69045
|
+
async shutdown(deadlineMs) {
|
|
69046
|
+
this.shuttingDown = true;
|
|
69047
|
+
const deadline = this.now() + Math.max(0, deadlineMs);
|
|
69048
|
+
if (this.inFlight.size > 0) {
|
|
69049
|
+
const remaining = Math.max(0, deadline - this.now());
|
|
69050
|
+
await Promise.race([Promise.allSettled(Array.from(this.inFlight)), sleep4(remaining)]);
|
|
69051
|
+
}
|
|
69052
|
+
for (const [item, controller] of this.activeControllers) {
|
|
69053
|
+
item.cancelledByShutdown = true;
|
|
69054
|
+
controller.abort();
|
|
69055
|
+
}
|
|
69056
|
+
const stillPending = this.pendingQueue.splice(0, this.pendingQueue.length);
|
|
69057
|
+
this.pendingBytes = 0;
|
|
69058
|
+
for (const item of stillPending) {
|
|
69059
|
+
this.emitCancelled(item, 0);
|
|
69060
|
+
}
|
|
69061
|
+
}
|
|
69062
|
+
emitDropped(params) {
|
|
69063
|
+
logger.info(LogEvent.DEVKIT_DELIVERY_DROPPED, {
|
|
69064
|
+
component: COMPONENT,
|
|
69065
|
+
outcome: DEVKIT_OUTCOME.DROPPED,
|
|
69066
|
+
deliveryId: params.deliveryId,
|
|
69067
|
+
kind: params.kind,
|
|
69068
|
+
reason: params.reason,
|
|
69069
|
+
durationMs: params.durationMs,
|
|
69070
|
+
...params.statusCode !== void 0 ? { statusCode: params.statusCode } : {},
|
|
69071
|
+
...params.responseBytesRead !== void 0 ? { responseBytesRead: params.responseBytesRead } : {},
|
|
69072
|
+
...params.responseTruncated !== void 0 ? { responseTruncated: params.responseTruncated } : {},
|
|
69073
|
+
...params.responseSummary !== void 0 ? { responseSummary: params.responseSummary } : {}
|
|
69074
|
+
});
|
|
69075
|
+
}
|
|
69076
|
+
emitHttpFailed(item, reason, diagnostics, durationMs, err2) {
|
|
69077
|
+
logger.error(LogEvent.DEVKIT_DELIVERY_HTTP_FAILED, err2, {
|
|
69078
|
+
component: COMPONENT,
|
|
69079
|
+
outcome: DEVKIT_OUTCOME.DROPPED,
|
|
69080
|
+
deliveryId: item.envelope.deliveryId,
|
|
69081
|
+
kind: item.envelope.kind,
|
|
69082
|
+
reason,
|
|
69083
|
+
durationMs,
|
|
69084
|
+
...diagnostics.errorCategory ? { errorCategory: diagnostics.errorCategory } : {},
|
|
69085
|
+
...diagnostics.errorCode ? { errorCode: diagnostics.errorCode } : {}
|
|
69086
|
+
});
|
|
69087
|
+
}
|
|
69088
|
+
emitCancelled(item, durationMs) {
|
|
69089
|
+
logger.info(LogEvent.DEVKIT_DELIVERY_CANCELLED, {
|
|
69090
|
+
component: COMPONENT,
|
|
69091
|
+
outcome: DEVKIT_OUTCOME.DROPPED,
|
|
69092
|
+
deliveryId: item.envelope.deliveryId,
|
|
69093
|
+
kind: item.envelope.kind,
|
|
69094
|
+
reason: DEVKIT_DROP_REASON.SHUTDOWN_CANCELLED,
|
|
69095
|
+
durationMs
|
|
69096
|
+
});
|
|
69097
|
+
}
|
|
69098
|
+
};
|
|
69099
|
+
}
|
|
69100
|
+
});
|
|
69101
|
+
|
|
67674
69102
|
// src/ai-dispatch-queue.ts
|
|
67675
69103
|
async function enqueueAiJobMessageDispatch(params) {
|
|
67676
69104
|
const commands = params.commands ?? new CommandStore(params.homeDir);
|
|
@@ -67702,6 +69130,95 @@ var init_ai_dispatch_queue = __esm({
|
|
|
67702
69130
|
}
|
|
67703
69131
|
});
|
|
67704
69132
|
|
|
69133
|
+
// src/devkit-router.ts
|
|
69134
|
+
function createDevkitAutoRouter(deps) {
|
|
69135
|
+
const { commands, dispatcher, readSnapshot } = deps;
|
|
69136
|
+
function readConfigOrNull(phase) {
|
|
69137
|
+
try {
|
|
69138
|
+
return { ok: true, config: readSnapshot() };
|
|
69139
|
+
} catch (err2) {
|
|
69140
|
+
logger.error(
|
|
69141
|
+
LogEvent.DEVKIT_ROUTE_CONFIG_READ_FAILED,
|
|
69142
|
+
err2 instanceof Error ? err2 : new Error(String(err2)),
|
|
69143
|
+
{
|
|
69144
|
+
component: "node_devkit",
|
|
69145
|
+
phase,
|
|
69146
|
+
outcome: "dropped",
|
|
69147
|
+
reason: "config_read_failed"
|
|
69148
|
+
}
|
|
69149
|
+
);
|
|
69150
|
+
return { ok: false };
|
|
69151
|
+
}
|
|
69152
|
+
}
|
|
69153
|
+
async function routeSession(event) {
|
|
69154
|
+
const read = readConfigOrNull("session");
|
|
69155
|
+
if (!read.ok) {
|
|
69156
|
+
return;
|
|
69157
|
+
}
|
|
69158
|
+
if (read.config === null) {
|
|
69159
|
+
await enqueueAiSessionMessageDispatch({ commands, event });
|
|
69160
|
+
logger.info(LogEvent.DEVKIT_ROUTE_DEFAULT_AI, {
|
|
69161
|
+
component: "node_devkit",
|
|
69162
|
+
phase: "session",
|
|
69163
|
+
kind: "session",
|
|
69164
|
+
messageId: event.messageId ?? "",
|
|
69165
|
+
jobId: event.jobId ?? "",
|
|
69166
|
+
agentId: event.agentId ?? ""
|
|
69167
|
+
});
|
|
69168
|
+
return;
|
|
69169
|
+
}
|
|
69170
|
+
const config = read.config;
|
|
69171
|
+
const envelope = buildSessionEnvelope(event);
|
|
69172
|
+
dispatcher.enqueue({ envelope, config });
|
|
69173
|
+
logger.info(LogEvent.DEVKIT_ROUTE_CUSTOM_SERVER, {
|
|
69174
|
+
component: "node_devkit",
|
|
69175
|
+
phase: "session",
|
|
69176
|
+
kind: "session",
|
|
69177
|
+
deliveryId: envelope.deliveryId,
|
|
69178
|
+
messageId: event.messageId ?? "",
|
|
69179
|
+
jobId: event.jobId ?? "",
|
|
69180
|
+
agentId: event.agentId ?? ""
|
|
69181
|
+
});
|
|
69182
|
+
}
|
|
69183
|
+
async function routeJob(event) {
|
|
69184
|
+
const read = readConfigOrNull("job");
|
|
69185
|
+
if (!read.ok) {
|
|
69186
|
+
return;
|
|
69187
|
+
}
|
|
69188
|
+
if (read.config === null) {
|
|
69189
|
+
await enqueueAiJobMessageDispatch({ commands, event });
|
|
69190
|
+
logger.info(LogEvent.DEVKIT_ROUTE_DEFAULT_AI, {
|
|
69191
|
+
component: "node_devkit",
|
|
69192
|
+
phase: "job",
|
|
69193
|
+
kind: "job",
|
|
69194
|
+
jobId: event.jobId,
|
|
69195
|
+
agentId: event.sessionAgentId ?? ""
|
|
69196
|
+
});
|
|
69197
|
+
return;
|
|
69198
|
+
}
|
|
69199
|
+
const config = read.config;
|
|
69200
|
+
const envelope = buildJobEnvelope(event);
|
|
69201
|
+
dispatcher.enqueue({ envelope, config });
|
|
69202
|
+
logger.info(LogEvent.DEVKIT_ROUTE_CUSTOM_SERVER, {
|
|
69203
|
+
component: "node_devkit",
|
|
69204
|
+
phase: "job",
|
|
69205
|
+
kind: "job",
|
|
69206
|
+
deliveryId: envelope.deliveryId,
|
|
69207
|
+
jobId: event.jobId,
|
|
69208
|
+
agentId: event.sessionAgentId ?? ""
|
|
69209
|
+
});
|
|
69210
|
+
}
|
|
69211
|
+
return { routeJob, routeSession };
|
|
69212
|
+
}
|
|
69213
|
+
var init_devkit_router = __esm({
|
|
69214
|
+
"src/devkit-router.ts"() {
|
|
69215
|
+
"use strict";
|
|
69216
|
+
init_ai_dispatch_queue();
|
|
69217
|
+
init_devkit_delivery();
|
|
69218
|
+
init_sentry_logger();
|
|
69219
|
+
}
|
|
69220
|
+
});
|
|
69221
|
+
|
|
67705
69222
|
// src/message-handler.ts
|
|
67706
69223
|
function tryMarkProcessed(messageId) {
|
|
67707
69224
|
if (processedMessageIds.has(messageId)) {
|
|
@@ -68691,7 +70208,7 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
68691
70208
|
timing.mark("payloadParse", parseStartedAt);
|
|
68692
70209
|
const directToUser = chatType === "dm" && parseResult.ok ? extractDirectToUserNotification(parseResult.data) : { kind: "none" };
|
|
68693
70210
|
if (directToUser.kind === "invalid") {
|
|
68694
|
-
const droppedMessageId = messageId || `direct-to-user-${(0,
|
|
70211
|
+
const droppedMessageId = messageId || `direct-to-user-${(0, import_node_crypto15.randomUUID)()}`;
|
|
68695
70212
|
logger.error(
|
|
68696
70213
|
LogEvent.INBOUND_DROP_DM_INVALID_PAYLOAD,
|
|
68697
70214
|
new Error("Invalid direct-to-user system DM"),
|
|
@@ -68715,7 +70232,7 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
68715
70232
|
await dispatchDirectToUserNotification({
|
|
68716
70233
|
deps,
|
|
68717
70234
|
notification: directToUser.notification,
|
|
68718
|
-
messageId: messageId || `direct-to-user-${(0,
|
|
70235
|
+
messageId: messageId || `direct-to-user-${(0, import_node_crypto15.randomUUID)()}`,
|
|
68719
70236
|
timing,
|
|
68720
70237
|
source: options.source ?? "live"
|
|
68721
70238
|
});
|
|
@@ -68723,7 +70240,7 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
68723
70240
|
}
|
|
68724
70241
|
const systemNotification = chatType === "dm" && parseResult.ok ? extractSystemNotification(parseResult.data) : null;
|
|
68725
70242
|
if (systemNotification) {
|
|
68726
|
-
const systemMessageId = messageId || `system-${(0,
|
|
70243
|
+
const systemMessageId = messageId || `system-${(0, import_node_crypto15.randomUUID)()}`;
|
|
68727
70244
|
logWithTimestamp(
|
|
68728
70245
|
`[okx-agent-task:${deps.myXmtpAddress}] xmtp_system_message_received agentId=${systemNotification.agentId ?? ""} msg=${shortenLogValue(systemMessageId)} event=${systemNotification.event ?? ""} job=${shortenLogValue(systemNotification.jobId)} conv=${conversationId} source=${options.source ?? "live"} rawBytes=${Buffer.byteLength(rawText, "utf8")} rawPreview=${previewRawEnvelope(rawText)}`
|
|
68729
70246
|
);
|
|
@@ -69019,7 +70536,7 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
69019
70536
|
}));
|
|
69020
70537
|
return true;
|
|
69021
70538
|
}
|
|
69022
|
-
const routedMessageId = messageId || `group-${(0,
|
|
70539
|
+
const routedMessageId = messageId || `group-${(0, import_node_crypto15.randomUUID)()}`;
|
|
69023
70540
|
const sessionKey = ensureInboundGroupSession(deps, {
|
|
69024
70541
|
jobId: route.jobId,
|
|
69025
70542
|
myAgentId,
|
|
@@ -69085,7 +70602,7 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
69085
70602
|
return true;
|
|
69086
70603
|
}
|
|
69087
70604
|
const stored = {
|
|
69088
|
-
id: messageId || `local-${(0,
|
|
70605
|
+
id: messageId || `local-${(0, import_node_crypto15.randomUUID)()}`,
|
|
69089
70606
|
direction: "inbound",
|
|
69090
70607
|
route: route.route,
|
|
69091
70608
|
routeReason: route.routeReason,
|
|
@@ -69266,7 +70783,7 @@ function processOfflineFromCoreDeps(store, ctx, deps, options) {
|
|
|
69266
70783
|
function buildSystemStoredMessage(params) {
|
|
69267
70784
|
const now = Date.now();
|
|
69268
70785
|
return {
|
|
69269
|
-
id: params.id ?? `system-${now}-${(0,
|
|
70786
|
+
id: params.id ?? `system-${now}-${(0, import_node_crypto15.randomUUID)()}`,
|
|
69270
70787
|
direction: "system",
|
|
69271
70788
|
route: "backup",
|
|
69272
70789
|
routeReason: params.reason,
|
|
@@ -69284,12 +70801,12 @@ function buildSystemStoredMessage(params) {
|
|
|
69284
70801
|
function isA2AEnvelope(payload) {
|
|
69285
70802
|
return isPlainObject3(payload) && payload.msgType === A2A_MESSAGE_TYPE;
|
|
69286
70803
|
}
|
|
69287
|
-
var
|
|
70804
|
+
var import_node_crypto15, PROCESSED_IDS_MAX, processedMessageIds, EXTERNAL_JOB_ID_PATTERN, INBOUND_TRANSPORT, INBOUND_EVENT_FAMILY, INBOUND_TERMINAL_FIELDS;
|
|
69288
70805
|
var init_message_handler = __esm({
|
|
69289
70806
|
"src/message-handler.ts"() {
|
|
69290
70807
|
"use strict";
|
|
69291
70808
|
init_log();
|
|
69292
|
-
|
|
70809
|
+
import_node_crypto15 = require("node:crypto");
|
|
69293
70810
|
init_dist2();
|
|
69294
70811
|
init_a2a();
|
|
69295
70812
|
init_envelope_shared();
|
|
@@ -69357,7 +70874,7 @@ function isOriginalParentProcessAlive(options) {
|
|
|
69357
70874
|
}
|
|
69358
70875
|
function registerUserAttentionWatcher(options) {
|
|
69359
70876
|
return options.store.registerUserAttentionWatcher({
|
|
69360
|
-
id: options.id ?? (0,
|
|
70877
|
+
id: options.id ?? (0, import_node_crypto16.randomUUID)(),
|
|
69361
70878
|
provider: options.provider,
|
|
69362
70879
|
jobId: options.jobId,
|
|
69363
70880
|
nowMs: options.nowMs ?? Date.now(),
|
|
@@ -69436,11 +70953,11 @@ function userWatchEventDeliveredSentryExtra(event) {
|
|
|
69436
70953
|
hasDecision: String(event.hasDecision)
|
|
69437
70954
|
};
|
|
69438
70955
|
}
|
|
69439
|
-
var
|
|
70956
|
+
var import_node_crypto16, USER_ATTENTION_WATCH_REPLACED_MESSAGE, USER_ATTENTION_WATCHER_SCAN_MS, USER_ATTENTION_WATCHER_TTL_MS, USER_ATTENTION_WATCH_PARENT_CHECK_MS;
|
|
69440
70957
|
var init_user_attention_watchers = __esm({
|
|
69441
70958
|
"src/user-attention-watchers.ts"() {
|
|
69442
70959
|
"use strict";
|
|
69443
|
-
|
|
70960
|
+
import_node_crypto16 = require("node:crypto");
|
|
69444
70961
|
init_sentry_logger();
|
|
69445
70962
|
USER_ATTENTION_WATCH_REPLACED_MESSAGE = "Another okx-a2a user watch with the same job scope was started, so this watcher has been closed. Do not run this watch command again automatically, because starting another watcher may interrupt a different session that is already monitoring task progress.";
|
|
69446
70963
|
USER_ATTENTION_WATCHER_SCAN_MS = 500;
|
|
@@ -69513,13 +71030,13 @@ async function getHermesGatewayPluginStatus(options = {}) {
|
|
|
69513
71030
|
const env = options.env ?? process.env;
|
|
69514
71031
|
const hermesHome = env.HERMES_HOME?.trim() || (0, import_node_path32.join)((0, import_node_os10.homedir)(), ".hermes");
|
|
69515
71032
|
const pluginYamlPath = (0, import_node_path32.join)(hermesHome, "plugins", "platforms", "okx-a2a", "plugin.yaml");
|
|
69516
|
-
if (!(0,
|
|
71033
|
+
if (!(0, import_node_fs28.existsSync)(pluginYamlPath)) {
|
|
69517
71034
|
return { enabled: false, reason: "plugin_yaml_missing", hermesHome, checkedPath: pluginYamlPath };
|
|
69518
71035
|
}
|
|
69519
71036
|
const configPath = (0, import_node_path32.join)(hermesHome, "config.yaml");
|
|
69520
71037
|
let content2;
|
|
69521
71038
|
try {
|
|
69522
|
-
content2 = await (0,
|
|
71039
|
+
content2 = await (0, import_promises14.readFile)(configPath, "utf8");
|
|
69523
71040
|
} catch {
|
|
69524
71041
|
return { enabled: false, reason: "config_read_error", hermesHome, checkedPath: configPath };
|
|
69525
71042
|
}
|
|
@@ -69603,12 +71120,12 @@ function parseYamlInlineEnabledList(line) {
|
|
|
69603
71120
|
}
|
|
69604
71121
|
function stopClients(service) {
|
|
69605
71122
|
for (const [address, client] of service.getClients()) {
|
|
69606
|
-
|
|
69607
|
-
|
|
69608
|
-
|
|
69609
|
-
|
|
69610
|
-
logWithTimestamp(`[okx-agent-task] failed to
|
|
69611
|
-
}
|
|
71123
|
+
void stopAndCloseXmtpClient(client, {
|
|
71124
|
+
address,
|
|
71125
|
+
agentId: "",
|
|
71126
|
+
phase: "shutdown",
|
|
71127
|
+
onCloseError: (err2) => logWithTimestamp(`[okx-agent-task] failed to close XMTP client ${address}:`, err2)
|
|
71128
|
+
}).then(() => logWithTimestamp(`[okx-agent-task] stopped XMTP client ${address}`)).catch((err2) => logWithTimestamp(`[okx-agent-task] failed to stop XMTP client ${address}:`, err2));
|
|
69612
71129
|
}
|
|
69613
71130
|
}
|
|
69614
71131
|
async function runListener(options = {}) {
|
|
@@ -69640,6 +71157,27 @@ async function runListenerWithLock(options, paths) {
|
|
|
69640
71157
|
const store = new TaskMessageStore(options.homeDir);
|
|
69641
71158
|
const sessionStore = new SessionStore({ homeDir: options.homeDir });
|
|
69642
71159
|
const commands = new CommandStore(options.homeDir);
|
|
71160
|
+
const devkitReadSnapshot = () => {
|
|
71161
|
+
const snapshotStore = DevkitServerStore.openForRead(options.homeDir);
|
|
71162
|
+
if (!snapshotStore) {
|
|
71163
|
+
return null;
|
|
71164
|
+
}
|
|
71165
|
+
try {
|
|
71166
|
+
return snapshotStore.readSnapshot();
|
|
71167
|
+
} finally {
|
|
71168
|
+
snapshotStore.close();
|
|
71169
|
+
}
|
|
71170
|
+
};
|
|
71171
|
+
const devkitDispatcher = new DevkitDeliveryDispatcher({
|
|
71172
|
+
homeDir: options.homeDir,
|
|
71173
|
+
readSnapshot: devkitReadSnapshot
|
|
71174
|
+
});
|
|
71175
|
+
const devkitRouter = createDevkitAutoRouter({
|
|
71176
|
+
homeDir: options.homeDir,
|
|
71177
|
+
commands,
|
|
71178
|
+
dispatcher: devkitDispatcher,
|
|
71179
|
+
readSnapshot: devkitReadSnapshot
|
|
71180
|
+
});
|
|
69643
71181
|
await store.ensureReady();
|
|
69644
71182
|
let userAttentionEvents = null;
|
|
69645
71183
|
try {
|
|
@@ -69703,20 +71241,20 @@ async function runListenerWithLock(options, paths) {
|
|
|
69703
71241
|
createInboundMiddleware: (deps) => createMiddlewareFromCoreDeps(store, deps, {
|
|
69704
71242
|
sessionStore,
|
|
69705
71243
|
onJobMessageStored: async (event) => {
|
|
69706
|
-
await
|
|
71244
|
+
await devkitRouter.routeJob(event);
|
|
69707
71245
|
},
|
|
69708
71246
|
onSessionMessage: async (event) => {
|
|
69709
|
-
await
|
|
71247
|
+
await devkitRouter.routeSession(event);
|
|
69710
71248
|
}
|
|
69711
71249
|
}),
|
|
69712
71250
|
processOfflineMessage: (ctx, deps, replayOptions) => processOfflineFromCoreDeps(store, ctx, deps, {
|
|
69713
71251
|
...replayOptions,
|
|
69714
71252
|
sessionStore,
|
|
69715
71253
|
onJobMessageStored: async (event) => {
|
|
69716
|
-
await
|
|
71254
|
+
await devkitRouter.routeJob(event);
|
|
69717
71255
|
},
|
|
69718
71256
|
onSessionMessage: async (event) => {
|
|
69719
|
-
await
|
|
71257
|
+
await devkitRouter.routeSession(event);
|
|
69720
71258
|
}
|
|
69721
71259
|
}),
|
|
69722
71260
|
notifySessionExpired: (command) => {
|
|
@@ -69748,12 +71286,12 @@ async function runListenerWithLock(options, paths) {
|
|
|
69748
71286
|
});
|
|
69749
71287
|
}
|
|
69750
71288
|
});
|
|
69751
|
-
service.setPluginVersion("0.2.
|
|
71289
|
+
service.setPluginVersion("0.2.17-beta-ab42219842-261020165552");
|
|
69752
71290
|
await service.init();
|
|
69753
71291
|
const pluginVersionStatus = service.pluginVersionStatus;
|
|
69754
71292
|
if (pluginVersionStatus.unavailable) {
|
|
69755
71293
|
throw new Error(
|
|
69756
|
-
`@okxweb3/a2a-node v${"0.2.
|
|
71294
|
+
`@okxweb3/a2a-node v${"0.2.17-beta-ab42219842-261020165552"} is below the required minimum v${pluginVersionStatus.minVersion}`
|
|
69757
71295
|
);
|
|
69758
71296
|
}
|
|
69759
71297
|
const systemConfig = service.getSystemConfig();
|
|
@@ -69781,7 +71319,7 @@ async function runListenerWithLock(options, paths) {
|
|
|
69781
71319
|
onchainosAgentId: "*",
|
|
69782
71320
|
reason: "system-config missing sentryDsn",
|
|
69783
71321
|
pluginId: "@okxweb3/a2a-node",
|
|
69784
|
-
pluginVersion: "0.2.
|
|
71322
|
+
pluginVersion: "0.2.17-beta-ab42219842-261020165552"
|
|
69785
71323
|
});
|
|
69786
71324
|
}
|
|
69787
71325
|
logWithTimestamp(
|
|
@@ -70113,6 +71651,7 @@ async function runListenerWithLock(options, paths) {
|
|
|
70113
71651
|
logWithTimestamp("[okx-agent-task] failed to close user_attention IPC wake:", err2);
|
|
70114
71652
|
}
|
|
70115
71653
|
stopClients(service);
|
|
71654
|
+
await devkitDispatcher.shutdown(SHUTDOWN_FORCE_RESOLVE_MS);
|
|
70116
71655
|
sessionStore.close();
|
|
70117
71656
|
clearTimeout(forceResolve);
|
|
70118
71657
|
resolve14();
|
|
@@ -70131,13 +71670,14 @@ async function timeSettled(fn) {
|
|
|
70131
71670
|
return { durationMs: Date.now() - startedAt, error };
|
|
70132
71671
|
}
|
|
70133
71672
|
}
|
|
70134
|
-
var
|
|
71673
|
+
var import_node_fs28, import_promises14, import_node_os10, import_node_path32, DEFAULT_OFFLINE_REPLAY_INTERVAL_SEC, DEFAULT_XMTP_CLIENT_RECYCLE_INTERVAL_SEC, XMTP_CLIENT_RECYCLE_INTERVAL_ENV, HEARTBEAT_GATEWAY_CHECK_TIMEOUT_MS, AUTH_RECOVERY_PROBE_INTERVAL_MS, AUTH_RECOVERY_REFRESH_BACKOFF_MS, AgentRefreshAuthGate, AgentRefreshCoordinator, ListenerDeferredTaskScheduler, ListenerMaintenanceGate, UPGRADE_RECOMMENDATION_IDEMPOTENCY_KEY, SHUTDOWN_FORCE_RESOLVE_MS;
|
|
70135
71674
|
var init_listener = __esm({
|
|
70136
71675
|
"src/listener.ts"() {
|
|
70137
71676
|
"use strict";
|
|
70138
71677
|
init_log();
|
|
70139
|
-
|
|
70140
|
-
|
|
71678
|
+
init_client_lifecycle();
|
|
71679
|
+
import_node_fs28 = require("node:fs");
|
|
71680
|
+
import_promises14 = require("node:fs/promises");
|
|
70141
71681
|
import_node_os10 = require("node:os");
|
|
70142
71682
|
import_node_path32 = require("node:path");
|
|
70143
71683
|
init_onchainos();
|
|
@@ -70150,7 +71690,9 @@ var init_listener = __esm({
|
|
|
70150
71690
|
init_session_store();
|
|
70151
71691
|
init_command_processor();
|
|
70152
71692
|
init_command_store();
|
|
70153
|
-
|
|
71693
|
+
init_devkit_delivery();
|
|
71694
|
+
init_devkit_router();
|
|
71695
|
+
init_devkit_server_store();
|
|
70154
71696
|
init_message_handler();
|
|
70155
71697
|
init_agent_message_notice();
|
|
70156
71698
|
init_paths();
|
|
@@ -70403,7 +71945,7 @@ async function startXmtpTest(args, releaseInfo) {
|
|
|
70403
71945
|
const runId = requestedRunId ? validateRunId(requestedRunId) : createRunId(requestedName);
|
|
70404
71946
|
const files = resolveRunFiles(testsDir, runId);
|
|
70405
71947
|
try {
|
|
70406
|
-
await (0,
|
|
71948
|
+
await (0, import_promises15.stat)(files.runDir);
|
|
70407
71949
|
throw new Error(`XMTP test run already exists: ${runId}`);
|
|
70408
71950
|
} catch (error) {
|
|
70409
71951
|
if (error.code !== "ENOENT") {
|
|
@@ -70411,7 +71953,7 @@ async function startXmtpTest(args, releaseInfo) {
|
|
|
70411
71953
|
}
|
|
70412
71954
|
}
|
|
70413
71955
|
await ensurePrivateDir(files.runDir);
|
|
70414
|
-
await (0,
|
|
71956
|
+
await (0, import_promises15.writeFile)(files.eventsPath, "", { encoding: "utf8", mode: 384 });
|
|
70415
71957
|
const manifest = {
|
|
70416
71958
|
runId,
|
|
70417
71959
|
name: requestedName,
|
|
@@ -70455,7 +71997,7 @@ async function stopXmtpTest(args) {
|
|
|
70455
71997
|
}
|
|
70456
71998
|
const runId = validateRunId(active.runId);
|
|
70457
71999
|
const files = resolveRunFiles(testsDir, runId);
|
|
70458
|
-
await (0,
|
|
72000
|
+
await (0, import_promises15.unlink)(activePath);
|
|
70459
72001
|
const manifest = await readRequiredJson(files.manifestPath);
|
|
70460
72002
|
const completed = {
|
|
70461
72003
|
...manifest,
|
|
@@ -70773,7 +72315,7 @@ async function resolveRequestedRunId(testsDir, args, preferActive = false) {
|
|
|
70773
72315
|
async function findLatestRunId(testsDir) {
|
|
70774
72316
|
let entries;
|
|
70775
72317
|
try {
|
|
70776
|
-
entries = await (0,
|
|
72318
|
+
entries = await (0, import_promises15.readdir)(testsDir, { withFileTypes: true });
|
|
70777
72319
|
} catch (error) {
|
|
70778
72320
|
if (error.code === "ENOENT") {
|
|
70779
72321
|
return null;
|
|
@@ -70798,7 +72340,7 @@ async function findLatestRunId(testsDir) {
|
|
|
70798
72340
|
async function readMetricEvents(path2) {
|
|
70799
72341
|
let text;
|
|
70800
72342
|
try {
|
|
70801
|
-
text = await (0,
|
|
72343
|
+
text = await (0, import_promises15.readFile)(path2, "utf8");
|
|
70802
72344
|
} catch (error) {
|
|
70803
72345
|
if (error.code === "ENOENT") {
|
|
70804
72346
|
return [];
|
|
@@ -70822,9 +72364,9 @@ function parseMetricEvent(line) {
|
|
|
70822
72364
|
}
|
|
70823
72365
|
}
|
|
70824
72366
|
async function ensurePrivateDir(path2) {
|
|
70825
|
-
await (0,
|
|
72367
|
+
await (0, import_promises15.mkdir)(path2, { recursive: true, mode: 448 });
|
|
70826
72368
|
try {
|
|
70827
|
-
await (0,
|
|
72369
|
+
await (0, import_promises15.chmod)(path2, 448);
|
|
70828
72370
|
} catch (error) {
|
|
70829
72371
|
const code = error.code;
|
|
70830
72372
|
if (code !== "EPERM" && code !== "EACCES") {
|
|
@@ -70834,12 +72376,12 @@ async function ensurePrivateDir(path2) {
|
|
|
70834
72376
|
}
|
|
70835
72377
|
async function writeJson(path2, value) {
|
|
70836
72378
|
const temporary = `${path2}.${process.pid}.tmp`;
|
|
70837
|
-
await (0,
|
|
72379
|
+
await (0, import_promises15.writeFile)(temporary, `${JSON.stringify(value, null, 2)}
|
|
70838
72380
|
`, {
|
|
70839
72381
|
encoding: "utf8",
|
|
70840
72382
|
mode: 384
|
|
70841
72383
|
});
|
|
70842
|
-
await (0,
|
|
72384
|
+
await (0, import_promises15.rename)(temporary, path2);
|
|
70843
72385
|
}
|
|
70844
72386
|
async function readRequiredJson(path2) {
|
|
70845
72387
|
const value = await readJsonIfExists(path2);
|
|
@@ -70850,7 +72392,7 @@ async function readRequiredJson(path2) {
|
|
|
70850
72392
|
}
|
|
70851
72393
|
async function readJsonIfExists(path2) {
|
|
70852
72394
|
try {
|
|
70853
|
-
return JSON.parse(await (0,
|
|
72395
|
+
return JSON.parse(await (0, import_promises15.readFile)(path2, "utf8"));
|
|
70854
72396
|
} catch (error) {
|
|
70855
72397
|
if (error.code === "ENOENT") {
|
|
70856
72398
|
return null;
|
|
@@ -71021,11 +72563,11 @@ function formatPercent(value) {
|
|
|
71021
72563
|
function validTimestamp(value) {
|
|
71022
72564
|
return typeof value === "string" && Number.isFinite(Date.parse(value));
|
|
71023
72565
|
}
|
|
71024
|
-
var
|
|
72566
|
+
var import_promises15, import_node_path33, RUN_ID_PATTERN2, ACTIVE_FILE;
|
|
71025
72567
|
var init_xmtp_test_cli = __esm({
|
|
71026
72568
|
"src/xmtp-test-cli.ts"() {
|
|
71027
72569
|
"use strict";
|
|
71028
|
-
|
|
72570
|
+
import_promises15 = require("node:fs/promises");
|
|
71029
72571
|
import_node_path33 = require("node:path");
|
|
71030
72572
|
init_daemon();
|
|
71031
72573
|
init_log_tail();
|
|
@@ -114004,10 +115546,10 @@ var require_node4 = __commonJS({
|
|
|
114004
115546
|
|
|
114005
115547
|
// ../../node_modules/@xmtp/content-type-remote-attachment/dist/index.js
|
|
114006
115548
|
async function encrypt(plain, secret, additionalData) {
|
|
114007
|
-
const salt =
|
|
114008
|
-
const nonce =
|
|
115549
|
+
const salt = import_node_crypto17.webcrypto.getRandomValues(new Uint8Array(KDFSaltSize));
|
|
115550
|
+
const nonce = import_node_crypto17.webcrypto.getRandomValues(new Uint8Array(AESGCMNonceSize));
|
|
114009
115551
|
const key = await hkdf(secret, salt);
|
|
114010
|
-
const encrypted = await
|
|
115552
|
+
const encrypted = await import_node_crypto17.webcrypto.subtle.encrypt(aesGcmParams(nonce), key, plain);
|
|
114011
115553
|
return new Ciphertext({
|
|
114012
115554
|
aes256GcmHkdfSha256: {
|
|
114013
115555
|
payload: new Uint8Array(encrypted),
|
|
@@ -114021,7 +115563,7 @@ async function decrypt(encrypted, secret, additionalData) {
|
|
|
114021
115563
|
throw new Error("invalid payload ciphertext");
|
|
114022
115564
|
}
|
|
114023
115565
|
const key = await hkdf(secret, encrypted.aes256GcmHkdfSha256.hkdfSalt);
|
|
114024
|
-
const decrypted = await
|
|
115566
|
+
const decrypted = await import_node_crypto17.webcrypto.subtle.decrypt(aesGcmParams(encrypted.aes256GcmHkdfSha256.gcmNonce), key, encrypted.aes256GcmHkdfSha256.payload);
|
|
114025
115567
|
return new Uint8Array(decrypted);
|
|
114026
115568
|
}
|
|
114027
115569
|
function aesGcmParams(nonce, additionalData) {
|
|
@@ -114032,18 +115574,18 @@ function aesGcmParams(nonce, additionalData) {
|
|
|
114032
115574
|
return spec;
|
|
114033
115575
|
}
|
|
114034
115576
|
async function hkdf(secret, salt) {
|
|
114035
|
-
const key = await
|
|
115577
|
+
const key = await import_node_crypto17.webcrypto.subtle.importKey("raw", secret, "HKDF", false, [
|
|
114036
115578
|
"deriveKey"
|
|
114037
115579
|
]);
|
|
114038
|
-
return
|
|
115580
|
+
return import_node_crypto17.webcrypto.subtle.deriveKey({ name: "HKDF", hash: "SHA-256", salt, info: hkdfNoInfo }, key, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
|
|
114039
115581
|
}
|
|
114040
|
-
var import_proto,
|
|
115582
|
+
var import_proto, import_node_crypto17, ContentTypeAttachment, AttachmentCodec, KDFSaltSize, AESGCMNonceSize, AESGCMTagLength, Ciphertext, hkdfNoInfo, ContentTypeRemoteAttachment, RemoteAttachmentCodec;
|
|
114041
115583
|
var init_dist6 = __esm({
|
|
114042
115584
|
"../../node_modules/@xmtp/content-type-remote-attachment/dist/index.js"() {
|
|
114043
115585
|
init_dist5();
|
|
114044
115586
|
init_secp256k12();
|
|
114045
115587
|
import_proto = __toESM(require_node4(), 1);
|
|
114046
|
-
|
|
115588
|
+
import_node_crypto17 = require("node:crypto");
|
|
114047
115589
|
ContentTypeAttachment = new ContentTypeId({
|
|
114048
115590
|
authorityId: "xmtp.org",
|
|
114049
115591
|
typeId: "attachment",
|
|
@@ -114123,7 +115665,7 @@ var init_dist6 = __esm({
|
|
|
114123
115665
|
if (payload.length === 0) {
|
|
114124
115666
|
throw new Error(`no payload for remote attachment at ${remoteAttachment.url}`);
|
|
114125
115667
|
}
|
|
114126
|
-
const digestBytes = new Uint8Array(await
|
|
115668
|
+
const digestBytes = new Uint8Array(await import_node_crypto17.webcrypto.subtle.digest("SHA-256", payload));
|
|
114127
115669
|
const digest = etc.bytesToHex(digestBytes);
|
|
114128
115670
|
if (digest !== remoteAttachment.contentDigest) {
|
|
114129
115671
|
throw new Error("content digest does not match");
|
|
@@ -114147,7 +115689,7 @@ var init_dist6 = __esm({
|
|
|
114147
115689
|
return codec.decode(encodedContent, codecRegistry);
|
|
114148
115690
|
}
|
|
114149
115691
|
static async encodeEncrypted(content$1, codec) {
|
|
114150
|
-
const secret =
|
|
115692
|
+
const secret = import_node_crypto17.webcrypto.getRandomValues(new Uint8Array(32));
|
|
114151
115693
|
const encodedContent = import_proto.content.EncodedContent.encode(codec.encode(content$1, {
|
|
114152
115694
|
codecFor() {
|
|
114153
115695
|
return void 0;
|
|
@@ -114160,7 +115702,7 @@ var init_dist6 = __esm({
|
|
|
114160
115702
|
if (!salt || !nonce || !payload) {
|
|
114161
115703
|
throw new Error("missing encryption key");
|
|
114162
115704
|
}
|
|
114163
|
-
const digestBytes = new Uint8Array(await
|
|
115705
|
+
const digestBytes = new Uint8Array(await import_node_crypto17.webcrypto.subtle.digest("SHA-256", payload));
|
|
114164
115706
|
const digest = etc.bytesToHex(digestBytes);
|
|
114165
115707
|
return {
|
|
114166
115708
|
digest,
|
|
@@ -114216,7 +115758,7 @@ var init_dist6 = __esm({
|
|
|
114216
115758
|
// ../core/src/file-upload-safety.ts
|
|
114217
115759
|
function getUnsafeFileUploadReason(filePath, sensitiveUploadReg = []) {
|
|
114218
115760
|
const expanded = (0, import_node_path34.resolve)(expandHome(filePath));
|
|
114219
|
-
const target = (0,
|
|
115761
|
+
const target = (0, import_node_fs29.realpathSync)(expanded);
|
|
114220
115762
|
const targetName = (0, import_node_path34.basename)(target);
|
|
114221
115763
|
if (targetName === ".env" || targetName.startsWith(".env.")) {
|
|
114222
115764
|
return ".env";
|
|
@@ -114270,19 +115812,19 @@ function expandHome(filePath) {
|
|
|
114270
115812
|
return filePath;
|
|
114271
115813
|
}
|
|
114272
115814
|
function safeRealpath(path2) {
|
|
114273
|
-
if (!(0,
|
|
115815
|
+
if (!(0, import_node_fs29.existsSync)(path2)) {
|
|
114274
115816
|
return null;
|
|
114275
115817
|
}
|
|
114276
|
-
return (0,
|
|
115818
|
+
return (0, import_node_fs29.realpathSync)(path2);
|
|
114277
115819
|
}
|
|
114278
115820
|
function isPathInside(target, dir) {
|
|
114279
115821
|
return target === dir || target.startsWith(`${dir}${import_node_path34.sep}`);
|
|
114280
115822
|
}
|
|
114281
|
-
var
|
|
115823
|
+
var import_node_fs29, import_node_os11, import_node_path34, SENSITIVE_HOME_DIRS, SENSITIVE_HOME_FILES, UNSAFE_FILE_UPLOAD_MESSAGE;
|
|
114282
115824
|
var init_file_upload_safety = __esm({
|
|
114283
115825
|
"../core/src/file-upload-safety.ts"() {
|
|
114284
115826
|
"use strict";
|
|
114285
|
-
|
|
115827
|
+
import_node_fs29 = require("node:fs");
|
|
114286
115828
|
import_node_os11 = require("node:os");
|
|
114287
115829
|
import_node_path34 = require("node:path");
|
|
114288
115830
|
SENSITIVE_HOME_DIRS = [
|
|
@@ -114370,16 +115912,16 @@ async function uploadFile(params) {
|
|
|
114370
115912
|
return;
|
|
114371
115913
|
}
|
|
114372
115914
|
const maxFileSizeBytes = uploadConfig.maxFileSizeBytes;
|
|
114373
|
-
const fileSize = (0,
|
|
115915
|
+
const fileSize = (0, import_node_fs30.statSync)(params.filePath).size;
|
|
114374
115916
|
if (fileSize > maxFileSizeBytes) {
|
|
114375
115917
|
throw new Error(formatFileTooLargeMessage(maxFileSizeBytes));
|
|
114376
115918
|
}
|
|
114377
|
-
const data = (0,
|
|
115919
|
+
const data = (0, import_node_fs30.readFileSync)(params.filePath);
|
|
114378
115920
|
const attachment = { filename, mimeType, data: new Uint8Array(data) };
|
|
114379
115921
|
const encrypted = await RemoteAttachmentCodec.encodeEncrypted(attachment, new AttachmentCodec());
|
|
114380
115922
|
ensureFileDirs();
|
|
114381
|
-
const encryptedPath = (0, import_node_path35.resolve)(FILE_WORK_DIR, `${(0,
|
|
114382
|
-
(0,
|
|
115923
|
+
const encryptedPath = (0, import_node_path35.resolve)(FILE_WORK_DIR, `${(0, import_node_crypto18.randomUUID)()}.enc`);
|
|
115924
|
+
(0, import_node_fs30.writeFileSync)(encryptedPath, encrypted.payload);
|
|
114383
115925
|
try {
|
|
114384
115926
|
const stdout = runOnchainos([
|
|
114385
115927
|
"agent",
|
|
@@ -114415,14 +115957,14 @@ async function uploadFile(params) {
|
|
|
114415
115957
|
}, null, 2));
|
|
114416
115958
|
} finally {
|
|
114417
115959
|
try {
|
|
114418
|
-
(0,
|
|
115960
|
+
(0, import_node_fs30.unlinkSync)(encryptedPath);
|
|
114419
115961
|
} catch {
|
|
114420
115962
|
}
|
|
114421
115963
|
}
|
|
114422
115964
|
}
|
|
114423
115965
|
async function downloadFile(params) {
|
|
114424
115966
|
ensureFileDirs();
|
|
114425
|
-
const encryptedPath = (0, import_node_path35.resolve)(FILE_WORK_DIR, `${(0,
|
|
115967
|
+
const encryptedPath = (0, import_node_path35.resolve)(FILE_WORK_DIR, `${(0, import_node_crypto18.randomUUID)()}.enc`);
|
|
114426
115968
|
try {
|
|
114427
115969
|
const stdout = runOnchainos([
|
|
114428
115970
|
"agent",
|
|
@@ -114446,8 +115988,8 @@ async function downloadFile(params) {
|
|
|
114446
115988
|
}));
|
|
114447
115989
|
throw new Error(`file download failed: ${stdout}`);
|
|
114448
115990
|
}
|
|
114449
|
-
const payload = new Uint8Array((0,
|
|
114450
|
-
const digestBytes = new Uint8Array(await
|
|
115991
|
+
const payload = new Uint8Array((0, import_node_fs30.readFileSync)(encryptedPath));
|
|
115992
|
+
const digestBytes = new Uint8Array(await import_node_crypto18.webcrypto.subtle.digest("SHA-256", payload));
|
|
114451
115993
|
const actualDigest = Array.from(digestBytes).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
114452
115994
|
if (actualDigest !== params.digest) {
|
|
114453
115995
|
throw new Error(`file download digest verification failed: expected=${params.digest}, actual=${actualDigest}`);
|
|
@@ -114455,15 +115997,15 @@ async function downloadFile(params) {
|
|
|
114455
115997
|
const decryptedBytes = await decryptAttachmentPayload(payload, params);
|
|
114456
115998
|
const encodedContent = import_proto2.content.EncodedContent.decode(decryptedBytes);
|
|
114457
115999
|
const attachment = new AttachmentCodec().decode(encodedContent);
|
|
114458
|
-
const outputFilename = params.filename || attachment.filename || `${(0,
|
|
116000
|
+
const outputFilename = params.filename || attachment.filename || `${(0, import_node_crypto18.randomUUID)()}.bin`;
|
|
114459
116001
|
const outputDir = DOWNLOADS_DIR;
|
|
114460
116002
|
ensureA2aTaskDir(outputDir);
|
|
114461
116003
|
const outputPath = (0, import_node_path35.resolve)(outputDir, (0, import_node_path35.basename)(outputFilename));
|
|
114462
|
-
(0,
|
|
116004
|
+
(0, import_node_fs30.writeFileSync)(outputPath, attachment.data);
|
|
114463
116005
|
console.log(outputPath);
|
|
114464
116006
|
} finally {
|
|
114465
116007
|
try {
|
|
114466
|
-
(0,
|
|
116008
|
+
(0, import_node_fs30.unlinkSync)(encryptedPath);
|
|
114467
116009
|
} catch {
|
|
114468
116010
|
}
|
|
114469
116011
|
}
|
|
@@ -114472,15 +116014,15 @@ async function decryptAttachmentPayload(payload, params) {
|
|
|
114472
116014
|
const secretBytes = new Uint8Array(Buffer.from(params.secret, "base64"));
|
|
114473
116015
|
const saltBytes = new Uint8Array(Buffer.from(params.salt, "base64"));
|
|
114474
116016
|
const nonceBytes = new Uint8Array(Buffer.from(params.nonce, "base64"));
|
|
114475
|
-
const hkdfKey = await
|
|
114476
|
-
const aesKey = await
|
|
116017
|
+
const hkdfKey = await import_node_crypto18.webcrypto.subtle.importKey("raw", secretBytes, "HKDF", false, ["deriveKey"]);
|
|
116018
|
+
const aesKey = await import_node_crypto18.webcrypto.subtle.deriveKey(
|
|
114477
116019
|
{ name: "HKDF", hash: "SHA-256", salt: saltBytes, info: new Uint8Array().buffer },
|
|
114478
116020
|
hkdfKey,
|
|
114479
116021
|
{ name: "AES-GCM", length: 256 },
|
|
114480
116022
|
false,
|
|
114481
116023
|
["decrypt"]
|
|
114482
116024
|
);
|
|
114483
|
-
return new Uint8Array(await
|
|
116025
|
+
return new Uint8Array(await import_node_crypto18.webcrypto.subtle.decrypt({ name: "AES-GCM", iv: nonceBytes }, aesKey, toArrayBuffer(payload)));
|
|
114484
116026
|
}
|
|
114485
116027
|
function toArrayBuffer(bytes) {
|
|
114486
116028
|
return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
@@ -114560,7 +116102,7 @@ function readUploadSystemConfig() {
|
|
|
114560
116102
|
const res = parseCliJson2(stdout, "system-config");
|
|
114561
116103
|
if (res.data && typeof res.data === "object") {
|
|
114562
116104
|
ensureA2aTaskDir(OKX_A2A_PATHS.xmtpDir);
|
|
114563
|
-
(0,
|
|
116105
|
+
(0, import_node_fs30.writeFileSync)(SYSTEM_CONFIG_PATH, JSON.stringify(res.data));
|
|
114564
116106
|
}
|
|
114565
116107
|
return parseUploadSystemConfig(res.data ?? {});
|
|
114566
116108
|
} catch {
|
|
@@ -114583,10 +116125,10 @@ function fileCliSentryExtra(operation, reason, extra = {}) {
|
|
|
114583
116125
|
}
|
|
114584
116126
|
function readSystemConfigFromCache() {
|
|
114585
116127
|
try {
|
|
114586
|
-
if (!(0,
|
|
116128
|
+
if (!(0, import_node_fs30.existsSync)(SYSTEM_CONFIG_PATH)) {
|
|
114587
116129
|
return null;
|
|
114588
116130
|
}
|
|
114589
|
-
return JSON.parse((0,
|
|
116131
|
+
return JSON.parse((0, import_node_fs30.readFileSync)(SYSTEM_CONFIG_PATH, "utf8"));
|
|
114590
116132
|
} catch {
|
|
114591
116133
|
return null;
|
|
114592
116134
|
}
|
|
@@ -114620,13 +116162,13 @@ function readRequiredOption(args, name) {
|
|
|
114620
116162
|
}
|
|
114621
116163
|
return value;
|
|
114622
116164
|
}
|
|
114623
|
-
var
|
|
116165
|
+
var import_node_crypto18, import_node_fs30, import_node_path35, import_proto2, OKX_A2A_PATHS, OKX_A2A_HOME_DIR, FILE_WORK_DIR, DOWNLOADS_DIR, SYSTEM_CONFIG_PATH;
|
|
114624
116166
|
var init_file_cli = __esm({
|
|
114625
116167
|
"src/file-cli.ts"() {
|
|
114626
116168
|
"use strict";
|
|
114627
116169
|
init_win_spawn();
|
|
114628
|
-
|
|
114629
|
-
|
|
116170
|
+
import_node_crypto18 = require("node:crypto");
|
|
116171
|
+
import_node_fs30 = require("node:fs");
|
|
114630
116172
|
import_node_path35 = require("node:path");
|
|
114631
116173
|
init_dist6();
|
|
114632
116174
|
import_proto2 = __toESM(require_node4());
|
|
@@ -114649,12 +116191,12 @@ __export(user_attention_cli_exports, {
|
|
|
114649
116191
|
});
|
|
114650
116192
|
async function handleUserCommand(args) {
|
|
114651
116193
|
const subcommand = args[0];
|
|
114652
|
-
if (!subcommand || args.every(
|
|
116194
|
+
if (!subcommand || args.every(isHelpArg3)) {
|
|
114653
116195
|
printUserUsage();
|
|
114654
116196
|
return;
|
|
114655
116197
|
}
|
|
114656
116198
|
if (subcommand === "help") {
|
|
114657
|
-
const helpTarget = args.slice(1).find((arg) => !
|
|
116199
|
+
const helpTarget = args.slice(1).find((arg) => !isHelpArg3(arg));
|
|
114658
116200
|
if (!helpTarget) {
|
|
114659
116201
|
printUserUsage();
|
|
114660
116202
|
return;
|
|
@@ -114671,7 +116213,7 @@ async function handleUserCommand(args) {
|
|
|
114671
116213
|
return;
|
|
114672
116214
|
}
|
|
114673
116215
|
const commandStartedAt = Date.now();
|
|
114674
|
-
const parsed =
|
|
116216
|
+
const parsed = parseArgs3(args.slice(1));
|
|
114675
116217
|
const json = parsed.flags.has("json");
|
|
114676
116218
|
const storeInitStartedAt = Date.now();
|
|
114677
116219
|
const store = new SessionStore();
|
|
@@ -114788,7 +116330,7 @@ async function handleUserCommand(args) {
|
|
|
114788
116330
|
function hasHelpFlag2(args) {
|
|
114789
116331
|
return args.some((arg) => arg === "-h" || arg === "--help");
|
|
114790
116332
|
}
|
|
114791
|
-
function
|
|
116333
|
+
function isHelpArg3(arg) {
|
|
114792
116334
|
return arg === "-h" || arg === "--help" || arg === "help";
|
|
114793
116335
|
}
|
|
114794
116336
|
function printUserUsage() {
|
|
@@ -115120,7 +116662,7 @@ async function watchUserAttentionViaDaemon(store, parsed, json, options) {
|
|
|
115120
116662
|
nextHeartbeatAt = Date.now() + Math.min(1e3, Math.max(100, pollMs));
|
|
115121
116663
|
}
|
|
115122
116664
|
const waitMs = deadline ? Math.max(0, Math.min(pollMs, USER_ATTENTION_WATCH_PARENT_CHECK_MS, deadline - Date.now())) : Math.min(pollMs, USER_ATTENTION_WATCH_PARENT_CHECK_MS);
|
|
115123
|
-
await
|
|
116665
|
+
await sleep5(waitMs);
|
|
115124
116666
|
}
|
|
115125
116667
|
} finally {
|
|
115126
116668
|
watcherCleanup.cleanup();
|
|
@@ -115140,7 +116682,7 @@ async function registerWatcherWithBusyRetry(options) {
|
|
|
115140
116682
|
if (!isSqliteBusyError(err2) || attempt >= attempts) {
|
|
115141
116683
|
throw err2;
|
|
115142
116684
|
}
|
|
115143
|
-
await
|
|
116685
|
+
await sleep5(250 * attempt);
|
|
115144
116686
|
}
|
|
115145
116687
|
}
|
|
115146
116688
|
}
|
|
@@ -115266,7 +116808,7 @@ function createWakeSignal() {
|
|
|
115266
116808
|
}
|
|
115267
116809
|
};
|
|
115268
116810
|
}
|
|
115269
|
-
function
|
|
116811
|
+
function sleep5(ms) {
|
|
115270
116812
|
return new Promise((resolve14) => setTimeout(resolve14, ms));
|
|
115271
116813
|
}
|
|
115272
116814
|
function output(json, payload, human) {
|
|
@@ -115307,7 +116849,7 @@ function runSyncWithoutConsoleOutput(fn) {
|
|
|
115307
116849
|
console.error = originalError;
|
|
115308
116850
|
}
|
|
115309
116851
|
}
|
|
115310
|
-
function
|
|
116852
|
+
function parseArgs3(args) {
|
|
115311
116853
|
const positional = [];
|
|
115312
116854
|
const options = /* @__PURE__ */ new Map();
|
|
115313
116855
|
const flags = /* @__PURE__ */ new Set();
|
|
@@ -115761,12 +117303,12 @@ __export(session_cli_exports, {
|
|
|
115761
117303
|
});
|
|
115762
117304
|
async function handleSessionCommand(args) {
|
|
115763
117305
|
const subcommand = args[0];
|
|
115764
|
-
if (!subcommand || args.every(
|
|
117306
|
+
if (!subcommand || args.every(isHelpArg4)) {
|
|
115765
117307
|
printSessionUsage();
|
|
115766
117308
|
return;
|
|
115767
117309
|
}
|
|
115768
117310
|
if (subcommand === "help") {
|
|
115769
|
-
const helpTarget = args.slice(1).find((arg) => !
|
|
117311
|
+
const helpTarget = args.slice(1).find((arg) => !isHelpArg4(arg));
|
|
115770
117312
|
if (!helpTarget) {
|
|
115771
117313
|
printSessionUsage();
|
|
115772
117314
|
return;
|
|
@@ -115782,7 +117324,7 @@ async function handleSessionCommand(args) {
|
|
|
115782
117324
|
}
|
|
115783
117325
|
return;
|
|
115784
117326
|
}
|
|
115785
|
-
const parsed =
|
|
117327
|
+
const parsed = parseArgs4(args.slice(1));
|
|
115786
117328
|
const json = parsed.flags.has("json");
|
|
115787
117329
|
const store = new SessionStore();
|
|
115788
117330
|
let usedOpenClawGateway = false;
|
|
@@ -115948,9 +117490,9 @@ async function handleSessionCommand(args) {
|
|
|
115948
117490
|
}
|
|
115949
117491
|
}
|
|
115950
117492
|
function hasHelpFlag3(args) {
|
|
115951
|
-
return args.some(
|
|
117493
|
+
return args.some(isHelpArg4);
|
|
115952
117494
|
}
|
|
115953
|
-
function
|
|
117495
|
+
function isHelpArg4(arg) {
|
|
115954
117496
|
return arg === "-h" || arg === "--help" || arg === "help";
|
|
115955
117497
|
}
|
|
115956
117498
|
function printSessionUsage() {
|
|
@@ -116756,7 +118298,7 @@ function normalizeOptionalText4(value) {
|
|
|
116756
118298
|
const normalized = value?.trim();
|
|
116757
118299
|
return normalized ? normalized : null;
|
|
116758
118300
|
}
|
|
116759
|
-
function
|
|
118301
|
+
function parseArgs4(args) {
|
|
116760
118302
|
const positional = [];
|
|
116761
118303
|
const options = /* @__PURE__ */ new Map();
|
|
116762
118304
|
const flags = /* @__PURE__ */ new Set();
|
|
@@ -116839,7 +118381,7 @@ async function handleXmtpDebugCli(args) {
|
|
|
116839
118381
|
throw new Error(`Unknown xmtp-debug command: ${subcommand}`);
|
|
116840
118382
|
}
|
|
116841
118383
|
const action = subcommand;
|
|
116842
|
-
const parsed =
|
|
118384
|
+
const parsed = parseArgs5(args.slice(1));
|
|
116843
118385
|
rejectAccountOverride(parsed);
|
|
116844
118386
|
const groupId = parsed.options.get("group-id");
|
|
116845
118387
|
const jobId = parsed.options.get("job-id");
|
|
@@ -116933,7 +118475,7 @@ Options:
|
|
|
116933
118475
|
--json Print machine-readable JSON.
|
|
116934
118476
|
`);
|
|
116935
118477
|
}
|
|
116936
|
-
function
|
|
118478
|
+
function parseArgs5(args) {
|
|
116937
118479
|
const options = /* @__PURE__ */ new Map();
|
|
116938
118480
|
const flags = /* @__PURE__ */ new Set();
|
|
116939
118481
|
for (let index2 = 0; index2 < args.length; index2 += 1) {
|
|
@@ -117021,7 +118563,7 @@ async function handleAiCommand(args) {
|
|
|
117021
118563
|
return;
|
|
117022
118564
|
}
|
|
117023
118565
|
const subcommand = args[0] ?? "status";
|
|
117024
|
-
const parsed =
|
|
118566
|
+
const parsed = parseArgs6(args.slice(1));
|
|
117025
118567
|
const json = parsed.flags.has("json");
|
|
117026
118568
|
const store = new SessionStore();
|
|
117027
118569
|
try {
|
|
@@ -117145,7 +118687,7 @@ function output4(json, payload, human) {
|
|
|
117145
118687
|
}
|
|
117146
118688
|
console.log(human);
|
|
117147
118689
|
}
|
|
117148
|
-
function
|
|
118690
|
+
function parseArgs6(args) {
|
|
117149
118691
|
const positional = [];
|
|
117150
118692
|
const options = /* @__PURE__ */ new Map();
|
|
117151
118693
|
const flags = /* @__PURE__ */ new Set();
|
|
@@ -117201,7 +118743,7 @@ function isPostjectRunnable() {
|
|
|
117201
118743
|
function resolvePostjectCommand() {
|
|
117202
118744
|
try {
|
|
117203
118745
|
const cliPath = (0, import_node_module.createRequire)(__filename).resolve("postject/dist/cli.js");
|
|
117204
|
-
if ((0,
|
|
118746
|
+
if ((0, import_node_fs31.existsSync)(cliPath)) {
|
|
117205
118747
|
return { command: process.execPath, prefixArgs: [cliPath] };
|
|
117206
118748
|
}
|
|
117207
118749
|
} catch {
|
|
@@ -117272,26 +118814,26 @@ function buildSeaConfig(entryPath, blobPath) {
|
|
|
117272
118814
|
}
|
|
117273
118815
|
async function installWindowsNativeLauncher(options) {
|
|
117274
118816
|
const nodeExe = options.nodeExe ?? process.execPath;
|
|
117275
|
-
if (!(0,
|
|
118817
|
+
if (!(0, import_node_fs31.existsSync)(options.cliPath)) {
|
|
117276
118818
|
throw new Error(`cannot build okx-a2a.exe: CLI entry not found at ${options.cliPath}`);
|
|
117277
118819
|
}
|
|
117278
|
-
if (!(0,
|
|
118820
|
+
if (!(0, import_node_fs31.existsSync)(nodeExe)) {
|
|
117279
118821
|
throw new Error(`cannot build okx-a2a.exe: node executable not found at ${nodeExe}`);
|
|
117280
118822
|
}
|
|
117281
118823
|
const exePath = (0, import_node_path36.join)(options.targetDir, NATIVE_LAUNCHER_EXE_NAME);
|
|
117282
|
-
(0,
|
|
117283
|
-
const work = (0,
|
|
118824
|
+
(0, import_node_fs31.mkdirSync)(options.targetDir, { recursive: true });
|
|
118825
|
+
const work = (0, import_node_fs31.mkdtempSync)((0, import_node_path36.join)((0, import_node_os12.tmpdir)(), "okx-a2a-sea-"));
|
|
117284
118826
|
try {
|
|
117285
118827
|
const entryPath = (0, import_node_path36.join)(work, "launcher-entry.js");
|
|
117286
118828
|
const blobPath = (0, import_node_path36.join)(work, "okx-a2a.blob");
|
|
117287
118829
|
const configPath = (0, import_node_path36.join)(work, "sea-config.json");
|
|
117288
|
-
(0,
|
|
117289
|
-
(0,
|
|
118830
|
+
(0, import_node_fs31.writeFileSync)(entryPath, buildLauncherEntryJs(options.cliPath), "utf8");
|
|
118831
|
+
(0, import_node_fs31.writeFileSync)(configPath, buildSeaConfig(entryPath, blobPath), "utf8");
|
|
117290
118832
|
(0, import_node_child_process9.execFileSync)(nodeExe, ["--experimental-sea-config", configPath], {
|
|
117291
118833
|
stdio: "ignore",
|
|
117292
118834
|
windowsHide: true
|
|
117293
118835
|
});
|
|
117294
|
-
(0,
|
|
118836
|
+
(0, import_node_fs31.copyFileSync)(nodeExe, exePath);
|
|
117295
118837
|
const isMac = process.platform === "darwin";
|
|
117296
118838
|
if (isMac) {
|
|
117297
118839
|
try {
|
|
@@ -117311,10 +118853,10 @@ async function installWindowsNativeLauncher(options) {
|
|
|
117311
118853
|
);
|
|
117312
118854
|
return { exePath, cliPath: options.cliPath, nodeExe };
|
|
117313
118855
|
} finally {
|
|
117314
|
-
(0,
|
|
118856
|
+
(0, import_node_fs31.rmSync)(work, { recursive: true, force: true });
|
|
117315
118857
|
}
|
|
117316
118858
|
}
|
|
117317
|
-
function findWindowsNativeOkxA2aExe(pathValue, appData, userProfile, fileExists2 =
|
|
118859
|
+
function findWindowsNativeOkxA2aExe(pathValue, appData, userProfile, fileExists2 = import_node_fs31.existsSync) {
|
|
117318
118860
|
const dirs = pathValue.split(";").map((d) => d.trim()).filter(Boolean);
|
|
117319
118861
|
if (appData) {
|
|
117320
118862
|
dirs.push((0, import_node_path36.join)(appData, "npm"));
|
|
@@ -117332,11 +118874,11 @@ function findWindowsNativeOkxA2aExe(pathValue, appData, userProfile, fileExists2
|
|
|
117332
118874
|
}
|
|
117333
118875
|
function resolveRunningCliPath() {
|
|
117334
118876
|
const fromArgv = process.argv[1];
|
|
117335
|
-
if (fromArgv && /(?:^|[\\/])cli\.js$/.test(fromArgv) && (0,
|
|
118877
|
+
if (fromArgv && /(?:^|[\\/])cli\.js$/.test(fromArgv) && (0, import_node_fs31.existsSync)(fromArgv)) {
|
|
117336
118878
|
return fromArgv;
|
|
117337
118879
|
}
|
|
117338
118880
|
const beside = (0, import_node_path36.join)(__dirname, "cli.js");
|
|
117339
|
-
if ((0,
|
|
118881
|
+
if ((0, import_node_fs31.existsSync)(beside)) {
|
|
117340
118882
|
return beside;
|
|
117341
118883
|
}
|
|
117342
118884
|
if (fromArgv) {
|
|
@@ -117358,12 +118900,12 @@ async function ensureWindowsNativeLauncher(options = {}) {
|
|
|
117358
118900
|
const result = await installWindowsNativeLauncher({ cliPath: resolveRunningCliPath(), targetDir });
|
|
117359
118901
|
return { exePath: result.exePath, installed: true };
|
|
117360
118902
|
}
|
|
117361
|
-
var import_node_child_process9,
|
|
118903
|
+
var import_node_child_process9, import_node_fs31, import_node_module, import_node_os12, import_node_path36, SEA_SENTINEL_FUSE, NATIVE_LAUNCHER_EXE_NAME, POSTJECT_SPEC, POSTJECT_BIN;
|
|
117362
118904
|
var init_win_native_launcher = __esm({
|
|
117363
118905
|
"src/win-native-launcher.ts"() {
|
|
117364
118906
|
"use strict";
|
|
117365
118907
|
import_node_child_process9 = require("node:child_process");
|
|
117366
|
-
|
|
118908
|
+
import_node_fs31 = require("node:fs");
|
|
117367
118909
|
import_node_module = require("node:module");
|
|
117368
118910
|
import_node_os12 = require("node:os");
|
|
117369
118911
|
import_node_path36 = require("node:path");
|
|
@@ -117505,7 +119047,7 @@ function buildProviderMismatchWarning(target, provider) {
|
|
|
117505
119047
|
].join("\n");
|
|
117506
119048
|
}
|
|
117507
119049
|
async function handleUpdateCommand(args) {
|
|
117508
|
-
if (args.some(
|
|
119050
|
+
if (args.some(isHelpArg5)) {
|
|
117509
119051
|
printUpdateUsage();
|
|
117510
119052
|
return;
|
|
117511
119053
|
}
|
|
@@ -117546,7 +119088,7 @@ function resolveUpdateTarget(target) {
|
|
|
117546
119088
|
return detectGatewayInvocation() ?? "node";
|
|
117547
119089
|
}
|
|
117548
119090
|
async function handleSetupCommand(args) {
|
|
117549
|
-
if (args.some(
|
|
119091
|
+
if (args.some(isHelpArg5)) {
|
|
117550
119092
|
printSetupUsage();
|
|
117551
119093
|
return;
|
|
117552
119094
|
}
|
|
@@ -118123,7 +119665,7 @@ async function getCurrentNodeCliVersion() {
|
|
|
118123
119665
|
return await getGlobalNpmPackageVersion(UPDATE_PACKAGES.node) ?? getBundledNodeCliVersion();
|
|
118124
119666
|
}
|
|
118125
119667
|
function getBundledNodeCliVersion() {
|
|
118126
|
-
return true ? "0.2.
|
|
119668
|
+
return true ? "0.2.17-beta-ab42219842-261020165552" : null;
|
|
118127
119669
|
}
|
|
118128
119670
|
function readConfiguredAiProvider() {
|
|
118129
119671
|
const explicit = process.env.OKX_A2A_AI_PROVIDER || process.env.OKX_AGENT_TASK_AI_CLI;
|
|
@@ -118308,7 +119850,7 @@ async function updateHermes(release, options) {
|
|
|
118308
119850
|
assertNotRunningInsideGateway("hermes");
|
|
118309
119851
|
}
|
|
118310
119852
|
const spec = buildNpmPackageSpec("hermes", release);
|
|
118311
|
-
const workDir = await (0,
|
|
119853
|
+
const workDir = await (0, import_promises16.mkdtemp)((0, import_node_path37.join)((0, import_node_os13.tmpdir)(), `okx-a2a-${label}-hermes-`));
|
|
118312
119854
|
try {
|
|
118313
119855
|
console.log(`[${label}] downloading ${spec}`);
|
|
118314
119856
|
const npmTarball = await npmPack(spec, workDir);
|
|
@@ -118329,11 +119871,11 @@ async function updateHermes(release, options) {
|
|
|
118329
119871
|
}
|
|
118330
119872
|
console.log(`[${label}] hermes ${label} done`);
|
|
118331
119873
|
} finally {
|
|
118332
|
-
await (0,
|
|
119874
|
+
await (0, import_promises16.rm)(workDir, { recursive: true, force: true });
|
|
118333
119875
|
}
|
|
118334
119876
|
}
|
|
118335
119877
|
async function installGatewayPluginForDoctor(target) {
|
|
118336
|
-
const release = isPrereleaseVersion("0.2.
|
|
119878
|
+
const release = isPrereleaseVersion("0.2.17-beta-ab42219842-261020165552") ? "beta" : "latest";
|
|
118337
119879
|
const insideTargetGateway = detectGatewayInvocation() === target;
|
|
118338
119880
|
const options = {
|
|
118339
119881
|
restart: !insideTargetGateway,
|
|
@@ -118360,7 +119902,7 @@ function setupReadyMessage(target) {
|
|
|
118360
119902
|
async function normalizeHermesOkxA2aPluginConfig(configFile = resolveHermesConfigPath()) {
|
|
118361
119903
|
let content2;
|
|
118362
119904
|
try {
|
|
118363
|
-
content2 = await (0,
|
|
119905
|
+
content2 = await (0, import_promises16.readFile)(configFile, "utf8");
|
|
118364
119906
|
} catch (error) {
|
|
118365
119907
|
if (isNodeError(error) && error.code === "ENOENT") {
|
|
118366
119908
|
return false;
|
|
@@ -118371,21 +119913,21 @@ async function normalizeHermesOkxA2aPluginConfig(configFile = resolveHermesConfi
|
|
|
118371
119913
|
if (!normalized.changed) {
|
|
118372
119914
|
return false;
|
|
118373
119915
|
}
|
|
118374
|
-
await (0,
|
|
119916
|
+
await (0, import_promises16.writeFile)(configFile, normalized.content);
|
|
118375
119917
|
console.log(`[update] normalized Hermes plugins.enabled okx-a2a entry in ${configFile}`);
|
|
118376
119918
|
return true;
|
|
118377
119919
|
}
|
|
118378
119920
|
async function ensureHermesOkxA2aPluginConfig(configFile = resolveHermesConfigPath(), options = {}) {
|
|
118379
119921
|
let content2;
|
|
118380
119922
|
try {
|
|
118381
|
-
content2 = await (0,
|
|
119923
|
+
content2 = await (0, import_promises16.readFile)(configFile, "utf8");
|
|
118382
119924
|
} catch (error) {
|
|
118383
119925
|
if (isNodeError(error) && error.code === "ENOENT") {
|
|
118384
119926
|
if (options.dryRun) {
|
|
118385
119927
|
return true;
|
|
118386
119928
|
}
|
|
118387
|
-
await (0,
|
|
118388
|
-
await (0,
|
|
119929
|
+
await (0, import_promises16.mkdir)((0, import_node_path37.resolve)(configFile, ".."), { recursive: true });
|
|
119930
|
+
await (0, import_promises16.writeFile)(configFile, "plugins:\n enabled:\n - okx-a2a\n");
|
|
118389
119931
|
console.log(`[update] added Hermes plugins.enabled okx-a2a entry in ${configFile}`);
|
|
118390
119932
|
return true;
|
|
118391
119933
|
}
|
|
@@ -118396,7 +119938,7 @@ async function ensureHermesOkxA2aPluginConfig(configFile = resolveHermesConfigPa
|
|
|
118396
119938
|
if (options.dryRun) {
|
|
118397
119939
|
return true;
|
|
118398
119940
|
}
|
|
118399
|
-
await (0,
|
|
119941
|
+
await (0, import_promises16.writeFile)(configFile, normalized.content);
|
|
118400
119942
|
console.log(`[update] normalized Hermes plugins.enabled okx-a2a entry in ${configFile}`);
|
|
118401
119943
|
return true;
|
|
118402
119944
|
}
|
|
@@ -118407,7 +119949,7 @@ async function ensureHermesOkxA2aPluginConfig(configFile = resolveHermesConfigPa
|
|
|
118407
119949
|
return true;
|
|
118408
119950
|
}
|
|
118409
119951
|
const updated = addHermesOkxA2aEnabled(content2);
|
|
118410
|
-
await (0,
|
|
119952
|
+
await (0, import_promises16.writeFile)(configFile, updated);
|
|
118411
119953
|
console.log(`[update] added Hermes plugins.enabled okx-a2a entry in ${configFile}`);
|
|
118412
119954
|
return true;
|
|
118413
119955
|
}
|
|
@@ -118708,7 +120250,7 @@ async function isGatewayPluginInstalled(target) {
|
|
|
118708
120250
|
if (target === "openclaw") {
|
|
118709
120251
|
return (await getInstalledOpenClawPluginInfo()).installed;
|
|
118710
120252
|
}
|
|
118711
|
-
return (0,
|
|
120253
|
+
return (0, import_node_fs32.existsSync)(resolveHermesPluginYamlPath());
|
|
118712
120254
|
}
|
|
118713
120255
|
async function getInstalledGatewayPluginVersion(target) {
|
|
118714
120256
|
if (target === "hermes") {
|
|
@@ -118797,7 +120339,7 @@ function parsePackageVersionFromText(output5) {
|
|
|
118797
120339
|
async function getInstalledHermesPluginVersion() {
|
|
118798
120340
|
const pluginYaml = (0, import_node_path37.join)(process.env.HERMES_HOME ?? (0, import_node_path37.join)((0, import_node_os13.homedir)(), ".hermes"), "plugins", "platforms", "okx-a2a", "plugin.yaml");
|
|
118799
120341
|
try {
|
|
118800
|
-
const content2 = await (0,
|
|
120342
|
+
const content2 = await (0, import_promises16.readFile)(pluginYaml, "utf8");
|
|
118801
120343
|
return parsePluginYamlVersion(content2);
|
|
118802
120344
|
} catch (error) {
|
|
118803
120345
|
if (isNodeError(error) && error.code === "ENOENT") {
|
|
@@ -118856,7 +120398,7 @@ async function npmPack(spec, destination) {
|
|
|
118856
120398
|
return (0, import_node_path37.resolve)(destination, (0, import_node_path37.basename)(tarballName));
|
|
118857
120399
|
}
|
|
118858
120400
|
async function findHermesPluginTarball(distDir) {
|
|
118859
|
-
const entries = await (0,
|
|
120401
|
+
const entries = await (0, import_promises16.readdir)(distDir);
|
|
118860
120402
|
const tarball = entries.find((entry) => /^okx-a2a-hermes-plugin-.+\.tar\.gz$/.test(entry));
|
|
118861
120403
|
if (!tarball) {
|
|
118862
120404
|
throw new Error(`Hermes npm package did not contain dist/okx-a2a-hermes-plugin-*.tar.gz`);
|
|
@@ -118864,7 +120406,7 @@ async function findHermesPluginTarball(distDir) {
|
|
|
118864
120406
|
return (0, import_node_path37.join)(distDir, tarball);
|
|
118865
120407
|
}
|
|
118866
120408
|
async function findFirstDirectory(parent) {
|
|
118867
|
-
const entries = await (0,
|
|
120409
|
+
const entries = await (0, import_promises16.readdir)(parent, { withFileTypes: true });
|
|
118868
120410
|
const dir = entries.find((entry) => entry.isDirectory());
|
|
118869
120411
|
if (!dir) {
|
|
118870
120412
|
throw new Error(`No unpacked plugin directory found under ${parent}`);
|
|
@@ -118881,7 +120423,7 @@ function readOption4(args, name) {
|
|
|
118881
120423
|
function hasFlag(args, name) {
|
|
118882
120424
|
return args.includes(name);
|
|
118883
120425
|
}
|
|
118884
|
-
function
|
|
120426
|
+
function isHelpArg5(value) {
|
|
118885
120427
|
return value === "-h" || value === "--help" || value === "help";
|
|
118886
120428
|
}
|
|
118887
120429
|
function isSupportedRelease(value) {
|
|
@@ -119090,13 +120632,13 @@ function buildExternalCommandInvocation(command, args, platform = process.platfo
|
|
|
119090
120632
|
function formatExternalCommand(command, args) {
|
|
119091
120633
|
return [command, ...args].join(" ");
|
|
119092
120634
|
}
|
|
119093
|
-
var import_node_child_process10,
|
|
120635
|
+
var import_node_child_process10, import_node_fs32, import_promises16, import_node_os13, import_node_path37, 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;
|
|
119094
120636
|
var init_update_cli = __esm({
|
|
119095
120637
|
"src/update-cli.ts"() {
|
|
119096
120638
|
"use strict";
|
|
119097
120639
|
import_node_child_process10 = require("node:child_process");
|
|
119098
|
-
|
|
119099
|
-
|
|
120640
|
+
import_node_fs32 = require("node:fs");
|
|
120641
|
+
import_promises16 = require("node:fs/promises");
|
|
119100
120642
|
import_node_os13 = require("node:os");
|
|
119101
120643
|
import_node_path37 = require("node:path");
|
|
119102
120644
|
init_ai_command();
|
|
@@ -119386,7 +120928,7 @@ async function runDoctor(options = {}) {
|
|
|
119386
120928
|
platform: options.platform ?? process.platform,
|
|
119387
120929
|
env: options.env ?? process.env,
|
|
119388
120930
|
target: options.target ?? resolveDoctorTarget(options.env ?? process.env),
|
|
119389
|
-
cliVersion: options.cliVersion ?? (true ? "0.2.
|
|
120931
|
+
cliVersion: options.cliVersion ?? (true ? "0.2.17-beta-ab42219842-261020165552" : "0.0.0"),
|
|
119390
120932
|
fixMode: options.fix === true,
|
|
119391
120933
|
nonInteractive: options.nonInteractive === true,
|
|
119392
120934
|
packageChanged: false,
|
|
@@ -120423,7 +121965,7 @@ var init_doctor_cli = __esm({
|
|
|
120423
121965
|
});
|
|
120424
121966
|
|
|
120425
121967
|
// src/cli.ts
|
|
120426
|
-
var
|
|
121968
|
+
var import_node_fs33 = require("node:fs");
|
|
120427
121969
|
var import_node_os14 = require("node:os");
|
|
120428
121970
|
var import_node_path39 = require("node:path");
|
|
120429
121971
|
init_daemon();
|
|
@@ -120493,7 +122035,7 @@ init_sentry_config();
|
|
|
120493
122035
|
init_runtime_metadata();
|
|
120494
122036
|
var CURRENT_GATEWAY_SESSION_KEYS_ENV4 = "OKX_A2A_CURRENT_GATEWAY_SESSION_KEYS";
|
|
120495
122037
|
function printUsage3() {
|
|
120496
|
-
console.log(`okx-a2a ${"0.2.
|
|
122038
|
+
console.log(`okx-a2a ${"0.2.17-beta-ab42219842-261020165552"}
|
|
120497
122039
|
|
|
120498
122040
|
Usage:
|
|
120499
122041
|
okx-a2a <command> [options]
|
|
@@ -120526,6 +122068,7 @@ Commands:
|
|
|
120526
122068
|
trade-records
|
|
120527
122069
|
Insert, query, and soft-delete local business trade records
|
|
120528
122070
|
capabilities Print machine-readable A2A capability negotiation status (used by OnchainOS)
|
|
122071
|
+
devkit Register/unregister a local custom server for daemon message delivery
|
|
120529
122072
|
|
|
120530
122073
|
Global options:
|
|
120531
122074
|
-h, --help Show help
|
|
@@ -120535,7 +122078,7 @@ Run \`okx-a2a <command> -h\` for command-specific help.
|
|
|
120535
122078
|
`);
|
|
120536
122079
|
}
|
|
120537
122080
|
function printVersion() {
|
|
120538
|
-
console.log("0.2.
|
|
122081
|
+
console.log("0.2.17-beta-ab42219842-261020165552");
|
|
120539
122082
|
}
|
|
120540
122083
|
function printDaemonUsage() {
|
|
120541
122084
|
console.log(`Usage: okx-a2a daemon <start|restart|stop|status|autostart> [options]
|
|
@@ -120803,11 +122346,11 @@ Commands:
|
|
|
120803
122346
|
Print setup status JSON to stdout. Installer logs are written to stderr.
|
|
120804
122347
|
`);
|
|
120805
122348
|
}
|
|
120806
|
-
function
|
|
122349
|
+
function isHelpArg6(value) {
|
|
120807
122350
|
return value === "-h" || value === "--help" || value === "help";
|
|
120808
122351
|
}
|
|
120809
122352
|
function hasHelpFlag5(args) {
|
|
120810
|
-
return args.some(
|
|
122353
|
+
return args.some(isHelpArg6);
|
|
120811
122354
|
}
|
|
120812
122355
|
function isVersionArg(value) {
|
|
120813
122356
|
return value === "-v" || value === "--version" || value === "version";
|
|
@@ -120834,14 +122377,14 @@ function maybeRedirectDaemonSelfLog() {
|
|
|
120834
122377
|
}
|
|
120835
122378
|
try {
|
|
120836
122379
|
const logPath = resolveTaskPaths().listenerLogPath;
|
|
120837
|
-
(0,
|
|
120838
|
-
const fd = (0,
|
|
122380
|
+
(0, import_node_fs33.mkdirSync)((0, import_node_path39.join)(logPath, ".."), { recursive: true });
|
|
122381
|
+
const fd = (0, import_node_fs33.openSync)(logPath, "a");
|
|
120839
122382
|
const writeToLog = ((chunk, encoding, cb) => {
|
|
120840
122383
|
try {
|
|
120841
122384
|
if (typeof chunk === "string") {
|
|
120842
|
-
(0,
|
|
122385
|
+
(0, import_node_fs33.writeSync)(fd, chunk);
|
|
120843
122386
|
} else {
|
|
120844
|
-
(0,
|
|
122387
|
+
(0, import_node_fs33.writeSync)(fd, chunk);
|
|
120845
122388
|
}
|
|
120846
122389
|
} catch {
|
|
120847
122390
|
}
|
|
@@ -121191,12 +122734,12 @@ async function queueXmtpDaemonCommand(args, type) {
|
|
|
121191
122734
|
}
|
|
121192
122735
|
async function handleTaskCommand(args) {
|
|
121193
122736
|
const subcommand = args[0];
|
|
121194
|
-
if (!subcommand || args.every(
|
|
122737
|
+
if (!subcommand || args.every(isHelpArg6)) {
|
|
121195
122738
|
printTaskUsage();
|
|
121196
122739
|
return;
|
|
121197
122740
|
}
|
|
121198
122741
|
if (subcommand === "help") {
|
|
121199
|
-
const helpTarget = args.slice(1).find((arg) => !
|
|
122742
|
+
const helpTarget = args.slice(1).find((arg) => !isHelpArg6(arg));
|
|
121200
122743
|
if (!helpTarget) {
|
|
121201
122744
|
printTaskUsage();
|
|
121202
122745
|
return;
|
|
@@ -121885,10 +123428,10 @@ async function initDirectCliSentry() {
|
|
|
121885
123428
|
cliSentryInitAttempted = true;
|
|
121886
123429
|
try {
|
|
121887
123430
|
const configPath = (0, import_node_path39.join)(resolveTaskHomeForSentryConfig(), "xmtp", "system-config.json");
|
|
121888
|
-
if (!(0,
|
|
123431
|
+
if (!(0, import_node_fs33.existsSync)(configPath)) {
|
|
121889
123432
|
return;
|
|
121890
123433
|
}
|
|
121891
|
-
const config = JSON.parse((0,
|
|
123434
|
+
const config = JSON.parse((0, import_node_fs33.readFileSync)(configPath, "utf8"));
|
|
121892
123435
|
if (typeof config.sentryDsn !== "string" || !config.sentryDsn) {
|
|
121893
123436
|
return;
|
|
121894
123437
|
}
|
|
@@ -121950,7 +123493,7 @@ async function main() {
|
|
|
121950
123493
|
assertSupportedNodeVersion();
|
|
121951
123494
|
}
|
|
121952
123495
|
const args = process.argv.slice(3);
|
|
121953
|
-
if (
|
|
123496
|
+
if (isHelpArg6(command)) {
|
|
121954
123497
|
printUsage3();
|
|
121955
123498
|
return;
|
|
121956
123499
|
}
|
|
@@ -121971,6 +123514,15 @@ async function main() {
|
|
|
121971
123514
|
await handleTradeRecordsCommand2(args);
|
|
121972
123515
|
return;
|
|
121973
123516
|
}
|
|
123517
|
+
if (command === "devkit") {
|
|
123518
|
+
const { handleDevkitCommand: handleDevkitCommand2, printDevkitUsage: printDevkitUsage2 } = await Promise.resolve().then(() => (init_devkit_cli(), devkit_cli_exports));
|
|
123519
|
+
if (hasHelpFlag5(args)) {
|
|
123520
|
+
printDevkitUsage2();
|
|
123521
|
+
return;
|
|
123522
|
+
}
|
|
123523
|
+
await handleDevkitCommand2(args);
|
|
123524
|
+
return;
|
|
123525
|
+
}
|
|
121974
123526
|
if (command === "daemon") {
|
|
121975
123527
|
if (hasHelpFlag5(args)) {
|
|
121976
123528
|
printDaemonUsage();
|
|
@@ -122030,7 +123582,7 @@ async function main() {
|
|
|
122030
123582
|
if (command === "xmtp-test") {
|
|
122031
123583
|
const { handleXmtpTestCommand: handleXmtpTestCommand2 } = await Promise.resolve().then(() => (init_xmtp_test_cli(), xmtp_test_cli_exports));
|
|
122032
123584
|
await handleXmtpTestCommand2(process.argv.slice(3), {
|
|
122033
|
-
packageVersion: "0.2.
|
|
123585
|
+
packageVersion: "0.2.17-beta-ab42219842-261020165552",
|
|
122034
123586
|
agentSdkVersion: "2.3.0",
|
|
122035
123587
|
nodeSdkVersion: "6.1.0",
|
|
122036
123588
|
nodeBindingsVersion: "1.11.0"
|
|
@@ -122136,12 +123688,12 @@ function shouldDeferHelpToNestedHandler(command, args) {
|
|
|
122136
123688
|
return true;
|
|
122137
123689
|
}
|
|
122138
123690
|
if (command === "trade-records") {
|
|
122139
|
-
return args.some((arg) => !
|
|
123691
|
+
return args.some((arg) => !isHelpArg6(arg));
|
|
122140
123692
|
}
|
|
122141
123693
|
if (command !== "session" && command !== "user" && command !== "task") {
|
|
122142
123694
|
return false;
|
|
122143
123695
|
}
|
|
122144
|
-
return args.some((arg) => !
|
|
123696
|
+
return args.some((arg) => !isHelpArg6(arg));
|
|
122145
123697
|
}
|
|
122146
123698
|
main().then(() => {
|
|
122147
123699
|
if (cliSentryFlushTimedOut) {
|