@okxweb3/a2a-node 0.2.18-beta-4dd056b897-261015113839 → 0.2.18
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 +708 -1849
- package/dist/index.js +704 -1745
- package/package.json +4 -4
package/dist/cli.js
CHANGED
|
@@ -3788,10 +3788,6 @@ function isDaemonCommand(value) {
|
|
|
3788
3788
|
if (parsed.type === "xmtp-send") {
|
|
3789
3789
|
return typeof parsed.jobId === "string" && typeof parsed.message === "string";
|
|
3790
3790
|
}
|
|
3791
|
-
if (parsed.type === "xmtp-subscription-push") {
|
|
3792
|
-
const command = parsed;
|
|
3793
|
-
return typeof command.myAgentId === "string" && typeof command.content === "string" && Array.isArray(command.conversationIds) && command.conversationIds.every((item) => typeof item === "string");
|
|
3794
|
-
}
|
|
3795
3791
|
if (parsed.type === "xmtp-get-pending-list") {
|
|
3796
3792
|
return true;
|
|
3797
3793
|
}
|
|
@@ -3847,7 +3843,6 @@ var init_command_store = __esm({
|
|
|
3847
3843
|
import_node_fs8 = require("node:fs");
|
|
3848
3844
|
import_node_path11 = require("node:path");
|
|
3849
3845
|
init_paths();
|
|
3850
|
-
init_session_store();
|
|
3851
3846
|
({ DatabaseSync: DatabaseSync2 } = loadSqlite2());
|
|
3852
3847
|
XMTP_DEBUG_RESULT_TTL_MS = 5 * 6e4;
|
|
3853
3848
|
CommandStore = class {
|
|
@@ -3877,17 +3872,6 @@ var init_command_store = __esm({
|
|
|
3877
3872
|
createdAt: Date.now()
|
|
3878
3873
|
};
|
|
3879
3874
|
}
|
|
3880
|
-
createXmtpSubscriptionPushCommand(params) {
|
|
3881
|
-
return {
|
|
3882
|
-
id: (0, import_node_crypto2.randomUUID)(),
|
|
3883
|
-
type: "xmtp-subscription-push",
|
|
3884
|
-
myAgentId: params.myAgentId,
|
|
3885
|
-
content: params.content,
|
|
3886
|
-
conversationIds: params.conversationIds,
|
|
3887
|
-
deliveryId: params.deliveryId,
|
|
3888
|
-
createdAt: Date.now()
|
|
3889
|
-
};
|
|
3890
|
-
}
|
|
3891
3875
|
createXmtpGetPendingListCommand() {
|
|
3892
3876
|
return {
|
|
3893
3877
|
id: (0, import_node_crypto2.randomUUID)(),
|
|
@@ -3981,65 +3965,6 @@ var init_command_store = __esm({
|
|
|
3981
3965
|
);
|
|
3982
3966
|
return this.commandPath(command.id);
|
|
3983
3967
|
}
|
|
3984
|
-
/**
|
|
3985
|
-
* Atomic idempotent submit keyed on a business `idempotencyKey` (DEXMARKET-9035,
|
|
3986
|
-
* M2). The FIRST caller for a given key inserts its command and gets
|
|
3987
|
-
* `created: true`; every later caller with the SAME key — including after a
|
|
3988
|
-
* daemon / CommandStore rebuild — gets the ALREADY-persisted command back with
|
|
3989
|
-
* `created: false` and NO new row. Concurrency-safe: correctness rests on the
|
|
3990
|
-
* partial UNIQUE index on `idempotency_key`, not a check-then-insert (which
|
|
3991
|
-
* races), so a `INSERT ... ON CONFLICT DO NOTHING` collapses concurrent
|
|
3992
|
-
* duplicates to exactly one row. Recoverable SQLITE_BUSY/LOCKED errors reuse
|
|
3993
|
-
* the repo's bounded exponential backoff. This never changes the plain
|
|
3994
|
-
* `submit` path used by `xmtp-send` and every other daemon command.
|
|
3995
|
-
*/
|
|
3996
|
-
async submitIdempotent(command, idempotencyKey) {
|
|
3997
|
-
if (!idempotencyKey) {
|
|
3998
|
-
throw new Error("submitIdempotent requires a non-empty idempotencyKey");
|
|
3999
|
-
}
|
|
4000
|
-
return this.withBusyRetry(
|
|
4001
|
-
() => this.transaction(() => {
|
|
4002
|
-
const now = Date.now();
|
|
4003
|
-
const insert = this.db.prepare(`
|
|
4004
|
-
INSERT INTO command_queue (
|
|
4005
|
-
id, type, status, command_json, result_json,
|
|
4006
|
-
created_at_ms, updated_at_ms, processing_started_at_ms, completed_at_ms,
|
|
4007
|
-
idempotency_key
|
|
4008
|
-
)
|
|
4009
|
-
VALUES (?, ?, 'pending', ?, NULL, ?, ?, NULL, NULL, ?)
|
|
4010
|
-
ON CONFLICT(idempotency_key) WHERE idempotency_key IS NOT NULL DO NOTHING
|
|
4011
|
-
`).run(
|
|
4012
|
-
command.id,
|
|
4013
|
-
command.type,
|
|
4014
|
-
stringifyForStorage(command),
|
|
4015
|
-
normalizeCreatedAt(command.createdAt, now),
|
|
4016
|
-
now,
|
|
4017
|
-
idempotencyKey
|
|
4018
|
-
);
|
|
4019
|
-
if (Number(insert.changes ?? 0) > 0) {
|
|
4020
|
-
return { path: this.commandPath(command.id), commandId: command.id, created: true };
|
|
4021
|
-
}
|
|
4022
|
-
const existing = this.db.prepare(`
|
|
4023
|
-
SELECT id FROM command_queue WHERE idempotency_key = ?
|
|
4024
|
-
`).get(idempotencyKey);
|
|
4025
|
-
const existingId = existing?.id ?? command.id;
|
|
4026
|
-
return { path: this.commandPath(existingId), commandId: existingId, created: false };
|
|
4027
|
-
})
|
|
4028
|
-
);
|
|
4029
|
-
}
|
|
4030
|
-
async withBusyRetry(operation) {
|
|
4031
|
-
const attempts = 6;
|
|
4032
|
-
for (let attempt = 1; ; attempt += 1) {
|
|
4033
|
-
try {
|
|
4034
|
-
return operation();
|
|
4035
|
-
} catch (err2) {
|
|
4036
|
-
if (!isSqliteBusyError(err2) || attempt >= attempts) {
|
|
4037
|
-
throw err2;
|
|
4038
|
-
}
|
|
4039
|
-
await new Promise((resolve14) => setTimeout(resolve14, Math.min(50 * 2 ** (attempt - 1), 1e3)));
|
|
4040
|
-
}
|
|
4041
|
-
}
|
|
4042
|
-
}
|
|
4043
3968
|
async listPending() {
|
|
4044
3969
|
return (await this.listPendingEntries()).map((entry) => entry.command);
|
|
4045
3970
|
}
|
|
@@ -4105,25 +4030,10 @@ var init_command_store = __esm({
|
|
|
4105
4030
|
this.db.exec(`
|
|
4106
4031
|
CREATE INDEX IF NOT EXISTS idx_command_queue_status_created
|
|
4107
4032
|
ON command_queue(status, created_at_ms, id)
|
|
4108
|
-
`);
|
|
4109
|
-
this.ensureColumn("command_queue", "idempotency_key", "TEXT");
|
|
4110
|
-
this.db.exec(`
|
|
4111
|
-
CREATE UNIQUE INDEX IF NOT EXISTS idx_command_queue_idempotency_key
|
|
4112
|
-
ON command_queue(idempotency_key)
|
|
4113
|
-
WHERE idempotency_key IS NOT NULL
|
|
4114
4033
|
`);
|
|
4115
4034
|
this.purgeExpiredXmtpDebugResults();
|
|
4116
4035
|
this.importLegacyFileCommands();
|
|
4117
4036
|
}
|
|
4118
|
-
ensureColumn(table, column, definition) {
|
|
4119
|
-
this.transaction(() => {
|
|
4120
|
-
const rows = this.db.prepare(`PRAGMA table_info(${table})`).all();
|
|
4121
|
-
if (rows.some((row) => row.name === column)) {
|
|
4122
|
-
return;
|
|
4123
|
-
}
|
|
4124
|
-
this.db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
4125
|
-
});
|
|
4126
|
-
}
|
|
4127
4037
|
purgeExpiredXmtpDebugResults() {
|
|
4128
4038
|
this.db.prepare(`
|
|
4129
4039
|
DELETE FROM command_queue
|
|
@@ -4777,7 +4687,7 @@ var require_is = __commonJS({
|
|
|
4777
4687
|
function isPrimitive(wat) {
|
|
4778
4688
|
return wat === null || typeof wat !== "object" && typeof wat !== "function";
|
|
4779
4689
|
}
|
|
4780
|
-
function
|
|
4690
|
+
function isPlainObject4(wat) {
|
|
4781
4691
|
return isBuiltin(wat, "Object");
|
|
4782
4692
|
}
|
|
4783
4693
|
function isEvent(wat) {
|
|
@@ -4793,7 +4703,7 @@ var require_is = __commonJS({
|
|
|
4793
4703
|
return Boolean(wat && wat.then && typeof wat.then === "function");
|
|
4794
4704
|
}
|
|
4795
4705
|
function isSyntheticEvent(wat) {
|
|
4796
|
-
return
|
|
4706
|
+
return isPlainObject4(wat) && "nativeEvent" in wat && "preventDefault" in wat && "stopPropagation" in wat;
|
|
4797
4707
|
}
|
|
4798
4708
|
function isNaN2(wat) {
|
|
4799
4709
|
return typeof wat === "number" && wat !== wat;
|
|
@@ -4816,7 +4726,7 @@ var require_is = __commonJS({
|
|
|
4816
4726
|
exports2.isEvent = isEvent;
|
|
4817
4727
|
exports2.isInstanceOf = isInstanceOf;
|
|
4818
4728
|
exports2.isNaN = isNaN2;
|
|
4819
|
-
exports2.isPlainObject =
|
|
4729
|
+
exports2.isPlainObject = isPlainObject4;
|
|
4820
4730
|
exports2.isPrimitive = isPrimitive;
|
|
4821
4731
|
exports2.isRegExp = isRegExp;
|
|
4822
4732
|
exports2.isString = isString;
|
|
@@ -20079,23 +19989,6 @@ var init_events = __esm({
|
|
|
20079
19989
|
XMTP_RATE_LIMIT_CREATE_SUPPRESSED: "XMTP rate limit create suppressed",
|
|
20080
19990
|
XMTP_RATE_LIMIT_PROBE: "XMTP rate limit probe",
|
|
20081
19991
|
XMTP_RATE_LIMIT_RECOVERED: "XMTP rate limit recovered",
|
|
20082
|
-
// ── subscription observability info (DEXMARKET-9096) ───────────
|
|
20083
|
-
// All of the following logger.info checkpoints MUST also be listed in
|
|
20084
|
-
// SENTRY_INFO_ALLOWLIST (index.ts): info() returns early for an unlisted
|
|
20085
|
-
// event, which ships a checkpoint that looks implemented but emits nothing.
|
|
20086
|
-
SUBSCRIPTION_PUSH_STARTED: "Subscription push started",
|
|
20087
|
-
SUBSCRIPTION_PUSH_TARGETS_RESOLVED: "Subscription push targets resolved",
|
|
20088
|
-
SUBSCRIPTION_PUSH_EMPTY_TARGETS: "Subscription push empty targets",
|
|
20089
|
-
SUBSCRIPTION_PUSH_SUMMARY: "Subscription push summary",
|
|
20090
|
-
SUBSCRIPTION_INBOUND_RECEIVED: "Subscription inbound received",
|
|
20091
|
-
SUBSCRIPTION_INBOUND_GATE_DROPPED: "Subscription inbound gate dropped",
|
|
20092
|
-
SUBSCRIPTION_JOBS_QUERY_STARTED: "Subscription jobs query started",
|
|
20093
|
-
SUBSCRIPTION_JOBS_QUERY_SUCCEEDED: "Subscription jobs query succeeded",
|
|
20094
|
-
SUBSCRIPTION_JOBS_EMPTY: "Subscription jobs empty",
|
|
20095
|
-
SUBSCRIPTION_INBOUND_OWNERSHIP_ROUTED: "Subscription inbound ownership routed",
|
|
20096
|
-
SUBSCRIPTION_JOB_DISPATCHED: "Subscription job dispatched",
|
|
20097
|
-
SUBSCRIPTION_JOB_DUPLICATE_IGNORED: "Subscription job duplicate ignored",
|
|
20098
|
-
SUBSCRIPTION_FANOUT_SUMMARY: "Subscription fan-out summary",
|
|
20099
19992
|
// ── error ─────────────────────────────────────────────────────
|
|
20100
19993
|
XMTP_CONNECTION_FAILED: "XMTP connection failed",
|
|
20101
19994
|
CONVERSATIONS_STREAM_FAILED: "conversations.stream failed",
|
|
@@ -20162,13 +20055,6 @@ var init_events = __esm({
|
|
|
20162
20055
|
AGENT_INSTALLATION_LIMIT_NEAR: "Agent installation limit near",
|
|
20163
20056
|
XMTP_HISTORY_SYNC_REQUEST_FAILED: "XMTP history sync request failed",
|
|
20164
20057
|
XMTP_DEBUG_SYNC_FAILED: "XMTP debug sync failed",
|
|
20165
|
-
// ── subscription observability error (DEXMARKET-9096) ──────────
|
|
20166
|
-
// error-level: always emitted (no allowlist gate). Error objects are
|
|
20167
|
-
// classified by buildErrorDiagnostics — never attach raw Error.message.
|
|
20168
|
-
SUBSCRIPTION_PUSH_TARGET_FAILED: "Subscription push target failed",
|
|
20169
|
-
SUBSCRIPTION_INBOUND_AGENTIC_ID_MISSING: "Subscription inbound agenticId missing",
|
|
20170
|
-
SUBSCRIPTION_JOBS_FAIL_CLOSED: "Subscription jobs fail closed",
|
|
20171
|
-
SUBSCRIPTION_JOB_FAILED: "Subscription job failed",
|
|
20172
20058
|
// Underlying XMTP SDK client close failed during recycle/removal/shutdown
|
|
20173
20059
|
// (DEXMARKET-9116). Error-level → NOT added to SENTRY_INFO_ALLOWLIST.
|
|
20174
20060
|
XMTP_CLIENT_CLOSE_FAILED: "XMTP client close failed"
|
|
@@ -20844,13 +20730,6 @@ var init_sentry_logger = __esm({
|
|
|
20844
20730
|
]);
|
|
20845
20731
|
SENTRY_TAG_KEYS = /* @__PURE__ */ new Set([
|
|
20846
20732
|
"agentId",
|
|
20847
|
-
// Subscription correlation agent ids (DEXMARKET-9096). Bounded-cardinality,
|
|
20848
|
-
// same class as agentId/senderAgentId/onchainosAgentId — promoted to indexed
|
|
20849
|
-
// tags for Sentry filtering. NOT added to SENTRY_FINGERPRINT_KEYS, so the
|
|
20850
|
-
// global issue fingerprint is unchanged. High-cardinality ids
|
|
20851
|
-
// (conversationId/messageId/deliveryId) are deliberately NOT here.
|
|
20852
|
-
"aspAgentId",
|
|
20853
|
-
"userAgentId",
|
|
20854
20733
|
"agentPlatform",
|
|
20855
20734
|
"aiProvider",
|
|
20856
20735
|
"cacheName",
|
|
@@ -21018,22 +20897,6 @@ var init_sentry_logger = __esm({
|
|
|
21018
20897
|
LogEvent.SESSION_KEY_DERIVED,
|
|
21019
20898
|
LogEvent.SESSIONS_QUERIED,
|
|
21020
20899
|
LogEvent.SYNC_TICK_COMPLETED,
|
|
21021
|
-
// Subscription observability info checkpoints (DEXMARKET-9096). Each is a
|
|
21022
|
-
// logger.info event; omitting any makes info() drop it silently so the whole
|
|
21023
|
-
// subscription trace would look implemented and emit nothing in production.
|
|
21024
|
-
LogEvent.SUBSCRIPTION_PUSH_STARTED,
|
|
21025
|
-
LogEvent.SUBSCRIPTION_PUSH_TARGETS_RESOLVED,
|
|
21026
|
-
LogEvent.SUBSCRIPTION_PUSH_EMPTY_TARGETS,
|
|
21027
|
-
LogEvent.SUBSCRIPTION_PUSH_SUMMARY,
|
|
21028
|
-
LogEvent.SUBSCRIPTION_INBOUND_RECEIVED,
|
|
21029
|
-
LogEvent.SUBSCRIPTION_INBOUND_GATE_DROPPED,
|
|
21030
|
-
LogEvent.SUBSCRIPTION_JOBS_QUERY_STARTED,
|
|
21031
|
-
LogEvent.SUBSCRIPTION_JOBS_QUERY_SUCCEEDED,
|
|
21032
|
-
LogEvent.SUBSCRIPTION_JOBS_EMPTY,
|
|
21033
|
-
LogEvent.SUBSCRIPTION_INBOUND_OWNERSHIP_ROUTED,
|
|
21034
|
-
LogEvent.SUBSCRIPTION_JOB_DISPATCHED,
|
|
21035
|
-
LogEvent.SUBSCRIPTION_JOB_DUPLICATE_IGNORED,
|
|
21036
|
-
LogEvent.SUBSCRIPTION_FANOUT_SUMMARY,
|
|
21037
20900
|
// XMTP creation rate-limit cooldown checkpoints (DEXMARKET-9116). info() drops
|
|
21038
20901
|
// any event not listed here, so these must stay registered.
|
|
21039
20902
|
LogEvent.XMTP_RATE_LIMIT_COOLDOWN_STARTED,
|
|
@@ -25400,7 +25263,7 @@ var require_websocket2 = __commonJS({
|
|
|
25400
25263
|
var http2 = require("http");
|
|
25401
25264
|
var net = require("net");
|
|
25402
25265
|
var tls = require("tls");
|
|
25403
|
-
var { randomBytes: randomBytes4, createHash:
|
|
25266
|
+
var { randomBytes: randomBytes4, createHash: createHash6 } = require("crypto");
|
|
25404
25267
|
var { Duplex, Readable } = require("stream");
|
|
25405
25268
|
var { URL: URL2 } = require("url");
|
|
25406
25269
|
var PerMessageDeflate = require_permessage_deflate();
|
|
@@ -26060,7 +25923,7 @@ var require_websocket2 = __commonJS({
|
|
|
26060
25923
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
26061
25924
|
return;
|
|
26062
25925
|
}
|
|
26063
|
-
const digest =
|
|
25926
|
+
const digest = createHash6("sha1").update(key + GUID).digest("base64");
|
|
26064
25927
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
26065
25928
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
26066
25929
|
return;
|
|
@@ -26427,7 +26290,7 @@ var require_websocket_server = __commonJS({
|
|
|
26427
26290
|
var EventEmitter2 = require("events");
|
|
26428
26291
|
var http2 = require("http");
|
|
26429
26292
|
var { Duplex } = require("stream");
|
|
26430
|
-
var { createHash:
|
|
26293
|
+
var { createHash: createHash6 } = require("crypto");
|
|
26431
26294
|
var extension = require_extension();
|
|
26432
26295
|
var PerMessageDeflate = require_permessage_deflate();
|
|
26433
26296
|
var subprotocol = require_subprotocol();
|
|
@@ -26728,7 +26591,7 @@ var require_websocket_server = __commonJS({
|
|
|
26728
26591
|
);
|
|
26729
26592
|
}
|
|
26730
26593
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
26731
|
-
const digest =
|
|
26594
|
+
const digest = createHash6("sha1").update(key + GUID).digest("base64");
|
|
26732
26595
|
const headers = [
|
|
26733
26596
|
"HTTP/1.1 101 Switching Protocols",
|
|
26734
26597
|
"Upgrade: websocket",
|
|
@@ -27155,7 +27018,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
|
|
|
27155
27018
|
client: {
|
|
27156
27019
|
id: "gateway-client",
|
|
27157
27020
|
displayName: "okx-a2a-node",
|
|
27158
|
-
version: "0.2.18
|
|
27021
|
+
version: "0.2.18",
|
|
27159
27022
|
platform: "node",
|
|
27160
27023
|
mode: "backend",
|
|
27161
27024
|
instanceId
|
|
@@ -27166,7 +27029,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
|
|
|
27166
27029
|
commands: [],
|
|
27167
27030
|
permissions: {},
|
|
27168
27031
|
locale: Intl.DateTimeFormat().resolvedOptions().locale || "en-US",
|
|
27169
|
-
userAgent: `okx-a2a-node/${"0.2.18
|
|
27032
|
+
userAgent: `okx-a2a-node/${"0.2.18"}`,
|
|
27170
27033
|
auth: {
|
|
27171
27034
|
...config.token ? { token: config.token } : {},
|
|
27172
27035
|
...config.password ? { password: config.password } : {}
|
|
@@ -29226,7 +29089,7 @@ var init_sentry_config = __esm({
|
|
|
29226
29089
|
environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
|
|
29227
29090
|
SENTRY_CONFIG = {
|
|
29228
29091
|
projectName: "okx/openclaw-okx-a2a-extension",
|
|
29229
|
-
release: "0.2.18
|
|
29092
|
+
release: "0.2.18",
|
|
29230
29093
|
environment,
|
|
29231
29094
|
runtimeContainer: normalizeRuntimeContainer(process.env.OKX_A2A_RUNTIME_CONTAINER)
|
|
29232
29095
|
};
|
|
@@ -40396,7 +40259,7 @@ async function exportDiagnosticLogs(options) {
|
|
|
40396
40259
|
node: process.version,
|
|
40397
40260
|
platform: process.platform,
|
|
40398
40261
|
arch: process.arch,
|
|
40399
|
-
packageVersion: true ? "0.2.18
|
|
40262
|
+
packageVersion: true ? "0.2.18" : "unknown",
|
|
40400
40263
|
sensitiveContentIncluded: options.includeSensitiveContent,
|
|
40401
40264
|
listenerAndLlmContentIncluded: true,
|
|
40402
40265
|
credentialsAlwaysRedacted: true,
|
|
@@ -43087,7 +42950,7 @@ function createAsyncStreamProxy(stream) {
|
|
|
43087
42950
|
}
|
|
43088
42951
|
});
|
|
43089
42952
|
}
|
|
43090
|
-
var import_node_bindings, import_node_bindings2, import_node_crypto9, 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,
|
|
42953
|
+
var import_node_bindings, import_node_bindings2, import_node_crypto9, 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, DEFAULT_RETRY_DELAY, DEFAULT_RETRY_ATTEMPTS, createStream, Conversation, Dm, Group, Conversations, DebugInformation, Preferences, networkOptionKeys, hasBackend, resolveBackend$1, createClient, resolveBackend, createEphemeralIdentifier, toInboxUpdatesCountMap, Client;
|
|
43091
42954
|
var init_dist2 = __esm({
|
|
43092
42955
|
"../../node_modules/@xmtp/node-sdk/dist/index.js"() {
|
|
43093
42956
|
import_node_bindings = require("@xmtp/node-bindings");
|
|
@@ -43497,7 +43360,6 @@ var init_dist2 = __esm({
|
|
|
43497
43360
|
isUsableProperty = (prop) => {
|
|
43498
43361
|
return usableProperties.includes(prop);
|
|
43499
43362
|
};
|
|
43500
|
-
wait = (ms) => new Promise((resolve14) => setTimeout(resolve14, ms));
|
|
43501
43363
|
DEFAULT_RETRY_DELAY = 6e4;
|
|
43502
43364
|
DEFAULT_RETRY_ATTEMPTS = 10;
|
|
43503
43365
|
createStream = async (streamFunction, streamValueMutator, options) => {
|
|
@@ -43506,82 +43368,161 @@ var init_dist2 = __esm({
|
|
|
43506
43368
|
throw new StreamInvalidRetryAttemptsError();
|
|
43507
43369
|
}
|
|
43508
43370
|
const asyncStream = new AsyncStream();
|
|
43371
|
+
let stopped = false;
|
|
43372
|
+
let current;
|
|
43373
|
+
let recovering = false;
|
|
43374
|
+
let cancelDelay;
|
|
43375
|
+
const isStopped = () => stopped;
|
|
43376
|
+
const isCurrent = (native) => !stopped && current === native;
|
|
43377
|
+
asyncStream.onDone = () => {
|
|
43378
|
+
if (stopped) {
|
|
43379
|
+
return;
|
|
43380
|
+
}
|
|
43381
|
+
stopped = true;
|
|
43382
|
+
cancelDelay?.();
|
|
43383
|
+
const native = current;
|
|
43384
|
+
current = void 0;
|
|
43385
|
+
native?.closer?.end();
|
|
43386
|
+
};
|
|
43387
|
+
const delay = (ms) => new Promise((resolve14) => {
|
|
43388
|
+
const timer = setTimeout(() => {
|
|
43389
|
+
cancelDelay = void 0;
|
|
43390
|
+
resolve14();
|
|
43391
|
+
}, ms);
|
|
43392
|
+
cancelDelay = () => {
|
|
43393
|
+
clearTimeout(timer);
|
|
43394
|
+
cancelDelay = void 0;
|
|
43395
|
+
resolve14();
|
|
43396
|
+
};
|
|
43397
|
+
});
|
|
43398
|
+
const reportError = (error) => {
|
|
43399
|
+
if (!stopped) {
|
|
43400
|
+
onError?.(error);
|
|
43401
|
+
}
|
|
43402
|
+
};
|
|
43403
|
+
const deliver = (value) => {
|
|
43404
|
+
if (stopped || value === void 0) {
|
|
43405
|
+
return;
|
|
43406
|
+
}
|
|
43407
|
+
asyncStream.push(value);
|
|
43408
|
+
onValue?.(value);
|
|
43409
|
+
};
|
|
43509
43410
|
const streamCallback = (error, value) => {
|
|
43411
|
+
if (stopped) {
|
|
43412
|
+
return;
|
|
43413
|
+
}
|
|
43510
43414
|
if (error) {
|
|
43511
43415
|
onError?.(error);
|
|
43512
43416
|
return;
|
|
43513
43417
|
}
|
|
43514
|
-
if (value
|
|
43515
|
-
|
|
43516
|
-
|
|
43517
|
-
|
|
43518
|
-
|
|
43519
|
-
|
|
43520
|
-
|
|
43521
|
-
|
|
43522
|
-
onValue?.(mutatedValue2);
|
|
43523
|
-
}
|
|
43524
|
-
}).catch((error2) => {
|
|
43525
|
-
onError?.(error2);
|
|
43526
|
-
});
|
|
43527
|
-
} else {
|
|
43528
|
-
if (mutatedValue !== void 0) {
|
|
43529
|
-
asyncStream.push(mutatedValue);
|
|
43530
|
-
onValue?.(mutatedValue);
|
|
43531
|
-
}
|
|
43532
|
-
}
|
|
43418
|
+
if (value === void 0) {
|
|
43419
|
+
return;
|
|
43420
|
+
}
|
|
43421
|
+
try {
|
|
43422
|
+
if (streamValueMutator) {
|
|
43423
|
+
const mutatedValue = streamValueMutator(value);
|
|
43424
|
+
if ((0, import_types.isPromise)(mutatedValue)) {
|
|
43425
|
+
void mutatedValue.then(deliver).catch(reportError);
|
|
43533
43426
|
} else {
|
|
43534
|
-
|
|
43535
|
-
onValue?.(value);
|
|
43427
|
+
deliver(mutatedValue);
|
|
43536
43428
|
}
|
|
43537
|
-
}
|
|
43538
|
-
|
|
43429
|
+
} else {
|
|
43430
|
+
deliver(value);
|
|
43539
43431
|
}
|
|
43432
|
+
} catch (error2) {
|
|
43433
|
+
reportError(error2);
|
|
43540
43434
|
}
|
|
43541
43435
|
};
|
|
43542
|
-
const
|
|
43543
|
-
|
|
43544
|
-
|
|
43545
|
-
|
|
43546
|
-
|
|
43436
|
+
const fail = (error) => {
|
|
43437
|
+
void asyncStream.end();
|
|
43438
|
+
onError?.(error);
|
|
43439
|
+
};
|
|
43440
|
+
const open2 = async () => {
|
|
43441
|
+
if (stopped) {
|
|
43442
|
+
return false;
|
|
43547
43443
|
}
|
|
43548
|
-
|
|
43549
|
-
|
|
43444
|
+
const native = { ready: false, closed: false };
|
|
43445
|
+
current = native;
|
|
43446
|
+
const closer = await streamFunction(streamCallback, () => {
|
|
43447
|
+
onNativeClose(native);
|
|
43448
|
+
});
|
|
43449
|
+
native.closer = closer;
|
|
43450
|
+
if (!isCurrent(native)) {
|
|
43451
|
+
closer.end();
|
|
43452
|
+
return false;
|
|
43453
|
+
}
|
|
43454
|
+
await closer.waitForReady();
|
|
43455
|
+
if (!isCurrent(native)) {
|
|
43456
|
+
closer.end();
|
|
43457
|
+
return false;
|
|
43458
|
+
}
|
|
43459
|
+
if (native.closed || closer.isClosed()) {
|
|
43460
|
+
closer.end();
|
|
43461
|
+
return false;
|
|
43462
|
+
}
|
|
43463
|
+
native.ready = true;
|
|
43464
|
+
return true;
|
|
43465
|
+
};
|
|
43466
|
+
const restart = async () => {
|
|
43550
43467
|
try {
|
|
43551
|
-
|
|
43552
|
-
|
|
43553
|
-
|
|
43554
|
-
|
|
43555
|
-
|
|
43556
|
-
|
|
43557
|
-
|
|
43558
|
-
|
|
43559
|
-
|
|
43560
|
-
|
|
43561
|
-
|
|
43562
|
-
|
|
43468
|
+
for (let attempt = 1; attempt <= retryAttempts; attempt++) {
|
|
43469
|
+
await delay(retryDelay);
|
|
43470
|
+
if (isStopped()) {
|
|
43471
|
+
return;
|
|
43472
|
+
}
|
|
43473
|
+
onRetry?.(attempt, retryAttempts);
|
|
43474
|
+
let restarted = false;
|
|
43475
|
+
try {
|
|
43476
|
+
restarted = await open2();
|
|
43477
|
+
} catch (error) {
|
|
43478
|
+
reportError(error);
|
|
43479
|
+
}
|
|
43480
|
+
if (isStopped()) {
|
|
43481
|
+
return;
|
|
43482
|
+
}
|
|
43483
|
+
if (restarted) {
|
|
43484
|
+
try {
|
|
43485
|
+
onRestart?.();
|
|
43486
|
+
} catch (error) {
|
|
43487
|
+
reportError(error);
|
|
43488
|
+
}
|
|
43489
|
+
return;
|
|
43490
|
+
}
|
|
43491
|
+
}
|
|
43492
|
+
fail(new StreamFailedError(retryAttempts));
|
|
43493
|
+
} finally {
|
|
43494
|
+
recovering = false;
|
|
43563
43495
|
}
|
|
43564
43496
|
};
|
|
43565
|
-
const
|
|
43566
|
-
if (
|
|
43567
|
-
|
|
43568
|
-
}
|
|
43569
|
-
|
|
43570
|
-
|
|
43497
|
+
const recover = () => {
|
|
43498
|
+
if (stopped || recovering) {
|
|
43499
|
+
return;
|
|
43500
|
+
}
|
|
43501
|
+
if (!retryOnFail) {
|
|
43502
|
+
fail(new StreamFailedError(0));
|
|
43503
|
+
return;
|
|
43571
43504
|
}
|
|
43505
|
+
recovering = true;
|
|
43506
|
+
void restart();
|
|
43572
43507
|
};
|
|
43508
|
+
function onNativeClose(native) {
|
|
43509
|
+
if (!isCurrent(native) || native.closed) {
|
|
43510
|
+
return;
|
|
43511
|
+
}
|
|
43512
|
+
native.closed = true;
|
|
43513
|
+
onFail?.();
|
|
43514
|
+
if (native.ready) {
|
|
43515
|
+
recover();
|
|
43516
|
+
}
|
|
43517
|
+
}
|
|
43518
|
+
let started = false;
|
|
43573
43519
|
try {
|
|
43574
|
-
|
|
43575
|
-
onFail?.();
|
|
43576
|
-
startRetry();
|
|
43577
|
-
});
|
|
43578
|
-
await streamCloser.waitForReady();
|
|
43579
|
-
asyncStream.onDone = () => {
|
|
43580
|
-
streamCloser.end();
|
|
43581
|
-
};
|
|
43520
|
+
started = await open2();
|
|
43582
43521
|
} catch (error) {
|
|
43583
|
-
|
|
43584
|
-
|
|
43522
|
+
reportError(error);
|
|
43523
|
+
}
|
|
43524
|
+
if (!started) {
|
|
43525
|
+
recover();
|
|
43585
43526
|
}
|
|
43586
43527
|
return createAsyncStreamProxy(asyncStream);
|
|
43587
43528
|
};
|
|
@@ -45751,7 +45692,7 @@ var require_retry_promise = __commonJS({
|
|
|
45751
45692
|
return true;
|
|
45752
45693
|
}
|
|
45753
45694
|
};
|
|
45754
|
-
function
|
|
45695
|
+
function wait2(ms) {
|
|
45755
45696
|
return __awaiter(this, void 0, void 0, function() {
|
|
45756
45697
|
return __generator(this, function(_a) {
|
|
45757
45698
|
return [2, new Promise(function(resolve14) {
|
|
@@ -45760,7 +45701,7 @@ var require_retry_promise = __commonJS({
|
|
|
45760
45701
|
});
|
|
45761
45702
|
});
|
|
45762
45703
|
}
|
|
45763
|
-
exports2.wait =
|
|
45704
|
+
exports2.wait = wait2;
|
|
45764
45705
|
function retry2(f, config) {
|
|
45765
45706
|
return __awaiter(this, void 0, void 0, function() {
|
|
45766
45707
|
var effectiveConfig;
|
|
@@ -45850,7 +45791,7 @@ var require_retry_promise = __commonJS({
|
|
|
45850
45791
|
return [3, 5];
|
|
45851
45792
|
case 5:
|
|
45852
45793
|
millisToWait = delay(i + 1, config.delay);
|
|
45853
|
-
return [4,
|
|
45794
|
+
return [4, wait2(millisToWait > config.maxBackOff ? config.maxBackOff : millisToWait)];
|
|
45854
45795
|
case 6:
|
|
45855
45796
|
_a.sent();
|
|
45856
45797
|
if (done()) {
|
|
@@ -53724,7 +53665,7 @@ var init_withResolvers = __esm({
|
|
|
53724
53665
|
});
|
|
53725
53666
|
|
|
53726
53667
|
// ../../node_modules/viem/_esm/utils/promise/createBatchScheduler.js
|
|
53727
|
-
function createBatchScheduler({ fn, id, shouldSplitBatch, wait:
|
|
53668
|
+
function createBatchScheduler({ fn, id, shouldSplitBatch, wait: wait2 = 0, sort }) {
|
|
53728
53669
|
const exec2 = async () => {
|
|
53729
53670
|
const scheduler = getScheduler();
|
|
53730
53671
|
flush2();
|
|
@@ -53762,7 +53703,7 @@ function createBatchScheduler({ fn, id, shouldSplitBatch, wait: wait3 = 0, sort
|
|
|
53762
53703
|
return promise;
|
|
53763
53704
|
}
|
|
53764
53705
|
setScheduler({ args, resolve: resolve14, reject });
|
|
53765
|
-
setTimeout(exec2,
|
|
53706
|
+
setTimeout(exec2, wait2);
|
|
53766
53707
|
return promise;
|
|
53767
53708
|
}
|
|
53768
53709
|
};
|
|
@@ -53828,7 +53769,7 @@ var init_observe = __esm({
|
|
|
53828
53769
|
});
|
|
53829
53770
|
|
|
53830
53771
|
// ../../node_modules/viem/_esm/utils/wait.js
|
|
53831
|
-
async function
|
|
53772
|
+
async function wait(time) {
|
|
53832
53773
|
return new Promise((res) => setTimeout(res, time));
|
|
53833
53774
|
}
|
|
53834
53775
|
var init_wait = __esm({
|
|
@@ -53845,12 +53786,12 @@ function poll(fn, { emitOnBegin, initialWaitTime, interval }) {
|
|
|
53845
53786
|
if (emitOnBegin)
|
|
53846
53787
|
data = await fn({ unpoll: unwatch });
|
|
53847
53788
|
const initialWait = await initialWaitTime?.(data) ?? interval;
|
|
53848
|
-
await
|
|
53789
|
+
await wait(initialWait);
|
|
53849
53790
|
const poll2 = async () => {
|
|
53850
53791
|
if (!active)
|
|
53851
53792
|
return;
|
|
53852
53793
|
await fn({ unpoll: unwatch });
|
|
53853
|
-
await
|
|
53794
|
+
await wait(interval);
|
|
53854
53795
|
poll2();
|
|
53855
53796
|
};
|
|
53856
53797
|
poll2();
|
|
@@ -54214,7 +54155,7 @@ function withRetry(fn, { delay: delay_ = 100, retryCount = 2, shouldRetry: shoul
|
|
|
54214
54155
|
const retry2 = async ({ error }) => {
|
|
54215
54156
|
const delay = typeof delay_ === "function" ? delay_({ count, error }) : delay_;
|
|
54216
54157
|
if (delay)
|
|
54217
|
-
await
|
|
54158
|
+
await wait(delay);
|
|
54218
54159
|
attemptRetry({ count: count + 1 });
|
|
54219
54160
|
};
|
|
54220
54161
|
try {
|
|
@@ -56679,7 +56620,7 @@ var init_transport = __esm({
|
|
|
56679
56620
|
function http(url, config = {}) {
|
|
56680
56621
|
const { batch, fetchFn, fetchOptions, key = "http", methods, name = "HTTP JSON-RPC", onFetchRequest, onFetchResponse, retryDelay, raw } = config;
|
|
56681
56622
|
return ({ chain, retryCount: retryCount_, timeout: timeout_ }) => {
|
|
56682
|
-
const { batchSize = 1e3, wait:
|
|
56623
|
+
const { batchSize = 1e3, wait: wait2 = 0 } = typeof batch === "object" ? batch : {};
|
|
56683
56624
|
const retryCount = config.retryCount ?? retryCount_;
|
|
56684
56625
|
const timeout = timeout_ ?? config.timeout ?? 1e4;
|
|
56685
56626
|
const url_ = url || chain?.rpcUrls.default.http[0];
|
|
@@ -56700,7 +56641,7 @@ function http(url, config = {}) {
|
|
|
56700
56641
|
const body = { method, params };
|
|
56701
56642
|
const { schedule } = createBatchScheduler({
|
|
56702
56643
|
id: url_,
|
|
56703
|
-
wait:
|
|
56644
|
+
wait: wait2,
|
|
56704
56645
|
shouldSplitBatch(requests) {
|
|
56705
56646
|
return requests.length > batchSize;
|
|
56706
56647
|
},
|
|
@@ -57039,7 +56980,7 @@ var init_dist4 = __esm({
|
|
|
57039
56980
|
init_accounts();
|
|
57040
56981
|
init_chains();
|
|
57041
56982
|
import_node_crypto10 = require("node:crypto");
|
|
57042
|
-
version2 = "2.3.
|
|
56983
|
+
version2 = "2.3.1";
|
|
57043
56984
|
fromSelf = (message, client) => {
|
|
57044
56985
|
return message.senderInboxId === client.inboxId;
|
|
57045
56986
|
};
|
|
@@ -58987,6 +58928,9 @@ function replayScanBackoffWithJitterMs(consecutiveFailures, randomValue = Math.r
|
|
|
58987
58928
|
const jitteredMs = Math.round(baseMs * (0.9 + boundedRandom * 0.2));
|
|
58988
58929
|
return Math.min(REPLAY_SCAN_MAX_BACKOFF_MS, jitteredMs);
|
|
58989
58930
|
}
|
|
58931
|
+
function isListenHealthy(outcome) {
|
|
58932
|
+
return outcome === "started" || outcome === "retrying";
|
|
58933
|
+
}
|
|
58990
58934
|
function isOfflineReplayForTrigger(trigger) {
|
|
58991
58935
|
return trigger === "startup";
|
|
58992
58936
|
}
|
|
@@ -59014,7 +58958,7 @@ function createOfflineReplayAddressSummary(address) {
|
|
|
59014
58958
|
durationMs: 0
|
|
59015
58959
|
};
|
|
59016
58960
|
}
|
|
59017
|
-
var import_node_fs24, 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;
|
|
58961
|
+
var import_node_fs24, 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, XmtpClientCreateBlockedError, XmtpService;
|
|
59018
58962
|
var init_xmtp_sdk = __esm({
|
|
59019
58963
|
"../core/src/xmtp-sdk/index.ts"() {
|
|
59020
58964
|
"use strict";
|
|
@@ -59146,6 +59090,18 @@ var init_xmtp_sdk = __esm({
|
|
|
59146
59090
|
minAvailablePluginVersion: (value) => typeof value === "string",
|
|
59147
59091
|
extConfig: (value) => isRecord5(value) && (value.tips === void 0 || isRecord5(value.tips) && Object.values(value.tips).every((item) => typeof item === "string"))
|
|
59148
59092
|
};
|
|
59093
|
+
XmtpClientCreateBlockedError = class extends Error {
|
|
59094
|
+
reason;
|
|
59095
|
+
address;
|
|
59096
|
+
agentId;
|
|
59097
|
+
constructor(reason, address, agentId) {
|
|
59098
|
+
super(`xmtp client create blocked (${reason})`);
|
|
59099
|
+
this.name = "XmtpClientCreateBlockedError";
|
|
59100
|
+
this.reason = reason;
|
|
59101
|
+
this.address = address;
|
|
59102
|
+
this.agentId = agentId;
|
|
59103
|
+
}
|
|
59104
|
+
};
|
|
59149
59105
|
XmtpService = class _XmtpService {
|
|
59150
59106
|
static instance = null;
|
|
59151
59107
|
env = process.env.XMTP_ENV ?? "production";
|
|
@@ -59183,6 +59139,25 @@ var init_xmtp_sdk = __esm({
|
|
|
59183
59139
|
streamRecoverySetTimeout = (callback, delayMs) => setTimeout(callback, delayMs);
|
|
59184
59140
|
streamRecoveryClearTimeout = (timer) => clearTimeout(timer);
|
|
59185
59141
|
streamStartSetTimeout = (callback, delayMs) => setTimeout(callback, delayMs);
|
|
59142
|
+
xmtpAgentFactory = createAgentWithInstallationPrune;
|
|
59143
|
+
// Old clients whose close() was not confirmed. Keyed by lower-cased address.
|
|
59144
|
+
// The reference is kept only for controlled cleanup; it is never served.
|
|
59145
|
+
pendingReleaseByAddress = /* @__PURE__ */ new Map();
|
|
59146
|
+
// Addresses whose pending release was confirmed late (after the caller gave
|
|
59147
|
+
// up waiting) and still need a replacement client on the next recycle.
|
|
59148
|
+
releaseConfirmedNeedsCreate = /* @__PURE__ */ new Set();
|
|
59149
|
+
// Lower-cased addresses owned by a create. The slot is held from before the
|
|
59150
|
+
// SDK factory runs until the new client is registered in `clients` (or the
|
|
59151
|
+
// create failed), so no flow can observe "no lock and no client".
|
|
59152
|
+
clientCreateInFlight = /* @__PURE__ */ new Set();
|
|
59153
|
+
// Clients whose close() was confirmed; a repeated release is a no-op.
|
|
59154
|
+
releasedClients = /* @__PURE__ */ new WeakSet();
|
|
59155
|
+
// One listener setup per client, shared by concurrent init/refresh callers.
|
|
59156
|
+
listenTaskByClient = /* @__PURE__ */ new WeakMap();
|
|
59157
|
+
inboundReplayGateOwners = /* @__PURE__ */ new WeakMap();
|
|
59158
|
+
releaseWaitTimeoutMs = 3e4;
|
|
59159
|
+
releaseWaitSetTimeout = (callback, delayMs) => setTimeout(callback, delayMs);
|
|
59160
|
+
releaseWaitClearTimeout = (timer) => clearTimeout(timer);
|
|
59186
59161
|
nextClientGeneration = 1;
|
|
59187
59162
|
clientGenerationByClient = /* @__PURE__ */ new WeakMap();
|
|
59188
59163
|
resolveStartupReplayCompletion;
|
|
@@ -59331,6 +59306,56 @@ var init_xmtp_sdk = __esm({
|
|
|
59331
59306
|
return { ok: remaining.length === 0, failures: remaining };
|
|
59332
59307
|
}
|
|
59333
59308
|
async createClientForAgent(agentInfo, options = {}) {
|
|
59309
|
+
const address = agentInfo.communicationAddress;
|
|
59310
|
+
const addressKey = address.toLowerCase();
|
|
59311
|
+
let blockedReason;
|
|
59312
|
+
if (this.pendingReleaseByAddress.has(addressKey)) {
|
|
59313
|
+
blockedReason = "release_pending";
|
|
59314
|
+
} else if (this.clientCreateInFlight.has(addressKey)) {
|
|
59315
|
+
blockedReason = "create_in_flight";
|
|
59316
|
+
} else if (this.getClientByAddress(address)) {
|
|
59317
|
+
blockedReason = "client_active";
|
|
59318
|
+
}
|
|
59319
|
+
if (blockedReason) {
|
|
59320
|
+
throw new XmtpClientCreateBlockedError(
|
|
59321
|
+
blockedReason,
|
|
59322
|
+
address,
|
|
59323
|
+
agentInfo.agentId
|
|
59324
|
+
);
|
|
59325
|
+
}
|
|
59326
|
+
this.clientCreateInFlight.add(addressKey);
|
|
59327
|
+
try {
|
|
59328
|
+
const created = await this.createClientForAgentGuarded(agentInfo, options);
|
|
59329
|
+
await this.registerCreatedClient(created, options.logPrefix ?? "[xmtp-sdk]");
|
|
59330
|
+
return created;
|
|
59331
|
+
} finally {
|
|
59332
|
+
this.clientCreateInFlight.delete(addressKey);
|
|
59333
|
+
}
|
|
59334
|
+
}
|
|
59335
|
+
// Ownership hand-off, still inside the create slot: the new client becomes
|
|
59336
|
+
// visible in `clients` before the slot is released. Never overwrites an
|
|
59337
|
+
// existing registration; a conflicting new object is released, not dropped.
|
|
59338
|
+
async registerCreatedClient(created, phase) {
|
|
59339
|
+
const { address, agent, agentInfo } = created;
|
|
59340
|
+
const addressKey = address.toLowerCase();
|
|
59341
|
+
const existing = this.getClientByAddress(address);
|
|
59342
|
+
if (existing && existing !== agent || this.pendingReleaseByAddress.has(addressKey)) {
|
|
59343
|
+
const reason = existing ? "client_active" : "release_pending";
|
|
59344
|
+
logWithTimestamp(
|
|
59345
|
+
`[xmtp-sdk] create registration conflict (${reason}): ${address} (agentId=${agentInfo.agentId}), releasing the new client`
|
|
59346
|
+
);
|
|
59347
|
+
await this.releaseClient(
|
|
59348
|
+
address,
|
|
59349
|
+
agent,
|
|
59350
|
+
agentInfo.agentId,
|
|
59351
|
+
`${phase}/register-conflict`
|
|
59352
|
+
);
|
|
59353
|
+
throw new XmtpClientCreateBlockedError(reason, address, agentInfo.agentId);
|
|
59354
|
+
}
|
|
59355
|
+
this.stoppedAddresses.delete(addressKey);
|
|
59356
|
+
this.clients.set(address, agent);
|
|
59357
|
+
}
|
|
59358
|
+
async createClientForAgentGuarded(agentInfo, options = {}) {
|
|
59334
59359
|
const address = agentInfo.communicationAddress;
|
|
59335
59360
|
const phase = options.logPrefix ?? "[xmtp-sdk]";
|
|
59336
59361
|
const cooldown = getXmtpCreationCooldown();
|
|
@@ -59359,7 +59384,7 @@ var init_xmtp_sdk = __esm({
|
|
|
59359
59384
|
try {
|
|
59360
59385
|
const signer = this.tools.createSigner(agentInfo);
|
|
59361
59386
|
const dbPath = (inboxId2) => `${this.dataDir}/${inboxId2}-${this.env}.db3`;
|
|
59362
|
-
const agent = await
|
|
59387
|
+
const agent = await this.xmtpAgentFactory(signer, {
|
|
59363
59388
|
dbPath,
|
|
59364
59389
|
env: this.env
|
|
59365
59390
|
}, {
|
|
@@ -59368,6 +59393,7 @@ var init_xmtp_sdk = __esm({
|
|
|
59368
59393
|
logPrefix: options.logPrefix
|
|
59369
59394
|
});
|
|
59370
59395
|
cooldown.recordCreateSuccess(decision);
|
|
59396
|
+
this.releaseConfirmedNeedsCreate.delete(address.toLowerCase());
|
|
59371
59397
|
if (decision.mode === "probe") {
|
|
59372
59398
|
logger.info(LogEvent.XMTP_RATE_LIMIT_RECOVERED, {
|
|
59373
59399
|
onchainosAgentId: agentInfo.agentId,
|
|
@@ -59405,6 +59431,128 @@ var init_xmtp_sdk = __esm({
|
|
|
59405
59431
|
throw err2;
|
|
59406
59432
|
}
|
|
59407
59433
|
}
|
|
59434
|
+
logReleaseNotConfirmed(address, agentId, phase, reason, err2) {
|
|
59435
|
+
logger.error(
|
|
59436
|
+
LogEvent.XMTP_CLIENT_CLOSE_FAILED,
|
|
59437
|
+
err2 instanceof Error ? err2 : new Error(`xmtp client close not confirmed (${reason})`),
|
|
59438
|
+
{ walletAddress: address, onchainosAgentId: agentId, phase, reason }
|
|
59439
|
+
);
|
|
59440
|
+
}
|
|
59441
|
+
// Single release entry (recycle / refresh remove / failed replacement).
|
|
59442
|
+
// Confirmation is ONLY a successful client.close(); a timeout, a missing
|
|
59443
|
+
// close() or a close failure keeps the old reference in
|
|
59444
|
+
// pendingReleaseByAddress and blocks new creates for that address.
|
|
59445
|
+
async releaseClient(address, client, agentId, phase) {
|
|
59446
|
+
const key = address.toLowerCase();
|
|
59447
|
+
if (this.releasedClients.has(client)) {
|
|
59448
|
+
this.unpublishClient(address, client, phase);
|
|
59449
|
+
return true;
|
|
59450
|
+
}
|
|
59451
|
+
const existing = this.pendingReleaseByAddress.get(key);
|
|
59452
|
+
if (existing?.inFlight) {
|
|
59453
|
+
this.unpublishClient(address, client, phase);
|
|
59454
|
+
return false;
|
|
59455
|
+
}
|
|
59456
|
+
const entry = existing ?? { client, agentId, phase };
|
|
59457
|
+
entry.client = client;
|
|
59458
|
+
entry.agentId = agentId;
|
|
59459
|
+
entry.phase = phase;
|
|
59460
|
+
this.pendingReleaseByAddress.set(key, entry);
|
|
59461
|
+
this.unpublishClient(address, client, phase);
|
|
59462
|
+
let timedOut = false;
|
|
59463
|
+
const task = stopAndCloseXmtpClient(client, {
|
|
59464
|
+
address,
|
|
59465
|
+
agentId,
|
|
59466
|
+
phase,
|
|
59467
|
+
onCloseError: (err2) => this.logReleaseNotConfirmed(address, agentId, phase, "close_threw", err2)
|
|
59468
|
+
}).then((result) => {
|
|
59469
|
+
if (!result.stopped) {
|
|
59470
|
+
logWithTimestamp(
|
|
59471
|
+
`[xmtp-sdk] release: stop failed but close proceeded: ${address} (agentId=${agentId}) phase=${phase}`
|
|
59472
|
+
);
|
|
59473
|
+
}
|
|
59474
|
+
entry.inFlight = void 0;
|
|
59475
|
+
if (result.closed) {
|
|
59476
|
+
this.releasedClients.add(client);
|
|
59477
|
+
}
|
|
59478
|
+
if (result.closed && this.pendingReleaseByAddress.get(key) === entry) {
|
|
59479
|
+
this.pendingReleaseByAddress.delete(key);
|
|
59480
|
+
if (timedOut) {
|
|
59481
|
+
this.releaseConfirmedNeedsCreate.add(key);
|
|
59482
|
+
}
|
|
59483
|
+
}
|
|
59484
|
+
return result;
|
|
59485
|
+
});
|
|
59486
|
+
entry.inFlight = task.then((result) => result.closed);
|
|
59487
|
+
const timeoutHandle = {};
|
|
59488
|
+
const timeoutPromise = new Promise((resolve14) => {
|
|
59489
|
+
timeoutHandle.timer = this.releaseWaitSetTimeout(
|
|
59490
|
+
() => resolve14(null),
|
|
59491
|
+
this.releaseWaitTimeoutMs
|
|
59492
|
+
);
|
|
59493
|
+
});
|
|
59494
|
+
const outcome = await Promise.race([task, timeoutPromise]);
|
|
59495
|
+
if (timeoutHandle.timer !== void 0) {
|
|
59496
|
+
this.releaseWaitClearTimeout(timeoutHandle.timer);
|
|
59497
|
+
}
|
|
59498
|
+
if (outcome === null) {
|
|
59499
|
+
timedOut = true;
|
|
59500
|
+
this.logReleaseNotConfirmed(address, agentId, phase, "close_timeout");
|
|
59501
|
+
return false;
|
|
59502
|
+
}
|
|
59503
|
+
if (outcome.closed) {
|
|
59504
|
+
if (this.pendingReleaseByAddress.get(key) === entry) {
|
|
59505
|
+
this.pendingReleaseByAddress.delete(key);
|
|
59506
|
+
}
|
|
59507
|
+
return true;
|
|
59508
|
+
}
|
|
59509
|
+
if (!outcome.closeFailed) {
|
|
59510
|
+
this.logReleaseNotConfirmed(address, agentId, phase, "close_unavailable");
|
|
59511
|
+
}
|
|
59512
|
+
return false;
|
|
59513
|
+
}
|
|
59514
|
+
// Stops serving `client` to new operations. Every removal is identity
|
|
59515
|
+
// checked, so a late caller can never remove a newer instance (or its replay
|
|
59516
|
+
// gate / recovery / retry state) registered for the same address.
|
|
59517
|
+
unpublishClient(address, client, phase) {
|
|
59518
|
+
const key = address.toLowerCase();
|
|
59519
|
+
let removed = false;
|
|
59520
|
+
for (const [registeredAddress, registered] of this.clients) {
|
|
59521
|
+
if (registered === client && registeredAddress.toLowerCase() === key) {
|
|
59522
|
+
this.clients.delete(registeredAddress);
|
|
59523
|
+
removed = true;
|
|
59524
|
+
}
|
|
59525
|
+
}
|
|
59526
|
+
const gate = this.inboundReplayGates.get(key);
|
|
59527
|
+
if (gate) {
|
|
59528
|
+
const owner = this.inboundReplayGateOwners.get(gate);
|
|
59529
|
+
if (owner === client || owner === void 0 && removed) {
|
|
59530
|
+
this.inboundReplayGates.delete(key);
|
|
59531
|
+
}
|
|
59532
|
+
}
|
|
59533
|
+
this.cancelStreamRecoveryForAddress(address, client);
|
|
59534
|
+
if (removed) {
|
|
59535
|
+
this.replayScanFailuresByAddress.delete(key);
|
|
59536
|
+
this.clearReplayScanRetry(
|
|
59537
|
+
address,
|
|
59538
|
+
phase.startsWith("recycle") ? "client_recycled" : "client_removed"
|
|
59539
|
+
);
|
|
59540
|
+
}
|
|
59541
|
+
if (!this.getClientByAddress(address)) {
|
|
59542
|
+
this.stoppedAddresses.add(key);
|
|
59543
|
+
}
|
|
59544
|
+
}
|
|
59545
|
+
async settlePendingRelease(address) {
|
|
59546
|
+
const entry = this.pendingReleaseByAddress.get(address.toLowerCase());
|
|
59547
|
+
if (!entry) {
|
|
59548
|
+
return true;
|
|
59549
|
+
}
|
|
59550
|
+
if (entry.inFlight) {
|
|
59551
|
+
return false;
|
|
59552
|
+
}
|
|
59553
|
+
const retryPhase = entry.phase.endsWith("/retry") ? entry.phase : `${entry.phase}/retry`;
|
|
59554
|
+
return this.releaseClient(address, entry.client, entry.agentId, retryPhase);
|
|
59555
|
+
}
|
|
59408
59556
|
async recordInstallationHealth(params) {
|
|
59409
59557
|
const { address, agent, agentInfo, phase, attempt } = params;
|
|
59410
59558
|
try {
|
|
@@ -59525,8 +59673,6 @@ var init_xmtp_sdk = __esm({
|
|
|
59525
59673
|
const r = results[i];
|
|
59526
59674
|
if (r.status === "fulfilled") {
|
|
59527
59675
|
const { address, agent, agentInfo } = r.value;
|
|
59528
|
-
this.stoppedAddresses.delete(address.toLowerCase());
|
|
59529
|
-
this.clients.set(address, agent);
|
|
59530
59676
|
logWithTimestamp(
|
|
59531
59677
|
`[xmtp-sdk] identity initialized: ${address} (agentId=${agentInfo.agentId})`
|
|
59532
59678
|
);
|
|
@@ -59552,6 +59698,10 @@ var init_xmtp_sdk = __esm({
|
|
|
59552
59698
|
phase: "init",
|
|
59553
59699
|
attempt: "1"
|
|
59554
59700
|
});
|
|
59701
|
+
} else if (r.reason instanceof XmtpClientCreateBlockedError) {
|
|
59702
|
+
logWithTimestamp(
|
|
59703
|
+
`[xmtp-sdk] identity init: create blocked (${r.reason.reason}): ${agents[i].communicationAddress} (agentId=${agents[i].agentId})`
|
|
59704
|
+
);
|
|
59555
59705
|
} else {
|
|
59556
59706
|
failedAgents.push(agents[i]);
|
|
59557
59707
|
if (r.reason instanceof XmtpCreationCooldownSkipError) {
|
|
@@ -59588,8 +59738,6 @@ var init_xmtp_sdk = __esm({
|
|
|
59588
59738
|
const r = retryResults[i];
|
|
59589
59739
|
if (r.status === "fulfilled") {
|
|
59590
59740
|
const { address, agent, agentInfo } = r.value;
|
|
59591
|
-
this.stoppedAddresses.delete(address.toLowerCase());
|
|
59592
|
-
this.clients.set(address, agent);
|
|
59593
59741
|
logWithTimestamp(
|
|
59594
59742
|
`[xmtp-sdk] retry succeeded: ${address} (agentId=${agentInfo.agentId})`
|
|
59595
59743
|
);
|
|
@@ -59615,6 +59763,11 @@ var init_xmtp_sdk = __esm({
|
|
|
59615
59763
|
phase: "init",
|
|
59616
59764
|
attempt: "2"
|
|
59617
59765
|
});
|
|
59766
|
+
} else if (r.reason instanceof XmtpClientCreateBlockedError) {
|
|
59767
|
+
const info = failedAgents[i];
|
|
59768
|
+
logWithTimestamp(
|
|
59769
|
+
`[xmtp-sdk] retry create blocked (${r.reason.reason}): ${info.communicationAddress} (agentId=${info.agentId})`
|
|
59770
|
+
);
|
|
59618
59771
|
} else if (r.reason instanceof XmtpCreationCooldownSkipError) {
|
|
59619
59772
|
const info = failedAgents[i];
|
|
59620
59773
|
logWithTimestamp(
|
|
@@ -59697,36 +59850,38 @@ var init_xmtp_sdk = __esm({
|
|
|
59697
59850
|
throw err2;
|
|
59698
59851
|
}
|
|
59699
59852
|
}
|
|
59853
|
+
for (const pendingKey of [...this.pendingReleaseByAddress.keys()]) {
|
|
59854
|
+
const settled = await this.settlePendingRelease(pendingKey);
|
|
59855
|
+
logWithTimestamp(
|
|
59856
|
+
`[xmtp-sdk] refresh: pending release ${pendingKey} ${settled ? "confirmed" : "still pending"}`
|
|
59857
|
+
);
|
|
59858
|
+
}
|
|
59700
59859
|
const oldAddresses = new Set(
|
|
59701
|
-
this.allAgents.map((a) => a.communicationAddress)
|
|
59860
|
+
this.allAgents.map((a) => a.communicationAddress.toLowerCase())
|
|
59861
|
+
);
|
|
59862
|
+
const newAddresses = new Set(
|
|
59863
|
+
newAgents.map((a) => a.communicationAddress.toLowerCase())
|
|
59702
59864
|
);
|
|
59703
|
-
const newAddresses = new Set(newAgents.map((a) => a.communicationAddress));
|
|
59704
59865
|
const added = newAgents.filter(
|
|
59705
|
-
(a) => !oldAddresses.has(a.communicationAddress) || !this.
|
|
59866
|
+
(a) => !oldAddresses.has(a.communicationAddress.toLowerCase()) || !this.getClientByAddress(a.communicationAddress)
|
|
59706
59867
|
);
|
|
59707
59868
|
const removed = this.allAgents.filter(
|
|
59708
|
-
(a) => !newAddresses.has(a.communicationAddress)
|
|
59869
|
+
(a) => !newAddresses.has(a.communicationAddress.toLowerCase())
|
|
59709
59870
|
);
|
|
59710
59871
|
this.allAgents = newAgents;
|
|
59711
59872
|
for (const agentInfo of removed) {
|
|
59712
59873
|
const address = agentInfo.communicationAddress;
|
|
59713
|
-
const client = this.
|
|
59874
|
+
const client = this.getClientByAddress(address);
|
|
59714
59875
|
if (client) {
|
|
59715
59876
|
try {
|
|
59716
|
-
this.
|
|
59717
|
-
this.stoppedAddresses.add(address.toLowerCase());
|
|
59718
|
-
await stopAndCloseXmtpClient(client, {
|
|
59877
|
+
const released = await this.releaseClient(
|
|
59719
59878
|
address,
|
|
59720
|
-
|
|
59721
|
-
|
|
59722
|
-
|
|
59723
|
-
|
|
59724
|
-
err2 instanceof Error ? err2 : new Error(String(err2)),
|
|
59725
|
-
{ walletAddress: address, onchainosAgentId: agentInfo.agentId, phase: "refresh/remove" }
|
|
59726
|
-
)
|
|
59727
|
-
});
|
|
59879
|
+
client,
|
|
59880
|
+
agentInfo.agentId,
|
|
59881
|
+
"refresh/remove"
|
|
59882
|
+
);
|
|
59728
59883
|
logWithTimestamp(
|
|
59729
|
-
`[xmtp-sdk] refresh: stopped client: ${address} (agentId=${agentInfo.agentId})`
|
|
59884
|
+
`[xmtp-sdk] refresh: stopped client: ${address} (agentId=${agentInfo.agentId}) released=${released}`
|
|
59730
59885
|
);
|
|
59731
59886
|
} catch (err2) {
|
|
59732
59887
|
logWithTimestamp(`[xmtp-sdk] refresh: failed to stop client: ${address}`, err2);
|
|
@@ -59736,10 +59891,6 @@ var init_xmtp_sdk = __esm({
|
|
|
59736
59891
|
phase: "stop-client"
|
|
59737
59892
|
});
|
|
59738
59893
|
}
|
|
59739
|
-
this.clients.delete(address);
|
|
59740
|
-
this.inboundReplayGates.delete(address.toLowerCase());
|
|
59741
|
-
this.replayScanFailuresByAddress.delete(address.toLowerCase());
|
|
59742
|
-
this.clearReplayScanRetry(address, "client_removed");
|
|
59743
59894
|
logger.info(LogEvent.AGENT_CLIENT_REMOVED, {
|
|
59744
59895
|
...agentExtras({
|
|
59745
59896
|
walletAddress: address,
|
|
@@ -59781,8 +59932,6 @@ var init_xmtp_sdk = __esm({
|
|
|
59781
59932
|
const r = addResults[i];
|
|
59782
59933
|
if (r.status === "fulfilled") {
|
|
59783
59934
|
const { address, agentInfo } = r.value;
|
|
59784
|
-
this.stoppedAddresses.delete(address.toLowerCase());
|
|
59785
|
-
this.clients.set(address, r.value.agent);
|
|
59786
59935
|
logWithTimestamp(
|
|
59787
59936
|
`[xmtp-sdk] refresh: identity initialized: ${address} (agentId=${agentInfo.agentId})`
|
|
59788
59937
|
);
|
|
@@ -59809,6 +59958,10 @@ var init_xmtp_sdk = __esm({
|
|
|
59809
59958
|
phase: "refresh",
|
|
59810
59959
|
attempt: "1"
|
|
59811
59960
|
});
|
|
59961
|
+
} else if (r.reason instanceof XmtpClientCreateBlockedError) {
|
|
59962
|
+
logWithTimestamp(
|
|
59963
|
+
`[xmtp-sdk] refresh: create blocked (${r.reason.reason}): ${added[i].communicationAddress} (agentId=${added[i].agentId})`
|
|
59964
|
+
);
|
|
59812
59965
|
} else {
|
|
59813
59966
|
failedAgents.push(added[i]);
|
|
59814
59967
|
if (r.reason instanceof XmtpCreationCooldownSkipError) {
|
|
@@ -59848,8 +60001,6 @@ var init_xmtp_sdk = __esm({
|
|
|
59848
60001
|
const r = retryResults[i];
|
|
59849
60002
|
if (r.status === "fulfilled") {
|
|
59850
60003
|
const { address, agentInfo } = r.value;
|
|
59851
|
-
this.stoppedAddresses.delete(address.toLowerCase());
|
|
59852
|
-
this.clients.set(address, r.value.agent);
|
|
59853
60004
|
logWithTimestamp(
|
|
59854
60005
|
`[xmtp-sdk] refresh: retry succeeded: ${address} (agentId=${agentInfo.agentId})`
|
|
59855
60006
|
);
|
|
@@ -59876,6 +60027,11 @@ var init_xmtp_sdk = __esm({
|
|
|
59876
60027
|
phase: "refresh",
|
|
59877
60028
|
attempt: "2"
|
|
59878
60029
|
});
|
|
60030
|
+
} else if (r.reason instanceof XmtpClientCreateBlockedError) {
|
|
60031
|
+
const info = failedAgents[i];
|
|
60032
|
+
logWithTimestamp(
|
|
60033
|
+
`[xmtp-sdk] refresh: retry create blocked (${r.reason.reason}): ${info.communicationAddress} (agentId=${info.agentId})`
|
|
60034
|
+
);
|
|
59879
60035
|
} else if (r.reason instanceof XmtpCreationCooldownSkipError) {
|
|
59880
60036
|
const info = failedAgents[i];
|
|
59881
60037
|
logWithTimestamp(
|
|
@@ -59901,7 +60057,8 @@ var init_xmtp_sdk = __esm({
|
|
|
59901
60057
|
}
|
|
59902
60058
|
}
|
|
59903
60059
|
await this.startListeningForAddresses(
|
|
59904
|
-
added.map((a) => a.communicationAddress)
|
|
60060
|
+
added.map((a) => a.communicationAddress),
|
|
60061
|
+
"refresh/listen-failed"
|
|
59905
60062
|
);
|
|
59906
60063
|
for (const agentInfo of added) {
|
|
59907
60064
|
const address = agentInfo.communicationAddress;
|
|
@@ -59966,30 +60123,42 @@ var init_xmtp_sdk = __esm({
|
|
|
59966
60123
|
}
|
|
59967
60124
|
for (const agentInfo of this.allAgents) {
|
|
59968
60125
|
const address = agentInfo.communicationAddress;
|
|
59969
|
-
const
|
|
59970
|
-
|
|
60126
|
+
const addressKey = address.toLowerCase();
|
|
60127
|
+
const oldClient = this.getClientByAddress(address);
|
|
60128
|
+
const hasPendingRelease = this.pendingReleaseByAddress.has(addressKey) || this.releaseConfirmedNeedsCreate.has(addressKey);
|
|
60129
|
+
if (!oldClient && !hasPendingRelease) {
|
|
59971
60130
|
continue;
|
|
59972
60131
|
}
|
|
59973
|
-
|
|
59974
|
-
|
|
59975
|
-
|
|
59976
|
-
|
|
59977
|
-
|
|
59978
|
-
address
|
|
59979
|
-
|
|
59980
|
-
|
|
59981
|
-
|
|
59982
|
-
|
|
59983
|
-
|
|
59984
|
-
|
|
59985
|
-
|
|
59986
|
-
|
|
59987
|
-
|
|
59988
|
-
|
|
59989
|
-
|
|
59990
|
-
|
|
60132
|
+
if (!oldClient) {
|
|
60133
|
+
let settled = false;
|
|
60134
|
+
try {
|
|
60135
|
+
settled = await this.settlePendingRelease(address);
|
|
60136
|
+
} catch (err2) {
|
|
60137
|
+
logWithTimestamp(`[xmtp-sdk] recycle: pending release retry failed: ${address}`, err2);
|
|
60138
|
+
}
|
|
60139
|
+
if (!settled) {
|
|
60140
|
+
failed++;
|
|
60141
|
+
continue;
|
|
60142
|
+
}
|
|
60143
|
+
} else {
|
|
60144
|
+
let released = false;
|
|
60145
|
+
try {
|
|
60146
|
+
released = await this.releaseClient(
|
|
60147
|
+
address,
|
|
60148
|
+
oldClient,
|
|
60149
|
+
agentInfo.agentId,
|
|
60150
|
+
"recycle"
|
|
60151
|
+
);
|
|
60152
|
+
} catch (err2) {
|
|
60153
|
+
logWithTimestamp(`[xmtp-sdk] recycle: failed to stop client: ${address}`, err2);
|
|
60154
|
+
logger.error(LogEvent.AGENT_REFRESH_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), {
|
|
60155
|
+
walletAddress: address,
|
|
60156
|
+
onchainosAgentId: agentInfo.agentId,
|
|
60157
|
+
phase: "recycle/stop-client"
|
|
60158
|
+
});
|
|
60159
|
+
}
|
|
59991
60160
|
logWithTimestamp(
|
|
59992
|
-
`[xmtp-sdk] recycle: stopped client: ${address} (agentId=${agentInfo.agentId})`
|
|
60161
|
+
`[xmtp-sdk] recycle: stopped client: ${address} (agentId=${agentInfo.agentId}) released=${released}`
|
|
59993
60162
|
);
|
|
59994
60163
|
logger.info(LogEvent.AGENT_CLIENT_REMOVED, {
|
|
59995
60164
|
...agentExtras({
|
|
@@ -59999,23 +60168,18 @@ var init_xmtp_sdk = __esm({
|
|
|
59999
60168
|
}),
|
|
60000
60169
|
phase: "recycle"
|
|
60001
60170
|
});
|
|
60002
|
-
|
|
60003
|
-
|
|
60004
|
-
|
|
60005
|
-
|
|
60006
|
-
logger.error(LogEvent.AGENT_REFRESH_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), {
|
|
60007
|
-
walletAddress: address,
|
|
60008
|
-
onchainosAgentId: agentInfo.agentId,
|
|
60009
|
-
phase: "recycle/stop-client"
|
|
60010
|
-
});
|
|
60011
|
-
continue;
|
|
60171
|
+
if (!released) {
|
|
60172
|
+
failed++;
|
|
60173
|
+
continue;
|
|
60174
|
+
}
|
|
60012
60175
|
}
|
|
60176
|
+
let newAgent;
|
|
60177
|
+
let newAgentReleased = false;
|
|
60013
60178
|
try {
|
|
60014
60179
|
const { agent } = await this.createClientForAgent(agentInfo, {
|
|
60015
60180
|
logPrefix: "[xmtp-sdk:recycle]"
|
|
60016
60181
|
});
|
|
60017
|
-
|
|
60018
|
-
this.clients.set(address, agent);
|
|
60182
|
+
newAgent = agent;
|
|
60019
60183
|
logWithTimestamp(
|
|
60020
60184
|
`[xmtp-sdk] recycle: identity initialized: ${address} (agentId=${agentInfo.agentId})`
|
|
60021
60185
|
);
|
|
@@ -60039,7 +60203,13 @@ var init_xmtp_sdk = __esm({
|
|
|
60039
60203
|
agentInfo,
|
|
60040
60204
|
phase: "recycle"
|
|
60041
60205
|
});
|
|
60042
|
-
await this.startListeningForAddresses([address]);
|
|
60206
|
+
const listen = (await this.startListeningForAddresses([address], "recycle/listen-failed")).get(address);
|
|
60207
|
+
if (listen?.client !== agent || !isListenHealthy(listen.outcome)) {
|
|
60208
|
+
newAgentReleased = listen?.client === agent && listen.outcome === "failed";
|
|
60209
|
+
throw new Error(
|
|
60210
|
+
`xmtp listener not started (${listen?.client === agent ? listen.outcome : "client_replaced"})`
|
|
60211
|
+
);
|
|
60212
|
+
}
|
|
60043
60213
|
const replayGate = this.inboundReplayGates.get(addressKey);
|
|
60044
60214
|
let replaySummary;
|
|
60045
60215
|
try {
|
|
@@ -60058,8 +60228,21 @@ var init_xmtp_sdk = __esm({
|
|
|
60058
60228
|
recycled++;
|
|
60059
60229
|
} catch (err2) {
|
|
60060
60230
|
failed++;
|
|
60061
|
-
|
|
60062
|
-
|
|
60231
|
+
if (newAgent && !newAgentReleased) {
|
|
60232
|
+
try {
|
|
60233
|
+
await this.releaseClient(
|
|
60234
|
+
address,
|
|
60235
|
+
newAgent,
|
|
60236
|
+
agentInfo.agentId,
|
|
60237
|
+
"recycle/create-failed"
|
|
60238
|
+
);
|
|
60239
|
+
} catch (releaseErr) {
|
|
60240
|
+
logWithTimestamp(
|
|
60241
|
+
`[xmtp-sdk] recycle: failed to release new client: ${address}`,
|
|
60242
|
+
releaseErr
|
|
60243
|
+
);
|
|
60244
|
+
}
|
|
60245
|
+
}
|
|
60063
60246
|
logWithTimestamp(`[xmtp-sdk] recycle: failed to recreate client: ${address}`, err2);
|
|
60064
60247
|
logger.error(
|
|
60065
60248
|
LogEvent.XMTP_CONNECTION_FAILED,
|
|
@@ -60463,7 +60646,7 @@ var init_xmtp_sdk = __esm({
|
|
|
60463
60646
|
}
|
|
60464
60647
|
}
|
|
60465
60648
|
async startListening() {
|
|
60466
|
-
await this.startListeningForAddresses([...this.clients.keys()]);
|
|
60649
|
+
await this.startListeningForAddresses([...this.clients.keys()], "listen-failed");
|
|
60467
60650
|
}
|
|
60468
60651
|
async drainInboundReplayGate(address, expectedGate) {
|
|
60469
60652
|
if (!expectedGate) {
|
|
@@ -60528,11 +60711,22 @@ var init_xmtp_sdk = __esm({
|
|
|
60528
60711
|
);
|
|
60529
60712
|
return gate;
|
|
60530
60713
|
}
|
|
60531
|
-
|
|
60714
|
+
// With `client`, only that client's recovery is cancelled, so a late caller
|
|
60715
|
+
// cannot cancel the recovery of a newer instance on the same address.
|
|
60716
|
+
cancelStreamRecoveryForAddress(address, client) {
|
|
60532
60717
|
const addressKey = address.toLowerCase();
|
|
60533
|
-
const
|
|
60718
|
+
const entry = this.streamRecoveryCleanupByAddress.get(addressKey);
|
|
60719
|
+
if (!entry || client && entry.client !== client) {
|
|
60720
|
+
return;
|
|
60721
|
+
}
|
|
60534
60722
|
this.streamRecoveryCleanupByAddress.delete(addressKey);
|
|
60535
|
-
cleanup
|
|
60723
|
+
entry.cleanup();
|
|
60724
|
+
}
|
|
60725
|
+
// True while `client` is the registered client of `address` (case-insensitive)
|
|
60726
|
+
// and the address is neither stopped nor being released.
|
|
60727
|
+
isCurrentListenOwner(address, client) {
|
|
60728
|
+
const key = address.toLowerCase();
|
|
60729
|
+
return this.getClientByAddress(address) === client && !this.stoppedAddresses.has(key) && !this.pendingReleaseByAddress.has(key);
|
|
60536
60730
|
}
|
|
60537
60731
|
getClientGeneration(client) {
|
|
60538
60732
|
const existing = this.clientGenerationByClient.get(client);
|
|
@@ -60684,10 +60878,17 @@ var init_xmtp_sdk = __esm({
|
|
|
60684
60878
|
this.notifyAgentsWakeupAfterReplay();
|
|
60685
60879
|
return summary;
|
|
60686
60880
|
}
|
|
60687
|
-
|
|
60881
|
+
// Starts (at most once per client) the listener of every registered address
|
|
60882
|
+
// and reports each outcome. A "failed" client, i.e. one with neither a live
|
|
60883
|
+
// listener nor an owned retry task, is released with `releasePhase` before
|
|
60884
|
+
// this returns, so it is never served as a healthy instance.
|
|
60885
|
+
async startListeningForAddresses(addresses, releasePhase = "listen-failed") {
|
|
60688
60886
|
const valid = addresses.filter((addr) => this.clients.has(addr));
|
|
60689
|
-
|
|
60690
|
-
|
|
60887
|
+
const targets = valid.map((address) => ({
|
|
60888
|
+
address,
|
|
60889
|
+
client: this.clients.get(address)
|
|
60890
|
+
}));
|
|
60891
|
+
const listenForClient = async (address, agent) => {
|
|
60691
60892
|
const clientGeneration = this.getClientGeneration(agent);
|
|
60692
60893
|
const addressKey = address.toLowerCase();
|
|
60693
60894
|
const tag = `[xmtp-sdk:${address}]`;
|
|
@@ -60698,6 +60899,11 @@ var init_xmtp_sdk = __esm({
|
|
|
60698
60899
|
onchainosAgentId: onchainosAgent?.agentId,
|
|
60699
60900
|
role: onchainosAgent?.role
|
|
60700
60901
|
};
|
|
60902
|
+
const ownsAddress = () => this.isCurrentListenOwner(address, agent);
|
|
60903
|
+
if (!ownsAddress()) {
|
|
60904
|
+
logWithTimestamp(`${tag} listener setup skipped: client no longer current`);
|
|
60905
|
+
return "skipped";
|
|
60906
|
+
}
|
|
60701
60907
|
try {
|
|
60702
60908
|
await agent.client.conversations.syncAll([
|
|
60703
60909
|
import_node_bindings2.ConsentState.Allowed,
|
|
@@ -60705,13 +60911,21 @@ var init_xmtp_sdk = __esm({
|
|
|
60705
60911
|
]);
|
|
60706
60912
|
logWithTimestamp(`${tag} conversations synced (non-Denied)`);
|
|
60707
60913
|
} catch (err2) {
|
|
60708
|
-
|
|
60914
|
+
if (!ownsAddress()) {
|
|
60915
|
+
logWithTimestamp(`${tag} stale conversation sync failed after replacement, ignored:`, err2);
|
|
60916
|
+
return "skipped";
|
|
60917
|
+
}
|
|
60918
|
+
logWithTimestamp(`${tag} conversation sync failed, listener not started:`, err2);
|
|
60709
60919
|
logger.error(
|
|
60710
60920
|
LogEvent.CONVERSATIONS_STREAM_FAILED,
|
|
60711
60921
|
err2 instanceof Error ? err2 : void 0,
|
|
60712
60922
|
agentExtras(identity)
|
|
60713
60923
|
);
|
|
60714
|
-
return;
|
|
60924
|
+
return "failed";
|
|
60925
|
+
}
|
|
60926
|
+
if (!ownsAddress()) {
|
|
60927
|
+
logWithTimestamp(`${tag} listener setup skipped after sync: client no longer current`);
|
|
60928
|
+
return "skipped";
|
|
60715
60929
|
}
|
|
60716
60930
|
agent.use(loggingMiddleware(identity));
|
|
60717
60931
|
agent.use(selfFilterMiddleware());
|
|
@@ -60740,6 +60954,7 @@ var init_xmtp_sdk = __esm({
|
|
|
60740
60954
|
});
|
|
60741
60955
|
const gate = new InboundReplayGate(inbound);
|
|
60742
60956
|
this.inboundReplayGates.set(address.toLowerCase(), gate);
|
|
60957
|
+
this.inboundReplayGateOwners.set(gate, agent);
|
|
60743
60958
|
agent.use(gate.middleware);
|
|
60744
60959
|
} else {
|
|
60745
60960
|
logWithTimestamp(
|
|
@@ -60757,16 +60972,25 @@ var init_xmtp_sdk = __esm({
|
|
|
60757
60972
|
const MAX_RETRIES = 5;
|
|
60758
60973
|
const BASE_DELAY_MS = 1e3;
|
|
60759
60974
|
const startWithRetry = async (attempt = 0) => {
|
|
60760
|
-
if (
|
|
60975
|
+
if (!ownsAddress()) {
|
|
60761
60976
|
logWithTimestamp(`${tag} start skipped: client stopped or removed`);
|
|
60762
|
-
return;
|
|
60977
|
+
return "skipped";
|
|
60763
60978
|
}
|
|
60764
60979
|
try {
|
|
60765
60980
|
const liveStreamOptions = {
|
|
60766
60981
|
consentStates: [import_node_bindings2.ConsentState.Allowed, import_node_bindings2.ConsentState.Unknown]
|
|
60767
60982
|
};
|
|
60768
60983
|
await agent.start(liveStreamOptions);
|
|
60984
|
+
if (!ownsAddress()) {
|
|
60985
|
+
logWithTimestamp(`${tag} stale agent.start resolved after replacement, ignored`);
|
|
60986
|
+
return "skipped";
|
|
60987
|
+
}
|
|
60988
|
+
return "started";
|
|
60769
60989
|
} catch (err2) {
|
|
60990
|
+
if (!ownsAddress()) {
|
|
60991
|
+
logWithTimestamp(`${tag} stale agent.start failed after replacement, ignored:`, err2);
|
|
60992
|
+
return "skipped";
|
|
60993
|
+
}
|
|
60770
60994
|
logWithTimestamp(`${tag} agent.start error (attempt=${attempt}):`, err2);
|
|
60771
60995
|
logger.error(
|
|
60772
60996
|
LogEvent.AGENT_START_FAILED,
|
|
@@ -60776,17 +61000,27 @@ var init_xmtp_sdk = __esm({
|
|
|
60776
61000
|
attempt: String(attempt)
|
|
60777
61001
|
}
|
|
60778
61002
|
);
|
|
60779
|
-
scheduleRetry(attempt);
|
|
61003
|
+
return scheduleRetry(attempt);
|
|
60780
61004
|
}
|
|
60781
61005
|
};
|
|
60782
61006
|
const scheduleRetry = (attempt) => {
|
|
60783
|
-
if (
|
|
61007
|
+
if (!ownsAddress()) {
|
|
60784
61008
|
logWithTimestamp(`${tag} reconnect skipped: client stopped or removed`);
|
|
60785
|
-
return;
|
|
61009
|
+
return "skipped";
|
|
60786
61010
|
}
|
|
60787
61011
|
if (attempt >= MAX_RETRIES) {
|
|
60788
|
-
logWithTimestamp(
|
|
60789
|
-
|
|
61012
|
+
logWithTimestamp(
|
|
61013
|
+
`${tag} reached max retries (${MAX_RETRIES}), giving up reconnect; releasing client`
|
|
61014
|
+
);
|
|
61015
|
+
void this.releaseClient(
|
|
61016
|
+
address,
|
|
61017
|
+
agent,
|
|
61018
|
+
identity.onchainosAgentId ?? "",
|
|
61019
|
+
"listen/retry-exhausted"
|
|
61020
|
+
).catch((err2) => {
|
|
61021
|
+
logWithTimestamp(`${tag} release after retry exhaustion failed:`, err2);
|
|
61022
|
+
});
|
|
61023
|
+
return "failed";
|
|
60790
61024
|
}
|
|
60791
61025
|
const delay = BASE_DELAY_MS * 2 ** attempt;
|
|
60792
61026
|
logWithTimestamp(`${tag} reconnecting in ${delay}ms (attempt=${attempt + 1})`);
|
|
@@ -60794,6 +61028,7 @@ var init_xmtp_sdk = __esm({
|
|
|
60794
61028
|
() => void startWithRetry(attempt + 1),
|
|
60795
61029
|
delay
|
|
60796
61030
|
);
|
|
61031
|
+
return "retrying";
|
|
60797
61032
|
};
|
|
60798
61033
|
const streamRecovery = new StreamRecoveryTelemetry();
|
|
60799
61034
|
let recoveryTimeout;
|
|
@@ -60813,10 +61048,10 @@ var init_xmtp_sdk = __esm({
|
|
|
60813
61048
|
recoveryStabilityTimeout = void 0;
|
|
60814
61049
|
}
|
|
60815
61050
|
};
|
|
60816
|
-
this.streamRecoveryCleanupByAddress.set(
|
|
60817
|
-
|
|
60818
|
-
cleanupStreamRecovery
|
|
60819
|
-
);
|
|
61051
|
+
this.streamRecoveryCleanupByAddress.set(addressKey, {
|
|
61052
|
+
client: agent,
|
|
61053
|
+
cleanup: cleanupStreamRecovery
|
|
61054
|
+
});
|
|
60820
61055
|
agent.on("unhandledError", (err2) => {
|
|
60821
61056
|
if (recoveryDisposed || this.clients.get(address) !== agent || this.stoppedAddresses.has(addressKey)) {
|
|
60822
61057
|
return;
|
|
@@ -60978,9 +61213,54 @@ var init_xmtp_sdk = __esm({
|
|
|
60978
61213
|
`${tag} agent message event msg=${msg?.id ?? "(unknown)"} kind=${msg?.kind ?? "(unknown)"} conv=${conversation?.id ?? msg?.conversationId ?? "(unknown)"} sender=${msg?.senderInboxId ?? "(unknown)"} isText=${typeof ctx.isText === "function" ? String(ctx.isText()) : "unknown"} preview="${previewDebugContent(msg?.content)}"`
|
|
60979
61214
|
);
|
|
60980
61215
|
});
|
|
60981
|
-
await startWithRetry();
|
|
60982
|
-
logWithTimestamp(`${tag} message listener
|
|
61216
|
+
const outcome = await startWithRetry();
|
|
61217
|
+
logWithTimestamp(`${tag} message listener ${outcome}`);
|
|
61218
|
+
return outcome;
|
|
61219
|
+
};
|
|
61220
|
+
const settled = await parallelMap(targets, async ({ address, client }) => {
|
|
61221
|
+
let task = this.listenTaskByClient.get(client);
|
|
61222
|
+
if (!task) {
|
|
61223
|
+
task = listenForClient(address, client);
|
|
61224
|
+
this.listenTaskByClient.set(client, task);
|
|
61225
|
+
}
|
|
61226
|
+
let outcome;
|
|
61227
|
+
try {
|
|
61228
|
+
outcome = await task;
|
|
61229
|
+
} catch (err2) {
|
|
61230
|
+
logWithTimestamp(`[xmtp-sdk:${address}] listener setup failed:`, err2);
|
|
61231
|
+
logger.error(
|
|
61232
|
+
LogEvent.AGENT_START_FAILED,
|
|
61233
|
+
err2 instanceof Error ? err2 : new Error(String(err2)),
|
|
61234
|
+
{
|
|
61235
|
+
...agentExtras({
|
|
61236
|
+
walletAddress: address,
|
|
61237
|
+
inboxId: client.client?.inboxId,
|
|
61238
|
+
onchainosAgentId: this.getAgentByAddress(address)?.agentId
|
|
61239
|
+
}),
|
|
61240
|
+
phase: "listener-setup"
|
|
61241
|
+
}
|
|
61242
|
+
);
|
|
61243
|
+
outcome = "failed";
|
|
61244
|
+
}
|
|
61245
|
+
if (outcome === "failed") {
|
|
61246
|
+
await this.releaseClient(
|
|
61247
|
+
address,
|
|
61248
|
+
client,
|
|
61249
|
+
this.getAgentByAddress(address)?.agentId ?? "",
|
|
61250
|
+
releasePhase
|
|
61251
|
+
);
|
|
61252
|
+
}
|
|
61253
|
+
return outcome;
|
|
61254
|
+
});
|
|
61255
|
+
const results = /* @__PURE__ */ new Map();
|
|
61256
|
+
targets.forEach(({ address, client }, i) => {
|
|
61257
|
+
const r = settled[i];
|
|
61258
|
+
results.set(address, {
|
|
61259
|
+
client,
|
|
61260
|
+
outcome: r.status === "fulfilled" ? r.value : "failed"
|
|
61261
|
+
});
|
|
60983
61262
|
});
|
|
61263
|
+
return results;
|
|
60984
61264
|
}
|
|
60985
61265
|
async replayOfflineMessagesForAddress(address, expectedClient, trigger = "periodic_repair", recoveryIdentity) {
|
|
60986
61266
|
const addressReplayStartedAt = Date.now();
|
|
@@ -62127,247 +62407,6 @@ var init_onchainos = __esm({
|
|
|
62127
62407
|
}
|
|
62128
62408
|
});
|
|
62129
62409
|
|
|
62130
|
-
// ../core/src/xmtp-sdk/onchainos/list-jobs-by-verified-sender.ts
|
|
62131
|
-
function isPlainObject(value) {
|
|
62132
|
-
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
62133
|
-
}
|
|
62134
|
-
function isNonEmptyString(value) {
|
|
62135
|
-
return typeof value === "string" && value.length > 0;
|
|
62136
|
-
}
|
|
62137
|
-
function redactLogValue(value, left = 6, right = 4) {
|
|
62138
|
-
if (!value) {
|
|
62139
|
-
return "(none)";
|
|
62140
|
-
}
|
|
62141
|
-
if (value.length <= left + right + 1) {
|
|
62142
|
-
return "(redacted)";
|
|
62143
|
-
}
|
|
62144
|
-
return `${value.slice(0, left)}\u2026${value.slice(-right)}`;
|
|
62145
|
-
}
|
|
62146
|
-
function guardSessionExpired3(stdout, command) {
|
|
62147
|
-
if (isSessionExpired(stdout)) {
|
|
62148
|
-
reportSessionExpired(command);
|
|
62149
|
-
}
|
|
62150
|
-
}
|
|
62151
|
-
function guardCatchSessionExpired3(err2, command) {
|
|
62152
|
-
const stdout = String(err2?.stdout ?? "");
|
|
62153
|
-
if (stdout && isSessionExpired(stdout)) {
|
|
62154
|
-
reportSessionExpired(command);
|
|
62155
|
-
}
|
|
62156
|
-
}
|
|
62157
|
-
function buildListJobsByVerifiedSenderArgs(params) {
|
|
62158
|
-
return [
|
|
62159
|
-
"agent",
|
|
62160
|
-
"list-jobs-by-verified-sender",
|
|
62161
|
-
"--group-id",
|
|
62162
|
-
params.groupId,
|
|
62163
|
-
"--sender-inbox-id",
|
|
62164
|
-
params.senderInboxId,
|
|
62165
|
-
"--agentic-id",
|
|
62166
|
-
params.agenticId
|
|
62167
|
-
];
|
|
62168
|
-
}
|
|
62169
|
-
function extractErrorText(errorLike) {
|
|
62170
|
-
if (typeof errorLike === "string") {
|
|
62171
|
-
return errorLike;
|
|
62172
|
-
}
|
|
62173
|
-
if (typeof errorLike === "number") {
|
|
62174
|
-
return String(errorLike);
|
|
62175
|
-
}
|
|
62176
|
-
if (errorLike && typeof errorLike === "object") {
|
|
62177
|
-
const anyErr = errorLike;
|
|
62178
|
-
return [anyErr.code, anyErr.message, anyErr.stdout, anyErr.stderr].filter((value) => typeof value === "string" || typeof value === "number").map(String).join(" ");
|
|
62179
|
-
}
|
|
62180
|
-
return errorLike == null ? "" : String(errorLike);
|
|
62181
|
-
}
|
|
62182
|
-
function classifyListJobsError(errorLike) {
|
|
62183
|
-
const text = extractErrorText(errorLike);
|
|
62184
|
-
for (const [code, reason] of Object.entries(KNOWN_ERROR_CODES2)) {
|
|
62185
|
-
if (text.includes(code)) {
|
|
62186
|
-
return { reason, errorCode: code };
|
|
62187
|
-
}
|
|
62188
|
-
}
|
|
62189
|
-
if (/\b401\b/.test(text)) {
|
|
62190
|
-
return { reason: "auth_error", errorCode: "401" };
|
|
62191
|
-
}
|
|
62192
|
-
if (/\b403\b/.test(text)) {
|
|
62193
|
-
return { reason: "auth_error", errorCode: "403" };
|
|
62194
|
-
}
|
|
62195
|
-
return { reason: "invalid_response" };
|
|
62196
|
-
}
|
|
62197
|
-
function normalizeListJobsResponse(data) {
|
|
62198
|
-
const rawJobs = isPlainObject(data) && Array.isArray(data.jobs) ? data.jobs : [];
|
|
62199
|
-
const seen = /* @__PURE__ */ new Set();
|
|
62200
|
-
const jobs = [];
|
|
62201
|
-
let invalidCount = 0;
|
|
62202
|
-
for (const item of rawJobs) {
|
|
62203
|
-
if (!isPlainObject(item) || !isNonEmptyString(item.jobId) || !isNonEmptyString(item.userAgentId) || !isNonEmptyString(item.aspAgentId)) {
|
|
62204
|
-
invalidCount += 1;
|
|
62205
|
-
continue;
|
|
62206
|
-
}
|
|
62207
|
-
const key = `${item.jobId}|${item.userAgentId}|${item.aspAgentId}`;
|
|
62208
|
-
if (seen.has(key)) {
|
|
62209
|
-
continue;
|
|
62210
|
-
}
|
|
62211
|
-
seen.add(key);
|
|
62212
|
-
jobs.push({ jobId: item.jobId, userAgentId: item.userAgentId, aspAgentId: item.aspAgentId });
|
|
62213
|
-
}
|
|
62214
|
-
return { jobs, invalidCount };
|
|
62215
|
-
}
|
|
62216
|
-
async function listJobsByVerifiedSender(params, execFn = exec) {
|
|
62217
|
-
logWithTimestamp(
|
|
62218
|
-
`[onchainos] listing jobs by verified sender: group=${params.groupId} sender=${redactLogValue(params.senderInboxId)} agentic=${params.agenticId}`
|
|
62219
|
-
);
|
|
62220
|
-
let stdout;
|
|
62221
|
-
let stderr;
|
|
62222
|
-
try {
|
|
62223
|
-
({ stdout, stderr } = await execFn(buildListJobsByVerifiedSenderArgs(params)));
|
|
62224
|
-
} catch (err2) {
|
|
62225
|
-
guardCatchSessionExpired3(err2, "list-jobs-by-verified-sender");
|
|
62226
|
-
const classified = classifyListJobsError(err2);
|
|
62227
|
-
const reason = classified.reason === "invalid_response" ? "network_error" : classified.reason;
|
|
62228
|
-
warnWithTimestamp(
|
|
62229
|
-
`[onchainos] list-jobs-by-verified-sender exec failed (group=${params.groupId} sender=${redactLogValue(params.senderInboxId)}); fail-closed reason=${reason}`
|
|
62230
|
-
);
|
|
62231
|
-
return { status: "fail_closed", jobs: [], invalidCount: 0, reason, errorCode: classified.errorCode };
|
|
62232
|
-
}
|
|
62233
|
-
if (stderr) {
|
|
62234
|
-
logWithTimestamp(`[onchainos] stderr (list-jobs-by-verified-sender): ${stderr}`);
|
|
62235
|
-
}
|
|
62236
|
-
let res;
|
|
62237
|
-
try {
|
|
62238
|
-
res = parseCliJson(stdout, "list-jobs-by-verified-sender", {
|
|
62239
|
-
groupId: params.groupId,
|
|
62240
|
-
agenticId: params.agenticId
|
|
62241
|
-
});
|
|
62242
|
-
} catch {
|
|
62243
|
-
return { status: "fail_closed", jobs: [], invalidCount: 0, reason: "invalid_response" };
|
|
62244
|
-
}
|
|
62245
|
-
if (!res.ok) {
|
|
62246
|
-
guardSessionExpired3(stdout, "list-jobs-by-verified-sender");
|
|
62247
|
-
const classified = classifyListJobsError(res.error);
|
|
62248
|
-
warnWithTimestamp(
|
|
62249
|
-
`[onchainos] list-jobs-by-verified-sender ok=false (group=${params.groupId}); fail-closed reason=${classified.reason}`
|
|
62250
|
-
);
|
|
62251
|
-
logger.error(
|
|
62252
|
-
LogEvent.ONCHAINOS_CLI_ERROR,
|
|
62253
|
-
new Error("list-jobs-by-verified-sender ok=false"),
|
|
62254
|
-
cliOkFalseExtras(stdout, "list-jobs-by-verified-sender", {
|
|
62255
|
-
groupId: params.groupId,
|
|
62256
|
-
agenticId: params.agenticId,
|
|
62257
|
-
reason: classified.reason
|
|
62258
|
-
})
|
|
62259
|
-
);
|
|
62260
|
-
return { status: "fail_closed", jobs: [], invalidCount: 0, reason: classified.reason, errorCode: classified.errorCode };
|
|
62261
|
-
}
|
|
62262
|
-
const { jobs, invalidCount } = normalizeListJobsResponse(res.data);
|
|
62263
|
-
if (jobs.length === 0) {
|
|
62264
|
-
logWithTimestamp(
|
|
62265
|
-
`[onchainos] list-jobs-by-verified-sender: empty (group=${params.groupId} invalidCount=${invalidCount})`
|
|
62266
|
-
);
|
|
62267
|
-
return { status: "empty", jobs, invalidCount };
|
|
62268
|
-
}
|
|
62269
|
-
logWithTimestamp(
|
|
62270
|
-
`[onchainos] list-jobs-by-verified-sender: ok (group=${params.groupId} jobs=${jobs.length} invalidCount=${invalidCount})`
|
|
62271
|
-
);
|
|
62272
|
-
return { status: "ok", jobs, invalidCount };
|
|
62273
|
-
}
|
|
62274
|
-
function listJobsByVerifiedSenderHelpAdvertisesCommand(helpText) {
|
|
62275
|
-
if (typeof helpText !== "string" || helpText.length === 0) {
|
|
62276
|
-
return false;
|
|
62277
|
-
}
|
|
62278
|
-
const lower = helpText.toLowerCase();
|
|
62279
|
-
if (/unknown command|unrecognized|not a valid command|no such (sub)?command|command not found/.test(lower)) {
|
|
62280
|
-
return false;
|
|
62281
|
-
}
|
|
62282
|
-
return lower.includes(LIST_JOBS_BY_VERIFIED_SENDER_HELP_TOKEN);
|
|
62283
|
-
}
|
|
62284
|
-
function maybeRecommendListJobsUpgrade(capability) {
|
|
62285
|
-
if (capability.supported || capabilityRecommendedPairs.has(CAPABILITY_UPGRADE_PAIR_KEY)) {
|
|
62286
|
-
return;
|
|
62287
|
-
}
|
|
62288
|
-
warnWithTimestamp(
|
|
62289
|
-
`[onchainos] list-jobs-by-verified-sender unsupported (reason=${capability.reason}); ${CAPABILITY_UPGRADE_REASON}`
|
|
62290
|
-
);
|
|
62291
|
-
const hook = XmtpService.getInstance().tools?.notifyUpgradeRecommendation;
|
|
62292
|
-
if (!hook) {
|
|
62293
|
-
return;
|
|
62294
|
-
}
|
|
62295
|
-
capabilityRecommendedPairs.add(CAPABILITY_UPGRADE_PAIR_KEY);
|
|
62296
|
-
try {
|
|
62297
|
-
void Promise.resolve(
|
|
62298
|
-
hook({
|
|
62299
|
-
component: "onchainos",
|
|
62300
|
-
capability: LIST_JOBS_BY_VERIFIED_SENDER_HELP_TOKEN,
|
|
62301
|
-
reason: CAPABILITY_UPGRADE_REASON
|
|
62302
|
-
})
|
|
62303
|
-
).catch((err2) => {
|
|
62304
|
-
warnWithTimestamp("[onchainos] list-jobs-by-verified-sender upgrade notice async delivery failed:", err2);
|
|
62305
|
-
});
|
|
62306
|
-
} catch (err2) {
|
|
62307
|
-
warnWithTimestamp("[onchainos] list-jobs-by-verified-sender upgrade notice threw:", err2);
|
|
62308
|
-
}
|
|
62309
|
-
}
|
|
62310
|
-
function detectListJobsByVerifiedSenderSupport(execFn = exec) {
|
|
62311
|
-
if (!capabilityProbe2) {
|
|
62312
|
-
capabilityProbe2 = (async () => {
|
|
62313
|
-
try {
|
|
62314
|
-
const { stdout, stderr } = await execFn([
|
|
62315
|
-
"agent",
|
|
62316
|
-
"list-jobs-by-verified-sender",
|
|
62317
|
-
"--help"
|
|
62318
|
-
]);
|
|
62319
|
-
const supported = listJobsByVerifiedSenderHelpAdvertisesCommand(`${stdout}
|
|
62320
|
-
${stderr}`);
|
|
62321
|
-
logWithTimestamp(
|
|
62322
|
-
`[onchainos] list-jobs-by-verified-sender capability: ${supported ? "supported" : "unsupported_cli_capability"}`
|
|
62323
|
-
);
|
|
62324
|
-
return supported ? { supported: true } : { supported: false, reason: "unsupported_cli_capability" };
|
|
62325
|
-
} catch (err2) {
|
|
62326
|
-
logWithTimestamp(
|
|
62327
|
-
"[onchainos] list-jobs-by-verified-sender --help probe failed; treating as onchainos_upgrade_required:",
|
|
62328
|
-
err2
|
|
62329
|
-
);
|
|
62330
|
-
return { supported: false, reason: "onchainos_upgrade_required" };
|
|
62331
|
-
}
|
|
62332
|
-
})().then((capability) => {
|
|
62333
|
-
maybeRecommendListJobsUpgrade(capability);
|
|
62334
|
-
return capability;
|
|
62335
|
-
});
|
|
62336
|
-
}
|
|
62337
|
-
return capabilityProbe2;
|
|
62338
|
-
}
|
|
62339
|
-
async function listJobsByVerifiedSenderWithCapability(params, execFn = exec) {
|
|
62340
|
-
const capability = await detectListJobsByVerifiedSenderSupport(execFn);
|
|
62341
|
-
if (!capability.supported) {
|
|
62342
|
-
warnWithTimestamp(
|
|
62343
|
-
`[onchainos] list-jobs-by-verified-sender skipped: CLI capability unavailable (reason=${capability.reason}) group=${params.groupId} sender=${redactLogValue(params.senderInboxId)}`
|
|
62344
|
-
);
|
|
62345
|
-
return { status: "fail_closed", jobs: [], invalidCount: 0, reason: capability.reason };
|
|
62346
|
-
}
|
|
62347
|
-
return listJobsByVerifiedSender(params, execFn);
|
|
62348
|
-
}
|
|
62349
|
-
var KNOWN_ERROR_CODES2, LIST_JOBS_BY_VERIFIED_SENDER_HELP_TOKEN, CAPABILITY_UPGRADE_PAIR_KEY, CAPABILITY_UPGRADE_REASON, capabilityProbe2, capabilityRecommendedPairs;
|
|
62350
|
-
var init_list_jobs_by_verified_sender = __esm({
|
|
62351
|
-
"../core/src/xmtp-sdk/onchainos/list-jobs-by-verified-sender.ts"() {
|
|
62352
|
-
"use strict";
|
|
62353
|
-
init_log();
|
|
62354
|
-
init_sentry_logger();
|
|
62355
|
-
init_bin();
|
|
62356
|
-
init_cli_response();
|
|
62357
|
-
init_session_expired();
|
|
62358
|
-
init_xmtp_sdk();
|
|
62359
|
-
KNOWN_ERROR_CODES2 = {
|
|
62360
|
-
"130100079": "sender_not_authorized",
|
|
62361
|
-
"130100073": "sender_not_eligible"
|
|
62362
|
-
};
|
|
62363
|
-
LIST_JOBS_BY_VERIFIED_SENDER_HELP_TOKEN = "list-jobs-by-verified-sender";
|
|
62364
|
-
CAPABILITY_UPGRADE_PAIR_KEY = "onchainos:list-jobs-by-verified-sender";
|
|
62365
|
-
CAPABILITY_UPGRADE_REASON = "OnchainOS does not support `agent list-jobs-by-verified-sender`; the V2 subscription shared-group inbound path is fail-closed until OnchainOS is upgraded. Upgrade the OnchainOS CLI, then re-run.";
|
|
62366
|
-
capabilityProbe2 = null;
|
|
62367
|
-
capabilityRecommendedPairs = /* @__PURE__ */ new Set();
|
|
62368
|
-
}
|
|
62369
|
-
});
|
|
62370
|
-
|
|
62371
62410
|
// ../core/src/xmtp-sdk/onchainos/signer.ts
|
|
62372
62411
|
async function onchainosSign(agentId, keyUuid, walletAddress, message) {
|
|
62373
62412
|
logWithTimestamp(
|
|
@@ -63037,7 +63076,7 @@ function buildXmtpMessageSentExtra(params) {
|
|
|
63037
63076
|
function logXmtpMessageSent(params) {
|
|
63038
63077
|
logger.info(LogEvent.MESSAGE_SENT, buildXmtpMessageSentExtra(params));
|
|
63039
63078
|
}
|
|
63040
|
-
function
|
|
63079
|
+
function isPlainObject(value) {
|
|
63041
63080
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
63042
63081
|
}
|
|
63043
63082
|
function readString3(value) {
|
|
@@ -63223,8 +63262,8 @@ function buildDmReplyRaw(command, target, localAgentId) {
|
|
|
63223
63262
|
});
|
|
63224
63263
|
}
|
|
63225
63264
|
function buildGroupReplyRaw(command, target, myXmtpAddress, localAgent) {
|
|
63226
|
-
const payload =
|
|
63227
|
-
const sender =
|
|
63265
|
+
const payload = isPlainObject(target.payload) ? target.payload : null;
|
|
63266
|
+
const sender = isPlainObject(payload?.sender) ? payload.sender : null;
|
|
63228
63267
|
return buildSendEnvelope({
|
|
63229
63268
|
content: command.message,
|
|
63230
63269
|
myXmtpAddress,
|
|
@@ -63821,8 +63860,8 @@ async function handleXmtpSendCommand(params) {
|
|
|
63821
63860
|
payload: parseJson(rawText)
|
|
63822
63861
|
};
|
|
63823
63862
|
await store.append(command.jobId, stored, sessionAgentId);
|
|
63824
|
-
const payloadObject =
|
|
63825
|
-
const sender =
|
|
63863
|
+
const payloadObject = isPlainObject(target.payload) ? target.payload : null;
|
|
63864
|
+
const sender = isPlainObject(payloadObject?.sender) ? payloadObject.sender : null;
|
|
63826
63865
|
const remoteAgentId = readString3(sender?.agentId);
|
|
63827
63866
|
await notifyAgentMessageToUserAttention({
|
|
63828
63867
|
direction: "outbound" /* OUTBOUND */,
|
|
@@ -63875,438 +63914,6 @@ var init_xmtp_send = __esm({
|
|
|
63875
63914
|
}
|
|
63876
63915
|
});
|
|
63877
63916
|
|
|
63878
|
-
// ../core/src/a2a/subscription-types.ts
|
|
63879
|
-
var SUBSCRIPTION_MESSAGE_TYPE;
|
|
63880
|
-
var init_subscription_types = __esm({
|
|
63881
|
-
"../core/src/a2a/subscription-types.ts"() {
|
|
63882
|
-
"use strict";
|
|
63883
|
-
SUBSCRIPTION_MESSAGE_TYPE = "a2a-subscription-push";
|
|
63884
|
-
}
|
|
63885
|
-
});
|
|
63886
|
-
|
|
63887
|
-
// ../core/src/a2a/subscription-envelope.ts
|
|
63888
|
-
function isPlainObject3(value) {
|
|
63889
|
-
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
63890
|
-
}
|
|
63891
|
-
function buildSubscriptionEnvelope(params) {
|
|
63892
|
-
const envelope = {
|
|
63893
|
-
msgType: SUBSCRIPTION_MESSAGE_TYPE,
|
|
63894
|
-
content: params.content,
|
|
63895
|
-
senderAgentId: params.senderAgentId
|
|
63896
|
-
};
|
|
63897
|
-
if (params.deliveryId) {
|
|
63898
|
-
envelope.deliveryId = params.deliveryId;
|
|
63899
|
-
}
|
|
63900
|
-
return JSON.stringify(envelope);
|
|
63901
|
-
}
|
|
63902
|
-
function isSubscriptionEnvelope(payload) {
|
|
63903
|
-
return isPlainObject3(payload) && payload.msgType === SUBSCRIPTION_MESSAGE_TYPE;
|
|
63904
|
-
}
|
|
63905
|
-
function isNonEmptyString2(value) {
|
|
63906
|
-
return typeof value === "string" && value.length > 0;
|
|
63907
|
-
}
|
|
63908
|
-
function readSubscriptionEnvelope(payload) {
|
|
63909
|
-
if (!isSubscriptionEnvelope(payload)) {
|
|
63910
|
-
return { ok: false, reason: "not_subscription" };
|
|
63911
|
-
}
|
|
63912
|
-
const record = payload;
|
|
63913
|
-
if (!isNonEmptyString2(record.content)) {
|
|
63914
|
-
return { ok: false, reason: "missing_content" };
|
|
63915
|
-
}
|
|
63916
|
-
const envelope = {
|
|
63917
|
-
msgType: SUBSCRIPTION_MESSAGE_TYPE,
|
|
63918
|
-
content: record.content,
|
|
63919
|
-
senderAgentId: isNonEmptyString2(record.senderAgentId) ? record.senderAgentId : ""
|
|
63920
|
-
};
|
|
63921
|
-
if (isNonEmptyString2(record.deliveryId)) {
|
|
63922
|
-
envelope.deliveryId = record.deliveryId;
|
|
63923
|
-
}
|
|
63924
|
-
return { ok: true, envelope };
|
|
63925
|
-
}
|
|
63926
|
-
var init_subscription_envelope = __esm({
|
|
63927
|
-
"../core/src/a2a/subscription-envelope.ts"() {
|
|
63928
|
-
"use strict";
|
|
63929
|
-
init_subscription_types();
|
|
63930
|
-
}
|
|
63931
|
-
});
|
|
63932
|
-
|
|
63933
|
-
// src/subscription-telemetry.ts
|
|
63934
|
-
function definedExtras(input) {
|
|
63935
|
-
return Object.entries(input).reduce((out, [key, value]) => {
|
|
63936
|
-
if (typeof value === "string" && value.trim().length > 0) {
|
|
63937
|
-
out[key] = value.trim();
|
|
63938
|
-
}
|
|
63939
|
-
return out;
|
|
63940
|
-
}, {});
|
|
63941
|
-
}
|
|
63942
|
-
function countExtras(input) {
|
|
63943
|
-
return Object.entries(input).reduce((out, [key, value]) => {
|
|
63944
|
-
if (typeof value === "number" && Number.isFinite(value)) {
|
|
63945
|
-
out[key] = String(value);
|
|
63946
|
-
}
|
|
63947
|
-
return out;
|
|
63948
|
-
}, {});
|
|
63949
|
-
}
|
|
63950
|
-
function buildSubscriptionSendExtras(input) {
|
|
63951
|
-
return {
|
|
63952
|
-
stage: input.checkpoint,
|
|
63953
|
-
...logFieldExtras({
|
|
63954
|
-
checkpoint: input.checkpoint,
|
|
63955
|
-
outcome: input.outcome ?? null,
|
|
63956
|
-
transport: SUBSCRIPTION_TRANSPORT,
|
|
63957
|
-
eventFamily: "outbound",
|
|
63958
|
-
deliveryId: input.deliveryId ?? null
|
|
63959
|
-
}),
|
|
63960
|
-
...definedExtras({
|
|
63961
|
-
aspAgentId: input.aspAgentId,
|
|
63962
|
-
conversationId: input.conversationId,
|
|
63963
|
-
reason: input.reason
|
|
63964
|
-
}),
|
|
63965
|
-
...countExtras({
|
|
63966
|
-
targetCount: input.targetCount,
|
|
63967
|
-
sentCount: input.sentCount,
|
|
63968
|
-
failedCount: input.failedCount,
|
|
63969
|
-
notGroupCount: input.notGroupCount
|
|
63970
|
-
})
|
|
63971
|
-
};
|
|
63972
|
-
}
|
|
63973
|
-
function buildSubscriptionInboundExtras(input) {
|
|
63974
|
-
return {
|
|
63975
|
-
stage: input.checkpoint,
|
|
63976
|
-
...logFieldExtras({
|
|
63977
|
-
checkpoint: input.checkpoint,
|
|
63978
|
-
outcome: input.outcome ?? null,
|
|
63979
|
-
transport: SUBSCRIPTION_TRANSPORT,
|
|
63980
|
-
eventFamily: "inbound",
|
|
63981
|
-
deliveryId: input.deliveryId ?? null
|
|
63982
|
-
}),
|
|
63983
|
-
...definedExtras({
|
|
63984
|
-
userAgentId: input.userAgentId,
|
|
63985
|
-
conversationId: input.conversationId,
|
|
63986
|
-
messageId: input.messageId,
|
|
63987
|
-
senderInboxId: input.senderInboxId,
|
|
63988
|
-
reason: input.reason,
|
|
63989
|
-
errorCode: input.errorCode
|
|
63990
|
-
}),
|
|
63991
|
-
...countExtras({
|
|
63992
|
-
returnedCount: input.returnedCount,
|
|
63993
|
-
invalidCount: input.invalidCount,
|
|
63994
|
-
ownedCount: input.ownedCount,
|
|
63995
|
-
ignoredCount: input.ignoredCount
|
|
63996
|
-
})
|
|
63997
|
-
};
|
|
63998
|
-
}
|
|
63999
|
-
function buildSubscriptionJobExtras(input) {
|
|
64000
|
-
return {
|
|
64001
|
-
stage: input.checkpoint,
|
|
64002
|
-
...logFieldExtras({
|
|
64003
|
-
checkpoint: input.checkpoint,
|
|
64004
|
-
outcome: input.outcome,
|
|
64005
|
-
transport: SUBSCRIPTION_TRANSPORT,
|
|
64006
|
-
eventFamily: "dispatch",
|
|
64007
|
-
deliveryId: input.deliveryId ?? null
|
|
64008
|
-
}),
|
|
64009
|
-
...definedExtras({
|
|
64010
|
-
jobId: input.jobId,
|
|
64011
|
-
userAgentId: input.userAgentId,
|
|
64012
|
-
aspAgentId: input.aspAgentId,
|
|
64013
|
-
conversationId: input.conversationId,
|
|
64014
|
-
reason: input.reason
|
|
64015
|
-
}),
|
|
64016
|
-
...countExtras({
|
|
64017
|
-
total: input.total,
|
|
64018
|
-
started: input.started,
|
|
64019
|
-
failed: input.failed,
|
|
64020
|
-
skippedDuplicate: input.skippedDuplicate
|
|
64021
|
-
})
|
|
64022
|
-
};
|
|
64023
|
-
}
|
|
64024
|
-
var SUBSCRIPTION_TRANSPORT;
|
|
64025
|
-
var init_subscription_telemetry = __esm({
|
|
64026
|
-
"src/subscription-telemetry.ts"() {
|
|
64027
|
-
"use strict";
|
|
64028
|
-
init_log_fields();
|
|
64029
|
-
SUBSCRIPTION_TRANSPORT = "xmtp";
|
|
64030
|
-
}
|
|
64031
|
-
});
|
|
64032
|
-
|
|
64033
|
-
// src/subscription-push.ts
|
|
64034
|
-
function describeError(err2) {
|
|
64035
|
-
if (err2 instanceof Error) {
|
|
64036
|
-
return err2.message;
|
|
64037
|
-
}
|
|
64038
|
-
if (typeof err2 === "string" && err2.length > 0) {
|
|
64039
|
-
return err2;
|
|
64040
|
-
}
|
|
64041
|
-
return "unknown error";
|
|
64042
|
-
}
|
|
64043
|
-
async function requireXmtpClient2(service, address) {
|
|
64044
|
-
const existing = service.getClientByAddress(address);
|
|
64045
|
-
if (existing) {
|
|
64046
|
-
return existing;
|
|
64047
|
-
}
|
|
64048
|
-
await service.refreshAgents();
|
|
64049
|
-
const refreshed = service.getClientByAddress(address);
|
|
64050
|
-
if (!refreshed) {
|
|
64051
|
-
throw new Error(`no XMTP client found for ${address}`);
|
|
64052
|
-
}
|
|
64053
|
-
return refreshed;
|
|
64054
|
-
}
|
|
64055
|
-
function resolveLocalAddress(service, myAgentId) {
|
|
64056
|
-
const address = service.getAddressByAgentId(myAgentId);
|
|
64057
|
-
if (!address) {
|
|
64058
|
-
throw new Error(`No local communication address found for myAgentId=${myAgentId}`);
|
|
64059
|
-
}
|
|
64060
|
-
return address;
|
|
64061
|
-
}
|
|
64062
|
-
async function syncConversationsOnLocalMiss2(agent) {
|
|
64063
|
-
const conversations = agent.client.conversations;
|
|
64064
|
-
const existing = conversationSyncPromises2.get(conversations);
|
|
64065
|
-
if (existing) {
|
|
64066
|
-
return existing;
|
|
64067
|
-
}
|
|
64068
|
-
const pending = conversations.sync();
|
|
64069
|
-
conversationSyncPromises2.set(conversations, pending);
|
|
64070
|
-
try {
|
|
64071
|
-
await pending;
|
|
64072
|
-
} finally {
|
|
64073
|
-
if (conversationSyncPromises2.get(conversations) === pending) {
|
|
64074
|
-
conversationSyncPromises2.delete(conversations);
|
|
64075
|
-
}
|
|
64076
|
-
}
|
|
64077
|
-
}
|
|
64078
|
-
async function findGroupConversation2(agent, conversationId) {
|
|
64079
|
-
let conversation = await agent.client.conversations.getConversationById(conversationId);
|
|
64080
|
-
if (!(conversation instanceof Group)) {
|
|
64081
|
-
await syncConversationsOnLocalMiss2(agent);
|
|
64082
|
-
conversation = await agent.client.conversations.getConversationById(conversationId);
|
|
64083
|
-
}
|
|
64084
|
-
return conversation instanceof Group ? conversation : null;
|
|
64085
|
-
}
|
|
64086
|
-
async function sendSubscriptionToGroup(params) {
|
|
64087
|
-
const { agent, conversationId, command, myXmtpAddress, senderRole } = params;
|
|
64088
|
-
let conversation;
|
|
64089
|
-
try {
|
|
64090
|
-
conversation = await findGroupConversation2(agent, conversationId);
|
|
64091
|
-
} catch (err2) {
|
|
64092
|
-
return { conversationId, status: "not_group", error: describeError(err2) };
|
|
64093
|
-
}
|
|
64094
|
-
if (!conversation) {
|
|
64095
|
-
return {
|
|
64096
|
-
conversationId,
|
|
64097
|
-
status: "not_group",
|
|
64098
|
-
error: `conversationId=${conversationId} is not a Group (DM or unknown conversation)`
|
|
64099
|
-
};
|
|
64100
|
-
}
|
|
64101
|
-
const envelope = buildSubscriptionEnvelope({
|
|
64102
|
-
content: command.content,
|
|
64103
|
-
senderAgentId: command.myAgentId,
|
|
64104
|
-
deliveryId: command.deliveryId
|
|
64105
|
-
});
|
|
64106
|
-
const sendStartMs = Date.now();
|
|
64107
|
-
try {
|
|
64108
|
-
const xmtpMessageId = await conversation.sendText(envelope);
|
|
64109
|
-
logXmtpMessageSent({
|
|
64110
|
-
xmtpMessageId,
|
|
64111
|
-
conversationId,
|
|
64112
|
-
// V2 has no job dimension (FR-1) — deliveryId (or a fixed marker)
|
|
64113
|
-
// stands in for the telemetry taxonomy's jobId slot.
|
|
64114
|
-
jobId: command.deliveryId ?? "subscription-push",
|
|
64115
|
-
chatType: "group",
|
|
64116
|
-
component: "node_xmtp_subscription_push",
|
|
64117
|
-
myXmtpAddress,
|
|
64118
|
-
senderAgentId: command.myAgentId,
|
|
64119
|
-
role: senderRole,
|
|
64120
|
-
sendDurationMs: Date.now() - sendStartMs
|
|
64121
|
-
});
|
|
64122
|
-
const messageId = typeof xmtpMessageId === "string" && xmtpMessageId.length > 0 ? xmtpMessageId : String(xmtpMessageId);
|
|
64123
|
-
logWithTimestamp(
|
|
64124
|
-
`[okx-agent-task] subscription-push sent conversationId=${conversationId} deliveryId=${command.deliveryId ?? "(none)"}`
|
|
64125
|
-
);
|
|
64126
|
-
return { conversationId, status: "sent", messageId };
|
|
64127
|
-
} catch (err2) {
|
|
64128
|
-
logWithTimestamp(
|
|
64129
|
-
`[okx-agent-task] subscription-push failed conversationId=${conversationId} deliveryId=${command.deliveryId ?? "(none)"}`
|
|
64130
|
-
);
|
|
64131
|
-
return { conversationId, status: "failed", error: describeError(err2) };
|
|
64132
|
-
}
|
|
64133
|
-
}
|
|
64134
|
-
function summarizeSubscriptionPush(results) {
|
|
64135
|
-
let sentCount = 0;
|
|
64136
|
-
let failedCount = 0;
|
|
64137
|
-
for (const result of results) {
|
|
64138
|
-
if (result.status === "sent") {
|
|
64139
|
-
sentCount++;
|
|
64140
|
-
} else {
|
|
64141
|
-
failedCount++;
|
|
64142
|
-
}
|
|
64143
|
-
}
|
|
64144
|
-
return { conversationCount: results.length, sentCount, failedCount };
|
|
64145
|
-
}
|
|
64146
|
-
async function handleSubscriptionPushCommand(params) {
|
|
64147
|
-
const { command, service } = params;
|
|
64148
|
-
const aspAgentId = command.myAgentId;
|
|
64149
|
-
const deliveryId = command.deliveryId;
|
|
64150
|
-
const conversationIds = command.conversationIds ?? [];
|
|
64151
|
-
logger.info(
|
|
64152
|
-
LogEvent.SUBSCRIPTION_PUSH_STARTED,
|
|
64153
|
-
buildSubscriptionSendExtras({
|
|
64154
|
-
checkpoint: "outbound/subscription_push_started",
|
|
64155
|
-
aspAgentId,
|
|
64156
|
-
deliveryId,
|
|
64157
|
-
targetCount: conversationIds.length
|
|
64158
|
-
})
|
|
64159
|
-
);
|
|
64160
|
-
if (conversationIds.length === 0) {
|
|
64161
|
-
logger.info(
|
|
64162
|
-
LogEvent.SUBSCRIPTION_PUSH_EMPTY_TARGETS,
|
|
64163
|
-
buildSubscriptionSendExtras({
|
|
64164
|
-
checkpoint: "outbound/subscription_push_empty_targets",
|
|
64165
|
-
outcome: "ignored",
|
|
64166
|
-
aspAgentId,
|
|
64167
|
-
deliveryId,
|
|
64168
|
-
targetCount: 0,
|
|
64169
|
-
reason: "empty_targets"
|
|
64170
|
-
})
|
|
64171
|
-
);
|
|
64172
|
-
return { conversationCount: 0, sentCount: 0, failedCount: 0, results: [] };
|
|
64173
|
-
}
|
|
64174
|
-
const myXmtpAddress = resolveLocalAddress(service, command.myAgentId);
|
|
64175
|
-
const agent = await requireXmtpClient2(service, myXmtpAddress);
|
|
64176
|
-
const senderRole = service.getAgentByAddress?.(myXmtpAddress)?.role;
|
|
64177
|
-
logger.info(
|
|
64178
|
-
LogEvent.SUBSCRIPTION_PUSH_TARGETS_RESOLVED,
|
|
64179
|
-
buildSubscriptionSendExtras({
|
|
64180
|
-
checkpoint: "outbound/subscription_push_targets_resolved",
|
|
64181
|
-
aspAgentId,
|
|
64182
|
-
deliveryId,
|
|
64183
|
-
targetCount: conversationIds.length
|
|
64184
|
-
})
|
|
64185
|
-
);
|
|
64186
|
-
const settled = await parallelMap(
|
|
64187
|
-
conversationIds,
|
|
64188
|
-
(conversationId) => sendSubscriptionToGroup({
|
|
64189
|
-
agent,
|
|
64190
|
-
conversationId,
|
|
64191
|
-
command,
|
|
64192
|
-
myXmtpAddress,
|
|
64193
|
-
senderRole
|
|
64194
|
-
}),
|
|
64195
|
-
DEFAULT_CONCURRENCY
|
|
64196
|
-
);
|
|
64197
|
-
const results = settled.map((outcome, index2) => {
|
|
64198
|
-
if (outcome.status === "fulfilled") {
|
|
64199
|
-
return outcome.value;
|
|
64200
|
-
}
|
|
64201
|
-
return {
|
|
64202
|
-
conversationId: conversationIds[index2],
|
|
64203
|
-
status: "failed",
|
|
64204
|
-
error: describeError(outcome.reason)
|
|
64205
|
-
};
|
|
64206
|
-
});
|
|
64207
|
-
for (const result of results) {
|
|
64208
|
-
if (result.status === "sent") {
|
|
64209
|
-
continue;
|
|
64210
|
-
}
|
|
64211
|
-
logger.error(
|
|
64212
|
-
LogEvent.SUBSCRIPTION_PUSH_TARGET_FAILED,
|
|
64213
|
-
void 0,
|
|
64214
|
-
buildSubscriptionSendExtras({
|
|
64215
|
-
checkpoint: "outbound/subscription_push_target_failed",
|
|
64216
|
-
outcome: "failed",
|
|
64217
|
-
aspAgentId,
|
|
64218
|
-
deliveryId,
|
|
64219
|
-
conversationId: result.conversationId,
|
|
64220
|
-
reason: result.status
|
|
64221
|
-
})
|
|
64222
|
-
);
|
|
64223
|
-
}
|
|
64224
|
-
const summary = summarizeSubscriptionPush(results);
|
|
64225
|
-
const summaryOutcome = summary.failedCount === 0 ? "success" : summary.sentCount > 0 ? "partial" : "failed";
|
|
64226
|
-
logger.info(
|
|
64227
|
-
LogEvent.SUBSCRIPTION_PUSH_SUMMARY,
|
|
64228
|
-
buildSubscriptionSendExtras({
|
|
64229
|
-
checkpoint: "outbound/subscription_push_summary",
|
|
64230
|
-
outcome: summaryOutcome,
|
|
64231
|
-
aspAgentId,
|
|
64232
|
-
deliveryId,
|
|
64233
|
-
targetCount: summary.conversationCount,
|
|
64234
|
-
sentCount: summary.sentCount,
|
|
64235
|
-
failedCount: summary.failedCount
|
|
64236
|
-
})
|
|
64237
|
-
);
|
|
64238
|
-
return { ...summary, results };
|
|
64239
|
-
}
|
|
64240
|
-
var DEFAULT_CONCURRENCY, conversationSyncPromises2;
|
|
64241
|
-
var init_subscription_push = __esm({
|
|
64242
|
-
"src/subscription-push.ts"() {
|
|
64243
|
-
"use strict";
|
|
64244
|
-
init_log();
|
|
64245
|
-
init_sentry_logger();
|
|
64246
|
-
init_dist2();
|
|
64247
|
-
init_subscription_envelope();
|
|
64248
|
-
init_concurrency();
|
|
64249
|
-
init_xmtp_send();
|
|
64250
|
-
init_subscription_telemetry();
|
|
64251
|
-
DEFAULT_CONCURRENCY = 20;
|
|
64252
|
-
conversationSyncPromises2 = /* @__PURE__ */ new WeakMap();
|
|
64253
|
-
}
|
|
64254
|
-
});
|
|
64255
|
-
|
|
64256
|
-
// src/ai-run-log-path.ts
|
|
64257
|
-
function buildRunLogFileName(request) {
|
|
64258
|
-
const source = request.source;
|
|
64259
|
-
const sessionKey = request.sessionKey;
|
|
64260
|
-
const messageId = request.messageId;
|
|
64261
|
-
const jobId = request.jobId;
|
|
64262
|
-
const safeMessageId = encodeURIComponent(messageId);
|
|
64263
|
-
const prefix = source === "job-dispatch" ? "ai-" : "ai-session-";
|
|
64264
|
-
const encodedContext = source === "job-dispatch" ? encodeURIComponent(jobId ?? "unknown") : encodeURIComponent(sessionKey);
|
|
64265
|
-
const readable = `${prefix}${encodedContext}-${safeMessageId}.log`;
|
|
64266
|
-
if (Buffer.byteLength(readable, "utf8") <= RUN_LOG_FILENAME_MAX_BYTES) {
|
|
64267
|
-
return readable;
|
|
64268
|
-
}
|
|
64269
|
-
const readableWithoutExt = readable.slice(0, -".log".length);
|
|
64270
|
-
const digest = (0, import_node_crypto13.createHash)("sha256").update(readableWithoutExt).digest("hex").slice(0, 24);
|
|
64271
|
-
const suffix = `-${digest}.log`;
|
|
64272
|
-
const budgetForContext = RUN_LOG_FILENAME_MAX_BYTES - Buffer.byteLength(prefix, "utf8") - Buffer.byteLength(suffix, "utf8");
|
|
64273
|
-
const contextHead = truncateToUtf8ByteBudgetSafe(encodedContext, Math.max(budgetForContext, 0));
|
|
64274
|
-
return `${prefix}${contextHead}${suffix}`;
|
|
64275
|
-
}
|
|
64276
|
-
function truncateToUtf8ByteBudgetSafe(encoded, maxBytes) {
|
|
64277
|
-
if (maxBytes <= 0) {
|
|
64278
|
-
return "";
|
|
64279
|
-
}
|
|
64280
|
-
if (Buffer.byteLength(encoded, "utf8") <= maxBytes) {
|
|
64281
|
-
return encoded;
|
|
64282
|
-
}
|
|
64283
|
-
let candidateLength = Math.min(maxBytes, encoded.length);
|
|
64284
|
-
while (candidateLength > 0) {
|
|
64285
|
-
const candidate = encoded.slice(0, candidateLength);
|
|
64286
|
-
if (!endsWithSplitEscape(candidate)) {
|
|
64287
|
-
return candidate;
|
|
64288
|
-
}
|
|
64289
|
-
candidateLength -= 1;
|
|
64290
|
-
}
|
|
64291
|
-
return "";
|
|
64292
|
-
}
|
|
64293
|
-
function endsWithSplitEscape(value) {
|
|
64294
|
-
const percentIndex = value.lastIndexOf("%");
|
|
64295
|
-
if (percentIndex === -1) {
|
|
64296
|
-
return false;
|
|
64297
|
-
}
|
|
64298
|
-
const tail = value.length - percentIndex - 1;
|
|
64299
|
-
return tail < 2;
|
|
64300
|
-
}
|
|
64301
|
-
var import_node_crypto13, RUN_LOG_FILENAME_MAX_BYTES;
|
|
64302
|
-
var init_ai_run_log_path = __esm({
|
|
64303
|
-
"src/ai-run-log-path.ts"() {
|
|
64304
|
-
"use strict";
|
|
64305
|
-
import_node_crypto13 = require("node:crypto");
|
|
64306
|
-
RUN_LOG_FILENAME_MAX_BYTES = 240;
|
|
64307
|
-
}
|
|
64308
|
-
});
|
|
64309
|
-
|
|
64310
63917
|
// src/ai-adapter.ts
|
|
64311
63918
|
function buildClaudeAllowedToolsArgs() {
|
|
64312
63919
|
return ["--allowedTools", ...CLAUDE_ALLOWED_TOOLS];
|
|
@@ -66154,7 +65761,7 @@ function normalizeAttentionProvider(provider) {
|
|
|
66154
65761
|
return provider === "unknown" ? null : provider;
|
|
66155
65762
|
}
|
|
66156
65763
|
function stableHash2(value) {
|
|
66157
|
-
return (0,
|
|
65764
|
+
return (0, import_node_crypto13.createHash)("sha256").update(value).digest("hex").slice(0, 24);
|
|
66158
65765
|
}
|
|
66159
65766
|
function formatCommand(args) {
|
|
66160
65767
|
return args.map(shellQuote).join(" ");
|
|
@@ -66178,18 +65785,17 @@ function shortenJobId2(jobId) {
|
|
|
66178
65785
|
}
|
|
66179
65786
|
return `${jobId.slice(0, 6)}\u2026${jobId.slice(-4)}`;
|
|
66180
65787
|
}
|
|
66181
|
-
var
|
|
65788
|
+
var import_node_crypto13, import_node_fs26, import_promises12, import_node_os9, import_node_path31, AiRunner, CODEX_TOOL_FAILURE_MARKER;
|
|
66182
65789
|
var init_ai_runner = __esm({
|
|
66183
65790
|
"src/ai-runner.ts"() {
|
|
66184
65791
|
"use strict";
|
|
66185
65792
|
init_log();
|
|
66186
|
-
|
|
65793
|
+
import_node_crypto13 = require("node:crypto");
|
|
66187
65794
|
import_node_fs26 = require("node:fs");
|
|
66188
65795
|
import_promises12 = require("node:fs/promises");
|
|
66189
65796
|
import_node_os9 = require("node:os");
|
|
66190
65797
|
import_node_path31 = require("node:path");
|
|
66191
65798
|
init_ai_command();
|
|
66192
|
-
init_ai_run_log_path();
|
|
66193
65799
|
init_paths();
|
|
66194
65800
|
init_file_store();
|
|
66195
65801
|
init_ai_provider();
|
|
@@ -66817,15 +66423,13 @@ var init_ai_runner = __esm({
|
|
|
66817
66423
|
);
|
|
66818
66424
|
}
|
|
66819
66425
|
buildRunLogPath(request) {
|
|
66820
|
-
|
|
66821
|
-
|
|
66822
|
-
|
|
66823
|
-
|
|
66824
|
-
|
|
66825
|
-
|
|
66826
|
-
|
|
66827
|
-
})
|
|
66828
|
-
);
|
|
66426
|
+
const safeMessageId = encodeURIComponent(request.messageId);
|
|
66427
|
+
if (request.source === "job-dispatch") {
|
|
66428
|
+
const safeJobId = encodeURIComponent(request.jobId ?? "unknown");
|
|
66429
|
+
return (0, import_node_path31.join)(this.logsDir, `ai-${safeJobId}-${safeMessageId}.log`);
|
|
66430
|
+
}
|
|
66431
|
+
const safeSessionKey = encodeURIComponent(request.sessionKey);
|
|
66432
|
+
return (0, import_node_path31.join)(this.logsDir, `ai-session-${safeSessionKey}-${safeMessageId}.log`);
|
|
66829
66433
|
}
|
|
66830
66434
|
readRunAiSessionId(provider, request, file, sessionMeta) {
|
|
66831
66435
|
if (request.source === "job-dispatch" && request.jobId) {
|
|
@@ -67850,9 +67454,6 @@ function commandSentryExtra(command, extra = {}) {
|
|
|
67850
67454
|
base.myAgentId = command.myAgentId ?? "";
|
|
67851
67455
|
base.toAgentId = command.toAgentId ?? "";
|
|
67852
67456
|
base.toXmtpAddress = command.toXmtpAddress ?? "";
|
|
67853
|
-
} else if (command.type === "xmtp-subscription-push") {
|
|
67854
|
-
base.myAgentId = command.myAgentId;
|
|
67855
|
-
base.conversationCount = command.conversationIds.length;
|
|
67856
67457
|
} else if (command.type === "xmtp-deny-pending-conversation") {
|
|
67857
67458
|
base.groupId = command.groupId;
|
|
67858
67459
|
base.jobId = command.jobId ?? "";
|
|
@@ -68208,10 +67809,6 @@ async function handleDaemonCommand(command, params) {
|
|
|
68208
67809
|
});
|
|
68209
67810
|
return { ok: true, messageId: result.messageId };
|
|
68210
67811
|
}
|
|
68211
|
-
if (command.type === "xmtp-subscription-push") {
|
|
68212
|
-
const result = await handleSubscriptionPushCommand({ command, service: params.service });
|
|
68213
|
-
return { ok: true, payload: result };
|
|
68214
|
-
}
|
|
68215
67812
|
if (command.type === "xmtp-get-pending-list") {
|
|
68216
67813
|
return { ok: true, payload: await listPendingTaskRequests(params) };
|
|
68217
67814
|
}
|
|
@@ -68294,12 +67891,12 @@ async function listPendingTaskRequests(params) {
|
|
|
68294
67891
|
}
|
|
68295
67892
|
async function denyPendingConversationsByJobId(jobId, params, content2) {
|
|
68296
67893
|
const pending = await listPendingTaskRequests(params);
|
|
68297
|
-
const matched = pending.filter((item) =>
|
|
67894
|
+
const matched = pending.filter((item) => isPlainObject2(item) && readString4(item.jobId) === jobId);
|
|
68298
67895
|
const clientAddresses = [...params.service.getClients().keys()];
|
|
68299
67896
|
const targetsByKey = collectDenyTargetsFromPending(matched, clientAddresses);
|
|
68300
67897
|
const groupIds = /* @__PURE__ */ new Set();
|
|
68301
67898
|
for (const item of matched) {
|
|
68302
|
-
if (!
|
|
67899
|
+
if (!isPlainObject2(item)) {
|
|
68303
67900
|
continue;
|
|
68304
67901
|
}
|
|
68305
67902
|
const groupId = readString4(item.groupId);
|
|
@@ -68326,7 +67923,7 @@ async function denyPendingConversationsByJobId(jobId, params, content2) {
|
|
|
68326
67923
|
function collectDenyTargetsFromPending(pending, fallbackAddresses) {
|
|
68327
67924
|
const targetsByKey = /* @__PURE__ */ new Map();
|
|
68328
67925
|
for (const item of pending) {
|
|
68329
|
-
if (!
|
|
67926
|
+
if (!isPlainObject2(item)) {
|
|
68330
67927
|
continue;
|
|
68331
67928
|
}
|
|
68332
67929
|
const groupId = readString4(item.groupId);
|
|
@@ -68351,7 +67948,7 @@ ${groupId}`, {
|
|
|
68351
67948
|
async function resolvePendingTargetsByGroupId(groupId, addresses, params) {
|
|
68352
67949
|
const addressSet = addresses ? new Set(addresses) : null;
|
|
68353
67950
|
const pending = (await listPendingTaskRequests(params)).filter((item) => {
|
|
68354
|
-
if (!
|
|
67951
|
+
if (!isPlainObject2(item) || readString4(item.groupId) !== groupId) {
|
|
68355
67952
|
return false;
|
|
68356
67953
|
}
|
|
68357
67954
|
const address = readString4(item.myXmtpAddress);
|
|
@@ -68471,7 +68068,7 @@ function filterKnownPendingGroups(items, sessionStore) {
|
|
|
68471
68068
|
return items;
|
|
68472
68069
|
}
|
|
68473
68070
|
return items.filter((item) => {
|
|
68474
|
-
if (!
|
|
68071
|
+
if (!isPlainObject2(item)) {
|
|
68475
68072
|
return true;
|
|
68476
68073
|
}
|
|
68477
68074
|
const jobId = readString4(item.jobId);
|
|
@@ -68482,7 +68079,7 @@ function filterKnownPendingGroups(items, sessionStore) {
|
|
|
68482
68079
|
return sessionStore.querySessions({ jobId, toAgentId, limit: 1 }).length === 0;
|
|
68483
68080
|
});
|
|
68484
68081
|
}
|
|
68485
|
-
function
|
|
68082
|
+
function isPlainObject2(value) {
|
|
68486
68083
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
68487
68084
|
}
|
|
68488
68085
|
function readString4(value) {
|
|
@@ -68616,10 +68213,6 @@ function formatCommandCompleted(command, result) {
|
|
|
68616
68213
|
if (command.type === "xmtp-send") {
|
|
68617
68214
|
return `[okx-agent-task] xmtp-send command completed id=${command.id} job=${command.jobId} messageId=${result.messageId}`;
|
|
68618
68215
|
}
|
|
68619
|
-
if (command.type === "xmtp-subscription-push") {
|
|
68620
|
-
const payload = isPlainObject4(result.payload) ? result.payload : {};
|
|
68621
|
-
return `[okx-agent-task] xmtp-subscription-push command completed id=${command.id} deliveryId=${command.deliveryId ?? "(none)"} conversationCount=${payload.conversationCount ?? 0} sentCount=${payload.sentCount ?? 0} failedCount=${payload.failedCount ?? 0}`;
|
|
68622
|
-
}
|
|
68623
68216
|
if (command.type === "xmtp-get-pending-list") {
|
|
68624
68217
|
return `[okx-agent-task] xmtp-get-pending-list command completed id=${command.id}`;
|
|
68625
68218
|
}
|
|
@@ -68640,8 +68233,8 @@ function formatCommandCompleted(command, result) {
|
|
|
68640
68233
|
return `[okx-agent-task] xmtp-refresh-agents command completed id=${command.id}`;
|
|
68641
68234
|
}
|
|
68642
68235
|
function formatXmtpDebugCompleted(command, payload) {
|
|
68643
|
-
const record =
|
|
68644
|
-
const summary =
|
|
68236
|
+
const record = isPlainObject2(payload) ? payload : {};
|
|
68237
|
+
const summary = isPlainObject2(record.summary) ? record.summary : {};
|
|
68645
68238
|
const count = command.action === "group-list" ? record.groupCount ?? 0 : command.action === "group-inspect" ? record.conversationFound ? 1 : 0 : summary.matchedCount ?? 0;
|
|
68646
68239
|
return `[okx-agent-task] xmtp-debug command completed id=${command.id} action=${command.action} rows=${String(count)}`;
|
|
68647
68240
|
}
|
|
@@ -68802,7 +68395,6 @@ var init_command_processor = __esm({
|
|
|
68802
68395
|
init_command_store();
|
|
68803
68396
|
init_invalid_message_store();
|
|
68804
68397
|
init_xmtp_send();
|
|
68805
|
-
init_subscription_push();
|
|
68806
68398
|
init_ai_runner();
|
|
68807
68399
|
init_session_store();
|
|
68808
68400
|
init_ai_provider();
|
|
@@ -68830,7 +68422,7 @@ async function enqueueAiJobMessageDispatch(params) {
|
|
|
68830
68422
|
await commands.submit(command);
|
|
68831
68423
|
return command;
|
|
68832
68424
|
}
|
|
68833
|
-
async function
|
|
68425
|
+
async function enqueueAiSessionMessageDispatch(params) {
|
|
68834
68426
|
const commands = params.commands ?? new CommandStore(params.homeDir);
|
|
68835
68427
|
const messageId = params.event.messageId ?? `session-${Date.now()}`;
|
|
68836
68428
|
const command = commands.createAiSessionMessageDispatchCommand({
|
|
@@ -68840,21 +68432,7 @@ async function enqueueAiSessionMessageDispatchIdempotent(params) {
|
|
|
68840
68432
|
jobId: params.event.jobId,
|
|
68841
68433
|
agentId: params.event.agentId
|
|
68842
68434
|
});
|
|
68843
|
-
const idempotencyKey = params.event.idempotencyKey?.trim();
|
|
68844
|
-
if (idempotencyKey) {
|
|
68845
|
-
const dbKey = `${command.sessionKey}
|
|
68846
|
-
${command.messageId}`;
|
|
68847
|
-
const result = await commands.submitIdempotent(command, dbKey);
|
|
68848
|
-
return {
|
|
68849
|
-
command: result.created ? command : { ...command, id: result.commandId },
|
|
68850
|
-
created: result.created
|
|
68851
|
-
};
|
|
68852
|
-
}
|
|
68853
68435
|
await commands.submit(command);
|
|
68854
|
-
return { command, created: true };
|
|
68855
|
-
}
|
|
68856
|
-
async function enqueueAiSessionMessageDispatch(params) {
|
|
68857
|
-
const { command } = await enqueueAiSessionMessageDispatchIdempotent(params);
|
|
68858
68436
|
return command;
|
|
68859
68437
|
}
|
|
68860
68438
|
var init_ai_dispatch_queue = __esm({
|
|
@@ -68864,156 +68442,6 @@ var init_ai_dispatch_queue = __esm({
|
|
|
68864
68442
|
}
|
|
68865
68443
|
});
|
|
68866
68444
|
|
|
68867
|
-
// src/subscription-inbound.ts
|
|
68868
|
-
function decideSubscriptionGate(input) {
|
|
68869
|
-
if (!isSubscriptionEnvelope(input.payload)) {
|
|
68870
|
-
return { kind: "not_subscription" };
|
|
68871
|
-
}
|
|
68872
|
-
if (input.chatType === "dm") {
|
|
68873
|
-
return { kind: "drop", reason: "dm_subscription" };
|
|
68874
|
-
}
|
|
68875
|
-
if (input.chatType === "unknown") {
|
|
68876
|
-
return { kind: "drop", reason: "unknown_conversation_subscription" };
|
|
68877
|
-
}
|
|
68878
|
-
const read = readSubscriptionEnvelope(input.payload);
|
|
68879
|
-
if (!read.ok) {
|
|
68880
|
-
return { kind: "drop", reason: "invalid_envelope", detail: read.reason };
|
|
68881
|
-
}
|
|
68882
|
-
if (!input.senderInboxId) {
|
|
68883
|
-
return { kind: "drop", reason: "missing_sender_inbox_id" };
|
|
68884
|
-
}
|
|
68885
|
-
return { kind: "v2", envelope: read.envelope };
|
|
68886
|
-
}
|
|
68887
|
-
function partitionSubscriptionJobsByOwner(input) {
|
|
68888
|
-
const owned = [];
|
|
68889
|
-
for (const job of input.jobs) {
|
|
68890
|
-
if (job.userAgentId === input.localAgentId) {
|
|
68891
|
-
owned.push(job);
|
|
68892
|
-
}
|
|
68893
|
-
}
|
|
68894
|
-
return {
|
|
68895
|
-
owned,
|
|
68896
|
-
returnedCount: input.jobs.length,
|
|
68897
|
-
ownedCount: owned.length,
|
|
68898
|
-
ignoredCount: input.jobs.length - owned.length
|
|
68899
|
-
};
|
|
68900
|
-
}
|
|
68901
|
-
function normalizeSubscriptionJobs(input) {
|
|
68902
|
-
const seen = /* @__PURE__ */ new Set();
|
|
68903
|
-
const normalized = [];
|
|
68904
|
-
for (const job of input.jobs) {
|
|
68905
|
-
const dedupKey = `${job.jobId}|${job.userAgentId}|${job.aspAgentId}`;
|
|
68906
|
-
if (seen.has(dedupKey)) {
|
|
68907
|
-
continue;
|
|
68908
|
-
}
|
|
68909
|
-
seen.add(dedupKey);
|
|
68910
|
-
normalized.push({
|
|
68911
|
-
jobId: job.jobId,
|
|
68912
|
-
userAgentId: job.userAgentId,
|
|
68913
|
-
aspAgentId: job.aspAgentId,
|
|
68914
|
-
msgType: SUBSCRIPTION_MESSAGE_TYPE,
|
|
68915
|
-
content: input.envelope.content,
|
|
68916
|
-
...input.envelope.deliveryId ? { deliveryId: input.envelope.deliveryId } : {},
|
|
68917
|
-
conversationId: input.conversationId,
|
|
68918
|
-
senderInboxId: input.senderInboxId
|
|
68919
|
-
});
|
|
68920
|
-
}
|
|
68921
|
-
return normalized;
|
|
68922
|
-
}
|
|
68923
|
-
function subscriptionIdempotencyKey(input) {
|
|
68924
|
-
const messageDimension = input.deliveryId || input.messageId;
|
|
68925
|
-
return `${input.myXmtpAddress}|${messageDimension}|${input.jobId}`;
|
|
68926
|
-
}
|
|
68927
|
-
function tryMarkSubscriptionTarget(key) {
|
|
68928
|
-
if (subscriptionTargets.has(key)) {
|
|
68929
|
-
return false;
|
|
68930
|
-
}
|
|
68931
|
-
subscriptionTargets.set(key, Date.now());
|
|
68932
|
-
while (subscriptionTargets.size > SUBSCRIPTION_TARGETS_MAX) {
|
|
68933
|
-
const oldest = subscriptionTargets.keys().next().value;
|
|
68934
|
-
if (oldest === void 0) {
|
|
68935
|
-
break;
|
|
68936
|
-
}
|
|
68937
|
-
subscriptionTargets.delete(oldest);
|
|
68938
|
-
}
|
|
68939
|
-
return true;
|
|
68940
|
-
}
|
|
68941
|
-
function redactSenderInboxId(senderInboxId, left = 8, right = 6) {
|
|
68942
|
-
if (!senderInboxId) {
|
|
68943
|
-
return "(none)";
|
|
68944
|
-
}
|
|
68945
|
-
if (senderInboxId.length <= left + right + 1) {
|
|
68946
|
-
return senderInboxId;
|
|
68947
|
-
}
|
|
68948
|
-
return `${senderInboxId.slice(0, left)}\u2026${senderInboxId.slice(-right)}`;
|
|
68949
|
-
}
|
|
68950
|
-
async function fanOutSubscriptionJobs(input) {
|
|
68951
|
-
const { jobs, myXmtpAddress, messageId, dispatch, concurrency } = input;
|
|
68952
|
-
const total = jobs.length;
|
|
68953
|
-
const capacityAnomaly = total > SUBSCRIPTION_FANOUT_MAX;
|
|
68954
|
-
if (capacityAnomaly) {
|
|
68955
|
-
logWithTimestamp(
|
|
68956
|
-
`[okx-agent-task:${myXmtpAddress}] subscription fan-out capacity anomaly: jobs=${total} max=${SUBSCRIPTION_FANOUT_MAX} message=${messageId}`
|
|
68957
|
-
);
|
|
68958
|
-
}
|
|
68959
|
-
const settled = await parallelMap(
|
|
68960
|
-
jobs,
|
|
68961
|
-
async (job) => {
|
|
68962
|
-
const idempotencyKey = subscriptionIdempotencyKey({
|
|
68963
|
-
myXmtpAddress,
|
|
68964
|
-
deliveryId: job.deliveryId,
|
|
68965
|
-
messageId,
|
|
68966
|
-
jobId: job.jobId
|
|
68967
|
-
});
|
|
68968
|
-
if (subscriptionTargets.has(idempotencyKey)) {
|
|
68969
|
-
return { key: idempotencyKey, outcome: "duplicate" };
|
|
68970
|
-
}
|
|
68971
|
-
const dispatchOutcome = await dispatch(job, idempotencyKey);
|
|
68972
|
-
const isDurableDuplicate = !!dispatchOutcome && dispatchOutcome.created === false;
|
|
68973
|
-
return { key: idempotencyKey, outcome: isDurableDuplicate ? "duplicate" : "started" };
|
|
68974
|
-
},
|
|
68975
|
-
concurrency ?? 20
|
|
68976
|
-
);
|
|
68977
|
-
let started = 0;
|
|
68978
|
-
let failed = 0;
|
|
68979
|
-
let skippedDuplicate = 0;
|
|
68980
|
-
const results = [];
|
|
68981
|
-
settled.forEach((result, idx) => {
|
|
68982
|
-
const job = jobs[idx];
|
|
68983
|
-
if (result.status === "rejected") {
|
|
68984
|
-
failed += 1;
|
|
68985
|
-
results.push({ jobId: job?.jobId ?? "(unknown)", outcome: "failed", error: result.reason });
|
|
68986
|
-
logWithTimestamp(
|
|
68987
|
-
`[okx-agent-task:${myXmtpAddress}] subscription dispatch failed message=${messageId} job=${job?.jobId ?? "(unknown)"} sender=${redactSenderInboxId(job?.senderInboxId)}:`,
|
|
68988
|
-
result.reason
|
|
68989
|
-
);
|
|
68990
|
-
return;
|
|
68991
|
-
}
|
|
68992
|
-
tryMarkSubscriptionTarget(result.value.key);
|
|
68993
|
-
if (result.value.outcome === "duplicate") {
|
|
68994
|
-
skippedDuplicate += 1;
|
|
68995
|
-
results.push({ jobId: job?.jobId ?? "(unknown)", outcome: "duplicate" });
|
|
68996
|
-
} else {
|
|
68997
|
-
started += 1;
|
|
68998
|
-
results.push({ jobId: job?.jobId ?? "(unknown)", outcome: "started" });
|
|
68999
|
-
}
|
|
69000
|
-
});
|
|
69001
|
-
return { total, started, failed, skippedDuplicate, capacityAnomaly, results };
|
|
69002
|
-
}
|
|
69003
|
-
var SUBSCRIPTION_TARGETS_MAX, subscriptionTargets, SUBSCRIPTION_FANOUT_MAX;
|
|
69004
|
-
var init_subscription_inbound = __esm({
|
|
69005
|
-
"src/subscription-inbound.ts"() {
|
|
69006
|
-
"use strict";
|
|
69007
|
-
init_log();
|
|
69008
|
-
init_concurrency();
|
|
69009
|
-
init_subscription_types();
|
|
69010
|
-
init_subscription_envelope();
|
|
69011
|
-
SUBSCRIPTION_TARGETS_MAX = 2e3;
|
|
69012
|
-
subscriptionTargets = /* @__PURE__ */ new Map();
|
|
69013
|
-
SUBSCRIPTION_FANOUT_MAX = 250;
|
|
69014
|
-
}
|
|
69015
|
-
});
|
|
69016
|
-
|
|
69017
68445
|
// src/message-handler.ts
|
|
69018
68446
|
function tryMarkProcessed(messageId) {
|
|
69019
68447
|
if (processedMessageIds.has(messageId)) {
|
|
@@ -69029,7 +68457,7 @@ function tryMarkProcessed(messageId) {
|
|
|
69029
68457
|
}
|
|
69030
68458
|
return true;
|
|
69031
68459
|
}
|
|
69032
|
-
function
|
|
68460
|
+
function isPlainObject3(value) {
|
|
69033
68461
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
69034
68462
|
}
|
|
69035
68463
|
function safeStringify(value) {
|
|
@@ -69089,9 +68517,9 @@ function readNumber(value) {
|
|
|
69089
68517
|
}
|
|
69090
68518
|
function resolveSessionAgentId(params) {
|
|
69091
68519
|
const { chatType, payload, myXmtpAddress } = params;
|
|
69092
|
-
const payloadObject =
|
|
69093
|
-
const sender =
|
|
69094
|
-
const message =
|
|
68520
|
+
const payloadObject = isPlainObject3(payload) ? payload : null;
|
|
68521
|
+
const sender = isPlainObject3(payloadObject?.sender) ? payloadObject.sender : null;
|
|
68522
|
+
const message = isPlainObject3(payloadObject?.message) ? payloadObject.message : null;
|
|
69095
68523
|
const localAgentId = XmtpService.getInstance().getAgentByAddress(myXmtpAddress)?.agentId ?? null;
|
|
69096
68524
|
if (chatType === "group") {
|
|
69097
68525
|
return readString5(sender?.agentId) ?? readString5(payloadObject?.receiverAgentId) ?? localAgentId;
|
|
@@ -69102,7 +68530,7 @@ function resolveSessionAgentId(params) {
|
|
|
69102
68530
|
return localAgentId;
|
|
69103
68531
|
}
|
|
69104
68532
|
function routeMessage(chatType, parsed, payload) {
|
|
69105
|
-
if (!parsed || !
|
|
68533
|
+
if (!parsed || !isPlainObject3(payload)) {
|
|
69106
68534
|
return {
|
|
69107
68535
|
jobId: BACKUP_JOB_ID,
|
|
69108
68536
|
route: "backup",
|
|
@@ -69114,7 +68542,7 @@ function routeMessage(chatType, parsed, payload) {
|
|
|
69114
68542
|
return jobId ? { jobId, route: "job", routeReason: "group-job-id" } : { jobId: BACKUP_JOB_ID, route: "backup", routeReason: "group-missing-job-id" };
|
|
69115
68543
|
}
|
|
69116
68544
|
if (chatType === "dm") {
|
|
69117
|
-
const message =
|
|
68545
|
+
const message = isPlainObject3(payload.message) ? payload.message : null;
|
|
69118
68546
|
const nestedJobId = readString5(message?.jobId);
|
|
69119
68547
|
const directJobId = readString5(payload.jobId);
|
|
69120
68548
|
const jobId = nestedJobId ?? directJobId;
|
|
@@ -69127,10 +68555,10 @@ function routeMessage(chatType, parsed, payload) {
|
|
|
69127
68555
|
return { jobId: BACKUP_JOB_ID, route: "backup", routeReason: "unknown-conversation" };
|
|
69128
68556
|
}
|
|
69129
68557
|
function extractDirectToUserNotification(payload) {
|
|
69130
|
-
if (!
|
|
68558
|
+
if (!isPlainObject3(payload)) {
|
|
69131
68559
|
return { kind: "none" };
|
|
69132
68560
|
}
|
|
69133
|
-
const message =
|
|
68561
|
+
const message = isPlainObject3(payload.message) ? payload.message : null;
|
|
69134
68562
|
if (message?.isDirectToUser !== true) {
|
|
69135
68563
|
return { kind: "none" };
|
|
69136
68564
|
}
|
|
@@ -69154,10 +68582,10 @@ function extractDirectToUserNotification(payload) {
|
|
|
69154
68582
|
};
|
|
69155
68583
|
}
|
|
69156
68584
|
function extractSystemNotification(payload) {
|
|
69157
|
-
if (!
|
|
68585
|
+
if (!isPlainObject3(payload)) {
|
|
69158
68586
|
return null;
|
|
69159
68587
|
}
|
|
69160
|
-
const message =
|
|
68588
|
+
const message = isPlainObject3(payload.message) ? payload.message : null;
|
|
69161
68589
|
const isDirectCommunication = message?.isDirectCommunication === true;
|
|
69162
68590
|
if (message?.source !== "system" && !isDirectCommunication) {
|
|
69163
68591
|
return null;
|
|
@@ -69383,7 +68811,7 @@ function inboundStageExtras(stage, outcome) {
|
|
|
69383
68811
|
})
|
|
69384
68812
|
};
|
|
69385
68813
|
}
|
|
69386
|
-
function
|
|
68814
|
+
function definedExtras(input) {
|
|
69387
68815
|
return Object.entries(input).reduce((out, [key, value]) => {
|
|
69388
68816
|
const text = readString5(value);
|
|
69389
68817
|
if (text) {
|
|
@@ -69415,7 +68843,7 @@ function buildInboundTerminalExtras(input) {
|
|
|
69415
68843
|
originPlatform: classifyOriginPlatform({ env: process.env }),
|
|
69416
68844
|
deliveryId: resolveDeliveryId({ messageId, jobId, sessionKey })
|
|
69417
68845
|
}),
|
|
69418
|
-
...
|
|
68846
|
+
...definedExtras({
|
|
69419
68847
|
messageId,
|
|
69420
68848
|
conversationId,
|
|
69421
68849
|
chatType,
|
|
@@ -69449,7 +68877,7 @@ function maybeNotifyInboundAgentMessage(params) {
|
|
|
69449
68877
|
return;
|
|
69450
68878
|
}
|
|
69451
68879
|
const content2 = payloadObject.content;
|
|
69452
|
-
const sender =
|
|
68880
|
+
const sender = isPlainObject3(payloadObject.sender) ? payloadObject.sender : null;
|
|
69453
68881
|
const localAgent = XmtpService.getInstance().getAgentByAddress(params.deps.myXmtpAddress);
|
|
69454
68882
|
void notifyAgentMessageToUserAttention({
|
|
69455
68883
|
direction: "inbound" /* INBOUND */,
|
|
@@ -69480,11 +68908,11 @@ function stringifySystemPayload(payload) {
|
|
|
69480
68908
|
}
|
|
69481
68909
|
}
|
|
69482
68910
|
function summarizePayloadForLog(payload) {
|
|
69483
|
-
if (!
|
|
68911
|
+
if (!isPlainObject3(payload)) {
|
|
69484
68912
|
return "payload=non-object";
|
|
69485
68913
|
}
|
|
69486
|
-
const message =
|
|
69487
|
-
const sender =
|
|
68914
|
+
const message = isPlainObject3(payload.message) ? payload.message : null;
|
|
68915
|
+
const sender = isPlainObject3(payload.sender) ? payload.sender : null;
|
|
69488
68916
|
const jobId = readString5(payload.jobId) ?? readString5(message?.jobId);
|
|
69489
68917
|
const parts = [
|
|
69490
68918
|
readString5(payload.msgType) ? `type=${readString5(payload.msgType)}` : null,
|
|
@@ -69753,7 +69181,7 @@ async function verifyInboundA2AGroupMessage(params) {
|
|
|
69753
69181
|
messageId,
|
|
69754
69182
|
groupId,
|
|
69755
69183
|
jobId,
|
|
69756
|
-
agentId: readString5(
|
|
69184
|
+
agentId: readString5(isPlainObject3(payload.sender) ? payload.sender.agentId : null),
|
|
69757
69185
|
localAgentId: myAgent?.agentId ?? null,
|
|
69758
69186
|
senderAddress,
|
|
69759
69187
|
senderInboxId,
|
|
@@ -69779,7 +69207,7 @@ async function verifyInboundA2AGroupMessage(params) {
|
|
|
69779
69207
|
});
|
|
69780
69208
|
return false;
|
|
69781
69209
|
}
|
|
69782
|
-
const sender =
|
|
69210
|
+
const sender = isPlainObject3(payload.sender) ? payload.sender : null;
|
|
69783
69211
|
const senderAgentId = readString5(sender?.agentId);
|
|
69784
69212
|
const senderRole = readNumber(sender?.role);
|
|
69785
69213
|
if (!senderAgentId || !myAgent) {
|
|
@@ -69948,302 +69376,9 @@ ${failureMessage}`,
|
|
|
69948
69376
|
}
|
|
69949
69377
|
return true;
|
|
69950
69378
|
}
|
|
69951
|
-
async function processSubscriptionInbound(ctx, deps, input) {
|
|
69952
|
-
const { decision, conversationId, messageId } = input;
|
|
69953
|
-
const senderInboxId = ctx.message.senderInboxId ?? "";
|
|
69954
|
-
if (decision.kind === "drop") {
|
|
69955
|
-
logger.info(
|
|
69956
|
-
LogEvent.SUBSCRIPTION_INBOUND_GATE_DROPPED,
|
|
69957
|
-
buildSubscriptionInboundExtras({
|
|
69958
|
-
checkpoint: "inbound/subscription_gate_dropped",
|
|
69959
|
-
outcome: "dropped",
|
|
69960
|
-
conversationId,
|
|
69961
|
-
messageId,
|
|
69962
|
-
senderInboxId: shortenLogValue(senderInboxId),
|
|
69963
|
-
reason: decision.reason
|
|
69964
|
-
})
|
|
69965
|
-
);
|
|
69966
|
-
logWithTimestamp(
|
|
69967
|
-
`[okx-agent-task:${deps.myXmtpAddress}] subscription message dropped reason=${decision.reason}${decision.detail ? ` detail=${decision.detail}` : ""} conv=${conversationId} message=${shortenLogValue(messageId)} sender=${shortenLogValue(senderInboxId)}`
|
|
69968
|
-
);
|
|
69969
|
-
return true;
|
|
69970
|
-
}
|
|
69971
|
-
if (decision.kind === "not_subscription") {
|
|
69972
|
-
return true;
|
|
69973
|
-
}
|
|
69974
|
-
const { envelope } = decision;
|
|
69975
|
-
const agenticId = XmtpService.getInstance().getAgentByAddress(deps.myXmtpAddress)?.agentId;
|
|
69976
|
-
if (!agenticId) {
|
|
69977
|
-
logWithTimestamp(
|
|
69978
|
-
`[okx-agent-task:${deps.myXmtpAddress}] subscription fail-closed: no local agenticId for ${deps.myXmtpAddress}, conv=${conversationId} message=${shortenLogValue(messageId)}`
|
|
69979
|
-
);
|
|
69980
|
-
logger.error(
|
|
69981
|
-
LogEvent.SUBSCRIPTION_INBOUND_AGENTIC_ID_MISSING,
|
|
69982
|
-
new Error("Subscription inbound: local agenticId not resolved"),
|
|
69983
|
-
buildSubscriptionInboundExtras({
|
|
69984
|
-
checkpoint: "inbound/subscription_agentic_id",
|
|
69985
|
-
outcome: "blocked",
|
|
69986
|
-
conversationId,
|
|
69987
|
-
messageId,
|
|
69988
|
-
senderInboxId: shortenLogValue(senderInboxId),
|
|
69989
|
-
reason: "missing_agentic_id"
|
|
69990
|
-
})
|
|
69991
|
-
);
|
|
69992
|
-
return true;
|
|
69993
|
-
}
|
|
69994
|
-
logWithTimestamp(
|
|
69995
|
-
`[okx-agent-task:${deps.myXmtpAddress}] subscription received msgType=${envelope.msgType} conv=${conversationId} message=${shortenLogValue(messageId)} sender=${shortenLogValue(senderInboxId)}`
|
|
69996
|
-
);
|
|
69997
|
-
logger.info(
|
|
69998
|
-
LogEvent.SUBSCRIPTION_INBOUND_RECEIVED,
|
|
69999
|
-
buildSubscriptionInboundExtras({
|
|
70000
|
-
checkpoint: "inbound/subscription_received",
|
|
70001
|
-
userAgentId: agenticId,
|
|
70002
|
-
conversationId,
|
|
70003
|
-
messageId,
|
|
70004
|
-
deliveryId: envelope.deliveryId,
|
|
70005
|
-
senderInboxId: shortenLogValue(senderInboxId)
|
|
70006
|
-
})
|
|
70007
|
-
);
|
|
70008
|
-
const listJobs = deps.listJobsByVerifiedSenderImpl ?? listJobsByVerifiedSenderWithCapability;
|
|
70009
|
-
logger.info(
|
|
70010
|
-
LogEvent.SUBSCRIPTION_JOBS_QUERY_STARTED,
|
|
70011
|
-
buildSubscriptionInboundExtras({
|
|
70012
|
-
checkpoint: "inbound/subscription_jobs_query_started",
|
|
70013
|
-
userAgentId: agenticId,
|
|
70014
|
-
conversationId,
|
|
70015
|
-
messageId
|
|
70016
|
-
})
|
|
70017
|
-
);
|
|
70018
|
-
const listJobsResult = await listJobs({
|
|
70019
|
-
groupId: conversationId,
|
|
70020
|
-
senderInboxId,
|
|
70021
|
-
agenticId
|
|
70022
|
-
});
|
|
70023
|
-
logWithTimestamp(
|
|
70024
|
-
`[okx-agent-task:${deps.myXmtpAddress}] subscription queried status=${listJobsResult.status} jobs=${listJobsResult.jobs.length} invalid=${listJobsResult.invalidCount} conv=${conversationId} message=${shortenLogValue(messageId)}`
|
|
70025
|
-
);
|
|
70026
|
-
if (listJobsResult.status === "fail_closed") {
|
|
70027
|
-
logger.error(
|
|
70028
|
-
LogEvent.SUBSCRIPTION_JOBS_FAIL_CLOSED,
|
|
70029
|
-
new Error("Subscription inbound: listJobsByVerifiedSender fail-closed"),
|
|
70030
|
-
buildSubscriptionInboundExtras({
|
|
70031
|
-
checkpoint: "inbound/subscription_jobs_fail_closed",
|
|
70032
|
-
outcome: "blocked",
|
|
70033
|
-
userAgentId: agenticId,
|
|
70034
|
-
conversationId,
|
|
70035
|
-
messageId,
|
|
70036
|
-
senderInboxId: shortenLogValue(senderInboxId),
|
|
70037
|
-
reason: listJobsResult.reason ?? "unknown",
|
|
70038
|
-
errorCode: listJobsResult.errorCode
|
|
70039
|
-
})
|
|
70040
|
-
);
|
|
70041
|
-
return true;
|
|
70042
|
-
}
|
|
70043
|
-
if (listJobsResult.status === "empty") {
|
|
70044
|
-
logWithTimestamp(
|
|
70045
|
-
`[okx-agent-task:${deps.myXmtpAddress}] subscription empty: no verified jobs for conv=${conversationId} message=${shortenLogValue(messageId)}`
|
|
70046
|
-
);
|
|
70047
|
-
logger.info(
|
|
70048
|
-
LogEvent.SUBSCRIPTION_JOBS_EMPTY,
|
|
70049
|
-
buildSubscriptionInboundExtras({
|
|
70050
|
-
checkpoint: "inbound/subscription_jobs_empty",
|
|
70051
|
-
outcome: "ignored",
|
|
70052
|
-
userAgentId: agenticId,
|
|
70053
|
-
conversationId,
|
|
70054
|
-
messageId,
|
|
70055
|
-
reason: "jobs_empty",
|
|
70056
|
-
returnedCount: 0,
|
|
70057
|
-
invalidCount: listJobsResult.invalidCount
|
|
70058
|
-
})
|
|
70059
|
-
);
|
|
70060
|
-
return true;
|
|
70061
|
-
}
|
|
70062
|
-
logger.info(
|
|
70063
|
-
LogEvent.SUBSCRIPTION_JOBS_QUERY_SUCCEEDED,
|
|
70064
|
-
buildSubscriptionInboundExtras({
|
|
70065
|
-
checkpoint: "inbound/subscription_jobs_query_succeeded",
|
|
70066
|
-
userAgentId: agenticId,
|
|
70067
|
-
conversationId,
|
|
70068
|
-
messageId,
|
|
70069
|
-
returnedCount: listJobsResult.jobs.length,
|
|
70070
|
-
invalidCount: listJobsResult.invalidCount
|
|
70071
|
-
})
|
|
70072
|
-
);
|
|
70073
|
-
const ownership = partitionSubscriptionJobsByOwner({
|
|
70074
|
-
jobs: listJobsResult.jobs,
|
|
70075
|
-
localAgentId: agenticId
|
|
70076
|
-
});
|
|
70077
|
-
logWithTimestamp(
|
|
70078
|
-
`[okx-agent-task:${deps.myXmtpAddress}] subscription routed receiver=${agenticId} returned=${ownership.returnedCount} localOwned=${ownership.ownedCount} ignored=${ownership.ignoredCount} conv=${conversationId} message=${shortenLogValue(messageId)}`
|
|
70079
|
-
);
|
|
70080
|
-
logger.info(
|
|
70081
|
-
LogEvent.SUBSCRIPTION_INBOUND_OWNERSHIP_ROUTED,
|
|
70082
|
-
buildSubscriptionInboundExtras({
|
|
70083
|
-
checkpoint: "inbound/subscription_ownership_routed",
|
|
70084
|
-
outcome: ownership.ownedCount === 0 ? "ignored" : null,
|
|
70085
|
-
userAgentId: agenticId,
|
|
70086
|
-
conversationId,
|
|
70087
|
-
messageId,
|
|
70088
|
-
returnedCount: ownership.returnedCount,
|
|
70089
|
-
ownedCount: ownership.ownedCount,
|
|
70090
|
-
ignoredCount: ownership.ignoredCount
|
|
70091
|
-
})
|
|
70092
|
-
);
|
|
70093
|
-
if (ownership.ownedCount === 0) {
|
|
70094
|
-
return true;
|
|
70095
|
-
}
|
|
70096
|
-
const normalizedJobs = normalizeSubscriptionJobs({
|
|
70097
|
-
jobs: ownership.owned,
|
|
70098
|
-
envelope,
|
|
70099
|
-
conversationId,
|
|
70100
|
-
senderInboxId
|
|
70101
|
-
});
|
|
70102
|
-
logWithTimestamp(
|
|
70103
|
-
`[okx-agent-task:${deps.myXmtpAddress}] subscription expanded jobs=${normalizedJobs.length} conv=${conversationId} message=${shortenLogValue(messageId)}`
|
|
70104
|
-
);
|
|
70105
|
-
let senderXmtpAddress = null;
|
|
70106
|
-
try {
|
|
70107
|
-
const resolved = await ctx.getSenderAddress();
|
|
70108
|
-
senderXmtpAddress = resolved ? resolved : null;
|
|
70109
|
-
} catch (err2) {
|
|
70110
|
-
logWithTimestamp(
|
|
70111
|
-
`[okx-agent-task:${deps.myXmtpAddress}] subscription sender address unresolved (degrading to null) conv=${conversationId} message=${shortenLogValue(messageId)}:`,
|
|
70112
|
-
err2
|
|
70113
|
-
);
|
|
70114
|
-
}
|
|
70115
|
-
const fanoutResult = await fanOutSubscriptionJobs({
|
|
70116
|
-
jobs: normalizedJobs,
|
|
70117
|
-
myXmtpAddress: deps.myXmtpAddress,
|
|
70118
|
-
messageId,
|
|
70119
|
-
dispatch: async (job, idempotencyKey) => {
|
|
70120
|
-
const sessionKey = buildSessionKey({
|
|
70121
|
-
jobId: job.jobId,
|
|
70122
|
-
myAgentId: job.userAgentId,
|
|
70123
|
-
toAgentId: job.aspAgentId
|
|
70124
|
-
});
|
|
70125
|
-
deps.sessionStore?.upsertSession({
|
|
70126
|
-
sessionKey,
|
|
70127
|
-
jobId: job.jobId,
|
|
70128
|
-
myAgentId: job.userAgentId,
|
|
70129
|
-
toAgentId: job.aspAgentId,
|
|
70130
|
-
groupId: job.conversationId,
|
|
70131
|
-
myAgentXmtpAddress: deps.myXmtpAddress,
|
|
70132
|
-
toAgentXmtpAddress: senderXmtpAddress
|
|
70133
|
-
});
|
|
70134
|
-
return deps.onSessionMessage?.({
|
|
70135
|
-
sessionKey,
|
|
70136
|
-
content: JSON.stringify({
|
|
70137
|
-
msgType: job.msgType,
|
|
70138
|
-
content: job.content,
|
|
70139
|
-
...job.deliveryId ? { deliveryId: job.deliveryId } : {},
|
|
70140
|
-
jobId: job.jobId,
|
|
70141
|
-
userAgentId: job.userAgentId,
|
|
70142
|
-
aspAgentId: job.aspAgentId,
|
|
70143
|
-
conversationId: job.conversationId,
|
|
70144
|
-
senderInboxId: job.senderInboxId,
|
|
70145
|
-
// Raw XMTP messageId preserved for sender/receiver telemetry join;
|
|
70146
|
-
// the durable dedup identity is the idempotencyKey passed as this
|
|
70147
|
-
// session-message's own `messageId` field below (M1 fix).
|
|
70148
|
-
xmtpMessageId: messageId
|
|
70149
|
-
}),
|
|
70150
|
-
messageId: idempotencyKey,
|
|
70151
|
-
// Durable exactly-once enqueue key (M2): the wiring persists via
|
|
70152
|
-
// CommandStore.submitIdempotent keyed on sessionKey+messageId so a
|
|
70153
|
-
// re-processed / replayed message never creates a second command.
|
|
70154
|
-
idempotencyKey,
|
|
70155
|
-
jobId: job.jobId,
|
|
70156
|
-
agentId: job.userAgentId
|
|
70157
|
-
});
|
|
70158
|
-
}
|
|
70159
|
-
});
|
|
70160
|
-
logWithTimestamp(
|
|
70161
|
-
`[okx-agent-task:${deps.myXmtpAddress}] subscription fan-out succeeded=${fanoutResult.started} failed=${fanoutResult.failed} skippedDuplicate=${fanoutResult.skippedDuplicate} total=${fanoutResult.total} capacityAnomaly=${fanoutResult.capacityAnomaly} conv=${conversationId} message=${shortenLogValue(messageId)}`
|
|
70162
|
-
);
|
|
70163
|
-
const normalizedJobsById = new Map(normalizedJobs.map((job) => [job.jobId, job]));
|
|
70164
|
-
for (const result of fanoutResult.results) {
|
|
70165
|
-
const job = normalizedJobsById.get(result.jobId);
|
|
70166
|
-
if (result.outcome === "started") {
|
|
70167
|
-
logger.info(
|
|
70168
|
-
LogEvent.SUBSCRIPTION_JOB_DISPATCHED,
|
|
70169
|
-
buildSubscriptionJobExtras({
|
|
70170
|
-
checkpoint: "dispatch/subscription_job_dispatched",
|
|
70171
|
-
outcome: "success",
|
|
70172
|
-
jobId: result.jobId,
|
|
70173
|
-
userAgentId: agenticId,
|
|
70174
|
-
aspAgentId: job?.aspAgentId,
|
|
70175
|
-
conversationId,
|
|
70176
|
-
deliveryId: envelope.deliveryId
|
|
70177
|
-
})
|
|
70178
|
-
);
|
|
70179
|
-
} else if (result.outcome === "duplicate") {
|
|
70180
|
-
logger.info(
|
|
70181
|
-
LogEvent.SUBSCRIPTION_JOB_DUPLICATE_IGNORED,
|
|
70182
|
-
buildSubscriptionJobExtras({
|
|
70183
|
-
checkpoint: "dispatch/subscription_job_duplicate_ignored",
|
|
70184
|
-
outcome: "ignored",
|
|
70185
|
-
jobId: result.jobId,
|
|
70186
|
-
userAgentId: agenticId,
|
|
70187
|
-
aspAgentId: job?.aspAgentId,
|
|
70188
|
-
conversationId,
|
|
70189
|
-
deliveryId: envelope.deliveryId,
|
|
70190
|
-
reason: "duplicate_delivery"
|
|
70191
|
-
})
|
|
70192
|
-
);
|
|
70193
|
-
} else {
|
|
70194
|
-
logger.error(
|
|
70195
|
-
LogEvent.SUBSCRIPTION_JOB_FAILED,
|
|
70196
|
-
toLoggableError(result.error),
|
|
70197
|
-
buildSubscriptionJobExtras({
|
|
70198
|
-
checkpoint: "dispatch/subscription_job_failed",
|
|
70199
|
-
outcome: "failed",
|
|
70200
|
-
jobId: result.jobId,
|
|
70201
|
-
userAgentId: agenticId,
|
|
70202
|
-
aspAgentId: job?.aspAgentId,
|
|
70203
|
-
conversationId,
|
|
70204
|
-
deliveryId: envelope.deliveryId,
|
|
70205
|
-
reason: "session_dispatch_failed"
|
|
70206
|
-
})
|
|
70207
|
-
);
|
|
70208
|
-
}
|
|
70209
|
-
}
|
|
70210
|
-
logger.info(
|
|
70211
|
-
LogEvent.SUBSCRIPTION_FANOUT_SUMMARY,
|
|
70212
|
-
buildSubscriptionJobExtras({
|
|
70213
|
-
checkpoint: "dispatch/subscription_fanout_summary",
|
|
70214
|
-
outcome: fanoutResult.failed === 0 ? "success" : fanoutResult.started > 0 || fanoutResult.skippedDuplicate > 0 ? "partial" : "failed",
|
|
70215
|
-
conversationId,
|
|
70216
|
-
userAgentId: agenticId,
|
|
70217
|
-
total: fanoutResult.total,
|
|
70218
|
-
started: fanoutResult.started,
|
|
70219
|
-
failed: fanoutResult.failed,
|
|
70220
|
-
skippedDuplicate: fanoutResult.skippedDuplicate
|
|
70221
|
-
})
|
|
70222
|
-
);
|
|
70223
|
-
return true;
|
|
70224
|
-
}
|
|
70225
69379
|
async function processFileMessage(ctx, deps, options = {}) {
|
|
70226
69380
|
const messageId = ctx.message.id ?? "";
|
|
70227
69381
|
const timing = createInboundTimingTracker(extractXmtpSentAtMs2(ctx.message));
|
|
70228
|
-
const subscriptionPrecheckRawText = extractRawText(ctx.message.content);
|
|
70229
|
-
const subscriptionPrecheckParse = parseJson2(subscriptionPrecheckRawText);
|
|
70230
|
-
if (subscriptionPrecheckParse.ok && isSubscriptionEnvelope(subscriptionPrecheckParse.data)) {
|
|
70231
|
-
const { chatType: subscriptionChatType, conversationId: subscriptionConversationId } = getConversationInfo(ctx.conversation);
|
|
70232
|
-
const gateDecision = decideSubscriptionGate({
|
|
70233
|
-
// getConversationInfo's declared StoredChatType also lists "system",
|
|
70234
|
-
// but that value is only ever produced for stored-message bookkeeping
|
|
70235
|
-
// elsewhere in this file — the conversation-type branch above never
|
|
70236
|
-
// returns it, so this narrowing is safe.
|
|
70237
|
-
chatType: subscriptionChatType === "system" ? "unknown" : subscriptionChatType,
|
|
70238
|
-
payload: subscriptionPrecheckParse.data,
|
|
70239
|
-
senderInboxId: ctx.message.senderInboxId ?? ""
|
|
70240
|
-
});
|
|
70241
|
-
return processSubscriptionInbound(ctx, deps, {
|
|
70242
|
-
decision: gateDecision,
|
|
70243
|
-
conversationId: subscriptionConversationId,
|
|
70244
|
-
messageId: messageId || `subscription-${(0, import_node_crypto15.randomUUID)()}`
|
|
70245
|
-
});
|
|
70246
|
-
}
|
|
70247
69382
|
if (messageId && !tryMarkProcessed(messageId)) {
|
|
70248
69383
|
logWithTimestamp(`[okx-agent-task:${deps.myXmtpAddress}] duplicate message ignored: ${messageId}`);
|
|
70249
69384
|
logger.info(LogEvent.INBOUND_IGNORED_DUPLICATE, timing.extras({
|
|
@@ -70266,6 +69401,19 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
70266
69401
|
chatType,
|
|
70267
69402
|
...extra
|
|
70268
69403
|
});
|
|
69404
|
+
if (chatType === "dm") {
|
|
69405
|
+
const dmTrustStartedAt = Date.now();
|
|
69406
|
+
const trusted = await isTrustedDmSender({
|
|
69407
|
+
myXmtpAddress: deps.myXmtpAddress,
|
|
69408
|
+
senderInboxId: ctx.message.senderInboxId ?? "",
|
|
69409
|
+
messageId,
|
|
69410
|
+
conversationId
|
|
69411
|
+
});
|
|
69412
|
+
timing.mark("dmTrustCheck", dmTrustStartedAt);
|
|
69413
|
+
if (!trusted) {
|
|
69414
|
+
return true;
|
|
69415
|
+
}
|
|
69416
|
+
}
|
|
70269
69417
|
const parseStartedAt = Date.now();
|
|
70270
69418
|
const receivedRawText = extractRawText(ctx.message.content);
|
|
70271
69419
|
const parseResult = parseJson2(receivedRawText);
|
|
@@ -70281,26 +69429,9 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
70281
69429
|
}
|
|
70282
69430
|
}
|
|
70283
69431
|
timing.mark("payloadParse", parseStartedAt);
|
|
70284
|
-
const parsedDmData = parseResult.ok ? parseResult.data : null;
|
|
70285
|
-
const parsedDmMessage = isPlainObject5(parsedDmData) && isPlainObject5(parsedDmData.message) ? parsedDmData.message : null;
|
|
70286
|
-
const dmCarriesSystemMarkers = parsedDmMessage?.isDirectToUser === true || parsedDmMessage?.source === "system" || parsedDmMessage?.isDirectCommunication === true;
|
|
70287
|
-
const isA2ADm = chatType === "dm" && parseResult.ok && isA2AEnvelope(parseResult.data) && !dmCarriesSystemMarkers;
|
|
70288
|
-
if (chatType === "dm" && !isA2ADm) {
|
|
70289
|
-
const dmTrustStartedAt = Date.now();
|
|
70290
|
-
const trusted = await isTrustedDmSender({
|
|
70291
|
-
myXmtpAddress: deps.myXmtpAddress,
|
|
70292
|
-
senderInboxId: ctx.message.senderInboxId ?? "",
|
|
70293
|
-
messageId,
|
|
70294
|
-
conversationId
|
|
70295
|
-
});
|
|
70296
|
-
timing.mark("dmTrustCheck", dmTrustStartedAt);
|
|
70297
|
-
if (!trusted) {
|
|
70298
|
-
return true;
|
|
70299
|
-
}
|
|
70300
|
-
}
|
|
70301
69432
|
const directToUser = chatType === "dm" && parseResult.ok ? extractDirectToUserNotification(parseResult.data) : { kind: "none" };
|
|
70302
69433
|
if (directToUser.kind === "invalid") {
|
|
70303
|
-
const droppedMessageId = messageId || `direct-to-user-${(0,
|
|
69434
|
+
const droppedMessageId = messageId || `direct-to-user-${(0, import_node_crypto14.randomUUID)()}`;
|
|
70304
69435
|
logger.error(
|
|
70305
69436
|
LogEvent.INBOUND_DROP_DM_INVALID_PAYLOAD,
|
|
70306
69437
|
new Error("Invalid direct-to-user system DM"),
|
|
@@ -70324,7 +69455,7 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
70324
69455
|
await dispatchDirectToUserNotification({
|
|
70325
69456
|
deps,
|
|
70326
69457
|
notification: directToUser.notification,
|
|
70327
|
-
messageId: messageId || `direct-to-user-${(0,
|
|
69458
|
+
messageId: messageId || `direct-to-user-${(0, import_node_crypto14.randomUUID)()}`,
|
|
70328
69459
|
timing,
|
|
70329
69460
|
source: options.source ?? "live"
|
|
70330
69461
|
});
|
|
@@ -70332,7 +69463,7 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
70332
69463
|
}
|
|
70333
69464
|
const systemNotification = chatType === "dm" && parseResult.ok ? extractSystemNotification(parseResult.data) : null;
|
|
70334
69465
|
if (systemNotification) {
|
|
70335
|
-
const systemMessageId = messageId || `system-${(0,
|
|
69466
|
+
const systemMessageId = messageId || `system-${(0, import_node_crypto14.randomUUID)()}`;
|
|
70336
69467
|
logWithTimestamp(
|
|
70337
69468
|
`[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)}`
|
|
70338
69469
|
);
|
|
@@ -70493,7 +69624,7 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
70493
69624
|
timing.mark("routeResolve", routeStartedAt);
|
|
70494
69625
|
if (route.route === "job" && parseResult.ok && isA2AEnvelope(parseResult.data) && !isValidExternalJobId(route.jobId)) {
|
|
70495
69626
|
const payloadObject = parseResult.data;
|
|
70496
|
-
const sender =
|
|
69627
|
+
const sender = isPlainObject3(payloadObject.sender) ? payloadObject.sender : null;
|
|
70497
69628
|
logWithTimestamp(
|
|
70498
69629
|
`[okx-agent-task:${deps.myXmtpAddress}] inbound A2A message has invalid jobId, dropping: jobLength=${route.jobId.length} group=${conversationId}`
|
|
70499
69630
|
);
|
|
@@ -70522,32 +69653,7 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
70522
69653
|
});
|
|
70523
69654
|
return true;
|
|
70524
69655
|
}
|
|
70525
|
-
if (
|
|
70526
|
-
const payloadObject = parseResult.data;
|
|
70527
|
-
const sender = isPlainObject5(payloadObject.sender) ? payloadObject.sender : null;
|
|
70528
|
-
recordInvalidXmtpMessageBestEffort({
|
|
70529
|
-
messageId,
|
|
70530
|
-
groupId: conversationId,
|
|
70531
|
-
jobId: null,
|
|
70532
|
-
agentId: readString5(sender?.agentId),
|
|
70533
|
-
localAgentId: XmtpService.getInstance().getAgentByAddress(deps.myXmtpAddress)?.agentId ?? null,
|
|
70534
|
-
senderInboxId: ctx.message.senderInboxId ?? "",
|
|
70535
|
-
reason: "dm_a2a_missing_job_id",
|
|
70536
|
-
stage: "inbound/job_id_validation",
|
|
70537
|
-
logTag: `[okx-agent-task:${deps.myXmtpAddress}]`
|
|
70538
|
-
});
|
|
70539
|
-
logger.info(LogEvent.INBOUND_DROP_INVALID_JOBID, {
|
|
70540
|
-
...agentExtras({ walletAddress: deps.myXmtpAddress }),
|
|
70541
|
-
conversationId,
|
|
70542
|
-
messageId,
|
|
70543
|
-
chatType,
|
|
70544
|
-
peerInboxId: ctx.message.senderInboxId ?? "",
|
|
70545
|
-
...inboundStageExtras("inbound/job_id_validation", "dropped"),
|
|
70546
|
-
reason: "dm_a2a_missing_job_id"
|
|
70547
|
-
});
|
|
70548
|
-
return true;
|
|
70549
|
-
}
|
|
70550
|
-
if (route.route === "job" && chatType !== "group" && !isA2ADm) {
|
|
69656
|
+
if (route.route === "job" && chatType !== "group") {
|
|
70551
69657
|
const providerBindStartedAt = Date.now();
|
|
70552
69658
|
const providerGate = await bindMessageJobProviderToCurrentDefault(deps, route.jobId, "inbound-xmtp");
|
|
70553
69659
|
timing.mark("providerBind", providerBindStartedAt);
|
|
@@ -70587,7 +69693,7 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
70587
69693
|
);
|
|
70588
69694
|
}
|
|
70589
69695
|
if (route.route === "job" && chatType === "group") {
|
|
70590
|
-
const payloadObject =
|
|
69696
|
+
const payloadObject = isPlainObject3(parseResult.ok ? parseResult.data : null) ? parseResult.data : null;
|
|
70591
69697
|
const service = XmtpService.getInstance();
|
|
70592
69698
|
const trustedSystemSender = service.isTrustedSystemAccountSender({
|
|
70593
69699
|
senderAddress,
|
|
@@ -70613,7 +69719,7 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
70613
69719
|
});
|
|
70614
69720
|
return true;
|
|
70615
69721
|
}
|
|
70616
|
-
const sender =
|
|
69722
|
+
const sender = isPlainObject3(payloadObject?.sender) ? payloadObject.sender : null;
|
|
70617
69723
|
const localAgent = service.getAgentByAddress(deps.myXmtpAddress);
|
|
70618
69724
|
const myAgentId = localAgent?.agentId ?? readString5(payloadObject?.receiverAgentId) ?? sessionAgentId ?? null;
|
|
70619
69725
|
const toAgentId = readString5(sender?.agentId);
|
|
@@ -70653,7 +69759,7 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
70653
69759
|
}));
|
|
70654
69760
|
return true;
|
|
70655
69761
|
}
|
|
70656
|
-
const routedMessageId = messageId || `group-${(0,
|
|
69762
|
+
const routedMessageId = messageId || `group-${(0, import_node_crypto14.randomUUID)()}`;
|
|
70657
69763
|
const sessionKey = ensureInboundGroupSession(deps, {
|
|
70658
69764
|
jobId: route.jobId,
|
|
70659
69765
|
myAgentId,
|
|
@@ -70718,102 +69824,8 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
70718
69824
|
);
|
|
70719
69825
|
return true;
|
|
70720
69826
|
}
|
|
70721
|
-
if (route.route === "job" && isA2ADm) {
|
|
70722
|
-
const payloadObject = parseResult.data;
|
|
70723
|
-
const accepted = await verifyInboundA2AGroupMessage({
|
|
70724
|
-
payload: parseResult.data,
|
|
70725
|
-
myXmtpAddress: deps.myXmtpAddress,
|
|
70726
|
-
senderAddress,
|
|
70727
|
-
senderInboxId: ctx.message.senderInboxId ?? "",
|
|
70728
|
-
jobId: route.jobId,
|
|
70729
|
-
groupId: conversationId,
|
|
70730
|
-
messageId,
|
|
70731
|
-
consentState: void 0,
|
|
70732
|
-
trustedSystemSender: false,
|
|
70733
|
-
isOfflineReplay: options.isOfflineReplay ?? false,
|
|
70734
|
-
timing
|
|
70735
|
-
});
|
|
70736
|
-
if (!accepted) {
|
|
70737
|
-
return true;
|
|
70738
|
-
}
|
|
70739
|
-
const providerBindStartedAt = Date.now();
|
|
70740
|
-
const providerGate = await bindMessageJobProviderToCurrentDefault(deps, route.jobId, "inbound-xmtp");
|
|
70741
|
-
timing.mark("providerBind", providerBindStartedAt);
|
|
70742
|
-
if (!providerGate.allowed) {
|
|
70743
|
-
logger.info(LogEvent.INBOUND_IGNORED_NON_BUSINESS, timing.extras({
|
|
70744
|
-
...buildInboundTerminalExtras({
|
|
70745
|
-
terminalState: "provider_gate_denied",
|
|
70746
|
-
myXmtpAddress: deps.myXmtpAddress,
|
|
70747
|
-
messageId,
|
|
70748
|
-
conversationId,
|
|
70749
|
-
chatType,
|
|
70750
|
-
jobId: route.jobId,
|
|
70751
|
-
route: route.route,
|
|
70752
|
-
reason: "job_provider_gate_denied"
|
|
70753
|
-
}),
|
|
70754
|
-
routeReason: route.routeReason,
|
|
70755
|
-
providerBinding: providerGate.provider ?? ""
|
|
70756
|
-
}));
|
|
70757
|
-
return true;
|
|
70758
|
-
}
|
|
70759
|
-
const myAgentId = XmtpService.getInstance().getAgentByAddress(deps.myXmtpAddress)?.agentId ?? readString5(payloadObject.receiverAgentId) ?? sessionAgentId ?? null;
|
|
70760
|
-
const sender = isPlainObject5(payloadObject.sender) ? payloadObject.sender : null;
|
|
70761
|
-
const toAgentId = readString5(sender?.agentId);
|
|
70762
|
-
const routedMessageId = messageId || `dm-${(0, import_node_crypto15.randomUUID)()}`;
|
|
70763
|
-
const sessionKey = ensureInboundGroupSession(deps, {
|
|
70764
|
-
jobId: route.jobId,
|
|
70765
|
-
myAgentId,
|
|
70766
|
-
toAgentId,
|
|
70767
|
-
groupId: null,
|
|
70768
|
-
toAgentXmtpAddress: senderAddress || readString5(payloadObject.fromXmtpAddress)
|
|
70769
|
-
});
|
|
70770
|
-
const dispatchStartedAt = Date.now();
|
|
70771
|
-
void Promise.resolve(deps.onSessionMessage?.({
|
|
70772
|
-
sessionKey,
|
|
70773
|
-
content: rawText,
|
|
70774
|
-
messageId: routedMessageId,
|
|
70775
|
-
jobId: route.jobId,
|
|
70776
|
-
agentId: myAgentId
|
|
70777
|
-
})).then(() => {
|
|
70778
|
-
timing.mark("sessionDispatch", dispatchStartedAt);
|
|
70779
|
-
logger.info(LogEvent.INBOUND_DELIVERED, commonDeliveryExtras({
|
|
70780
|
-
taskId: route.jobId,
|
|
70781
|
-
agentId: myAgentId ?? "",
|
|
70782
|
-
peerWalletAddress: senderAddress,
|
|
70783
|
-
peerInboxId: ctx.message.senderInboxId ?? "",
|
|
70784
|
-
peerAgentId: toAgentId ?? "",
|
|
70785
|
-
sessionKey,
|
|
70786
|
-
messageId: routedMessageId,
|
|
70787
|
-
route: "dm",
|
|
70788
|
-
...inboundStageExtras("inbound/dm_session_dispatch", "success"),
|
|
70789
|
-
dispatchTarget: deps.onSessionMessage ? "session" : "none"
|
|
70790
|
-
}));
|
|
70791
|
-
}).catch((err2) => {
|
|
70792
|
-
logWithTimestamp(`[okx-agent-task:${deps.myXmtpAddress}] onSessionMessage failed:`, err2);
|
|
70793
|
-
logger.error(LogEvent.INBOUND_DISPATCH_FAILED, toLoggableError(err2), timing.extras({
|
|
70794
|
-
...buildInboundTerminalExtras({
|
|
70795
|
-
terminalState: "dispatch_failed",
|
|
70796
|
-
myXmtpAddress: deps.myXmtpAddress,
|
|
70797
|
-
messageId: routedMessageId,
|
|
70798
|
-
conversationId,
|
|
70799
|
-
chatType,
|
|
70800
|
-
jobId: route.jobId,
|
|
70801
|
-
sessionKey,
|
|
70802
|
-
route: "dm",
|
|
70803
|
-
reason: "session_dispatch_failed"
|
|
70804
|
-
}),
|
|
70805
|
-
checkpoint: "inbound/dm_session_dispatch_failed",
|
|
70806
|
-
agentId: myAgentId ?? "",
|
|
70807
|
-
peerAgentId: toAgentId ?? ""
|
|
70808
|
-
}));
|
|
70809
|
-
});
|
|
70810
|
-
logWithTimestamp(
|
|
70811
|
-
`[okx-agent-task:${deps.myXmtpAddress}] session dispatch queued route=dm session=${sessionKey} message=${shortenLogValue(routedMessageId)} ${summarizePayloadForLog(parseResult.data)}`
|
|
70812
|
-
);
|
|
70813
|
-
return true;
|
|
70814
|
-
}
|
|
70815
69827
|
const stored = {
|
|
70816
|
-
id: messageId || `local-${(0,
|
|
69828
|
+
id: messageId || `local-${(0, import_node_crypto14.randomUUID)()}`,
|
|
70817
69829
|
direction: "inbound",
|
|
70818
69830
|
route: route.route,
|
|
70819
69831
|
routeReason: route.routeReason,
|
|
@@ -70831,8 +69843,8 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
70831
69843
|
await deps.store.append(route.jobId, stored, sessionAgentId);
|
|
70832
69844
|
timing.mark("storeAppend", storeAppendStartedAt);
|
|
70833
69845
|
if ((route.route === "job" || parseResult.ok && !isA2AEnvelope(stored.payload)) && !options.skipNotify) {
|
|
70834
|
-
const payloadObject =
|
|
70835
|
-
const sender =
|
|
69846
|
+
const payloadObject = isPlainObject3(stored.payload) ? stored.payload : null;
|
|
69847
|
+
const sender = isPlainObject3(payloadObject?.sender) ? payloadObject.sender : null;
|
|
70836
69848
|
const localAgent = XmtpService.getInstance().getAgentByAddress(deps.myXmtpAddress);
|
|
70837
69849
|
const sessionKey = route.route === "job" ? buildSessionKey({
|
|
70838
69850
|
jobId: route.jobId,
|
|
@@ -70850,8 +69862,8 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
70850
69862
|
});
|
|
70851
69863
|
}
|
|
70852
69864
|
if (route.route === "job" && chatType === "group" && conversationId && senderAddress) {
|
|
70853
|
-
const payloadObject =
|
|
70854
|
-
const sender =
|
|
69865
|
+
const payloadObject = isPlainObject3(stored.payload) ? stored.payload : null;
|
|
69866
|
+
const sender = isPlainObject3(payloadObject?.sender) ? payloadObject.sender : null;
|
|
70855
69867
|
await deps.store.updateXmtpSession(route.jobId, {
|
|
70856
69868
|
xmtpGroupId: conversationId,
|
|
70857
69869
|
myXmtpAddress: deps.myXmtpAddress,
|
|
@@ -70994,7 +70006,7 @@ function processOfflineFromCoreDeps(store, ctx, deps, options) {
|
|
|
70994
70006
|
function buildSystemStoredMessage(params) {
|
|
70995
70007
|
const now = Date.now();
|
|
70996
70008
|
return {
|
|
70997
|
-
id: params.id ?? `system-${now}-${(0,
|
|
70009
|
+
id: params.id ?? `system-${now}-${(0, import_node_crypto14.randomUUID)()}`,
|
|
70998
70010
|
direction: "system",
|
|
70999
70011
|
route: "backup",
|
|
71000
70012
|
routeReason: params.reason,
|
|
@@ -71010,14 +70022,14 @@ function buildSystemStoredMessage(params) {
|
|
|
71010
70022
|
};
|
|
71011
70023
|
}
|
|
71012
70024
|
function isA2AEnvelope(payload) {
|
|
71013
|
-
return
|
|
70025
|
+
return isPlainObject3(payload) && payload.msgType === A2A_MESSAGE_TYPE;
|
|
71014
70026
|
}
|
|
71015
|
-
var
|
|
70027
|
+
var import_node_crypto14, PROCESSED_IDS_MAX, processedMessageIds, EXTERNAL_JOB_ID_PATTERN, INBOUND_TRANSPORT, INBOUND_EVENT_FAMILY, INBOUND_TERMINAL_FIELDS;
|
|
71016
70028
|
var init_message_handler = __esm({
|
|
71017
70029
|
"src/message-handler.ts"() {
|
|
71018
70030
|
"use strict";
|
|
71019
70031
|
init_log();
|
|
71020
|
-
|
|
70032
|
+
import_node_crypto14 = require("node:crypto");
|
|
71021
70033
|
init_dist2();
|
|
71022
70034
|
init_a2a();
|
|
71023
70035
|
init_envelope_shared();
|
|
@@ -71032,10 +70044,6 @@ var init_message_handler = __esm({
|
|
|
71032
70044
|
init_session_store();
|
|
71033
70045
|
init_agent_message_notice();
|
|
71034
70046
|
init_ai_provider();
|
|
71035
|
-
init_subscription_envelope();
|
|
71036
|
-
init_subscription_inbound();
|
|
71037
|
-
init_list_jobs_by_verified_sender();
|
|
71038
|
-
init_subscription_telemetry();
|
|
71039
70047
|
PROCESSED_IDS_MAX = 1e3;
|
|
71040
70048
|
processedMessageIds = /* @__PURE__ */ new Map();
|
|
71041
70049
|
EXTERNAL_JOB_ID_PATTERN = /^0x[0-9a-fA-F]{64}$/;
|
|
@@ -71089,7 +70097,7 @@ function isOriginalParentProcessAlive(options) {
|
|
|
71089
70097
|
}
|
|
71090
70098
|
function registerUserAttentionWatcher(options) {
|
|
71091
70099
|
return options.store.registerUserAttentionWatcher({
|
|
71092
|
-
id: options.id ?? (0,
|
|
70100
|
+
id: options.id ?? (0, import_node_crypto15.randomUUID)(),
|
|
71093
70101
|
provider: options.provider,
|
|
71094
70102
|
jobId: options.jobId,
|
|
71095
70103
|
nowMs: options.nowMs ?? Date.now(),
|
|
@@ -71168,11 +70176,11 @@ function userWatchEventDeliveredSentryExtra(event) {
|
|
|
71168
70176
|
hasDecision: String(event.hasDecision)
|
|
71169
70177
|
};
|
|
71170
70178
|
}
|
|
71171
|
-
var
|
|
70179
|
+
var import_node_crypto15, USER_ATTENTION_WATCH_REPLACED_MESSAGE, USER_ATTENTION_WATCHER_SCAN_MS, USER_ATTENTION_WATCHER_TTL_MS, USER_ATTENTION_WATCH_PARENT_CHECK_MS;
|
|
71172
70180
|
var init_user_attention_watchers = __esm({
|
|
71173
70181
|
"src/user-attention-watchers.ts"() {
|
|
71174
70182
|
"use strict";
|
|
71175
|
-
|
|
70183
|
+
import_node_crypto15 = require("node:crypto");
|
|
71176
70184
|
init_sentry_logger();
|
|
71177
70185
|
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.";
|
|
71178
70186
|
USER_ATTENTION_WATCHER_SCAN_MS = 500;
|
|
@@ -71194,7 +70202,6 @@ __export(listener_exports, {
|
|
|
71194
70202
|
ListenerDeferredTaskScheduler: () => ListenerDeferredTaskScheduler,
|
|
71195
70203
|
ListenerMaintenanceGate: () => ListenerMaintenanceGate,
|
|
71196
70204
|
XMTP_CLIENT_RECYCLE_INTERVAL_ENV: () => XMTP_CLIENT_RECYCLE_INTERVAL_ENV,
|
|
71197
|
-
buildUpgradeRecommendationNotice: () => buildUpgradeRecommendationNotice,
|
|
71198
70205
|
getHermesGatewayPluginStatus: () => getHermesGatewayPluginStatus,
|
|
71199
70206
|
hermesConfigEnablesOkxA2a: () => hermesConfigEnablesOkxA2a,
|
|
71200
70207
|
isGatewayAvailableForHeartbeat: () => isGatewayAvailableForHeartbeat,
|
|
@@ -71211,34 +70218,6 @@ async function runHeartbeatRefreshCycle(options) {
|
|
|
71211
70218
|
const refresh = options.refresh && refreshAllowed ? await timeSettled(options.refresh) : void 0;
|
|
71212
70219
|
return { heartbeat, versionRefresh, refresh };
|
|
71213
70220
|
}
|
|
71214
|
-
function buildUpgradeRecommendationNotice(input) {
|
|
71215
|
-
const capability = input.capability?.trim() ?? "";
|
|
71216
|
-
if (capability === MESSAGE_ELIGIBLE_OFFLINE_REPLAY_HELP_TOKEN) {
|
|
71217
|
-
return {
|
|
71218
|
-
title: "OnchainOS upgrade recommended",
|
|
71219
|
-
content: "The installed OnchainOS version does not support offline-replay preferences. Subscription messages will continue to replay normally. Upgrade OnchainOS to enable this capability.\n\nSuggested command: onchainos upgrade",
|
|
71220
|
-
idempotencyKey: UPGRADE_RECOMMENDATION_IDEMPOTENCY_KEY
|
|
71221
|
-
};
|
|
71222
|
-
}
|
|
71223
|
-
if (capability === LIST_JOBS_BY_VERIFIED_SENDER_HELP_TOKEN) {
|
|
71224
|
-
return {
|
|
71225
|
-
title: "OnchainOS upgrade required for Subscription Shared Group",
|
|
71226
|
-
content: "The installed OnchainOS version does not support the verified-sender task query required by Subscription Shared Group. Until OnchainOS is upgraded, Subscription Shared Group messages fail closed and are NOT routed to an AI Session. Upgrade OnchainOS to enable this capability.\n\nSuggested command: onchainos upgrade",
|
|
71227
|
-
idempotencyKey: LIST_JOBS_UPGRADE_RECOMMENDATION_IDEMPOTENCY_KEY
|
|
71228
|
-
};
|
|
71229
|
-
}
|
|
71230
|
-
const capabilitySlug = capability ? capability.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") : "";
|
|
71231
|
-
const idempotencyKey = capabilitySlug ? `system:onchainos-${capabilitySlug}-upgrade` : "system:onchainos-capability-upgrade";
|
|
71232
|
-
const capabilityLabel = capability || "a required capability";
|
|
71233
|
-
const reasonSuffix = input.reason?.trim() ? ` ${input.reason.trim()}` : "";
|
|
71234
|
-
return {
|
|
71235
|
-
title: "OnchainOS upgrade recommended",
|
|
71236
|
-
content: `The installed OnchainOS version does not support ${capabilityLabel}.${reasonSuffix} Upgrade OnchainOS to enable this capability.
|
|
71237
|
-
|
|
71238
|
-
Suggested command: onchainos upgrade`,
|
|
71239
|
-
idempotencyKey
|
|
71240
|
-
};
|
|
71241
|
-
}
|
|
71242
70221
|
function resolveOfflineReplayIntervalSec(systemConfig) {
|
|
71243
70222
|
const interval = systemConfig.offlineReplayInterval;
|
|
71244
70223
|
if (typeof interval !== "number" || !Number.isFinite(interval) || interval <= 0) {
|
|
@@ -71466,12 +70445,8 @@ async function runListenerWithLock(options, paths) {
|
|
|
71466
70445
|
onJobMessageStored: async (event) => {
|
|
71467
70446
|
await enqueueAiJobMessageDispatch({ commands, event });
|
|
71468
70447
|
},
|
|
71469
|
-
// Returns { created } so the V2 subscription fan-out can distinguish a
|
|
71470
|
-
// durable DB duplicate (idempotent success) from a fresh enqueue. V1
|
|
71471
|
-
// group/system callers ignore the return; their events carry no
|
|
71472
|
-
// idempotencyKey, so the plain submit path (unchanged) is used.
|
|
71473
70448
|
onSessionMessage: async (event) => {
|
|
71474
|
-
|
|
70449
|
+
await enqueueAiSessionMessageDispatch({ commands, event });
|
|
71475
70450
|
}
|
|
71476
70451
|
}),
|
|
71477
70452
|
processOfflineMessage: (ctx, deps, replayOptions) => processOfflineFromCoreDeps(store, ctx, deps, {
|
|
@@ -71481,7 +70456,7 @@ async function runListenerWithLock(options, paths) {
|
|
|
71481
70456
|
await enqueueAiJobMessageDispatch({ commands, event });
|
|
71482
70457
|
},
|
|
71483
70458
|
onSessionMessage: async (event) => {
|
|
71484
|
-
|
|
70459
|
+
await enqueueAiSessionMessageDispatch({ commands, event });
|
|
71485
70460
|
}
|
|
71486
70461
|
}),
|
|
71487
70462
|
notifySessionExpired: (command) => {
|
|
@@ -71499,12 +70474,12 @@ async function runListenerWithLock(options, paths) {
|
|
|
71499
70474
|
});
|
|
71500
70475
|
},
|
|
71501
70476
|
notifyUpgradeRecommendation: (input) => {
|
|
71502
|
-
const
|
|
70477
|
+
const content2 = "The installed OnchainOS version does not support offline-replay preferences. Subscription messages will continue to replay normally. Upgrade OnchainOS to enable this capability.\n\nSuggested command: onchainos upgrade";
|
|
71503
70478
|
void notifySystemMessageToUser({
|
|
71504
|
-
title:
|
|
71505
|
-
content:
|
|
70479
|
+
title: "OnchainOS upgrade recommended",
|
|
70480
|
+
content: content2,
|
|
71506
70481
|
store: sessionStore,
|
|
71507
|
-
idempotencyKey:
|
|
70482
|
+
idempotencyKey: UPGRADE_RECOMMENDATION_IDEMPOTENCY_KEY
|
|
71508
70483
|
}).catch((err2) => {
|
|
71509
70484
|
logWithTimestamp(
|
|
71510
70485
|
`[okx-agent-task] upgrade recommendation notify failed component=${input.component} capability=${input.capability}:`,
|
|
@@ -71513,12 +70488,12 @@ async function runListenerWithLock(options, paths) {
|
|
|
71513
70488
|
});
|
|
71514
70489
|
}
|
|
71515
70490
|
});
|
|
71516
|
-
service.setPluginVersion("0.2.18
|
|
70491
|
+
service.setPluginVersion("0.2.18");
|
|
71517
70492
|
await service.init();
|
|
71518
70493
|
const pluginVersionStatus = service.pluginVersionStatus;
|
|
71519
70494
|
if (pluginVersionStatus.unavailable) {
|
|
71520
70495
|
throw new Error(
|
|
71521
|
-
`@okxweb3/a2a-node v${"0.2.18
|
|
70496
|
+
`@okxweb3/a2a-node v${"0.2.18"} is below the required minimum v${pluginVersionStatus.minVersion}`
|
|
71522
70497
|
);
|
|
71523
70498
|
}
|
|
71524
70499
|
const systemConfig = service.getSystemConfig();
|
|
@@ -71546,7 +70521,7 @@ async function runListenerWithLock(options, paths) {
|
|
|
71546
70521
|
onchainosAgentId: "*",
|
|
71547
70522
|
reason: "system-config missing sentryDsn",
|
|
71548
70523
|
pluginId: "@okxweb3/a2a-node",
|
|
71549
|
-
pluginVersion: "0.2.18
|
|
70524
|
+
pluginVersion: "0.2.18"
|
|
71550
70525
|
});
|
|
71551
70526
|
}
|
|
71552
70527
|
logWithTimestamp(
|
|
@@ -71896,7 +70871,7 @@ async function timeSettled(fn) {
|
|
|
71896
70871
|
return { durationMs: Date.now() - startedAt, error };
|
|
71897
70872
|
}
|
|
71898
70873
|
}
|
|
71899
|
-
var import_node_fs27, import_promises13, 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,
|
|
70874
|
+
var import_node_fs27, import_promises13, 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;
|
|
71900
70875
|
var init_listener = __esm({
|
|
71901
70876
|
"src/listener.ts"() {
|
|
71902
70877
|
"use strict";
|
|
@@ -71909,7 +70884,6 @@ var init_listener = __esm({
|
|
|
71909
70884
|
init_onchainos();
|
|
71910
70885
|
init_system_config();
|
|
71911
70886
|
init_offline_replay_capability();
|
|
71912
|
-
init_list_jobs_by_verified_sender();
|
|
71913
70887
|
init_signer();
|
|
71914
70888
|
init_bin();
|
|
71915
70889
|
init_xmtp_sdk();
|
|
@@ -72090,7 +71064,6 @@ var init_listener = __esm({
|
|
|
72090
71064
|
}
|
|
72091
71065
|
};
|
|
72092
71066
|
UPGRADE_RECOMMENDATION_IDEMPOTENCY_KEY = "system:onchainos-offline-replay-upgrade";
|
|
72093
|
-
LIST_JOBS_UPGRADE_RECOMMENDATION_IDEMPOTENCY_KEY = "system:onchainos-list-jobs-by-verified-sender-upgrade";
|
|
72094
71067
|
SHUTDOWN_FORCE_RESOLVE_MS = 5e3;
|
|
72095
71068
|
}
|
|
72096
71069
|
});
|
|
@@ -90180,7 +89153,7 @@ var require_fetch_pb = __commonJS({
|
|
|
90180
89153
|
}
|
|
90181
89154
|
});
|
|
90182
89155
|
}
|
|
90183
|
-
function
|
|
89156
|
+
function isPlainObject4(value) {
|
|
90184
89157
|
const isObject = Object.prototype.toString.call(value).slice(8, -1) === "Object";
|
|
90185
89158
|
const isObjLike = value !== null && isObject;
|
|
90186
89159
|
if (!isObjLike || !isObject) {
|
|
@@ -90203,7 +89176,7 @@ var require_fetch_pb = __commonJS({
|
|
|
90203
89176
|
const isNonEmptyPrimitiveArray = Array.isArray(value) && value.every((v) => isPrimitive(v)) && value.length > 0;
|
|
90204
89177
|
const isNonZeroValuePrimitive = isPrimitive(value) && !isZeroValuePrimitive(value);
|
|
90205
89178
|
let objectToMerge = {};
|
|
90206
|
-
if (
|
|
89179
|
+
if (isPlainObject4(value)) {
|
|
90207
89180
|
objectToMerge = flattenRequestPayload(value, newPath);
|
|
90208
89181
|
} else if (isNonZeroValuePrimitive || isNonEmptyPrimitiveArray) {
|
|
90209
89182
|
objectToMerge = { [newPath]: value };
|
|
@@ -115772,10 +114745,10 @@ var require_node4 = __commonJS({
|
|
|
115772
114745
|
|
|
115773
114746
|
// ../../node_modules/@xmtp/content-type-remote-attachment/dist/index.js
|
|
115774
114747
|
async function encrypt(plain, secret, additionalData) {
|
|
115775
|
-
const salt =
|
|
115776
|
-
const nonce =
|
|
114748
|
+
const salt = import_node_crypto16.webcrypto.getRandomValues(new Uint8Array(KDFSaltSize));
|
|
114749
|
+
const nonce = import_node_crypto16.webcrypto.getRandomValues(new Uint8Array(AESGCMNonceSize));
|
|
115777
114750
|
const key = await hkdf(secret, salt);
|
|
115778
|
-
const encrypted = await
|
|
114751
|
+
const encrypted = await import_node_crypto16.webcrypto.subtle.encrypt(aesGcmParams(nonce), key, plain);
|
|
115779
114752
|
return new Ciphertext({
|
|
115780
114753
|
aes256GcmHkdfSha256: {
|
|
115781
114754
|
payload: new Uint8Array(encrypted),
|
|
@@ -115789,7 +114762,7 @@ async function decrypt(encrypted, secret, additionalData) {
|
|
|
115789
114762
|
throw new Error("invalid payload ciphertext");
|
|
115790
114763
|
}
|
|
115791
114764
|
const key = await hkdf(secret, encrypted.aes256GcmHkdfSha256.hkdfSalt);
|
|
115792
|
-
const decrypted = await
|
|
114765
|
+
const decrypted = await import_node_crypto16.webcrypto.subtle.decrypt(aesGcmParams(encrypted.aes256GcmHkdfSha256.gcmNonce), key, encrypted.aes256GcmHkdfSha256.payload);
|
|
115793
114766
|
return new Uint8Array(decrypted);
|
|
115794
114767
|
}
|
|
115795
114768
|
function aesGcmParams(nonce, additionalData) {
|
|
@@ -115800,18 +114773,18 @@ function aesGcmParams(nonce, additionalData) {
|
|
|
115800
114773
|
return spec;
|
|
115801
114774
|
}
|
|
115802
114775
|
async function hkdf(secret, salt) {
|
|
115803
|
-
const key = await
|
|
114776
|
+
const key = await import_node_crypto16.webcrypto.subtle.importKey("raw", secret, "HKDF", false, [
|
|
115804
114777
|
"deriveKey"
|
|
115805
114778
|
]);
|
|
115806
|
-
return
|
|
114779
|
+
return import_node_crypto16.webcrypto.subtle.deriveKey({ name: "HKDF", hash: "SHA-256", salt, info: hkdfNoInfo }, key, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
|
|
115807
114780
|
}
|
|
115808
|
-
var import_proto,
|
|
114781
|
+
var import_proto, import_node_crypto16, ContentTypeAttachment, AttachmentCodec, KDFSaltSize, AESGCMNonceSize, AESGCMTagLength, Ciphertext, hkdfNoInfo, ContentTypeRemoteAttachment, RemoteAttachmentCodec;
|
|
115809
114782
|
var init_dist6 = __esm({
|
|
115810
114783
|
"../../node_modules/@xmtp/content-type-remote-attachment/dist/index.js"() {
|
|
115811
114784
|
init_dist5();
|
|
115812
114785
|
init_secp256k12();
|
|
115813
114786
|
import_proto = __toESM(require_node4(), 1);
|
|
115814
|
-
|
|
114787
|
+
import_node_crypto16 = require("node:crypto");
|
|
115815
114788
|
ContentTypeAttachment = new ContentTypeId({
|
|
115816
114789
|
authorityId: "xmtp.org",
|
|
115817
114790
|
typeId: "attachment",
|
|
@@ -115891,7 +114864,7 @@ var init_dist6 = __esm({
|
|
|
115891
114864
|
if (payload.length === 0) {
|
|
115892
114865
|
throw new Error(`no payload for remote attachment at ${remoteAttachment.url}`);
|
|
115893
114866
|
}
|
|
115894
|
-
const digestBytes = new Uint8Array(await
|
|
114867
|
+
const digestBytes = new Uint8Array(await import_node_crypto16.webcrypto.subtle.digest("SHA-256", payload));
|
|
115895
114868
|
const digest = etc.bytesToHex(digestBytes);
|
|
115896
114869
|
if (digest !== remoteAttachment.contentDigest) {
|
|
115897
114870
|
throw new Error("content digest does not match");
|
|
@@ -115915,7 +114888,7 @@ var init_dist6 = __esm({
|
|
|
115915
114888
|
return codec.decode(encodedContent, codecRegistry);
|
|
115916
114889
|
}
|
|
115917
114890
|
static async encodeEncrypted(content$1, codec) {
|
|
115918
|
-
const secret =
|
|
114891
|
+
const secret = import_node_crypto16.webcrypto.getRandomValues(new Uint8Array(32));
|
|
115919
114892
|
const encodedContent = import_proto.content.EncodedContent.encode(codec.encode(content$1, {
|
|
115920
114893
|
codecFor() {
|
|
115921
114894
|
return void 0;
|
|
@@ -115928,7 +114901,7 @@ var init_dist6 = __esm({
|
|
|
115928
114901
|
if (!salt || !nonce || !payload) {
|
|
115929
114902
|
throw new Error("missing encryption key");
|
|
115930
114903
|
}
|
|
115931
|
-
const digestBytes = new Uint8Array(await
|
|
114904
|
+
const digestBytes = new Uint8Array(await import_node_crypto16.webcrypto.subtle.digest("SHA-256", payload));
|
|
115932
114905
|
const digest = etc.bytesToHex(digestBytes);
|
|
115933
114906
|
return {
|
|
115934
114907
|
digest,
|
|
@@ -116146,7 +115119,7 @@ async function uploadFile(params) {
|
|
|
116146
115119
|
const attachment = { filename, mimeType, data: new Uint8Array(data) };
|
|
116147
115120
|
const encrypted = await RemoteAttachmentCodec.encodeEncrypted(attachment, new AttachmentCodec());
|
|
116148
115121
|
ensureFileDirs();
|
|
116149
|
-
const encryptedPath = (0, import_node_path35.resolve)(FILE_WORK_DIR, `${(0,
|
|
115122
|
+
const encryptedPath = (0, import_node_path35.resolve)(FILE_WORK_DIR, `${(0, import_node_crypto17.randomUUID)()}.enc`);
|
|
116150
115123
|
(0, import_node_fs29.writeFileSync)(encryptedPath, encrypted.payload);
|
|
116151
115124
|
try {
|
|
116152
115125
|
const stdout = runOnchainos([
|
|
@@ -116190,7 +115163,7 @@ async function uploadFile(params) {
|
|
|
116190
115163
|
}
|
|
116191
115164
|
async function downloadFile(params) {
|
|
116192
115165
|
ensureFileDirs();
|
|
116193
|
-
const encryptedPath = (0, import_node_path35.resolve)(FILE_WORK_DIR, `${(0,
|
|
115166
|
+
const encryptedPath = (0, import_node_path35.resolve)(FILE_WORK_DIR, `${(0, import_node_crypto17.randomUUID)()}.enc`);
|
|
116194
115167
|
try {
|
|
116195
115168
|
const stdout = runOnchainos([
|
|
116196
115169
|
"agent",
|
|
@@ -116215,7 +115188,7 @@ async function downloadFile(params) {
|
|
|
116215
115188
|
throw new Error(`file download failed: ${stdout}`);
|
|
116216
115189
|
}
|
|
116217
115190
|
const payload = new Uint8Array((0, import_node_fs29.readFileSync)(encryptedPath));
|
|
116218
|
-
const digestBytes = new Uint8Array(await
|
|
115191
|
+
const digestBytes = new Uint8Array(await import_node_crypto17.webcrypto.subtle.digest("SHA-256", payload));
|
|
116219
115192
|
const actualDigest = Array.from(digestBytes).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
116220
115193
|
if (actualDigest !== params.digest) {
|
|
116221
115194
|
throw new Error(`file download digest verification failed: expected=${params.digest}, actual=${actualDigest}`);
|
|
@@ -116223,7 +115196,7 @@ async function downloadFile(params) {
|
|
|
116223
115196
|
const decryptedBytes = await decryptAttachmentPayload(payload, params);
|
|
116224
115197
|
const encodedContent = import_proto2.content.EncodedContent.decode(decryptedBytes);
|
|
116225
115198
|
const attachment = new AttachmentCodec().decode(encodedContent);
|
|
116226
|
-
const outputFilename = params.filename || attachment.filename || `${(0,
|
|
115199
|
+
const outputFilename = params.filename || attachment.filename || `${(0, import_node_crypto17.randomUUID)()}.bin`;
|
|
116227
115200
|
const outputDir = DOWNLOADS_DIR;
|
|
116228
115201
|
ensureA2aTaskDir(outputDir);
|
|
116229
115202
|
const outputPath = (0, import_node_path35.resolve)(outputDir, (0, import_node_path35.basename)(outputFilename));
|
|
@@ -116240,15 +115213,15 @@ async function decryptAttachmentPayload(payload, params) {
|
|
|
116240
115213
|
const secretBytes = new Uint8Array(Buffer.from(params.secret, "base64"));
|
|
116241
115214
|
const saltBytes = new Uint8Array(Buffer.from(params.salt, "base64"));
|
|
116242
115215
|
const nonceBytes = new Uint8Array(Buffer.from(params.nonce, "base64"));
|
|
116243
|
-
const hkdfKey = await
|
|
116244
|
-
const aesKey = await
|
|
115216
|
+
const hkdfKey = await import_node_crypto17.webcrypto.subtle.importKey("raw", secretBytes, "HKDF", false, ["deriveKey"]);
|
|
115217
|
+
const aesKey = await import_node_crypto17.webcrypto.subtle.deriveKey(
|
|
116245
115218
|
{ name: "HKDF", hash: "SHA-256", salt: saltBytes, info: new Uint8Array().buffer },
|
|
116246
115219
|
hkdfKey,
|
|
116247
115220
|
{ name: "AES-GCM", length: 256 },
|
|
116248
115221
|
false,
|
|
116249
115222
|
["decrypt"]
|
|
116250
115223
|
);
|
|
116251
|
-
return new Uint8Array(await
|
|
115224
|
+
return new Uint8Array(await import_node_crypto17.webcrypto.subtle.decrypt({ name: "AES-GCM", iv: nonceBytes }, aesKey, toArrayBuffer(payload)));
|
|
116252
115225
|
}
|
|
116253
115226
|
function toArrayBuffer(bytes) {
|
|
116254
115227
|
return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
@@ -116388,12 +115361,12 @@ function readRequiredOption(args, name) {
|
|
|
116388
115361
|
}
|
|
116389
115362
|
return value;
|
|
116390
115363
|
}
|
|
116391
|
-
var
|
|
115364
|
+
var import_node_crypto17, import_node_fs29, import_node_path35, import_proto2, OKX_A2A_PATHS, OKX_A2A_HOME_DIR, FILE_WORK_DIR, DOWNLOADS_DIR, SYSTEM_CONFIG_PATH;
|
|
116392
115365
|
var init_file_cli = __esm({
|
|
116393
115366
|
"src/file-cli.ts"() {
|
|
116394
115367
|
"use strict";
|
|
116395
115368
|
init_win_spawn();
|
|
116396
|
-
|
|
115369
|
+
import_node_crypto17 = require("node:crypto");
|
|
116397
115370
|
import_node_fs29 = require("node:fs");
|
|
116398
115371
|
import_node_path35 = require("node:path");
|
|
116399
115372
|
init_dist6();
|
|
@@ -119891,7 +118864,7 @@ async function getCurrentNodeCliVersion() {
|
|
|
119891
118864
|
return await getGlobalNpmPackageVersion(UPDATE_PACKAGES.node) ?? getBundledNodeCliVersion();
|
|
119892
118865
|
}
|
|
119893
118866
|
function getBundledNodeCliVersion() {
|
|
119894
|
-
return true ? "0.2.18
|
|
118867
|
+
return true ? "0.2.18" : null;
|
|
119895
118868
|
}
|
|
119896
118869
|
function readConfiguredAiProvider() {
|
|
119897
118870
|
const explicit = process.env.OKX_A2A_AI_PROVIDER || process.env.OKX_AGENT_TASK_AI_CLI;
|
|
@@ -120101,7 +119074,7 @@ async function updateHermes(release, options) {
|
|
|
120101
119074
|
}
|
|
120102
119075
|
}
|
|
120103
119076
|
async function installGatewayPluginForDoctor(target) {
|
|
120104
|
-
const release = isPrereleaseVersion("0.2.18
|
|
119077
|
+
const release = isPrereleaseVersion("0.2.18") ? "beta" : "latest";
|
|
120105
119078
|
const insideTargetGateway = detectGatewayInvocation() === target;
|
|
120106
119079
|
const options = {
|
|
120107
119080
|
restart: !insideTargetGateway,
|
|
@@ -121154,7 +120127,7 @@ async function runDoctor(options = {}) {
|
|
|
121154
120127
|
platform: options.platform ?? process.platform,
|
|
121155
120128
|
env: options.env ?? process.env,
|
|
121156
120129
|
target: options.target ?? resolveDoctorTarget(options.env ?? process.env),
|
|
121157
|
-
cliVersion: options.cliVersion ?? (true ? "0.2.18
|
|
120130
|
+
cliVersion: options.cliVersion ?? (true ? "0.2.18" : "0.0.0"),
|
|
121158
120131
|
fixMode: options.fix === true,
|
|
121159
120132
|
nonInteractive: options.nonInteractive === true,
|
|
121160
120133
|
packageChanged: false,
|
|
@@ -122261,7 +121234,7 @@ init_sentry_config();
|
|
|
122261
121234
|
init_runtime_metadata();
|
|
122262
121235
|
var CURRENT_GATEWAY_SESSION_KEYS_ENV4 = "OKX_A2A_CURRENT_GATEWAY_SESSION_KEYS";
|
|
122263
121236
|
function printUsage3() {
|
|
122264
|
-
console.log(`okx-a2a ${"0.2.18
|
|
121237
|
+
console.log(`okx-a2a ${"0.2.18"}
|
|
122265
121238
|
|
|
122266
121239
|
Usage:
|
|
122267
121240
|
okx-a2a <command> [options]
|
|
@@ -122291,8 +121264,6 @@ Commands:
|
|
|
122291
121264
|
Alias for runtime switch-current
|
|
122292
121265
|
job-provider Manage job-to-provider bindings
|
|
122293
121266
|
xmtp-send Queue an XMTP message through the running daemon
|
|
122294
|
-
subscription-push
|
|
122295
|
-
Queue a V2 subscription push to one or more XMTP Group conversations
|
|
122296
121267
|
trade-records
|
|
122297
121268
|
Insert, query, and soft-delete local business trade records
|
|
122298
121269
|
capabilities Print machine-readable A2A capability negotiation status (used by OnchainOS)
|
|
@@ -122305,7 +121276,7 @@ Run \`okx-a2a <command> -h\` for command-specific help.
|
|
|
122305
121276
|
`);
|
|
122306
121277
|
}
|
|
122307
121278
|
function printVersion() {
|
|
122308
|
-
console.log("0.2.18
|
|
121279
|
+
console.log("0.2.18");
|
|
122309
121280
|
}
|
|
122310
121281
|
function printDaemonUsage() {
|
|
122311
121282
|
console.log(`Usage: okx-a2a daemon <start|restart|stop|status|autostart> [options]
|
|
@@ -122402,18 +121373,6 @@ Options:
|
|
|
122402
121373
|
--json Print machine-readable output with ok boolean
|
|
122403
121374
|
`);
|
|
122404
121375
|
}
|
|
122405
|
-
function printSubscriptionPushUsage() {
|
|
122406
|
-
console.log(`Usage: okx-a2a subscription-push --my-agent-id <id> --message <text> (--conversation-id <id> ... | --conversation-ids <id,id,...>) [options]
|
|
122407
|
-
|
|
122408
|
-
Options:
|
|
122409
|
-
--my-agent-id <id> Local sender agent id used to resolve the XMTP client
|
|
122410
|
-
--message <text> Subscription content
|
|
122411
|
-
--conversation-id <id> Target Group conversationId (repeatable)
|
|
122412
|
-
--conversation-ids <id,id> Comma-separated list of target Group conversationIds
|
|
122413
|
-
--delivery-id <id> Optional deliveryId carried in the V2 envelope
|
|
122414
|
-
--json Print machine-readable output with ok boolean
|
|
122415
|
-
`);
|
|
122416
|
-
}
|
|
122417
121376
|
function printCommandUsage(command) {
|
|
122418
121377
|
if (command === "daemon" || command === "start" || command === "restart" || command === "stop" || command === "status") {
|
|
122419
121378
|
printDaemonUsage();
|
|
@@ -122483,10 +121442,6 @@ function printCommandUsage(command) {
|
|
|
122483
121442
|
printXmtpSendUsage();
|
|
122484
121443
|
return true;
|
|
122485
121444
|
}
|
|
122486
|
-
if (command === "subscription-push") {
|
|
122487
|
-
printSubscriptionPushUsage();
|
|
122488
|
-
return true;
|
|
122489
|
-
}
|
|
122490
121445
|
if (command === "trade-records") {
|
|
122491
121446
|
printTradeRecordsUsageProxy();
|
|
122492
121447
|
return true;
|
|
@@ -122814,79 +121769,6 @@ async function queueXmtpSend(args) {
|
|
|
122814
121769
|
commands.close();
|
|
122815
121770
|
}
|
|
122816
121771
|
}
|
|
122817
|
-
async function queueXmtpSubscriptionPush(args) {
|
|
122818
|
-
if (hasHelpFlag5(args)) {
|
|
122819
|
-
printSubscriptionPushUsage();
|
|
122820
|
-
return;
|
|
122821
|
-
}
|
|
122822
|
-
assertOnlyKnownOptions(args, {
|
|
122823
|
-
command: "subscription-push",
|
|
122824
|
-
options: /* @__PURE__ */ new Set([
|
|
122825
|
-
"--my-agent-id",
|
|
122826
|
-
"--message",
|
|
122827
|
-
"--conversation-id",
|
|
122828
|
-
"--conversation-ids",
|
|
122829
|
-
"--delivery-id"
|
|
122830
|
-
]),
|
|
122831
|
-
flags: /* @__PURE__ */ new Set(["--json"])
|
|
122832
|
-
});
|
|
122833
|
-
const json = hasFlag2(args, "--json");
|
|
122834
|
-
const myAgentId = readOption5(args, "--my-agent-id");
|
|
122835
|
-
const content2 = readOption5(args, "--message");
|
|
122836
|
-
const deliveryId = readOption5(args, "--delivery-id");
|
|
122837
|
-
const conversationIds = readSubscriptionPushConversationIds(args);
|
|
122838
|
-
if (!myAgentId || !content2) {
|
|
122839
|
-
throw new Error("subscription-push requires --my-agent-id and --message");
|
|
122840
|
-
}
|
|
122841
|
-
await assertDaemonRunningForQueuedCommand2("subscription-push");
|
|
122842
|
-
const commands = new CommandStore();
|
|
122843
|
-
try {
|
|
122844
|
-
const command = commands.createXmtpSubscriptionPushCommand({
|
|
122845
|
-
myAgentId,
|
|
122846
|
-
content: content2,
|
|
122847
|
-
conversationIds,
|
|
122848
|
-
deliveryId
|
|
122849
|
-
});
|
|
122850
|
-
await commands.submit(command);
|
|
122851
|
-
const result = await commands.waitForResult(command.id, Number.POSITIVE_INFINITY);
|
|
122852
|
-
if (!result) {
|
|
122853
|
-
printSubscriptionPushCommandResult(json, {
|
|
122854
|
-
id: command.id,
|
|
122855
|
-
ok: false,
|
|
122856
|
-
completedAt: Date.now(),
|
|
122857
|
-
error: "subscription-push finished without result"
|
|
122858
|
-
});
|
|
122859
|
-
process.exitCode = 1;
|
|
122860
|
-
return;
|
|
122861
|
-
}
|
|
122862
|
-
if (!result.ok) {
|
|
122863
|
-
printSubscriptionPushCommandResult(json, result);
|
|
122864
|
-
process.exitCode = 1;
|
|
122865
|
-
return;
|
|
122866
|
-
}
|
|
122867
|
-
printSubscriptionPushCommandResult(json, result);
|
|
122868
|
-
} finally {
|
|
122869
|
-
commands.close();
|
|
122870
|
-
}
|
|
122871
|
-
}
|
|
122872
|
-
function readSubscriptionPushConversationIds(args) {
|
|
122873
|
-
const ids = /* @__PURE__ */ new Set();
|
|
122874
|
-
for (let i = 0; i < args.length; i++) {
|
|
122875
|
-
if (args[i] === "--conversation-id" && args[i + 1]) {
|
|
122876
|
-
ids.add(args[i + 1]);
|
|
122877
|
-
}
|
|
122878
|
-
}
|
|
122879
|
-
const commaList = readOption5(args, "--conversation-ids");
|
|
122880
|
-
if (commaList) {
|
|
122881
|
-
for (const item of commaList.split(",")) {
|
|
122882
|
-
const trimmed = item.trim();
|
|
122883
|
-
if (trimmed) {
|
|
122884
|
-
ids.add(trimmed);
|
|
122885
|
-
}
|
|
122886
|
-
}
|
|
122887
|
-
}
|
|
122888
|
-
return [...ids];
|
|
122889
|
-
}
|
|
122890
121772
|
function parseXmtpSendPayloadOption(raw) {
|
|
122891
121773
|
const trimmed = raw?.trim();
|
|
122892
121774
|
if (!trimmed) {
|
|
@@ -123020,12 +121902,12 @@ function assertOnlyKnownOptions(args, input) {
|
|
|
123020
121902
|
async function queueXmtpDaemonCommand(args, type) {
|
|
123021
121903
|
const json = hasFlag2(args, "--json");
|
|
123022
121904
|
const timeoutMsRaw = readOption5(args, "--timeout-ms");
|
|
123023
|
-
const
|
|
121905
|
+
const wait2 = type === "xmtp-get-pending-list" || type === "xmtp-deny-pending-conversation" || type === "xmtp-refresh-agents";
|
|
123024
121906
|
await assertDaemonRunningForQueuedCommand2(type);
|
|
123025
121907
|
const commands = new CommandStore();
|
|
123026
121908
|
const command = type === "xmtp-get-pending-list" ? commands.createXmtpGetPendingListCommand() : type === "xmtp-deny-pending-conversation" ? commands.createXmtpDenyPendingConversationCommand(readDenyPendingConversationOptions(args)) : commands.createXmtpRefreshAgentsCommand();
|
|
123027
121909
|
await commands.submit(command);
|
|
123028
|
-
if (!
|
|
121910
|
+
if (!wait2) {
|
|
123029
121911
|
outputCommandResult(json, { id: command.id, ok: true, completedAt: Date.now(), payload: { queued: true } }, `${type} queued command=${command.id}`);
|
|
123030
121912
|
return;
|
|
123031
121913
|
}
|
|
@@ -123196,23 +122078,6 @@ function printXmtpSendCommandResult(json, result) {
|
|
|
123196
122078
|
}
|
|
123197
122079
|
console.log(`ok=false xmtp-send failed command=${result.id} error=${result.error ?? "unknown error"}`);
|
|
123198
122080
|
}
|
|
123199
|
-
function printSubscriptionPushCommandResult(json, result) {
|
|
123200
|
-
const payload = result.payload;
|
|
123201
|
-
if (json) {
|
|
123202
|
-
console.log(JSON.stringify({
|
|
123203
|
-
ok: result.ok,
|
|
123204
|
-
commandId: result.id,
|
|
123205
|
-
payload: result.payload ?? null,
|
|
123206
|
-
error: result.error ?? null
|
|
123207
|
-
}));
|
|
123208
|
-
return;
|
|
123209
|
-
}
|
|
123210
|
-
if (result.ok) {
|
|
123211
|
-
console.log(`ok=true subscription-push command=${result.id} conversationCount=${payload?.conversationCount ?? 0} sentCount=${payload?.sentCount ?? 0} failedCount=${payload?.failedCount ?? 0}`);
|
|
123212
|
-
return;
|
|
123213
|
-
}
|
|
123214
|
-
console.log(`ok=false subscription-push failed command=${result.id} error=${result.error ?? "unknown error"}`);
|
|
123215
|
-
}
|
|
123216
122081
|
function formatDaemonCommandResult(type, result) {
|
|
123217
122082
|
if (!result.ok) {
|
|
123218
122083
|
return `ok=false ${type} command=${result.id} error=${result.error ?? "unknown error"}`;
|
|
@@ -123906,10 +122771,10 @@ async function main() {
|
|
|
123906
122771
|
if (command === "xmtp-test") {
|
|
123907
122772
|
const { handleXmtpTestCommand: handleXmtpTestCommand2 } = await Promise.resolve().then(() => (init_xmtp_test_cli(), xmtp_test_cli_exports));
|
|
123908
122773
|
await handleXmtpTestCommand2(process.argv.slice(3), {
|
|
123909
|
-
packageVersion: "0.2.18
|
|
123910
|
-
agentSdkVersion: "2.3.
|
|
123911
|
-
nodeSdkVersion: "6.1.
|
|
123912
|
-
nodeBindingsVersion: "1.11.
|
|
122774
|
+
packageVersion: "0.2.18",
|
|
122775
|
+
agentSdkVersion: "2.3.1",
|
|
122776
|
+
nodeSdkVersion: "6.1.1",
|
|
122777
|
+
nodeBindingsVersion: "1.11.1"
|
|
123913
122778
|
});
|
|
123914
122779
|
return;
|
|
123915
122780
|
}
|
|
@@ -123919,12 +122784,6 @@ async function main() {
|
|
|
123919
122784
|
await flushDirectCliSentry();
|
|
123920
122785
|
return;
|
|
123921
122786
|
}
|
|
123922
|
-
if (command === "subscription-push") {
|
|
123923
|
-
await initDirectCliSentry();
|
|
123924
|
-
await queueXmtpSubscriptionPush(process.argv.slice(3));
|
|
123925
|
-
await flushDirectCliSentry();
|
|
123926
|
-
return;
|
|
123927
|
-
}
|
|
123928
122787
|
if (command === "task") {
|
|
123929
122788
|
await initDirectCliSentry();
|
|
123930
122789
|
await handleTaskCommand(process.argv.slice(3));
|