@okxweb3/a2a-node 0.2.0 → 0.2.1-beta-8ae7a0d300-260807181806
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 +905 -69
- package/dist/index.js +893 -64
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -9433,7 +9433,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
|
|
|
9433
9433
|
client: {
|
|
9434
9434
|
id: "gateway-client",
|
|
9435
9435
|
displayName: "okx-a2a-node",
|
|
9436
|
-
version: "0.2.
|
|
9436
|
+
version: "0.2.1-beta-8ae7a0d300-260807181806",
|
|
9437
9437
|
platform: "node",
|
|
9438
9438
|
mode: "backend",
|
|
9439
9439
|
instanceId
|
|
@@ -9444,7 +9444,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
|
|
|
9444
9444
|
commands: [],
|
|
9445
9445
|
permissions: {},
|
|
9446
9446
|
locale: Intl.DateTimeFormat().resolvedOptions().locale || "en-US",
|
|
9447
|
-
userAgent: `okx-a2a-node/${"0.2.
|
|
9447
|
+
userAgent: `okx-a2a-node/${"0.2.1-beta-8ae7a0d300-260807181806"}`,
|
|
9448
9448
|
auth: {
|
|
9449
9449
|
...config.token ? { token: config.token } : {},
|
|
9450
9450
|
...config.password ? { password: config.password } : {}
|
|
@@ -25471,12 +25471,15 @@ var init_events = __esm({
|
|
|
25471
25471
|
INBOUND_DELIVERED: "Inbound delivered to session",
|
|
25472
25472
|
DM_DELIVERED: "DM delivered to session",
|
|
25473
25473
|
OUTBOUND_ELIGIBILITY_CHECKED: "Outbound eligibility checked",
|
|
25474
|
+
MESSAGE_ELIGIBILITY_CHECKED: "Message eligibility checked",
|
|
25474
25475
|
AGENT_CLIENT_CREATED: "Agent client created",
|
|
25475
25476
|
AGENT_INSTALLATION_SUMMARY: "Agent installation summary",
|
|
25476
25477
|
XMTP_HISTORY_SYNC_REQUESTED: "XMTP history sync requested",
|
|
25477
25478
|
XMTP_DEBUG_SYNC_REQUESTED: "XMTP debug sync requested",
|
|
25478
25479
|
XMTP_DEBUG_SYNC_COMPLETED: "XMTP debug sync completed",
|
|
25479
25480
|
AGENT_CLIENT_REMOVED: "Agent client removed",
|
|
25481
|
+
AGENT_STREAM_RECOVERED: "Agent stream recovered",
|
|
25482
|
+
AGENT_STREAM_RECOVERY_REPLAY_COMPLETED: "Agent stream recovery replay completed",
|
|
25480
25483
|
ADDRESS_SYNC_COMPLETED: "Address sync completed",
|
|
25481
25484
|
AGENT_REFRESH_SESSION_EXPIRED: "Agent refresh aborted: onchainos session expired, local clients taken offline",
|
|
25482
25485
|
OFFLINE_REPLAY_MESSAGE_REPLAYED: "Offline replay message replayed",
|
|
@@ -25511,6 +25514,8 @@ var init_events = __esm({
|
|
|
25511
25514
|
CONVERSATIONS_STREAM_FAILED: "conversations.stream failed",
|
|
25512
25515
|
AGENT_START_FAILED: "agent.start failed",
|
|
25513
25516
|
AGENT_STREAM_ERROR: "agent stream error",
|
|
25517
|
+
AGENT_UNHANDLED_ERROR: "Agent unhandled error",
|
|
25518
|
+
AGENT_STREAM_RECOVERY_TIMEOUT: "Agent stream recovery timeout",
|
|
25514
25519
|
BOOTSTRAP_FAILED: "Bootstrap failed",
|
|
25515
25520
|
ONCHAINOS_SESSION_EXPIRED: "Onchainos session expired",
|
|
25516
25521
|
ONCHAINOS_CLI_ERROR: "Onchainos CLI error",
|
|
@@ -25520,6 +25525,7 @@ var init_events = __esm({
|
|
|
25520
25525
|
MESSAGE_PARSE_FAILED: "Message parse failed",
|
|
25521
25526
|
MESSAGE_HANDLER_ERROR: "Message handler error",
|
|
25522
25527
|
INBOUND_DISPATCH_FAILED: "Inbound dispatch failed",
|
|
25528
|
+
INBOUND_REPLAY_GATE_DRAIN_FAILED: "Inbound replay gate drain failed",
|
|
25523
25529
|
// Default name stamped on events that reach Sentry without going through this
|
|
25524
25530
|
// logger — uncaught exceptions and unhandled rejections. Without it those
|
|
25525
25531
|
// events carry no eventName and cannot be classified.
|
|
@@ -25817,7 +25823,10 @@ var init_xmtp_test_metrics = __esm({
|
|
|
25817
25823
|
"Address sync completed",
|
|
25818
25824
|
"Agent client created",
|
|
25819
25825
|
"Agent client removed",
|
|
25820
|
-
"
|
|
25826
|
+
"agent stream error",
|
|
25827
|
+
"Agent stream recovered",
|
|
25828
|
+
"Agent stream recovery replay completed",
|
|
25829
|
+
"Agent stream recovery timeout",
|
|
25821
25830
|
"conversations.stream failed",
|
|
25822
25831
|
"Inbound delivered to session",
|
|
25823
25832
|
"Inbound dispatch failed",
|
|
@@ -25836,6 +25845,190 @@ var init_xmtp_test_metrics = __esm({
|
|
|
25836
25845
|
}
|
|
25837
25846
|
});
|
|
25838
25847
|
|
|
25848
|
+
// ../core/src/sentry-logger/error-diagnostics.ts
|
|
25849
|
+
function asErrorLike(value) {
|
|
25850
|
+
return value instanceof Error ? value : void 0;
|
|
25851
|
+
}
|
|
25852
|
+
function diagnosticToken(value) {
|
|
25853
|
+
if (typeof value !== "string" && typeof value !== "number") {
|
|
25854
|
+
return void 0;
|
|
25855
|
+
}
|
|
25856
|
+
const token = String(value).trim();
|
|
25857
|
+
if (!token || /^(?:null|undefined|unknown)$/i.test(token)) {
|
|
25858
|
+
return void 0;
|
|
25859
|
+
}
|
|
25860
|
+
if (!/^[A-Za-z0-9_.:-]+$/.test(token)) {
|
|
25861
|
+
return void 0;
|
|
25862
|
+
}
|
|
25863
|
+
return token.slice(0, MAX_DIAGNOSTIC_TOKEN_LENGTH);
|
|
25864
|
+
}
|
|
25865
|
+
function syscallToken(value) {
|
|
25866
|
+
if (typeof value !== "string") {
|
|
25867
|
+
return void 0;
|
|
25868
|
+
}
|
|
25869
|
+
const operation = diagnosticToken(value.trim().split(/\s+/, 1)[0])?.toLowerCase();
|
|
25870
|
+
return operation && KNOWN_SYSCALLS.has(operation) ? operation : void 0;
|
|
25871
|
+
}
|
|
25872
|
+
function knownErrorCode(value) {
|
|
25873
|
+
const code = diagnosticToken(value)?.toUpperCase();
|
|
25874
|
+
return code && KNOWN_ERROR_CODES.has(code) ? code : void 0;
|
|
25875
|
+
}
|
|
25876
|
+
function readCode(error) {
|
|
25877
|
+
return knownErrorCode(error?.code) ?? knownErrorCode(error?.errno);
|
|
25878
|
+
}
|
|
25879
|
+
function classifyError(error, code) {
|
|
25880
|
+
const normalizedCode = code?.toUpperCase();
|
|
25881
|
+
const name = error?.name.toLowerCase() ?? "";
|
|
25882
|
+
const message = error?.message.toLowerCase() ?? "";
|
|
25883
|
+
if (normalizedCode && RESOURCE_EXHAUSTED_CODES.has(normalizedCode)) {
|
|
25884
|
+
return "resource_exhausted";
|
|
25885
|
+
}
|
|
25886
|
+
if (normalizedCode && CONNECTION_INTERRUPTED_CODES.has(normalizedCode)) {
|
|
25887
|
+
return "connection_interrupted";
|
|
25888
|
+
}
|
|
25889
|
+
if (normalizedCode && NETWORK_UNAVAILABLE_CODES.has(normalizedCode)) {
|
|
25890
|
+
return "network_unavailable";
|
|
25891
|
+
}
|
|
25892
|
+
if (normalizedCode && TIMEOUT_CODES.has(normalizedCode)) {
|
|
25893
|
+
return "timeout";
|
|
25894
|
+
}
|
|
25895
|
+
if (normalizedCode && PERMISSION_CODES.has(normalizedCode)) {
|
|
25896
|
+
return "permission_denied";
|
|
25897
|
+
}
|
|
25898
|
+
if (normalizedCode === "ENOENT") {
|
|
25899
|
+
return "missing_dependency";
|
|
25900
|
+
}
|
|
25901
|
+
if (normalizedCode === "ABORT_ERR" || name === "aborterror") {
|
|
25902
|
+
return "cancelled";
|
|
25903
|
+
}
|
|
25904
|
+
if (name === "syntaxerror" || /(?:json|response).*(?:parse|invalid)/.test(message)) {
|
|
25905
|
+
return "invalid_response";
|
|
25906
|
+
}
|
|
25907
|
+
if (/session\s+(?:is\s+)?expired|login\s+expired/.test(message)) {
|
|
25908
|
+
return "session_expired";
|
|
25909
|
+
}
|
|
25910
|
+
if (/timed?\s*out|timeout/.test(message)) {
|
|
25911
|
+
return "timeout";
|
|
25912
|
+
}
|
|
25913
|
+
return "unknown";
|
|
25914
|
+
}
|
|
25915
|
+
function retryabilityFor(category) {
|
|
25916
|
+
switch (category) {
|
|
25917
|
+
case "connection_interrupted":
|
|
25918
|
+
case "network_unavailable":
|
|
25919
|
+
case "resource_exhausted":
|
|
25920
|
+
case "timeout":
|
|
25921
|
+
return "retryable";
|
|
25922
|
+
case "invalid_response":
|
|
25923
|
+
case "missing_dependency":
|
|
25924
|
+
case "permission_denied":
|
|
25925
|
+
case "session_expired":
|
|
25926
|
+
return "non_retryable";
|
|
25927
|
+
default:
|
|
25928
|
+
return "unknown";
|
|
25929
|
+
}
|
|
25930
|
+
}
|
|
25931
|
+
function causeChain(error) {
|
|
25932
|
+
const chain = [];
|
|
25933
|
+
const seen = /* @__PURE__ */ new Set();
|
|
25934
|
+
let current = error;
|
|
25935
|
+
while (current && chain.length < MAX_CAUSE_DEPTH && !seen.has(current)) {
|
|
25936
|
+
chain.push(current);
|
|
25937
|
+
seen.add(current);
|
|
25938
|
+
current = asErrorLike(current.cause);
|
|
25939
|
+
}
|
|
25940
|
+
return chain;
|
|
25941
|
+
}
|
|
25942
|
+
function buildErrorDiagnostics(eventName, error, existingExtra) {
|
|
25943
|
+
const errorLike = asErrorLike(error);
|
|
25944
|
+
const legacy = {};
|
|
25945
|
+
if (errorLike) {
|
|
25946
|
+
legacy.errorName = errorLike.name;
|
|
25947
|
+
legacy.errorMessageLength = String(errorLike.message.length);
|
|
25948
|
+
}
|
|
25949
|
+
if (!errorLike || eventName === LogEvent.AGENT_STREAM_ERROR) {
|
|
25950
|
+
return legacy;
|
|
25951
|
+
}
|
|
25952
|
+
const chain = causeChain(errorLike);
|
|
25953
|
+
const primary = chain[0];
|
|
25954
|
+
const cause = chain.length > 1 ? chain[chain.length - 1] : void 0;
|
|
25955
|
+
const fallbackExitCode = diagnosticToken(existingExtra.exitCode);
|
|
25956
|
+
const primaryCode = readCode(primary);
|
|
25957
|
+
const primaryCategory = classifyError(primary, primaryCode);
|
|
25958
|
+
const primarySyscall = syscallToken(primary.syscall);
|
|
25959
|
+
const causeCode = readCode(cause);
|
|
25960
|
+
const causeCategory = cause ? classifyError(cause, causeCode) : void 0;
|
|
25961
|
+
const causeSyscall = syscallToken(cause?.syscall);
|
|
25962
|
+
const classifiedCategory = primaryCategory === "unknown" && causeCategory ? causeCategory : primaryCategory;
|
|
25963
|
+
const effectiveCategory = classifiedCategory === "unknown" && fallbackExitCode && fallbackExitCode !== "0" ? "process_exit" : classifiedCategory;
|
|
25964
|
+
const effectiveCode = primaryCode ?? causeCode;
|
|
25965
|
+
const effectiveSyscall = primarySyscall ?? causeSyscall;
|
|
25966
|
+
return {
|
|
25967
|
+
...legacy,
|
|
25968
|
+
errorCategory: effectiveCategory,
|
|
25969
|
+
errorRetryability: retryabilityFor(effectiveCategory),
|
|
25970
|
+
errorCauseDepth: String(Math.max(0, chain.length - 1)),
|
|
25971
|
+
...effectiveCode ? { errorCode: effectiveCode } : {},
|
|
25972
|
+
...effectiveSyscall ? { errorSyscall: effectiveSyscall } : {},
|
|
25973
|
+
...cause ? {
|
|
25974
|
+
causeErrorMessageLength: String(cause.message.length),
|
|
25975
|
+
causeErrorCategory: causeCategory ?? "unknown",
|
|
25976
|
+
...causeCode ? { causeErrorCode: causeCode } : {},
|
|
25977
|
+
...causeSyscall ? { causeErrorSyscall: causeSyscall } : {}
|
|
25978
|
+
} : {}
|
|
25979
|
+
};
|
|
25980
|
+
}
|
|
25981
|
+
var MAX_DIAGNOSTIC_TOKEN_LENGTH, MAX_CAUSE_DEPTH, RESOURCE_EXHAUSTED_CODES, CONNECTION_INTERRUPTED_CODES, NETWORK_UNAVAILABLE_CODES, TIMEOUT_CODES, PERMISSION_CODES, KNOWN_ERROR_CODES, KNOWN_SYSCALLS;
|
|
25982
|
+
var init_error_diagnostics = __esm({
|
|
25983
|
+
"../core/src/sentry-logger/error-diagnostics.ts"() {
|
|
25984
|
+
"use strict";
|
|
25985
|
+
init_events();
|
|
25986
|
+
MAX_DIAGNOSTIC_TOKEN_LENGTH = 64;
|
|
25987
|
+
MAX_CAUSE_DEPTH = 4;
|
|
25988
|
+
RESOURCE_EXHAUSTED_CODES = /* @__PURE__ */ new Set(["EAGAIN", "EMFILE", "ENFILE", "ENOMEM"]);
|
|
25989
|
+
CONNECTION_INTERRUPTED_CODES = /* @__PURE__ */ new Set(["ECONNRESET", "EPIPE"]);
|
|
25990
|
+
NETWORK_UNAVAILABLE_CODES = /* @__PURE__ */ new Set([
|
|
25991
|
+
"EAI_AGAIN",
|
|
25992
|
+
"ECONNREFUSED",
|
|
25993
|
+
"EHOSTUNREACH",
|
|
25994
|
+
"ENETDOWN",
|
|
25995
|
+
"ENETUNREACH",
|
|
25996
|
+
"ENOTFOUND"
|
|
25997
|
+
]);
|
|
25998
|
+
TIMEOUT_CODES = /* @__PURE__ */ new Set(["ETIMEDOUT", "ESOCKETTIMEDOUT"]);
|
|
25999
|
+
PERMISSION_CODES = /* @__PURE__ */ new Set(["EACCES", "EPERM"]);
|
|
26000
|
+
KNOWN_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
26001
|
+
...RESOURCE_EXHAUSTED_CODES,
|
|
26002
|
+
...CONNECTION_INTERRUPTED_CODES,
|
|
26003
|
+
...NETWORK_UNAVAILABLE_CODES,
|
|
26004
|
+
...TIMEOUT_CODES,
|
|
26005
|
+
...PERMISSION_CODES,
|
|
26006
|
+
"ABORT_ERR",
|
|
26007
|
+
"ENOENT"
|
|
26008
|
+
]);
|
|
26009
|
+
KNOWN_SYSCALLS = /* @__PURE__ */ new Set([
|
|
26010
|
+
"access",
|
|
26011
|
+
"bind",
|
|
26012
|
+
"close",
|
|
26013
|
+
"connect",
|
|
26014
|
+
"getaddrinfo",
|
|
26015
|
+
"kill",
|
|
26016
|
+
"listen",
|
|
26017
|
+
"mkdir",
|
|
26018
|
+
"open",
|
|
26019
|
+
"read",
|
|
26020
|
+
"readdir",
|
|
26021
|
+
"readlink",
|
|
26022
|
+
"rename",
|
|
26023
|
+
"rmdir",
|
|
26024
|
+
"spawn",
|
|
26025
|
+
"stat",
|
|
26026
|
+
"unlink",
|
|
26027
|
+
"write"
|
|
26028
|
+
]);
|
|
26029
|
+
}
|
|
26030
|
+
});
|
|
26031
|
+
|
|
25839
26032
|
// ../core/src/sentry-logger/index.ts
|
|
25840
26033
|
function applyFatalEventDefaults(event) {
|
|
25841
26034
|
try {
|
|
@@ -25881,6 +26074,7 @@ var init_sentry_logger = __esm({
|
|
|
25881
26074
|
init_events();
|
|
25882
26075
|
init_log_fields();
|
|
25883
26076
|
init_xmtp_test_metrics();
|
|
26077
|
+
init_error_diagnostics();
|
|
25884
26078
|
init_events();
|
|
25885
26079
|
init_log_fields();
|
|
25886
26080
|
FLOW_ID = (0, import_node_crypto5.randomUUID)();
|
|
@@ -25968,14 +26162,23 @@ var init_sentry_logger = __esm({
|
|
|
25968
26162
|
"agentId",
|
|
25969
26163
|
"agentPlatform",
|
|
25970
26164
|
"cacheName",
|
|
26165
|
+
"causeCode",
|
|
26166
|
+
"causeType",
|
|
26167
|
+
"causeVariant",
|
|
25971
26168
|
"checkpoint",
|
|
25972
26169
|
"code",
|
|
25973
26170
|
"communicationClass",
|
|
25974
26171
|
"component",
|
|
25975
26172
|
"eventFamily",
|
|
25976
26173
|
"eventName",
|
|
26174
|
+
"endpoint",
|
|
26175
|
+
"errorCategory",
|
|
26176
|
+
"errorCode",
|
|
26177
|
+
"errorRetryability",
|
|
26178
|
+
"errorSyscall",
|
|
25977
26179
|
"exitCode",
|
|
25978
26180
|
"fromAgentId",
|
|
26181
|
+
"grpcMethod",
|
|
25979
26182
|
"jobId",
|
|
25980
26183
|
"kind",
|
|
25981
26184
|
"method",
|
|
@@ -25999,17 +26202,24 @@ var init_sentry_logger = __esm({
|
|
|
25999
26202
|
"source",
|
|
26000
26203
|
"stage",
|
|
26001
26204
|
"status",
|
|
26205
|
+
"streamErrorCode",
|
|
26206
|
+
"streamType",
|
|
26002
26207
|
"subcommand",
|
|
26003
26208
|
"systemEvent",
|
|
26004
26209
|
"taskId",
|
|
26005
26210
|
"taskMode",
|
|
26006
26211
|
"toAgentId",
|
|
26007
26212
|
"transport",
|
|
26213
|
+
"transportFailure",
|
|
26214
|
+
"transportProtocol",
|
|
26008
26215
|
"type",
|
|
26009
26216
|
"workloadClass"
|
|
26010
26217
|
]);
|
|
26011
26218
|
SENTRY_FINGERPRINT_KEYS = [
|
|
26012
26219
|
"eventName",
|
|
26220
|
+
"errorCategory",
|
|
26221
|
+
"errorCode",
|
|
26222
|
+
"errorSyscall",
|
|
26013
26223
|
"cacheName",
|
|
26014
26224
|
"component",
|
|
26015
26225
|
"method",
|
|
@@ -26057,6 +26267,7 @@ var init_sentry_logger = __esm({
|
|
|
26057
26267
|
LogEvent.HERMES_SESSION_ROUTE_BINDING,
|
|
26058
26268
|
LogEvent.INBOUND_BLOCKED_ADDRESS_MISMATCH,
|
|
26059
26269
|
LogEvent.INBOUND_BLOCKED_INELIGIBLE,
|
|
26270
|
+
LogEvent.MESSAGE_ELIGIBILITY_CHECKED,
|
|
26060
26271
|
LogEvent.INBOUND_BLOCKED_SENSITIVE,
|
|
26061
26272
|
LogEvent.INBOUND_DROP_DM_INVALID_PAYLOAD,
|
|
26062
26273
|
LogEvent.INBOUND_DROP_DM_NON_SYSTEM,
|
|
@@ -26072,6 +26283,9 @@ var init_sentry_logger = __esm({
|
|
|
26072
26283
|
LogEvent.MESSAGE_SENT,
|
|
26073
26284
|
LogEvent.AGENT_CLIENT_CREATED,
|
|
26074
26285
|
LogEvent.AGENT_CLIENT_REMOVED,
|
|
26286
|
+
LogEvent.AGENT_STREAM_ERROR,
|
|
26287
|
+
LogEvent.AGENT_STREAM_RECOVERED,
|
|
26288
|
+
LogEvent.AGENT_STREAM_RECOVERY_REPLAY_COMPLETED,
|
|
26075
26289
|
LogEvent.ADDRESS_SYNC_COMPLETED,
|
|
26076
26290
|
LogEvent.AGENTS_REFRESHED,
|
|
26077
26291
|
LogEvent.AGENTS_WAKEUP_NOTIFIED,
|
|
@@ -26203,19 +26417,24 @@ var init_sentry_logger = __esm({
|
|
|
26203
26417
|
}
|
|
26204
26418
|
captureError(message, error, extraWithFlow) {
|
|
26205
26419
|
try {
|
|
26420
|
+
const errorDiagnostics = buildErrorDiagnostics(
|
|
26421
|
+
message,
|
|
26422
|
+
error,
|
|
26423
|
+
extraWithFlow
|
|
26424
|
+
);
|
|
26425
|
+
const diagnosticExtra = {
|
|
26426
|
+
...extraWithFlow,
|
|
26427
|
+
...errorDiagnostics
|
|
26428
|
+
};
|
|
26206
26429
|
Sentry.withScope((scope) => {
|
|
26207
26430
|
scope.setLevel("error");
|
|
26208
|
-
_SentryLogger.applyDiagnostics(scope, message,
|
|
26431
|
+
_SentryLogger.applyDiagnostics(scope, message, diagnosticExtra);
|
|
26209
26432
|
Sentry.captureException(_SentryLogger.createSentryEvent(message), {
|
|
26210
26433
|
// eventName is unconditional: callers that pass no Error object are
|
|
26211
26434
|
// still classified events, and without it they reach SLS anonymous.
|
|
26212
26435
|
extra: {
|
|
26213
|
-
...
|
|
26214
|
-
eventName: message
|
|
26215
|
-
...error ? {
|
|
26216
|
-
errorName: error.name,
|
|
26217
|
-
errorMessageLength: String(error.message.length)
|
|
26218
|
-
} : {}
|
|
26436
|
+
...diagnosticExtra,
|
|
26437
|
+
eventName: message
|
|
26219
26438
|
}
|
|
26220
26439
|
});
|
|
26221
26440
|
});
|
|
@@ -27414,7 +27633,7 @@ var init_sentry_config = __esm({
|
|
|
27414
27633
|
environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
|
|
27415
27634
|
SENTRY_CONFIG = {
|
|
27416
27635
|
projectName: "okx/openclaw-okx-a2a-extension",
|
|
27417
|
-
release: "0.2.
|
|
27636
|
+
release: "0.2.1-beta-8ae7a0d300-260807181806",
|
|
27418
27637
|
environment,
|
|
27419
27638
|
runtimeContainer: normalizeRuntimeContainer(process.env.OKX_A2A_RUNTIME_CONTAINER)
|
|
27420
27639
|
};
|
|
@@ -38584,7 +38803,7 @@ async function exportDiagnosticLogs(options) {
|
|
|
38584
38803
|
node: process.version,
|
|
38585
38804
|
platform: process.platform,
|
|
38586
38805
|
arch: process.arch,
|
|
38587
|
-
packageVersion: true ? "0.2.
|
|
38806
|
+
packageVersion: true ? "0.2.1-beta-8ae7a0d300-260807181806" : "unknown",
|
|
38588
38807
|
sensitiveContentIncluded: options.includeSensitiveContent,
|
|
38589
38808
|
listenerAndLlmContentIncluded: true,
|
|
38590
38809
|
credentialsAlwaysRedacted: true,
|
|
@@ -39466,6 +39685,47 @@ var init_logs_export = __esm({
|
|
|
39466
39685
|
}
|
|
39467
39686
|
});
|
|
39468
39687
|
|
|
39688
|
+
// src/capabilities-cli.ts
|
|
39689
|
+
var capabilities_cli_exports = {};
|
|
39690
|
+
__export(capabilities_cli_exports, {
|
|
39691
|
+
getA2ACapabilities: () => getA2ACapabilities,
|
|
39692
|
+
handleCapabilitiesCommand: () => handleCapabilitiesCommand
|
|
39693
|
+
});
|
|
39694
|
+
function getA2ACapabilities() {
|
|
39695
|
+
return {
|
|
39696
|
+
messageEligibleOfflineReplay: {
|
|
39697
|
+
ok: true,
|
|
39698
|
+
fixCommands: [],
|
|
39699
|
+
message: ""
|
|
39700
|
+
}
|
|
39701
|
+
};
|
|
39702
|
+
}
|
|
39703
|
+
function handleCapabilitiesCommand(args) {
|
|
39704
|
+
if (args.some((arg) => arg === "-h" || arg === "--help")) {
|
|
39705
|
+
process.stdout.write(CAPABILITIES_USAGE);
|
|
39706
|
+
return;
|
|
39707
|
+
}
|
|
39708
|
+
const unknown = args.filter((arg) => arg !== "--json");
|
|
39709
|
+
if (unknown.length > 0) {
|
|
39710
|
+
throw new Error(`Unknown capabilities option: ${unknown[0]}`);
|
|
39711
|
+
}
|
|
39712
|
+
const capabilities = getA2ACapabilities();
|
|
39713
|
+
if (args.includes("--json")) {
|
|
39714
|
+
process.stdout.write(`${JSON.stringify(capabilities)}
|
|
39715
|
+
`);
|
|
39716
|
+
return;
|
|
39717
|
+
}
|
|
39718
|
+
process.stdout.write(`${JSON.stringify(capabilities, null, 2)}
|
|
39719
|
+
`);
|
|
39720
|
+
}
|
|
39721
|
+
var CAPABILITIES_USAGE;
|
|
39722
|
+
var init_capabilities_cli = __esm({
|
|
39723
|
+
"src/capabilities-cli.ts"() {
|
|
39724
|
+
"use strict";
|
|
39725
|
+
CAPABILITIES_USAGE = "Usage: okx-a2a capabilities [--json]\n\nPrint this package's machine-readable A2A capability negotiation status.\nOnchainOS runs `okx-a2a capabilities --json` to detect supported capabilities.\n";
|
|
39726
|
+
}
|
|
39727
|
+
});
|
|
39728
|
+
|
|
39469
39729
|
// ../core/src/xmtp-sdk/onchainos/bin.ts
|
|
39470
39730
|
async function resolve9() {
|
|
39471
39731
|
if (resolvedBin) {
|
|
@@ -39688,7 +39948,7 @@ async function exec(args) {
|
|
|
39688
39948
|
);
|
|
39689
39949
|
logger.error(
|
|
39690
39950
|
LogEvent.ONCHAINOS_CLI_ERROR,
|
|
39691
|
-
new Error("onchainos command failed"),
|
|
39951
|
+
err2 instanceof Error ? err2 : new Error("onchainos command failed"),
|
|
39692
39952
|
{
|
|
39693
39953
|
component: "onchainos_cli",
|
|
39694
39954
|
source: "onchainos",
|
|
@@ -54416,6 +54676,171 @@ var init_dist4 = __esm({
|
|
|
54416
54676
|
}
|
|
54417
54677
|
});
|
|
54418
54678
|
|
|
54679
|
+
// ../core/src/xmtp-sdk/stream-recovery-telemetry.ts
|
|
54680
|
+
function isAgentStreamRecoveryError(error) {
|
|
54681
|
+
return error instanceof Error && error.constructor.name === "AgentStreamingError" && typeof error.code === "number" && [1002, 1004, 1005].includes(error.code);
|
|
54682
|
+
}
|
|
54683
|
+
function extractStreamErrorTelemetry(error) {
|
|
54684
|
+
const telemetry = {};
|
|
54685
|
+
if (typeof error.code === "number" && Number.isSafeInteger(error.code)) {
|
|
54686
|
+
telemetry.streamErrorCode = String(error.code);
|
|
54687
|
+
const streamType = {
|
|
54688
|
+
1002: "conversation",
|
|
54689
|
+
1004: "message",
|
|
54690
|
+
1005: "setup"
|
|
54691
|
+
};
|
|
54692
|
+
if (streamType[error.code]) {
|
|
54693
|
+
telemetry.streamType = streamType[error.code];
|
|
54694
|
+
}
|
|
54695
|
+
}
|
|
54696
|
+
const cause = error.cause;
|
|
54697
|
+
if (!(cause instanceof Error)) {
|
|
54698
|
+
return telemetry;
|
|
54699
|
+
}
|
|
54700
|
+
telemetry.causeMessageLength = String(cause.message.length);
|
|
54701
|
+
const causeCode = cause.code;
|
|
54702
|
+
if (typeof causeCode === "string" && KNOWN_CAUSE_CODES.has(causeCode)) {
|
|
54703
|
+
telemetry.causeCode = causeCode;
|
|
54704
|
+
}
|
|
54705
|
+
const causeKind = cause.message.match(
|
|
54706
|
+
/^\[([A-Za-z][A-Za-z0-9]{0,63})::([A-Za-z][A-Za-z0-9]{0,63})\]/
|
|
54707
|
+
);
|
|
54708
|
+
const knownCauseKind = causeKind ? KNOWN_CAUSE_KINDS.get(`${causeKind[1]}::${causeKind[2]}`) : void 0;
|
|
54709
|
+
if (knownCauseKind) {
|
|
54710
|
+
telemetry.causeType = knownCauseKind[0];
|
|
54711
|
+
telemetry.causeVariant = knownCauseKind[1];
|
|
54712
|
+
}
|
|
54713
|
+
const grpcMethod = cause.message.match(
|
|
54714
|
+
/endpoint\s+["']\/[A-Za-z0-9_.]+\/([A-Za-z][A-Za-z0-9_]{0,63})["']/
|
|
54715
|
+
);
|
|
54716
|
+
if (grpcMethod && KNOWN_GRPC_METHODS.has(grpcMethod[1])) {
|
|
54717
|
+
telemetry.grpcMethod = grpcMethod[1];
|
|
54718
|
+
telemetry.endpoint = grpcMethod[1];
|
|
54719
|
+
}
|
|
54720
|
+
if (/\bh2 protocol error\b/i.test(cause.message)) {
|
|
54721
|
+
telemetry.transportProtocol = "h2";
|
|
54722
|
+
}
|
|
54723
|
+
const transportFailure = TRANSPORT_FAILURE_PATTERNS.find(
|
|
54724
|
+
([pattern]) => pattern.test(cause.message)
|
|
54725
|
+
);
|
|
54726
|
+
if (transportFailure) {
|
|
54727
|
+
telemetry.transportFailure = transportFailure[1];
|
|
54728
|
+
telemetry.reason = transportFailure[1];
|
|
54729
|
+
}
|
|
54730
|
+
return telemetry;
|
|
54731
|
+
}
|
|
54732
|
+
function createKeyedFlight(discriminator, operation) {
|
|
54733
|
+
let resolve14;
|
|
54734
|
+
let reject;
|
|
54735
|
+
const promise = new Promise((resolvePromise, rejectPromise) => {
|
|
54736
|
+
resolve14 = resolvePromise;
|
|
54737
|
+
reject = rejectPromise;
|
|
54738
|
+
});
|
|
54739
|
+
return { discriminator, operation, promise, resolve: resolve14, reject };
|
|
54740
|
+
}
|
|
54741
|
+
var TRANSPORT_FAILURE_PATTERNS, KNOWN_CAUSE_CODES, KNOWN_CAUSE_KINDS, KNOWN_GRPC_METHODS, StreamRecoveryTelemetry, KeyedSingleFlight;
|
|
54742
|
+
var init_stream_recovery_telemetry = __esm({
|
|
54743
|
+
"../core/src/xmtp-sdk/stream-recovery-telemetry.ts"() {
|
|
54744
|
+
"use strict";
|
|
54745
|
+
TRANSPORT_FAILURE_PATTERNS = [
|
|
54746
|
+
[/broken\s*pipe|BrokenPipe/i, "broken_pipe"],
|
|
54747
|
+
[/connection\s*reset|ConnectionReset/i, "connection_reset"],
|
|
54748
|
+
[/timed?\s*out|TimedOut/i, "timeout"],
|
|
54749
|
+
[/unexpected\s*eof|UnexpectedEof/i, "unexpected_eof"]
|
|
54750
|
+
];
|
|
54751
|
+
KNOWN_CAUSE_CODES = /* @__PURE__ */ new Set(["GenericFailure"]);
|
|
54752
|
+
KNOWN_CAUSE_KINDS = /* @__PURE__ */ new Map([
|
|
54753
|
+
["SubscribeError::BoxError", ["SubscribeError", "BoxError"]]
|
|
54754
|
+
]);
|
|
54755
|
+
KNOWN_GRPC_METHODS = /* @__PURE__ */ new Set([
|
|
54756
|
+
"SubscribeGroupMessages",
|
|
54757
|
+
"SubscribeWelcomeMessages"
|
|
54758
|
+
]);
|
|
54759
|
+
StreamRecoveryTelemetry = class {
|
|
54760
|
+
nextSequence = 1;
|
|
54761
|
+
activeRecovery;
|
|
54762
|
+
get activeSequence() {
|
|
54763
|
+
return this.activeRecovery?.sequence;
|
|
54764
|
+
}
|
|
54765
|
+
markError(nowMs = Date.now()) {
|
|
54766
|
+
if (this.activeRecovery) {
|
|
54767
|
+
return {
|
|
54768
|
+
recoverySequence: this.activeRecovery.sequence,
|
|
54769
|
+
alreadyRecovering: true
|
|
54770
|
+
};
|
|
54771
|
+
}
|
|
54772
|
+
const sequence = this.nextSequence++;
|
|
54773
|
+
this.activeRecovery = { sequence, startedAtMs: nowMs };
|
|
54774
|
+
return { recoverySequence: sequence, alreadyRecovering: false };
|
|
54775
|
+
}
|
|
54776
|
+
markStarted(nowMs = Date.now()) {
|
|
54777
|
+
if (!this.activeRecovery) {
|
|
54778
|
+
return void 0;
|
|
54779
|
+
}
|
|
54780
|
+
const completed = {
|
|
54781
|
+
recoverySequence: this.activeRecovery.sequence,
|
|
54782
|
+
recoveryDurationMs: Math.max(0, nowMs - this.activeRecovery.startedAtMs)
|
|
54783
|
+
};
|
|
54784
|
+
this.activeRecovery = void 0;
|
|
54785
|
+
return completed;
|
|
54786
|
+
}
|
|
54787
|
+
cancel() {
|
|
54788
|
+
this.activeRecovery = void 0;
|
|
54789
|
+
}
|
|
54790
|
+
};
|
|
54791
|
+
KeyedSingleFlight = class {
|
|
54792
|
+
inFlight = /* @__PURE__ */ new Map();
|
|
54793
|
+
run(key, discriminator, operation) {
|
|
54794
|
+
const normalizedKey = key.toLowerCase();
|
|
54795
|
+
const state = this.inFlight.get(normalizedKey);
|
|
54796
|
+
if (!state) {
|
|
54797
|
+
const active = createKeyedFlight(discriminator, operation);
|
|
54798
|
+
this.inFlight.set(normalizedKey, { active, queued: [] });
|
|
54799
|
+
this.execute(normalizedKey, active);
|
|
54800
|
+
return active.promise;
|
|
54801
|
+
}
|
|
54802
|
+
if (state.active.discriminator === discriminator) {
|
|
54803
|
+
return state.active.promise;
|
|
54804
|
+
}
|
|
54805
|
+
const queued = state.queued.find(
|
|
54806
|
+
(flight2) => flight2.discriminator === discriminator
|
|
54807
|
+
);
|
|
54808
|
+
if (queued) {
|
|
54809
|
+
return queued.promise;
|
|
54810
|
+
}
|
|
54811
|
+
const flight = createKeyedFlight(discriminator, operation);
|
|
54812
|
+
state.queued.push(flight);
|
|
54813
|
+
return flight.promise;
|
|
54814
|
+
}
|
|
54815
|
+
execute(key, flight) {
|
|
54816
|
+
void Promise.resolve().then(flight.operation).then(
|
|
54817
|
+
(value) => {
|
|
54818
|
+
flight.resolve(value);
|
|
54819
|
+
this.advance(key, flight);
|
|
54820
|
+
},
|
|
54821
|
+
(error) => {
|
|
54822
|
+
flight.reject(error);
|
|
54823
|
+
this.advance(key, flight);
|
|
54824
|
+
}
|
|
54825
|
+
);
|
|
54826
|
+
}
|
|
54827
|
+
advance(key, completed) {
|
|
54828
|
+
const state = this.inFlight.get(key);
|
|
54829
|
+
if (state?.active !== completed) {
|
|
54830
|
+
return;
|
|
54831
|
+
}
|
|
54832
|
+
const next = state.queued.shift();
|
|
54833
|
+
if (!next) {
|
|
54834
|
+
this.inFlight.delete(key);
|
|
54835
|
+
return;
|
|
54836
|
+
}
|
|
54837
|
+
state.active = next;
|
|
54838
|
+
this.execute(key, next);
|
|
54839
|
+
}
|
|
54840
|
+
};
|
|
54841
|
+
}
|
|
54842
|
+
});
|
|
54843
|
+
|
|
54419
54844
|
// ../core/src/xmtp-sdk/extract-job-id.ts
|
|
54420
54845
|
function extractJobIdFromContent(content2) {
|
|
54421
54846
|
const raw = typeof content2 === "string" ? content2 : stringifyJsonForEnvelope(content2);
|
|
@@ -55216,6 +55641,9 @@ function parseGroupPayload(content2) {
|
|
|
55216
55641
|
return null;
|
|
55217
55642
|
}
|
|
55218
55643
|
}
|
|
55644
|
+
function isOfflineReplayForTrigger(trigger) {
|
|
55645
|
+
return trigger === "startup";
|
|
55646
|
+
}
|
|
55219
55647
|
function createOfflineReplayAddressSummary(address) {
|
|
55220
55648
|
return {
|
|
55221
55649
|
address,
|
|
@@ -55233,7 +55661,7 @@ function createOfflineReplayAddressSummary(address) {
|
|
|
55233
55661
|
durationMs: 0
|
|
55234
55662
|
};
|
|
55235
55663
|
}
|
|
55236
|
-
var import_node_fs22, import_node_path26, DEFAULT_DATA_DIR, XMTP_INSTALLATION_WARNING_THRESHOLD, XMTP_INSTALLATION_NEAR_LIMIT_THRESHOLD, SENSITIVE_WORDS_LAZY_RETRY_COOLDOWN_MS, SESSION_EXPIRED_RE, InboundReplayGate, SYSTEM_CONFIG_DEFAULTS, SEMVER_RE, isRecord5, isPositiveNumber, SYSTEM_CONFIG_VALIDATORS, XmtpService;
|
|
55664
|
+
var import_node_fs22, import_node_path26, DEFAULT_DATA_DIR, XMTP_INSTALLATION_WARNING_THRESHOLD, XMTP_INSTALLATION_NEAR_LIMIT_THRESHOLD, SENSITIVE_WORDS_LAZY_RETRY_COOLDOWN_MS, SESSION_EXPIRED_RE, InboundReplayGate, SYSTEM_CONFIG_DEFAULTS, STREAM_RECOVERY_ALERT_THRESHOLD_MS, REPLAY_GATE_DRAIN_MAX_ATTEMPTS, REPLAY_GATE_DRAIN_RETRY_DELAY_MS, SEMVER_RE, isRecord5, isPositiveNumber, SYSTEM_CONFIG_VALIDATORS, XmtpService;
|
|
55237
55665
|
var init_xmtp_sdk = __esm({
|
|
55238
55666
|
"../core/src/xmtp-sdk/index.ts"() {
|
|
55239
55667
|
"use strict";
|
|
@@ -55243,6 +55671,7 @@ var init_xmtp_sdk = __esm({
|
|
|
55243
55671
|
init_dist4();
|
|
55244
55672
|
init_dist2();
|
|
55245
55673
|
init_sentry_logger();
|
|
55674
|
+
init_stream_recovery_telemetry();
|
|
55246
55675
|
init_extract_job_id();
|
|
55247
55676
|
init_self_filter();
|
|
55248
55677
|
init_logging();
|
|
@@ -55260,10 +55689,11 @@ var init_xmtp_sdk = __esm({
|
|
|
55260
55689
|
this.inbound = inbound;
|
|
55261
55690
|
}
|
|
55262
55691
|
inbound;
|
|
55263
|
-
|
|
55692
|
+
holds = 1;
|
|
55264
55693
|
queue = [];
|
|
55694
|
+
drainInFlight;
|
|
55265
55695
|
middleware = async (ctx, next) => {
|
|
55266
|
-
if (!this.
|
|
55696
|
+
if (this.holds === 0 && !this.drainInFlight) {
|
|
55267
55697
|
await this.inbound(ctx, next);
|
|
55268
55698
|
return;
|
|
55269
55699
|
}
|
|
@@ -55272,19 +55702,55 @@ var init_xmtp_sdk = __esm({
|
|
|
55272
55702
|
get bufferedCount() {
|
|
55273
55703
|
return this.queue.length;
|
|
55274
55704
|
}
|
|
55705
|
+
abandonFailedAndRelease() {
|
|
55706
|
+
const abandoned = this.queue.length > 0 ? 1 : 0;
|
|
55707
|
+
if (abandoned > 0) {
|
|
55708
|
+
this.queue.shift();
|
|
55709
|
+
}
|
|
55710
|
+
if (this.holds > 0) {
|
|
55711
|
+
this.holds--;
|
|
55712
|
+
}
|
|
55713
|
+
return abandoned;
|
|
55714
|
+
}
|
|
55715
|
+
hold() {
|
|
55716
|
+
this.holds++;
|
|
55717
|
+
}
|
|
55275
55718
|
async drain() {
|
|
55719
|
+
if (this.holds > 0) {
|
|
55720
|
+
this.holds--;
|
|
55721
|
+
}
|
|
55722
|
+
return this.drainReleased();
|
|
55723
|
+
}
|
|
55724
|
+
async drainReleased() {
|
|
55725
|
+
if (this.holds > 0) {
|
|
55726
|
+
return 0;
|
|
55727
|
+
}
|
|
55728
|
+
if (this.drainInFlight) {
|
|
55729
|
+
return this.drainInFlight;
|
|
55730
|
+
}
|
|
55731
|
+
const drain = Promise.resolve().then(() => this.drainQueue());
|
|
55732
|
+
this.drainInFlight = drain;
|
|
55733
|
+
try {
|
|
55734
|
+
return await drain;
|
|
55735
|
+
} finally {
|
|
55736
|
+
if (this.drainInFlight === drain) {
|
|
55737
|
+
this.drainInFlight = void 0;
|
|
55738
|
+
}
|
|
55739
|
+
}
|
|
55740
|
+
}
|
|
55741
|
+
async drainQueue() {
|
|
55276
55742
|
let drained = 0;
|
|
55277
|
-
while (this.queue.length > 0) {
|
|
55743
|
+
while (this.holds === 0 && this.queue.length > 0) {
|
|
55278
55744
|
const item = this.queue.shift();
|
|
55279
55745
|
try {
|
|
55280
55746
|
await this.inbound(item.ctx, item.next);
|
|
55281
55747
|
} catch (err2) {
|
|
55282
55748
|
this.queue.unshift(item);
|
|
55749
|
+
this.holds = Math.max(1, this.holds);
|
|
55283
55750
|
throw err2;
|
|
55284
55751
|
}
|
|
55285
55752
|
drained++;
|
|
55286
55753
|
}
|
|
55287
|
-
this.buffering = false;
|
|
55288
55754
|
return drained;
|
|
55289
55755
|
}
|
|
55290
55756
|
};
|
|
@@ -55300,6 +55766,9 @@ var init_xmtp_sdk = __esm({
|
|
|
55300
55766
|
}
|
|
55301
55767
|
}
|
|
55302
55768
|
};
|
|
55769
|
+
STREAM_RECOVERY_ALERT_THRESHOLD_MS = 3e4;
|
|
55770
|
+
REPLAY_GATE_DRAIN_MAX_ATTEMPTS = 3;
|
|
55771
|
+
REPLAY_GATE_DRAIN_RETRY_DELAY_MS = 100;
|
|
55303
55772
|
SEMVER_RE = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*)?$/;
|
|
55304
55773
|
isRecord5 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
55305
55774
|
isPositiveNumber = (value) => typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
@@ -55344,7 +55813,11 @@ var init_xmtp_sdk = __esm({
|
|
|
55344
55813
|
};
|
|
55345
55814
|
dataDir = DEFAULT_DATA_DIR;
|
|
55346
55815
|
syncByAddress = /* @__PURE__ */ new Map();
|
|
55816
|
+
offlineReplaySingleFlight = new KeyedSingleFlight();
|
|
55347
55817
|
inboundReplayGates = /* @__PURE__ */ new Map();
|
|
55818
|
+
streamRecoveryCleanupByAddress = /* @__PURE__ */ new Map();
|
|
55819
|
+
nextClientGeneration = 1;
|
|
55820
|
+
clientGenerationByClient = /* @__PURE__ */ new WeakMap();
|
|
55348
55821
|
agentListFingerprint;
|
|
55349
55822
|
// Only one refreshAgents can be in flight at a time; concurrent calls
|
|
55350
55823
|
// coalesce onto the same promise. This avoids duplicate Agent.create()
|
|
@@ -55799,6 +56272,7 @@ var init_xmtp_sdk = __esm({
|
|
|
55799
56272
|
const client = this.clients.get(address);
|
|
55800
56273
|
if (client) {
|
|
55801
56274
|
try {
|
|
56275
|
+
this.cancelStreamRecoveryForAddress(address);
|
|
55802
56276
|
this.stoppedAddresses.add(address.toLowerCase());
|
|
55803
56277
|
client.stop();
|
|
55804
56278
|
logWithTimestamp(
|
|
@@ -55972,7 +56446,10 @@ var init_xmtp_sdk = __esm({
|
|
|
55972
56446
|
logWithTimestamp(
|
|
55973
56447
|
`[xmtp-sdk] refresh: ${address} has a prior sync timestamp, triggering offline replay`
|
|
55974
56448
|
);
|
|
55975
|
-
void this.
|
|
56449
|
+
void this.replayOfflineMessagesForAddressSingleFlight(
|
|
56450
|
+
address,
|
|
56451
|
+
"agent_refresh"
|
|
56452
|
+
).catch((err2) => {
|
|
55976
56453
|
logWithTimestamp(`[xmtp-sdk] refresh: ${address} offline replay failed:`, err2);
|
|
55977
56454
|
logger.error(
|
|
55978
56455
|
LogEvent.OFFLINE_REPLAY_FAILED,
|
|
@@ -56014,6 +56491,7 @@ var init_xmtp_sdk = __esm({
|
|
|
56014
56491
|
}
|
|
56015
56492
|
const addressKey = address.toLowerCase();
|
|
56016
56493
|
try {
|
|
56494
|
+
this.cancelStreamRecoveryForAddress(address);
|
|
56017
56495
|
this.stoppedAddresses.add(addressKey);
|
|
56018
56496
|
await Promise.resolve(oldClient.stop());
|
|
56019
56497
|
this.clients.delete(address);
|
|
@@ -56072,7 +56550,10 @@ var init_xmtp_sdk = __esm({
|
|
|
56072
56550
|
await this.startListeningForAddresses([address]);
|
|
56073
56551
|
let replaySummary;
|
|
56074
56552
|
try {
|
|
56075
|
-
replaySummary = await this.
|
|
56553
|
+
replaySummary = await this.replayOfflineMessagesForAddressSingleFlight(
|
|
56554
|
+
address,
|
|
56555
|
+
"client_recycle"
|
|
56556
|
+
);
|
|
56076
56557
|
} finally {
|
|
56077
56558
|
await this.drainInboundReplayGate(address);
|
|
56078
56559
|
}
|
|
@@ -56082,6 +56563,7 @@ var init_xmtp_sdk = __esm({
|
|
|
56082
56563
|
recycled++;
|
|
56083
56564
|
} catch (err2) {
|
|
56084
56565
|
failed++;
|
|
56566
|
+
this.cancelStreamRecoveryForAddress(address);
|
|
56085
56567
|
this.clients.delete(address);
|
|
56086
56568
|
logWithTimestamp(`[xmtp-sdk] recycle: failed to recreate client: ${address}`, err2);
|
|
56087
56569
|
logger.error(
|
|
@@ -56482,16 +56964,80 @@ var init_xmtp_sdk = __esm({
|
|
|
56482
56964
|
async startListening() {
|
|
56483
56965
|
await this.startListeningForAddresses([...this.clients.keys()]);
|
|
56484
56966
|
}
|
|
56485
|
-
async drainInboundReplayGate(address) {
|
|
56967
|
+
async drainInboundReplayGate(address, expectedGate) {
|
|
56486
56968
|
const gate = this.inboundReplayGates.get(address.toLowerCase());
|
|
56487
|
-
if (!gate) {
|
|
56969
|
+
if (!gate || expectedGate && gate !== expectedGate) {
|
|
56488
56970
|
return 0;
|
|
56489
56971
|
}
|
|
56490
|
-
|
|
56972
|
+
let attempt = 0;
|
|
56973
|
+
let totalDrained = 0;
|
|
56974
|
+
let releaseHold = true;
|
|
56975
|
+
while (true) {
|
|
56976
|
+
try {
|
|
56977
|
+
const drained = releaseHold ? await gate.drain() : await gate.drainReleased();
|
|
56978
|
+
totalDrained += drained;
|
|
56979
|
+
logWithTimestamp(
|
|
56980
|
+
`[xmtp-sdk:${address}] replay barrier released, buffered=${totalDrained} attempt=${attempt + 1}`
|
|
56981
|
+
);
|
|
56982
|
+
return totalDrained;
|
|
56983
|
+
} catch (err2) {
|
|
56984
|
+
attempt++;
|
|
56985
|
+
logWithTimestamp(
|
|
56986
|
+
`[xmtp-sdk:${address}] replay barrier drain failed attempt=${attempt}/${REPLAY_GATE_DRAIN_MAX_ATTEMPTS}:`,
|
|
56987
|
+
err2
|
|
56988
|
+
);
|
|
56989
|
+
if (attempt < REPLAY_GATE_DRAIN_MAX_ATTEMPTS) {
|
|
56990
|
+
releaseHold = true;
|
|
56991
|
+
await new Promise(
|
|
56992
|
+
(resolve14) => setTimeout(resolve14, REPLAY_GATE_DRAIN_RETRY_DELAY_MS * attempt)
|
|
56993
|
+
);
|
|
56994
|
+
continue;
|
|
56995
|
+
}
|
|
56996
|
+
const abandoned = gate.abandonFailedAndRelease();
|
|
56997
|
+
logger.error(
|
|
56998
|
+
LogEvent.INBOUND_REPLAY_GATE_DRAIN_FAILED,
|
|
56999
|
+
err2 instanceof Error ? err2 : void 0,
|
|
57000
|
+
{
|
|
57001
|
+
walletAddress: address,
|
|
57002
|
+
attemptCount: String(REPLAY_GATE_DRAIN_MAX_ATTEMPTS),
|
|
57003
|
+
abandonedCount: String(abandoned),
|
|
57004
|
+
stage: "inboundReplayGate/fail-open",
|
|
57005
|
+
reason: "drain_retry_exhausted"
|
|
57006
|
+
}
|
|
57007
|
+
);
|
|
57008
|
+
logWithTimestamp(
|
|
57009
|
+
`[xmtp-sdk:${address}] replay barrier fail-open after ${REPLAY_GATE_DRAIN_MAX_ATTEMPTS} failed attempts, abandoned=${abandoned}`
|
|
57010
|
+
);
|
|
57011
|
+
attempt = 0;
|
|
57012
|
+
releaseHold = false;
|
|
57013
|
+
}
|
|
57014
|
+
}
|
|
57015
|
+
}
|
|
57016
|
+
holdInboundReplayGate(address) {
|
|
57017
|
+
const gate = this.inboundReplayGates.get(address.toLowerCase());
|
|
57018
|
+
if (!gate) {
|
|
57019
|
+
return void 0;
|
|
57020
|
+
}
|
|
57021
|
+
gate.hold();
|
|
56491
57022
|
logWithTimestamp(
|
|
56492
|
-
`[xmtp-sdk:${address}]
|
|
57023
|
+
`[xmtp-sdk:${address}] replay barrier held, buffered=${gate.bufferedCount}`
|
|
56493
57024
|
);
|
|
56494
|
-
return
|
|
57025
|
+
return gate;
|
|
57026
|
+
}
|
|
57027
|
+
cancelStreamRecoveryForAddress(address) {
|
|
57028
|
+
const addressKey = address.toLowerCase();
|
|
57029
|
+
const cleanup = this.streamRecoveryCleanupByAddress.get(addressKey);
|
|
57030
|
+
this.streamRecoveryCleanupByAddress.delete(addressKey);
|
|
57031
|
+
cleanup?.();
|
|
57032
|
+
}
|
|
57033
|
+
getClientGeneration(client) {
|
|
57034
|
+
const existing = this.clientGenerationByClient.get(client);
|
|
57035
|
+
if (existing !== void 0) {
|
|
57036
|
+
return existing;
|
|
57037
|
+
}
|
|
57038
|
+
const generation = this.nextClientGeneration++;
|
|
57039
|
+
this.clientGenerationByClient.set(client, generation);
|
|
57040
|
+
return generation;
|
|
56495
57041
|
}
|
|
56496
57042
|
notifyAgentsWakeupAfterReplay() {
|
|
56497
57043
|
const notifyAgentsWakeup2 = this.tools.notifyAgentsWakeup;
|
|
@@ -56525,7 +57071,7 @@ var init_xmtp_sdk = __esm({
|
|
|
56525
57071
|
* cannot overtake the stored backlog.
|
|
56526
57072
|
*/
|
|
56527
57073
|
async completeStartupReplay() {
|
|
56528
|
-
const summary = await this.replayOfflineMessages();
|
|
57074
|
+
const summary = await this.replayOfflineMessages("startup");
|
|
56529
57075
|
for (const address of this.clients.keys()) {
|
|
56530
57076
|
await this.drainInboundReplayGate(address);
|
|
56531
57077
|
}
|
|
@@ -56536,6 +57082,8 @@ var init_xmtp_sdk = __esm({
|
|
|
56536
57082
|
const valid = addresses.filter((addr) => this.clients.has(addr));
|
|
56537
57083
|
await parallelMap(valid, async (address) => {
|
|
56538
57084
|
const agent = this.clients.get(address);
|
|
57085
|
+
const clientGeneration = this.getClientGeneration(agent);
|
|
57086
|
+
const addressKey = address.toLowerCase();
|
|
56539
57087
|
const tag = `[xmtp-sdk:${address}]`;
|
|
56540
57088
|
const onchainosAgent = this.getAgentByAddress(address);
|
|
56541
57089
|
const identity = {
|
|
@@ -56638,14 +57186,131 @@ var init_xmtp_sdk = __esm({
|
|
|
56638
57186
|
logWithTimestamp(`${tag} reconnecting in ${delay}ms (attempt=${attempt + 1})`);
|
|
56639
57187
|
setTimeout(() => void startWithRetry(attempt + 1), delay);
|
|
56640
57188
|
};
|
|
57189
|
+
const streamRecovery = new StreamRecoveryTelemetry();
|
|
57190
|
+
let recoveryTimeout;
|
|
57191
|
+
let pendingRecoveryGate;
|
|
57192
|
+
let recoveryDisposed = false;
|
|
57193
|
+
this.cancelStreamRecoveryForAddress(address);
|
|
57194
|
+
const cleanupStreamRecovery = () => {
|
|
57195
|
+
recoveryDisposed = true;
|
|
57196
|
+
streamRecovery.cancel();
|
|
57197
|
+
if (recoveryTimeout) {
|
|
57198
|
+
clearTimeout(recoveryTimeout);
|
|
57199
|
+
recoveryTimeout = void 0;
|
|
57200
|
+
}
|
|
57201
|
+
};
|
|
57202
|
+
this.streamRecoveryCleanupByAddress.set(
|
|
57203
|
+
addressKey,
|
|
57204
|
+
cleanupStreamRecovery
|
|
57205
|
+
);
|
|
56641
57206
|
agent.on("unhandledError", (err2) => {
|
|
57207
|
+
if (recoveryDisposed || this.clients.get(address) !== agent || this.stoppedAddresses.has(addressKey)) {
|
|
57208
|
+
return;
|
|
57209
|
+
}
|
|
57210
|
+
if (!isAgentStreamRecoveryError(err2)) {
|
|
57211
|
+
logWithTimestamp(`${tag} agent unhandled error:`, err2);
|
|
57212
|
+
logger.error(LogEvent.AGENT_UNHANDLED_ERROR, err2, agentExtras(identity));
|
|
57213
|
+
return;
|
|
57214
|
+
}
|
|
57215
|
+
const recovery = streamRecovery.markError();
|
|
57216
|
+
const errorTelemetry = extractStreamErrorTelemetry(err2);
|
|
57217
|
+
if (!recovery.alreadyRecovering) {
|
|
57218
|
+
pendingRecoveryGate = this.holdInboundReplayGate(address);
|
|
57219
|
+
}
|
|
56642
57220
|
logWithTimestamp(`${tag} agent stream error:`, err2);
|
|
56643
|
-
logger.
|
|
57221
|
+
logger.info(LogEvent.AGENT_STREAM_ERROR, {
|
|
57222
|
+
...agentExtras(identity),
|
|
57223
|
+
...errorTelemetry,
|
|
57224
|
+
clientGeneration: String(clientGeneration),
|
|
57225
|
+
recoverySequence: String(recovery.recoverySequence),
|
|
57226
|
+
recoveryAlreadyActive: String(recovery.alreadyRecovering)
|
|
57227
|
+
});
|
|
57228
|
+
if (!recovery.alreadyRecovering) {
|
|
57229
|
+
recoveryTimeout = setTimeout(() => {
|
|
57230
|
+
if (recoveryDisposed || this.clients.get(address) !== agent || this.stoppedAddresses.has(addressKey) || streamRecovery.activeSequence !== recovery.recoverySequence) {
|
|
57231
|
+
return;
|
|
57232
|
+
}
|
|
57233
|
+
logger.error(LogEvent.AGENT_STREAM_RECOVERY_TIMEOUT, void 0, {
|
|
57234
|
+
...agentExtras(identity),
|
|
57235
|
+
...errorTelemetry,
|
|
57236
|
+
clientGeneration: String(clientGeneration),
|
|
57237
|
+
recoverySequence: String(recovery.recoverySequence),
|
|
57238
|
+
recoveryDurationMs: String(STREAM_RECOVERY_ALERT_THRESHOLD_MS),
|
|
57239
|
+
thresholdMs: String(STREAM_RECOVERY_ALERT_THRESHOLD_MS)
|
|
57240
|
+
});
|
|
57241
|
+
}, STREAM_RECOVERY_ALERT_THRESHOLD_MS);
|
|
57242
|
+
}
|
|
56644
57243
|
});
|
|
56645
57244
|
agent.on("start", () => {
|
|
57245
|
+
if (recoveryDisposed || this.clients.get(address) !== agent || this.stoppedAddresses.has(addressKey)) {
|
|
57246
|
+
return;
|
|
57247
|
+
}
|
|
57248
|
+
const recovery = streamRecovery.markStarted();
|
|
57249
|
+
if (recoveryTimeout) {
|
|
57250
|
+
clearTimeout(recoveryTimeout);
|
|
57251
|
+
recoveryTimeout = void 0;
|
|
57252
|
+
}
|
|
56646
57253
|
logWithTimestamp(
|
|
56647
57254
|
`${tag} agent stream started agentId=${identity.onchainosAgentId ?? "(unknown)"} inboxId=${identity.inboxId ?? "(unknown)"} role=${identity.role ?? "(unknown)"} consentStates=Allowed,Unknown lastSync=${formatLogTimestamp2(this.syncByAddress.get(address))}`
|
|
56648
57255
|
);
|
|
57256
|
+
if (recovery) {
|
|
57257
|
+
const recoveryGate = pendingRecoveryGate;
|
|
57258
|
+
pendingRecoveryGate = void 0;
|
|
57259
|
+
logger.info(LogEvent.AGENT_STREAM_RECOVERED, {
|
|
57260
|
+
...agentExtras(identity),
|
|
57261
|
+
clientGeneration: String(clientGeneration),
|
|
57262
|
+
recoverySequence: String(recovery.recoverySequence),
|
|
57263
|
+
recoveryDurationMs: String(recovery.recoveryDurationMs)
|
|
57264
|
+
});
|
|
57265
|
+
void (async () => {
|
|
57266
|
+
try {
|
|
57267
|
+
const summary = await this.replayOfflineMessagesForAddressSingleFlight(
|
|
57268
|
+
address,
|
|
57269
|
+
"stream_recovery",
|
|
57270
|
+
`${clientGeneration}:${recovery.recoverySequence}`
|
|
57271
|
+
);
|
|
57272
|
+
if (!recoveryDisposed && this.clients.get(address) === agent) {
|
|
57273
|
+
logger.info(LogEvent.AGENT_STREAM_RECOVERY_REPLAY_COMPLETED, {
|
|
57274
|
+
...agentExtras(identity),
|
|
57275
|
+
clientGeneration: String(clientGeneration),
|
|
57276
|
+
recoverySequence: String(recovery.recoverySequence),
|
|
57277
|
+
replayed: String(summary.replayed),
|
|
57278
|
+
skipped: String(summary.skipped),
|
|
57279
|
+
conversationCount: String(summary.conversations),
|
|
57280
|
+
replayDurationMs: String(summary.durationMs)
|
|
57281
|
+
});
|
|
57282
|
+
}
|
|
57283
|
+
} catch (err2) {
|
|
57284
|
+
logWithTimestamp(`${tag} recovery offline replay failed:`, err2);
|
|
57285
|
+
logger.error(
|
|
57286
|
+
LogEvent.OFFLINE_REPLAY_FAILED,
|
|
57287
|
+
err2 instanceof Error ? err2 : new Error(String(err2)),
|
|
57288
|
+
{
|
|
57289
|
+
...agentExtras(identity),
|
|
57290
|
+
clientGeneration: String(clientGeneration),
|
|
57291
|
+
recoverySequence: String(recovery.recoverySequence),
|
|
57292
|
+
stage: "streamRecovery/replay"
|
|
57293
|
+
}
|
|
57294
|
+
);
|
|
57295
|
+
} finally {
|
|
57296
|
+
try {
|
|
57297
|
+
await this.drainInboundReplayGate(address, recoveryGate);
|
|
57298
|
+
} catch (err2) {
|
|
57299
|
+
logWithTimestamp(`${tag} recovery replay gate drain failed:`, err2);
|
|
57300
|
+
logger.error(
|
|
57301
|
+
LogEvent.OFFLINE_REPLAY_FAILED,
|
|
57302
|
+
err2 instanceof Error ? err2 : new Error(String(err2)),
|
|
57303
|
+
{
|
|
57304
|
+
...agentExtras(identity),
|
|
57305
|
+
clientGeneration: String(clientGeneration),
|
|
57306
|
+
recoverySequence: String(recovery.recoverySequence),
|
|
57307
|
+
stage: "streamRecovery/drain-gate"
|
|
57308
|
+
}
|
|
57309
|
+
);
|
|
57310
|
+
}
|
|
57311
|
+
}
|
|
57312
|
+
})();
|
|
57313
|
+
}
|
|
56649
57314
|
if (process.env.XMTP_FORCE_DEBUG === "true") {
|
|
56650
57315
|
void logDetails(agent).catch((err2) => {
|
|
56651
57316
|
logWithTimestamp(`${tag} agent debug details failed:`, err2);
|
|
@@ -56663,9 +57328,10 @@ var init_xmtp_sdk = __esm({
|
|
|
56663
57328
|
logWithTimestamp(`${tag} message listener started`);
|
|
56664
57329
|
});
|
|
56665
57330
|
}
|
|
56666
|
-
async replayOfflineMessagesForAddress(address) {
|
|
57331
|
+
async replayOfflineMessagesForAddress(address, trigger = "periodic_repair") {
|
|
56667
57332
|
const addressReplayStartedAt = Date.now();
|
|
56668
57333
|
const summary = createOfflineReplayAddressSummary(address);
|
|
57334
|
+
const isOfflineReplay = isOfflineReplayForTrigger(trigger);
|
|
56669
57335
|
const agent = this.clients.get(address);
|
|
56670
57336
|
if (!agent) {
|
|
56671
57337
|
summary.durationMs = Date.now() - addressReplayStartedAt;
|
|
@@ -56789,7 +57455,8 @@ var init_xmtp_sdk = __esm({
|
|
|
56789
57455
|
};
|
|
56790
57456
|
const handleStartedAt = Date.now();
|
|
56791
57457
|
const handled = await processOffline(fakeCtx, handlerDeps, {
|
|
56792
|
-
skipNotify: true
|
|
57458
|
+
skipNotify: true,
|
|
57459
|
+
isOfflineReplay
|
|
56793
57460
|
});
|
|
56794
57461
|
const handleMs = Date.now() - handleStartedAt;
|
|
56795
57462
|
summary.handleMs += handleMs;
|
|
@@ -56871,14 +57538,28 @@ var init_xmtp_sdk = __esm({
|
|
|
56871
57538
|
);
|
|
56872
57539
|
return summary;
|
|
56873
57540
|
}
|
|
56874
|
-
|
|
57541
|
+
replayOfflineMessagesForAddressSingleFlight(address, trigger = "periodic_repair", recoveryIdentity) {
|
|
57542
|
+
const eligibilityClass = trigger === "stream_recovery" ? `stream_recovery:${recoveryIdentity ?? "unknown"}` : isOfflineReplayForTrigger(trigger) ? "startup_offline" : "online_repair";
|
|
57543
|
+
return this.offlineReplaySingleFlight.run(
|
|
57544
|
+
address,
|
|
57545
|
+
eligibilityClass,
|
|
57546
|
+
async () => {
|
|
57547
|
+
await this._backupReady;
|
|
57548
|
+
return this.replayOfflineMessagesForAddress(address, trigger);
|
|
57549
|
+
}
|
|
57550
|
+
);
|
|
57551
|
+
}
|
|
57552
|
+
async replayOfflineMessages(trigger = "periodic_repair") {
|
|
56875
57553
|
await this._backupReady;
|
|
56876
57554
|
const replayStartedAt = Date.now();
|
|
56877
57555
|
let totalReplayed = 0;
|
|
56878
57556
|
let totalSkipped = 0;
|
|
56879
57557
|
const addresses = [];
|
|
56880
57558
|
for (const address of this.clients.keys()) {
|
|
56881
|
-
const summary2 = await this.
|
|
57559
|
+
const summary2 = await this.replayOfflineMessagesForAddressSingleFlight(
|
|
57560
|
+
address,
|
|
57561
|
+
trigger
|
|
57562
|
+
);
|
|
56882
57563
|
addresses.push(summary2);
|
|
56883
57564
|
const { replayed, skipped: skipped2 } = summary2;
|
|
56884
57565
|
totalReplayed += replayed;
|
|
@@ -56987,6 +57668,111 @@ var init_session_expired = __esm({
|
|
|
56987
57668
|
}
|
|
56988
57669
|
});
|
|
56989
57670
|
|
|
57671
|
+
// ../core/src/xmtp-sdk/onchainos/offline-replay-capability.ts
|
|
57672
|
+
function messageEligibleHelpAdvertisesOfflineReplay(helpText) {
|
|
57673
|
+
if (typeof helpText !== "string" || helpText.length === 0) {
|
|
57674
|
+
return false;
|
|
57675
|
+
}
|
|
57676
|
+
return helpText.toLowerCase().includes(MESSAGE_ELIGIBLE_OFFLINE_REPLAY_HELP_TOKEN);
|
|
57677
|
+
}
|
|
57678
|
+
function buildMessageEligibleArgs(params, opts) {
|
|
57679
|
+
const args = [
|
|
57680
|
+
"agent",
|
|
57681
|
+
"message-eligible",
|
|
57682
|
+
"--agent-id",
|
|
57683
|
+
params.agentId,
|
|
57684
|
+
"--client-agent-id",
|
|
57685
|
+
params.clientAgentId,
|
|
57686
|
+
"--provider-agent-id",
|
|
57687
|
+
params.providerAgentId,
|
|
57688
|
+
"--client-communication-address",
|
|
57689
|
+
params.clientCommunicationAddress,
|
|
57690
|
+
"--provider-communication-address",
|
|
57691
|
+
params.providerCommunicationAddress,
|
|
57692
|
+
"--job-id",
|
|
57693
|
+
params.jobId,
|
|
57694
|
+
"--group-id",
|
|
57695
|
+
params.groupId,
|
|
57696
|
+
"--direction",
|
|
57697
|
+
params.direction,
|
|
57698
|
+
"--provider-security-rate",
|
|
57699
|
+
String(params.providerSecurityRate)
|
|
57700
|
+
];
|
|
57701
|
+
if (opts.offlineReplaySupported) {
|
|
57702
|
+
args.push(MESSAGE_ELIGIBLE_OFFLINE_REPLAY_FLAG, String(params.isOfflineReplay));
|
|
57703
|
+
}
|
|
57704
|
+
return args;
|
|
57705
|
+
}
|
|
57706
|
+
function resolveOfflineReplayCapabilityMarker(supported) {
|
|
57707
|
+
return supported ? "supported" : "legacy_downgrade";
|
|
57708
|
+
}
|
|
57709
|
+
function maybeRecommendOnchainosUpgrade(supported) {
|
|
57710
|
+
if (supported || recommendedPairs.has(UPGRADE_RECOMMENDATION_PAIR_KEY)) {
|
|
57711
|
+
return;
|
|
57712
|
+
}
|
|
57713
|
+
const hook = XmtpService.getInstance().tools.notifyUpgradeRecommendation;
|
|
57714
|
+
if (!hook) {
|
|
57715
|
+
logWithTimestamp(
|
|
57716
|
+
"[onchainos] tools.notifyUpgradeRecommendation not injected \u2014 deferring offline-replay upgrade notice"
|
|
57717
|
+
);
|
|
57718
|
+
return;
|
|
57719
|
+
}
|
|
57720
|
+
recommendedPairs.add(UPGRADE_RECOMMENDATION_PAIR_KEY);
|
|
57721
|
+
try {
|
|
57722
|
+
void Promise.resolve(
|
|
57723
|
+
hook({
|
|
57724
|
+
component: "onchainos",
|
|
57725
|
+
capability: MESSAGE_ELIGIBLE_OFFLINE_REPLAY_HELP_TOKEN,
|
|
57726
|
+
reason: UPGRADE_RECOMMENDATION_REASON
|
|
57727
|
+
})
|
|
57728
|
+
).catch((err2) => {
|
|
57729
|
+
logWithTimestamp("[onchainos] tools.notifyUpgradeRecommendation async delivery failed:", err2);
|
|
57730
|
+
});
|
|
57731
|
+
} catch (err2) {
|
|
57732
|
+
logWithTimestamp("[onchainos] tools.notifyUpgradeRecommendation threw:", err2);
|
|
57733
|
+
}
|
|
57734
|
+
}
|
|
57735
|
+
function detectMessageEligibleOfflineReplaySupport(execFn = exec) {
|
|
57736
|
+
if (!capabilityProbe) {
|
|
57737
|
+
capabilityProbe = (async () => {
|
|
57738
|
+
try {
|
|
57739
|
+
const { stdout, stderr } = await execFn(["agent", "message-eligible", "--help"]);
|
|
57740
|
+
const supported = messageEligibleHelpAdvertisesOfflineReplay(`${stdout}
|
|
57741
|
+
${stderr}`);
|
|
57742
|
+
logWithTimestamp(
|
|
57743
|
+
`[onchainos] message-eligible offline-replay capability: ${supported ? "supported" : "legacy_downgrade"}`
|
|
57744
|
+
);
|
|
57745
|
+
return supported;
|
|
57746
|
+
} catch (err2) {
|
|
57747
|
+
logWithTimestamp(
|
|
57748
|
+
"[onchainos] message-eligible --help probe failed; treating offline-replay as unsupported (legacy):",
|
|
57749
|
+
err2
|
|
57750
|
+
);
|
|
57751
|
+
return false;
|
|
57752
|
+
}
|
|
57753
|
+
})().then((supported) => {
|
|
57754
|
+
maybeRecommendOnchainosUpgrade(supported);
|
|
57755
|
+
return supported;
|
|
57756
|
+
});
|
|
57757
|
+
}
|
|
57758
|
+
return capabilityProbe;
|
|
57759
|
+
}
|
|
57760
|
+
var MESSAGE_ELIGIBLE_OFFLINE_REPLAY_FLAG, MESSAGE_ELIGIBLE_OFFLINE_REPLAY_HELP_TOKEN, UPGRADE_RECOMMENDATION_PAIR_KEY, UPGRADE_RECOMMENDATION_REASON, capabilityProbe, recommendedPairs;
|
|
57761
|
+
var init_offline_replay_capability = __esm({
|
|
57762
|
+
"../core/src/xmtp-sdk/onchainos/offline-replay-capability.ts"() {
|
|
57763
|
+
"use strict";
|
|
57764
|
+
init_log();
|
|
57765
|
+
init_bin();
|
|
57766
|
+
init_xmtp_sdk();
|
|
57767
|
+
MESSAGE_ELIGIBLE_OFFLINE_REPLAY_FLAG = "--is-offline-replay";
|
|
57768
|
+
MESSAGE_ELIGIBLE_OFFLINE_REPLAY_HELP_TOKEN = "is-offline-replay";
|
|
57769
|
+
UPGRADE_RECOMMENDATION_PAIR_KEY = "onchainos:message-eligible-offline-replay";
|
|
57770
|
+
UPGRADE_RECOMMENDATION_REASON = "OnchainOS does not support the offline-replay eligibility argument; using the legacy message-eligible contract.";
|
|
57771
|
+
capabilityProbe = null;
|
|
57772
|
+
recommendedPairs = /* @__PURE__ */ new Set();
|
|
57773
|
+
}
|
|
57774
|
+
});
|
|
57775
|
+
|
|
56990
57776
|
// ../core/src/xmtp-sdk/onchainos/system-config.ts
|
|
56991
57777
|
function notifyExpired(command, options) {
|
|
56992
57778
|
if (options?.notifySessionExpired) {
|
|
@@ -57385,35 +58171,32 @@ async function sendHeartbeat(chainIndex) {
|
|
|
57385
58171
|
}
|
|
57386
58172
|
async function checkMessageEligible(params) {
|
|
57387
58173
|
logWithTimestamp(
|
|
57388
|
-
`[onchainos] checking message-eligible: job=${params.jobId} direction=${params.direction} providerSecurityRate=${params.providerSecurityRate}`
|
|
58174
|
+
`[onchainos] checking message-eligible: job=${params.jobId} direction=${params.direction} providerSecurityRate=${params.providerSecurityRate} isOfflineReplay=${params.isOfflineReplay}`
|
|
57389
58175
|
);
|
|
58176
|
+
const offlineReplaySupported = await detectMessageEligibleOfflineReplaySupport();
|
|
58177
|
+
const offlineReplayCapability = resolveOfflineReplayCapabilityMarker(offlineReplaySupported);
|
|
58178
|
+
const emitEligibilityChecked = (outcome, eligible) => {
|
|
58179
|
+
logger.info(LogEvent.MESSAGE_ELIGIBILITY_CHECKED, {
|
|
58180
|
+
component: "onchainos_cli",
|
|
58181
|
+
source: "onchainos",
|
|
58182
|
+
stage: "eligibility_check",
|
|
58183
|
+
direction: params.direction,
|
|
58184
|
+
jobId: params.jobId,
|
|
58185
|
+
isOfflineReplay: String(params.isOfflineReplay),
|
|
58186
|
+
offlineReplayCapability,
|
|
58187
|
+
outcome,
|
|
58188
|
+
eligible
|
|
58189
|
+
});
|
|
58190
|
+
};
|
|
57390
58191
|
let stdout;
|
|
57391
58192
|
let stderr;
|
|
57392
58193
|
try {
|
|
57393
|
-
({ stdout, stderr } = await exec(
|
|
57394
|
-
|
|
57395
|
-
|
|
57396
|
-
"--agent-id",
|
|
57397
|
-
params.agentId,
|
|
57398
|
-
"--client-agent-id",
|
|
57399
|
-
params.clientAgentId,
|
|
57400
|
-
"--provider-agent-id",
|
|
57401
|
-
params.providerAgentId,
|
|
57402
|
-
"--client-communication-address",
|
|
57403
|
-
params.clientCommunicationAddress,
|
|
57404
|
-
"--provider-communication-address",
|
|
57405
|
-
params.providerCommunicationAddress,
|
|
57406
|
-
"--job-id",
|
|
57407
|
-
params.jobId,
|
|
57408
|
-
"--group-id",
|
|
57409
|
-
params.groupId,
|
|
57410
|
-
"--direction",
|
|
57411
|
-
params.direction,
|
|
57412
|
-
"--provider-security-rate",
|
|
57413
|
-
String(params.providerSecurityRate)
|
|
57414
|
-
]));
|
|
58194
|
+
({ stdout, stderr } = await exec(
|
|
58195
|
+
buildMessageEligibleArgs(params, { offlineReplaySupported })
|
|
58196
|
+
));
|
|
57415
58197
|
} catch (err2) {
|
|
57416
58198
|
guardCatchSessionExpired2(err2, "message-eligible");
|
|
58199
|
+
emitEligibilityChecked("failed", "unknown");
|
|
57417
58200
|
throw messageEligibleUnavailableError({
|
|
57418
58201
|
reason: "message-eligible-cli-error",
|
|
57419
58202
|
stdout: typeof err2?.stdout === "string" ? err2.stdout : "",
|
|
@@ -57438,6 +58221,7 @@ async function checkMessageEligible(params) {
|
|
|
57438
58221
|
providerSecurityRate: String(params.providerSecurityRate)
|
|
57439
58222
|
});
|
|
57440
58223
|
} catch (err2) {
|
|
58224
|
+
emitEligibilityChecked("failed", "unknown");
|
|
57441
58225
|
throw messageEligibleUnavailableError({
|
|
57442
58226
|
reason: "message-eligible-json-parse-failed",
|
|
57443
58227
|
stdout,
|
|
@@ -57467,6 +58251,7 @@ async function checkMessageEligible(params) {
|
|
|
57467
58251
|
reason: "ok=false"
|
|
57468
58252
|
})
|
|
57469
58253
|
);
|
|
58254
|
+
emitEligibilityChecked("failed", "unknown");
|
|
57470
58255
|
throw messageEligibleUnavailableError({
|
|
57471
58256
|
reason: "message-eligible-ok-false",
|
|
57472
58257
|
stdout,
|
|
@@ -57476,6 +58261,7 @@ async function checkMessageEligible(params) {
|
|
|
57476
58261
|
logWithTimestamp(
|
|
57477
58262
|
`[onchainos] message-eligible result: eligible=${res.data.eligible}`
|
|
57478
58263
|
);
|
|
58264
|
+
emitEligibilityChecked("success", String(res.data.eligible));
|
|
57479
58265
|
return res.data;
|
|
57480
58266
|
}
|
|
57481
58267
|
async function fetchSensitiveWords() {
|
|
@@ -57529,6 +58315,7 @@ var init_onchainos = __esm({
|
|
|
57529
58315
|
init_xmtp_sdk();
|
|
57530
58316
|
init_cli_response();
|
|
57531
58317
|
init_session_expired();
|
|
58318
|
+
init_offline_replay_capability();
|
|
57532
58319
|
init_cli_response();
|
|
57533
58320
|
init_session_expired();
|
|
57534
58321
|
init_system_config();
|
|
@@ -58394,7 +59181,9 @@ async function assertOutboundEligible(params) {
|
|
|
58394
59181
|
jobId,
|
|
58395
59182
|
groupId,
|
|
58396
59183
|
direction: isSenderClient ? "client_to_provider" : "provider_to_client",
|
|
58397
|
-
providerSecurityRate
|
|
59184
|
+
providerSecurityRate,
|
|
59185
|
+
// Outbound messages are never startup backlog recovery.
|
|
59186
|
+
isOfflineReplay: false
|
|
58398
59187
|
});
|
|
58399
59188
|
logWithTimestamp(
|
|
58400
59189
|
`[okx-agent-task] outbound message-eligible: senderAgentId=${senderAgent.agentId} receiverAgentId=${receiverAgent.agentId} job=${jobId} group=${groupId} result=${JSON.stringify(result)}`
|
|
@@ -63996,6 +64785,7 @@ async function verifyInboundA2AGroupMessage(params) {
|
|
|
63996
64785
|
messageId,
|
|
63997
64786
|
consentState,
|
|
63998
64787
|
trustedSystemSender = false,
|
|
64788
|
+
isOfflineReplay = false,
|
|
63999
64789
|
timing
|
|
64000
64790
|
} = params;
|
|
64001
64791
|
if (!isA2AEnvelope(payload)) {
|
|
@@ -64099,7 +64889,8 @@ async function verifyInboundA2AGroupMessage(params) {
|
|
|
64099
64889
|
jobId,
|
|
64100
64890
|
groupId,
|
|
64101
64891
|
direction: isSenderClient ? "client_to_provider" : "provider_to_client",
|
|
64102
|
-
providerSecurityRate
|
|
64892
|
+
providerSecurityRate,
|
|
64893
|
+
isOfflineReplay
|
|
64103
64894
|
});
|
|
64104
64895
|
timing?.mark("eligibilityCheck", eligibilityStartedAt);
|
|
64105
64896
|
logWithTimestamp(
|
|
@@ -64548,6 +65339,7 @@ async function processFileMessage(ctx, deps, options = {}) {
|
|
|
64548
65339
|
messageId,
|
|
64549
65340
|
consentState: ctx.conversation instanceof Group ? ctx.conversation.consentState() : void 0,
|
|
64550
65341
|
trustedSystemSender,
|
|
65342
|
+
isOfflineReplay: options.isOfflineReplay ?? false,
|
|
64551
65343
|
timing
|
|
64552
65344
|
});
|
|
64553
65345
|
if (!accepted) {
|
|
@@ -65272,14 +66064,28 @@ async function runListenerWithLock(options, paths) {
|
|
|
65272
66064
|
reason: "append_backup_failed"
|
|
65273
66065
|
});
|
|
65274
66066
|
});
|
|
66067
|
+
},
|
|
66068
|
+
notifyUpgradeRecommendation: (input) => {
|
|
66069
|
+
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";
|
|
66070
|
+
void notifySystemMessageToUser({
|
|
66071
|
+
title: "OnchainOS upgrade recommended",
|
|
66072
|
+
content: content2,
|
|
66073
|
+
store: sessionStore,
|
|
66074
|
+
idempotencyKey: UPGRADE_RECOMMENDATION_IDEMPOTENCY_KEY
|
|
66075
|
+
}).catch((err2) => {
|
|
66076
|
+
logWithTimestamp(
|
|
66077
|
+
`[okx-agent-task] upgrade recommendation notify failed component=${input.component} capability=${input.capability}:`,
|
|
66078
|
+
err2
|
|
66079
|
+
);
|
|
66080
|
+
});
|
|
65275
66081
|
}
|
|
65276
66082
|
});
|
|
65277
|
-
service.setPluginVersion("0.2.
|
|
66083
|
+
service.setPluginVersion("0.2.1-beta-8ae7a0d300-260807181806");
|
|
65278
66084
|
await service.init();
|
|
65279
66085
|
const pluginVersionStatus = service.pluginVersionStatus;
|
|
65280
66086
|
if (pluginVersionStatus.unavailable) {
|
|
65281
66087
|
throw new Error(
|
|
65282
|
-
`@okxweb3/a2a-node v${"0.2.
|
|
66088
|
+
`@okxweb3/a2a-node v${"0.2.1-beta-8ae7a0d300-260807181806"} is below the required minimum v${pluginVersionStatus.minVersion}`
|
|
65283
66089
|
);
|
|
65284
66090
|
}
|
|
65285
66091
|
const systemConfig = service.getSystemConfig();
|
|
@@ -65297,12 +66103,14 @@ async function runListenerWithLock(options, paths) {
|
|
|
65297
66103
|
onchainosAgentId: "*",
|
|
65298
66104
|
reason: "system-config missing sentryDsn",
|
|
65299
66105
|
pluginId: "@okxweb3/a2a-node",
|
|
65300
|
-
pluginVersion: "0.2.
|
|
66106
|
+
pluginVersion: "0.2.1-beta-8ae7a0d300-260807181806"
|
|
65301
66107
|
});
|
|
65302
66108
|
}
|
|
65303
66109
|
logWithTimestamp(
|
|
65304
66110
|
`[okx-agent-task] listener initialized, clients=${service.getClients().size}, home=${store.homeDir}`
|
|
65305
66111
|
);
|
|
66112
|
+
void detectMessageEligibleOfflineReplaySupport().catch(() => {
|
|
66113
|
+
});
|
|
65306
66114
|
const startupReplaySummary = await service.completeStartupReplay();
|
|
65307
66115
|
logWithTimestamp(
|
|
65308
66116
|
`[okx-agent-task] startup replay complete clients=${startupReplaySummary.clients} replayed=${startupReplaySummary.replayed} skipped=${startupReplaySummary.skipped} duration=${startupReplaySummary.durationMs}ms`
|
|
@@ -65440,7 +66248,7 @@ async function runListenerWithLock(options, paths) {
|
|
|
65440
66248
|
);
|
|
65441
66249
|
return;
|
|
65442
66250
|
}
|
|
65443
|
-
const replayResult = await timeSettled(() => service.replayOfflineMessages());
|
|
66251
|
+
const replayResult = await timeSettled(() => service.replayOfflineMessages("periodic_repair"));
|
|
65444
66252
|
const replayMs = replayResult.durationMs;
|
|
65445
66253
|
if (replayResult.error) {
|
|
65446
66254
|
logger.error(LogEvent.OFFLINE_REPLAY_FAILED, replayResult.error instanceof Error ? replayResult.error : new Error(String(replayResult.error)), {
|
|
@@ -65671,7 +66479,7 @@ async function timeSettled(fn) {
|
|
|
65671
66479
|
return { durationMs: Date.now() - startedAt, error };
|
|
65672
66480
|
}
|
|
65673
66481
|
}
|
|
65674
|
-
var import_node_fs25, import_promises13, import_node_os11, import_node_path30, DEFAULT_OFFLINE_REPLAY_INTERVAL_SEC, DEFAULT_XMTP_CLIENT_RECYCLE_INTERVAL_SEC, XMTP_CLIENT_RECYCLE_INTERVAL_ENV, HEARTBEAT_GATEWAY_CHECK_TIMEOUT_MS, SHUTDOWN_FORCE_RESOLVE_MS;
|
|
66482
|
+
var import_node_fs25, import_promises13, import_node_os11, import_node_path30, DEFAULT_OFFLINE_REPLAY_INTERVAL_SEC, DEFAULT_XMTP_CLIENT_RECYCLE_INTERVAL_SEC, XMTP_CLIENT_RECYCLE_INTERVAL_ENV, HEARTBEAT_GATEWAY_CHECK_TIMEOUT_MS, UPGRADE_RECOMMENDATION_IDEMPOTENCY_KEY, SHUTDOWN_FORCE_RESOLVE_MS;
|
|
65675
66483
|
var init_listener = __esm({
|
|
65676
66484
|
"src/listener.ts"() {
|
|
65677
66485
|
"use strict";
|
|
@@ -65682,6 +66490,7 @@ var init_listener = __esm({
|
|
|
65682
66490
|
import_node_path30 = require("node:path");
|
|
65683
66491
|
init_onchainos();
|
|
65684
66492
|
init_system_config();
|
|
66493
|
+
init_offline_replay_capability();
|
|
65685
66494
|
init_signer();
|
|
65686
66495
|
init_xmtp_sdk();
|
|
65687
66496
|
init_file_store();
|
|
@@ -65690,6 +66499,7 @@ var init_listener = __esm({
|
|
|
65690
66499
|
init_command_store();
|
|
65691
66500
|
init_ai_dispatch_queue();
|
|
65692
66501
|
init_message_handler();
|
|
66502
|
+
init_agent_message_notice();
|
|
65693
66503
|
init_paths();
|
|
65694
66504
|
init_user_attention_ipc();
|
|
65695
66505
|
init_user_attention_watchers();
|
|
@@ -65702,6 +66512,7 @@ var init_listener = __esm({
|
|
|
65702
66512
|
DEFAULT_XMTP_CLIENT_RECYCLE_INTERVAL_SEC = 6 * 60 * 60;
|
|
65703
66513
|
XMTP_CLIENT_RECYCLE_INTERVAL_ENV = "OKX_A2A_XMTP_CLIENT_RECYCLE_INTERVAL_SEC";
|
|
65704
66514
|
HEARTBEAT_GATEWAY_CHECK_TIMEOUT_MS = 2e3;
|
|
66515
|
+
UPGRADE_RECOMMENDATION_IDEMPOTENCY_KEY = "system:onchainos-offline-replay-upgrade";
|
|
65705
66516
|
SHUTDOWN_FORCE_RESOLVE_MS = 5e3;
|
|
65706
66517
|
}
|
|
65707
66518
|
});
|
|
@@ -65960,6 +66771,7 @@ function summarizeXmtpTestEvents(runId, events) {
|
|
|
65960
66771
|
const nodeDurations = /* @__PURE__ */ new Map();
|
|
65961
66772
|
const replayLags = /* @__PURE__ */ new Map();
|
|
65962
66773
|
const replayHandles = /* @__PURE__ */ new Map();
|
|
66774
|
+
const streamRecoveries = /* @__PURE__ */ new Map();
|
|
65963
66775
|
const agentMap = /* @__PURE__ */ new Map();
|
|
65964
66776
|
for (const event of events) {
|
|
65965
66777
|
const key = deliveryKey(event);
|
|
@@ -65992,6 +66804,18 @@ function summarizeXmtpTestEvents(runId, events) {
|
|
|
65992
66804
|
event.handlerTotalMs
|
|
65993
66805
|
);
|
|
65994
66806
|
}
|
|
66807
|
+
if (event.eventName === "Agent stream recovered") {
|
|
66808
|
+
setDuration(
|
|
66809
|
+
streamRecoveries,
|
|
66810
|
+
[
|
|
66811
|
+
eventAgentId(event),
|
|
66812
|
+
stringValue(event.clientGeneration) || "unknown-client",
|
|
66813
|
+
stringValue(event.recoverySequence) || "unknown-recovery",
|
|
66814
|
+
event.timestamp
|
|
66815
|
+
].join(":"),
|
|
66816
|
+
event.recoveryDurationMs
|
|
66817
|
+
);
|
|
66818
|
+
}
|
|
65995
66819
|
}
|
|
65996
66820
|
const agents = [...agentMap.entries()].filter(([, value]) => value.live.size > 0 || value.replay.size > 0).map(([agentId, value]) => {
|
|
65997
66821
|
const total = (/* @__PURE__ */ new Set([...value.live, ...value.replay])).size;
|
|
@@ -66013,7 +66837,9 @@ function summarizeXmtpTestEvents(runId, events) {
|
|
|
66013
66837
|
duplicateEvents: countEvent(events, "Inbound ignored: duplicate message"),
|
|
66014
66838
|
replayMessageFailures: countEvent(events, "Offline replay message failed"),
|
|
66015
66839
|
replayScanFailures: countEvent(events, "Offline replay failed"),
|
|
66016
|
-
streamFailures: countEvent(events, "conversations.stream failed") + countEvent(events, "
|
|
66840
|
+
streamFailures: countEvent(events, "conversations.stream failed") + countEvent(events, "agent stream error"),
|
|
66841
|
+
streamRecoveries: countEvent(events, "Agent stream recovered"),
|
|
66842
|
+
streamRecoveryTimeouts: countEvent(events, "Agent stream recovery timeout"),
|
|
66017
66843
|
connectionFailures: countEvent(events, "XMTP connection failed"),
|
|
66018
66844
|
successfulReplayScans: countEvent(events, "Address sync completed"),
|
|
66019
66845
|
replayScansWithMessages: events.filter((event) => event.eventName === "Address sync completed" && numericValue(event.replayed) > 0).length,
|
|
@@ -66021,6 +66847,7 @@ function summarizeXmtpTestEvents(runId, events) {
|
|
|
66021
66847
|
nodeHandlerMs: summarizeDurations([...nodeDurations.values()]),
|
|
66022
66848
|
replayLagMs: summarizeDurations([...replayLags.values()]),
|
|
66023
66849
|
replayHandleMs: summarizeDurations([...replayHandles.values()]),
|
|
66850
|
+
streamRecoveryMs: summarizeDurations([...streamRecoveries.values()]),
|
|
66024
66851
|
agents
|
|
66025
66852
|
};
|
|
66026
66853
|
}
|
|
@@ -66035,6 +66862,8 @@ Reliability
|
|
|
66035
66862
|
Replay message failures ${summary.replayMessageFailures}
|
|
66036
66863
|
Replay scan failures ${summary.replayScanFailures}
|
|
66037
66864
|
Stream failures ${summary.streamFailures}
|
|
66865
|
+
Stream recoveries ${summary.streamRecoveries}
|
|
66866
|
+
Recovery timeouts (>30s) ${summary.streamRecoveryTimeouts}
|
|
66038
66867
|
XMTP connection failures ${summary.connectionFailures}
|
|
66039
66868
|
Replay scans ${summary.successfulReplayScans}
|
|
66040
66869
|
Scans with replay ${summary.replayScansWithMessages}
|
|
@@ -66043,7 +66872,8 @@ Timing
|
|
|
66043
66872
|
XMTP delivery p50/p95/max ${formatDurationSummary(summary.xmtpDeliveryMs)}
|
|
66044
66873
|
Node handler p50/p95/max ${formatDurationSummary(summary.nodeHandlerMs)}
|
|
66045
66874
|
Replay lag p50/p95/max ${formatDurationSummary(summary.replayLagMs)}
|
|
66046
|
-
Replay handler p50/p95/max ${formatDurationSummary(summary.replayHandleMs)}
|
|
66875
|
+
Replay handler p50/p95/max ${formatDurationSummary(summary.replayHandleMs)}
|
|
66876
|
+
Stream recovery p50/p95/max ${formatDurationSummary(summary.streamRecoveryMs)}`);
|
|
66047
66877
|
if (summary.agents.length > 0) {
|
|
66048
66878
|
console.log("\nAgents");
|
|
66049
66879
|
for (const agent of summary.agents) {
|
|
@@ -113372,7 +114202,7 @@ async function getCurrentNodeCliVersion() {
|
|
|
113372
114202
|
return await getGlobalNpmPackageVersion(UPDATE_PACKAGES.node) ?? getBundledNodeCliVersion();
|
|
113373
114203
|
}
|
|
113374
114204
|
function getBundledNodeCliVersion() {
|
|
113375
|
-
return true ? "0.2.
|
|
114205
|
+
return true ? "0.2.1-beta-8ae7a0d300-260807181806" : null;
|
|
113376
114206
|
}
|
|
113377
114207
|
function readConfiguredAiProvider() {
|
|
113378
114208
|
const explicit = process.env.OKX_A2A_AI_PROVIDER || process.env.OKX_AGENT_TASK_AI_CLI;
|
|
@@ -113582,7 +114412,7 @@ async function updateHermes(release, options) {
|
|
|
113582
114412
|
}
|
|
113583
114413
|
}
|
|
113584
114414
|
async function installGatewayPluginForDoctor(target) {
|
|
113585
|
-
const release = isPrereleaseVersion("0.2.
|
|
114415
|
+
const release = isPrereleaseVersion("0.2.1-beta-8ae7a0d300-260807181806") ? "beta" : "latest";
|
|
113586
114416
|
const insideTargetGateway = detectGatewayInvocation() === target;
|
|
113587
114417
|
const options = {
|
|
113588
114418
|
restart: !insideTargetGateway,
|
|
@@ -114570,7 +115400,7 @@ async function runDoctor(options = {}) {
|
|
|
114570
115400
|
platform: options.platform ?? process.platform,
|
|
114571
115401
|
env: options.env ?? process.env,
|
|
114572
115402
|
target: options.target ?? resolveDoctorTarget(options.env ?? process.env),
|
|
114573
|
-
cliVersion: options.cliVersion ?? (true ? "0.2.
|
|
115403
|
+
cliVersion: options.cliVersion ?? (true ? "0.2.1-beta-8ae7a0d300-260807181806" : "0.0.0"),
|
|
114574
115404
|
fixMode: options.fix === true,
|
|
114575
115405
|
nonInteractive: options.nonInteractive === true,
|
|
114576
115406
|
packageChanged: false,
|
|
@@ -115538,7 +116368,7 @@ init_sentry_logger();
|
|
|
115538
116368
|
init_sentry_config();
|
|
115539
116369
|
var CURRENT_GATEWAY_SESSION_KEYS_ENV4 = "OKX_A2A_CURRENT_GATEWAY_SESSION_KEYS";
|
|
115540
116370
|
function printUsage3() {
|
|
115541
|
-
console.log(`okx-a2a ${"0.2.
|
|
116371
|
+
console.log(`okx-a2a ${"0.2.1-beta-8ae7a0d300-260807181806"}
|
|
115542
116372
|
|
|
115543
116373
|
Usage:
|
|
115544
116374
|
okx-a2a <command> [options]
|
|
@@ -115568,6 +116398,7 @@ Commands:
|
|
|
115568
116398
|
Alias for runtime switch-current
|
|
115569
116399
|
job-provider Manage job-to-provider bindings
|
|
115570
116400
|
xmtp-send Queue an XMTP message through the running daemon
|
|
116401
|
+
capabilities Print machine-readable A2A capability negotiation status (used by OnchainOS)
|
|
115571
116402
|
|
|
115572
116403
|
Global options:
|
|
115573
116404
|
-h, --help Show help
|
|
@@ -115577,7 +116408,7 @@ Run \`okx-a2a <command> -h\` for command-specific help.
|
|
|
115577
116408
|
`);
|
|
115578
116409
|
}
|
|
115579
116410
|
function printVersion() {
|
|
115580
|
-
console.log("0.2.
|
|
116411
|
+
console.log("0.2.1-beta-8ae7a0d300-260807181806");
|
|
115581
116412
|
}
|
|
115582
116413
|
function printDaemonUsage() {
|
|
115583
116414
|
console.log(`Usage: okx-a2a daemon <start|restart|stop|status|autostart> [options]
|
|
@@ -116924,6 +117755,11 @@ async function main() {
|
|
|
116924
117755
|
if (hasHelpFlag5(args) && !shouldDeferHelpToNestedHandler(command, args) && printCommandUsage(command)) {
|
|
116925
117756
|
return;
|
|
116926
117757
|
}
|
|
117758
|
+
if (command === "capabilities") {
|
|
117759
|
+
const { handleCapabilitiesCommand: handleCapabilitiesCommand2 } = await Promise.resolve().then(() => (init_capabilities_cli(), capabilities_cli_exports));
|
|
117760
|
+
handleCapabilitiesCommand2(process.argv.slice(3));
|
|
117761
|
+
return;
|
|
117762
|
+
}
|
|
116927
117763
|
if (command === "daemon") {
|
|
116928
117764
|
if (hasHelpFlag5(args)) {
|
|
116929
117765
|
printDaemonUsage();
|
|
@@ -116983,7 +117819,7 @@ async function main() {
|
|
|
116983
117819
|
if (command === "xmtp-test") {
|
|
116984
117820
|
const { handleXmtpTestCommand: handleXmtpTestCommand2 } = await Promise.resolve().then(() => (init_xmtp_test_cli(), xmtp_test_cli_exports));
|
|
116985
117821
|
await handleXmtpTestCommand2(process.argv.slice(3), {
|
|
116986
|
-
packageVersion: "0.2.
|
|
117822
|
+
packageVersion: "0.2.1-beta-8ae7a0d300-260807181806",
|
|
116987
117823
|
agentSdkVersion: "2.3.0",
|
|
116988
117824
|
nodeSdkVersion: "6.1.0",
|
|
116989
117825
|
nodeBindingsVersion: "1.11.0"
|